feat: allow 'answer' type in tree drafts, block on publish
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,13 @@ def validate_tree_structure(tree_structure: dict[str, Any]) -> tuple[bool, list[
|
||||
if "children" in tree_structure:
|
||||
_validate_children(tree_structure["children"], "root.children", errors)
|
||||
|
||||
# Block publish if any answer placeholder nodes remain
|
||||
if _has_answer_nodes(tree_structure):
|
||||
errors.append({
|
||||
"field": "tree_structure",
|
||||
"message": "Answer placeholders must be resolved to a node type before publishing."
|
||||
})
|
||||
|
||||
return len(errors) == 0, errors
|
||||
|
||||
|
||||
@@ -89,6 +96,10 @@ def _validate_node(node: dict[str, Any], path: str, errors: list[dict[str, str]]
|
||||
"message": "Solution nodes must have a non-empty solution"
|
||||
})
|
||||
|
||||
elif node_type == "answer":
|
||||
# Answer nodes are draft-only placeholders — no structural validation needed
|
||||
pass
|
||||
|
||||
else:
|
||||
errors.append({
|
||||
"field": f"{path}.type",
|
||||
@@ -115,6 +126,16 @@ def _validate_children(children: list[dict[str, Any]], path: str, errors: list[d
|
||||
_validate_children(child["children"], f"{child_path}.children", errors)
|
||||
|
||||
|
||||
def _has_answer_nodes(node: dict[str, Any]) -> bool:
|
||||
"""Recursively check if any node in the tree has type 'answer'."""
|
||||
if node.get("type") == "answer":
|
||||
return True
|
||||
for child in node.get("children", []):
|
||||
if _has_answer_nodes(child):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# --- Procedural Tree Validation ---
|
||||
|
||||
VALID_STEP_TYPES = {"procedure_step", "procedure_end", "section_header"}
|
||||
|
||||
Reference in New Issue
Block a user