Remove redundant dfiq_type request field from DFIQ create/validate/patch - #1340
Merged
Conversation
Every DFIQ create/validate/patch request already carries the object's
type embedded in its dfiq_yaml body (`type: scenario|facet|question`).
The separate `dfiq_type` request field duplicated that:
- On /from_yaml and /validate, it only selected which pydantic subclass
parsed the YAML, and that subclass already re-checks its own `type:`
field and raises ValueError on mismatch -- so the parameter could
only ever agree with the YAML or cause a 400. DFIQBase.from_yaml
(used by the batch/feed ingestion path) already dispatches on the
YAML's own embedded type with no separate parameter, proving one
isn't needed here either.
- On PATCH /{id}, it was outright dead: the handler dispatches on
db_dfiq.type (the object's existing type from the database), never
reads request.dfiq_type, yet every caller was required to send it.
Switches /from_yaml and /validate to the existing generic
DFIQBase.from_yaml dispatcher, and drops dfiq_type from all three
request schemas (extra="forbid" means callers must stop sending it,
hence the test updates -- no test exercised type-mismatch behavior, so
this is a mechanical payload cleanup, not a coverage change).
Also tightens DFIQBase.from_yaml itself to parse via parse_yaml (which
every subclass's own from_yaml already does) instead of a bare
yaml.safe_load -- needed so a malformed/missing 'type' now raises the
same ValueError every other path already guarantees, rather than an
uncaught KeyError/YAMLError this generic dispatcher previously let
through (relevant now that /from_yaml and /validate lean on it more).
Paired with a frontend fix (yeti-feeds-frontend) that stops sending
dfiq_type and fixes a real UI inconsistency the same redundancy was
masking (Approaches tab and Parents field disagreeing about an
object's type when its raw YAML is hand-edited).
Verified: full tests/apiv2/dfiq.py (18/18) and tests/apiv2/timeline.py
pass; tests/schemas, tests/apiv2, tests/core_tests show zero new
failures vs a clean origin/main baseline (pre-existing environmental
failures only: bloomcheck config, missing system config, missing
default group seed data); ruff clean on all touched lines; confirmed
via generated OpenAPI schema that dfiq_type no longer appears on
NewDFIQRequest/DFIQValidateRequest/PatchDFIQRequest.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011tXLywVq32tGPE7jCrdZVJ
4 tasks
tomchop
commented
Aug 8, 2026
Comment on lines
+243
to
+247
| # parse_yaml (not a bare yaml.safe_load) so a malformed/missing/ | ||
| # unrecognized 'type' raises the same ValueError every subclass's own | ||
| # from_yaml already guarantees, instead of a KeyError/YAMLError this | ||
| # generic dispatcher used to let through uncaught. | ||
| yaml_data = cls.parse_yaml(yaml_string) |
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011tXLywVq32tGPE7jCrdZVJ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
dfiq_yamlbody (type: scenario|facet|question). The separatedfiq_typerequest field duplicated that:/from_yamland/validate, it only selected which pydantic subclass parsed the YAML, and that subclass already re-checks its owntype:field and raisesValueErroron mismatch -- so the parameter could only ever agree with the YAML or cause a 400.DFIQBase.from_yaml(used by the batch/feed ingestion path,read_from_data_directory) already dispatches on the YAML's own embedded type with no separate parameter, proving one isn't needed here either.PATCH /{id}, it was outright dead: the handler dispatches ondb_dfiq.type(the object's existing type from the database), never readsrequest.dfiq_type, yet every caller was required to send it (confirmed by grep -- only the two declaration lines referenced it)./from_yamland/validateto the existing genericDFIQBase.from_yamldispatcher, and dropsdfiq_typefrom all three request schemas.extra="forbid"on these models means callers must stop sending it, hence the mechanical test-payload cleanup (no test exercised type-mismatch behavior, so this isn't a coverage change).DFIQBase.from_yamlitself to parse viaparse_yaml(which every subclass's ownfrom_yamlalready does) instead of a bareyaml.safe_load-- needed so a malformed/missingtypenow raises the sameValueErrorevery other path already guarantees, rather than an uncaughtKeyError/YAMLErrorthis generic dispatcher previously let through. Relevant now that/from_yamland/validatelean on it more.Paired with a frontend fix ([yeti-feeds-frontend#TBD]) that stops sending
dfiq_typeand fixes a real UI inconsistency this same redundancy was masking: the frontend's ownlocalObject.typewas frozen at dialog-open time while the "Approaches" tab's visibility tracked the live YAML, so hand-editing the raw YAML tab'stype:field (a first-class, unguarded editing path) made the Approaches tab and the Parents field visibly disagree about the object's type.Test plan
tests/apiv2/dfiq.py-- 18/18 passtests/apiv2/timeline.py-- passtests/schemas,tests/apiv2,tests/core_tests) -- zero new failures vs a cleanorigin/mainbaseline run the same way (pre-existing environmental failures only: bloomcheck config, missingsystemconfig section, missing default-group seed data in this throwaway container -- confirmed identical failure count on baseline)ruff check/ruff format --checkclean on every touched line (repo has a large pre-existing lint backlog elsewhere, unrelated)dfiq_typeno longer appears onNewDFIQRequest/DFIQValidateRequest/PatchDFIQRequestdfiq_type, and toggling a Question's raw YAMLtype:tofacetcorrectly flips the Approaches tab and Parents field into agreement (previously they'd disagree)