PR #277 · pramaan-io/pramaan-functions · merged 2026-06-08
Matter templates freeze every case at birth
snapshot tables, legacy shapes, locked composition
Lock the case to a frozen template version — forever.
The fix — Template is a recipe. Matter is the plate. Archive the recipe, never delete it while a plate still uses it.
sequenceDiagram autonumber participant cat as Catalog (recipe) participant kit as Service (kitchen) participant mat as Matter (plate) cat->>kit: create template → MT number kit->>kit: matter creation kit->>mat: copy template defaults mat->>mat: add filing / proceeding / label on the fly cat->>cat: archive (in-use safe) cat->>cat: delete (blocked if in use)
| Method | in → out | what it does |
|---|---|---|
_create_updated_at_trigger | (table_name) → None | |
_drop_updated_at_trigger | (table_name) → None | |
_replace_reference_kind_constraint | (include_matter_template) → None |
Alembic migration creating the new thin matter_templates catalog, three template default-link tables, three matter-owned copy tables, runtime tables, and per-matter RLS guards.
| new method | signature |
|---|---|
_create_updated_at_trigger | (table_name) → None |
_drop_updated_at_trigger | (table_name) → None |
_replace_reference_kind_constraint | (include_matter_template) → None |
_drop_policies | (table) → None |
_enable_catalog_rls | (table) → None |
_enable_matter_rls | (table, matter_expression) → None |
_add_staff_with_grant_select_policy | (table) → None |
_disable_rls_for_drop | (table) → None |
_create_matter_templates | () → None |
_create_template_link_tables | () → None |
_create_matter_copy_tables | () → None |
_create_runtime_tables | () → None |
_create_participant_summoner_trigger | (table_name) → None |
_upgrade_can_read_entity | () → None |
_downgrade_can_read_entity | () → None |
upgrade | () → None |
downgrade | () → None |
revision : strdown_revision : str | Sequence[str] | Nonebranch_labels : str | Sequence[str] | Nonedepends_on : str | Sequence[str] | NoneTemplate service: creates, updates, archives, deletes matter templates with duplicate-name checks, catalog-id validation, atomic link replacement, and in-use usage counting.
| new method | signature |
|---|---|
_current_user_id | (session) → UUID |
_dedupe | (ids) → list[UUID] |
_find_duplicate_name | (session, firm_id, name, excluding_template_id) → MatterTemplate | None |
_raise_if_name_conflict | (session, firm_id, name, excluding_template_id) → None |
_get_editable_template | (session, firm_id, matter_template_id) → MatterTemplate |
_validate_catalog_ids | (session, firm_id, entity, ids, field_name) → None |
_replace_links | (session, firm_id, template_id, filing_type_ids, proceeding_type_ids, participant_label_ids) → None |
_count_rows | (session, entity, firm_id, template_id) → int |
_usage_count | (session, firm_id, template_id) → int |
_list_item | (session, template) → MatterTemplateListItem |
_detail_view | (session, template) → MatterTemplateDetailView |
create_matter_template | (session, payload) → MatterTemplateDetailView |
update_matter_template | (session, matter_template_id, payload) → MatterTemplateDetailView |
archive_matter_template | (session, matter_template_id) → MatterTemplateDetailView |
unarchive_matter_template | (session, matter_template_id) → MatterTemplateDetailView |
delete_matter_template | (session, matter_template_id) → None |
Redesign service for add-on-the-fly matter-owned filing, proceeding, and participant-label rows, with live-source validation and display-order sequencing.
| new method | signature |
|---|---|
_snapshot_proceeding_kind_view | (row) → MatterSnapshotProceedingKindView |
_snapshot_filing_type_view | (row) → MatterSnapshotFilingTypeView |
get_template_snapshot | (session, matter_id) → MatterTemplateSnapshotView |
_next_display_order | (session, entity, firm_id, matter_id) → int |
_ensure_live_source | (session, entity, firm_id, source_id, field_name) → None |
_ensure_matter_owned_name_available | (session, entity, firm_id, matter_id, name, excluding_id) → None |
create_matter_filing_type | (session, matter_id, req) → MatterSnapshotFilingTypeView |
update_matter_filing_type | (matter_id, matter_filing_type_id, req) → MatterSnapshotFilingTypeView |
create_matter_proceeding_type | (session, matter_id, req) → MatterSnapshotProceedingKindView |
update_matter_proceeding_type | (session, matter_id, matter_proceeding_type_id, req) → MatterSnapshotProceedingKindView |
create_matter_participant_label | (req) → MatterParticipantLabelView |
update_matter_participant_label | (session, matter_id, matter_participant_label_id, req) → MatterParticipantLabelView |
src/domains/proceeding/service.py+399 −111Runtime logic for proceedings, participant-role assignment, and filings, with active-matter checks for type and label references.
| new method | signature |
|---|---|
_active_type_for_matter | (matter_proceeding_type_id) → MatterProceedingType |
_participant_role_view | (row, participant, label) → ProceedingParticipantRoleView |
_filing_view | (row, filing_type) → FilingView |
_active_participant | (session, firm_id, matter_id, participant_id) → MatterParticipant |
_active_participant_label | (session, firm_id, matter_id, participant_label_id) → MatterParticipantLabel |
_active_filing_type | (session, firm_id, matter_id, filing_type_id) → MatterFilingType |
list_participant_roles | (session, matter_id, proceeding_id) → ProceedingParticipantRoleListResponse |
assign_participant_role | (session, matter_id, proceeding_id, participant_id, req) → ProceedingParticipantRoleView |
list_filings | (session, matter_id, proceeding_id) → FilingListResponse |
create_filing | (session, matter_id, proceeding_id, req) → FilingView |
HTTP routes for the new matter-owned filing types, proceeding types, participant labels, per-proceeding participant roles, and per-proceeding filings.
| new method | signature |
|---|---|
create_matter_filing_type | (matter_id, req, db, _) → MatterSnapshotFilingTypeView |
update_matter_filing_type | (matter_id, matter_filing_type_id, req, db, _) → MatterSnapshotFilingTypeView |
create_matter_proceeding_type | (matter_id, req, db, _) → MatterSnapshotProceedingKindView |
update_matter_proceeding_type | (matter_id, matter_proceeding_type_id, req, db, _) → MatterSnapshotProceedingK |
create_matter_participant_label | (matter_id, req, db, _) → MatterParticipantLabelView |
update_matter_participant_label | (matter_id, matter_participant_label_id, req, db, _) → MatterParticipantLa |
list_matter_proceeding_participant_roles | (matter_id, proceeding_id, db) → ProceedingParticipantRoleListResponse |
assign_matter_proceeding_participant_role | async def assign_matter_proceeding_participant_role( matter_id: int, proceeding_id: UUID, participant_id: UUID, req: ProceedingParticipantRoleAssignRequest, db: AppDbDep, _: Annotated[None, Depends(require_permission("matters:write"))], ) - |
list_matter_proceeding_filings | (matter_id, proceeding_id, db) → FilingListResponse |
create_matter_proceeding_filing | (matter_id, proceeding_id, req, db, _) → FilingView |
src/domains/matter/entity.py+168 −223SQLAlchemy models for the matter-owned filing types, proceeding types, participant labels, and the new runtime proceeding-participant-role and filing rows.
| new class | signature |
|---|---|
MatterFilingType | (class) |
MatterProceedingType | (class) |
MatterParticipantLabel | (class) |
ProceedingParticipantRole | (class) |
Filing | (class) |
matter_template_id : UUID | Nonematter_template_name : str | Noneentity_id : UUID | Nonename : strsource_filing_type_id : UUID | Nonedescription : str | Nonestatus : strdisplay_order : intid : UUIDfirm_id : UUIDmatter_id : UUIDsource_proceeding_type_id : UUID | Nonesource_participant_label_id : UUID | Noneproceeding_id : UUIDparticipant_id : UUIDparticipant_label_id : UUIDfiling_type_id : UUIDtitle : strfiled_at : datetime | Nonecreated_by_user_id : UUID | Nonesrc/domains/matter/service.py+162 −62Matter creation logic that resolves a live template and copies its default filing, proceeding, and participant-label rows into the matter's own tables.
| new method | signature |
|---|---|
_get_live_template | (template_id) → MatterTemplate |
_copy_template_defaults | (session, firm_id, matter, template) → None |
src/domains/matter_type/entity.py+153 −184SQLAlchemy models for the thin MatterTemplate catalog row and the three default-link tables linking it to filing, proceeding, and participant-label catalog rows.
| new class | signature |
|---|---|
MatterTemplate | (type) |
MatterTemplateFilingType | (type) |
MatterTemplateProceedingType | (type) |
MatterTemplateParticipantLabel | (type) |
firm_id : UUIDmatter_template_number : intname : strdescription : str | Noneavailability : strcreated_by_user_id : UUID | Nonearchived_at : datetime | Nonearchived_by_user_id : UUID | Nonedeleted_at : datetime | Nonedeleted_by_user_id : UUID | Noneid : UUIDtemplate_id : UUIDfiling_type_id : UUIDdisplay_order : intproceeding_type_id : UUIDparticipant_label_id : UUIDPydantic request and view DTOs for matter template create, update, list, and detail, including availability enum, MT-number formatting, and usage flags.
| new class | signature |
|---|---|
MatterTemplateAvailability | (class) |
MatterTemplateCreateRequest | (class) |
_trim_name | (value) → str | None |
_trim_description | (value) → str | None |
MatterTemplateUpdateRequest | (class) |
MatterTemplateListItem | (class) |
MatterTemplateDetailView | (class) |
name : strdescription : str | Noneavailability : MatterTemplateAvailabilitydefault_filing_type_ids : list[UUID] | Nonedefault_proceeding_type_ids : list[UUID] | Nonedefault_participant_label_ids : list[UUID] | Noneid : UUIDfirm_id : UUIDmatter_template_number : intmatter_template_number_formatted : strfiling_type_count : intproceeding_type_count : intparticipant_label_count : intusage_count : intis_in_use : boolcan_delete : boolarchived_at : datetime | Nonearchived_by_user_id : UUID | Nonecreated_by_user_id : UUID | NoneHTTP routes for matter template CRUD, archive, unarchive, and delete operations guarded by permission checks.
| new method | signature |
|---|---|
create_matter_template | (req, db, _) → MatterTemplateDetailView |
update_matter_template | (matter_template_id, req, db, _) → MatterTemplateDetailView |
archive_matter_template | (matter_template_id, db, _) → MatterTemplateDetailView |
unarchive_matter_template | (matter_template_id, db, _) → MatterTemplateDetailView |
delete_matter_template | (matter_template_id, db, _) → Response |
Pydantic DTOs for per-proceeding participant-role assignment and matter-owned filing view, list, and create, including the filing status enum.
| new class | signature |
|---|---|
ProceedingParticipantRoleAssignRequest | (class) |
ProceedingParticipantRoleView | (class) |
ProceedingParticipantRoleListResponse | (class) |
FilingStatus | (class) |
FilingCreateRequest | (class) |
FilingView | (class) |
FilingListResponse | (class) |
matter_proceeding_type_id : UUIDproceeding_type_name : strparticipant_label_id : UUIDid : UUIDmatter_id : UUIDproceeding_id : UUIDparticipant_id : UUIDparticipant_name : strparticipant_label_name : strfiling_type_id : UUIDtitle : strfiled_at : datetime | Nonestatus : FilingStatusfiling_type_name : strcreated_by_user_id : UUID | NonePydantic DTOs for add-on-the-fly matter-owned filing, proceeding, and participant-label create and update requests.
| new class | signature |
|---|---|
MatterProceedingTypeCreateRequest | (class) |
MatterProceedingTypeUpdateRequest | (class) |
MatterFilingTypeCreateRequest | (class) |
MatterFilingTypeUpdateRequest | (class) |
MatterParticipantLabelCreateRequest | (class) |
MatterParticipantLabelUpdateRequest | (class) |
matter_template_id : UUID | Noneid : UUIDmatter_id : UUIDsource_proceeding_type_id : UUID | Nonename : str | Nonedescription : str | Nonestatus : MatterSnapshotVocabularyStatus | Nonedisplay_order : int | Nonesource_filing_type_id : UUID | Nonesource_participant_label_id : UUID | Nonetemplate_name : str | Nonesnapshot_reason : strMatter view DTO updated to surface source matter template id, copied template name, and a compatibility snapshot reason string.
matter_template_id : UUID | Nonematter_type_id : strmatter_template_name : str | Nonesrc/domains/proceeding/entity.py+17 −115Proceeding row updated to carry a per-proceeding matter_proceeding_type_id reference into the matter-owned proceeding type set.
matter_proceeding_type_id : UUIDSmall formatter that renders a firm-local template number into a display reference such as MT-001.
| new method | signature |
|---|---|
format_matter_template_ref | (number) → str |