[WIP] - Templates: redesign to the v1 API contract + visual layout support#596
Draft
chetanr25 wants to merge 13 commits into
Draft
[WIP] - Templates: redesign to the v1 API contract + visual layout support#596chetanr25 wants to merge 13 commits into
chetanr25 wants to merge 13 commits into
Conversation
a23ba45 to
0d0ef6f
Compare
…onical to incident form)
…n openapi contract
0d0ef6f to
f188299
Compare
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.
Templates: redesign to the v1 API contract + visual layout support
What this does
This rebuilds the whole templates layer to match the v1 API contract. The old prototype template endpoints are gone, and in their place there is a proper form template registry with the five contract endpoints, a service layer, a new DB model and migration, and strict request validation. I also updated the API contract itself while doing this, since two things in it needed fixing (a confusing name, and a missing piece that the visual editor on the website actually needs).
Closes the templates CRUD work (issue #549 / 08_templates_crud).
Why the old code had to go
The previous
app/api/routes/templates.pywas prototype code: upload a flat PDF, let the backend auto detect AcroForm widgets, store name/fields/pdf_path. The contract models a template completely differently. It is a registry keyed byform_typethat holds field definitions, validation rules, how each field maps from the incident schema, and (after this PR) where each field sits on the PDF. The form generation and extraction validation layers both depend on this shape, so it had to be redone before either of those can be built.Contract changes
Two edits to
contracts/:Renamed
canonicaltoincidenteverywhere it referred to the data schema.canonical_mappingbecameincident_mapping. The word "canonical" was accurate but kept tripping people up, and "incident" says exactly what it is (the FireForm incident schema). I left the broader "canonical" wording alone in the extraction/system specs where renaming it would read worse.Added visual layout to each field, which is the part the website template editor was already producing but the contract never had. Each
TemplateFieldnow carries a nestedlayoutobject withpage,x,y,width,height,font,font_size,color,align. Coordinates are in PDF points with the origin at the bottom left, so the box runs from start(x, y)to end(x + width, y + height). I also addedstatic_textfor fields that print fixed text instead of mapped data.While consolidating, I dropped the top level
field_mappings_from_incidentdict because it was just the inverse of the per fieldincident_mapping, so it was duplicate information.jurisdictionandagency_typeare now optional (the editor does not capture jurisdiction today), andform_typeis a plain string in the summary so custom jurisdictions likestate_texasvalidate.Endpoints
All five contract endpoints, live under
/api/v1/templates:GET /templateslists registered templates (summary view)POST /templatesregisters one, returns 201, returns 409 if theform_typealready exists
GET /templates/{id}returns the full templatePUT /templates/{id}replaces a templateGET /templates/{id}/fieldsreturns just the fields, with arequired_onlyquery flag
What got removed
app/api/routes/templates.pyis deleted along with its prototype routes (upload, preview, create, make-fillable, delete) and the schemas/repo helpers that only served them. The only forced change was the oldGET /templateslist, which saton the same path the contract list now owns.
The legacy
Templatemodel and table are kept on purpose. The fill pipeline (forms.py,jobs.py,tasks/fill.py) still reads from it, so removing it now would break those. They get replaced properly by the contract forms and input layers in later issues, so I left them alone here.Code structure
Kept to the project's routes to services to repositories layering:
app/api/routes/form_templates.pyis thin. Each handler is one call into the service.app/services/form_templates.pyholds the actual work: the 409/404 checks, building the ORM object, mapping the ORM back to the response schema, and therequired_onlyfiltering. It has no FastAPI imports.app/db/repositories.pygot theFormTemplatequeries.Model and migration
New
FormTemplatemodel with a UUID primary key, a uniqueform_type, the fields stored as JSON (each field carries its nested layout), and the usual status/version/timestamps.field_countandlast_updatedare derived in the response, not stored, so there is nothing to keep in sync.Migration
003_form_templatescreates theform_templatestable with a unique index onform_type.Note for reviewers: migration 003 was edited a couple of times while building this branch. That is fine here because it was never pushed before this PR and the only DB that ran it is my local dev one, which I re-ran from base each time. Once this merges it should be treated as frozen, and any further change goes in a new migration.
Fix: #549
Part of: #541