Specira sample artefact. Rendered from the governed default template on a fictional company. Names, figures and dates are illustrative.All artefacts →
SAMPLE
seeded demo data · specira.ai
Specira Data Model: Governed Template Rendering
Governed template rendering reference: Data Model default v2 (draft) definition 2a229c81…ffd0
Data Model · Project artifact SPECIRA

Data Model: Dispatch Modernization

Meridian Field Services: instructional example, not project evidence

Draft · watermark policy: draft_only template data_model v2 · pack: specira_default_delivery depth: standard
§1

Entity Relationship Views

mandatory 1 decision1 evidence rule validators: diagram_entity_cap_split_never_shrink · views_reconcile_with_architecture_inventory_both_ways

One view per bounded context, generated from versioned source: eight to ten entities per view, split by aggregate past the cap. The diagram carries structure, keys, and cardinality; precision, defaults, and enums live in the field tables a diagram cannot express. System-of-record stays the architecture's decision.

holds zero or many

receives

reports via vehicle

explains override

JOB

uuid

id

PK

text

skill_required

text

priority

text

status

text

source_system

transitional · pilot only

timestamptz

created_at

ASSIGNMENT

uuid

event_id

PK

uuid

job_id

FK

text

technician_id

FK

text

reason_code

FK

null = accepted suggestion

varchar_250

note

timestamptz

created_at

TECHNICIAN

text

hr_id

PK

read copy · SoR is Meridian HR

text

name

text

certifications

POSITION

text

vehicle_id

PK

timestamptz

observed_at

PK

decimal_9_6

lat

decimal_9_6

lon

boolean

stale_flag

REASONCODE

text

code

PK

RC-01..RC-06 governed list

text

meaning

Dispatch core: five entities, under the cap; crow's foot cardinality; generated from dispatch-core.mmd, stamped 2026-07-16. Fallback: Job holds zero-or-many Assignments; Technician receives Assignments and reports Positions via vehicle; ReasonCode optionally explains an override. Inventory reconciles with the architecture's data chapter[1] both ways; Job's pilot-to-cutover authority is cited there, never re-decided here.

§2

Entities, Keys & Conventions

mandatory 2 decisions1 evidence rule validators: every_pk_strategy_stated_natural_or_surrogate · convention_block_present_audit_delete_tenancy

Conventions stated once (audit, delete policy, tenancy), then per entity the key strategy and what it means. Business meaning links to the glossary; this document owns structure.

Conventions: once, uniformly Audit: created_at and created_by on every table; assignments are event-sourced and immutable: no updated_at there (deviation recorded). Delete policy: soft delete nowhere; positions hard-purge at 30 days per the architecture lifecycle (cited[1]). Tenancy: single-tenant enterprise deployment, no isolation column, stated.
EntityPK strategyWhyBusiness meaning
Assignmentsurrogate event_id Natural key job-plus-sequence rejected: replay ordering TERM-001[4]
Jobsurrogate id Lifecycle states created → assigned → completed → archived TERM-009[4]
Positionnatural (vehicle_id, observed_at) Readings are immutable facts TERM-012[4]
ReasonCodenatural code Governed list: the code is the identity TERM-004[4]
Techniciannatural hr_id Read copy; system of record is Meridian HR (architecture[1]) none
§3

Field Specifications

mandatory 1 decision1 evidence rule validators: every_field_has_type_nullability_default_sensitivity · no_tautological_field_description

Per field: type with precision, nullability and default stated (a blank cell is a gap), sensitivity citing the governing classification, source, and a description that adds meaning beyond the name. Every entity is fully specified, one table each.

Assignment

FieldTypeNull / defaultSensitivitySourceDescription (meaning beyond the name)
event_iduuid PK not null / generatedinternalsystem Surrogate event identity; ordering key for replay
job_iduuid FK not null / no defaultinternalsystem The job this event binds; partial-unique enforces one active per job (§5)
technician_idtext FK not null / no defaultinternalsystem The technician bound: HR id, read copy keyed (§2)
reason_codetext FK nullable / no defaultinternaluser-entered on override Why the dispatcher overrode; null means an accepted suggestion, never a blank string; immutable after write
notevarchar(250) nullable / no defaultinternaluser-entered Optional override context; the 250 boundary is the story's tested edge (US-3 row AT-3[3])
created_at / created_bytimestamptz · text not null / now · sessioninternalsystem The audit convention (§2); events are immutable, so no updated columns

Job

FieldTypeNull / defaultSensitivitySourceDescription
iduuid PK not null / generatedinternalsystem Surrogate; the customer-facing job number is presentation, not identity
skill_requiredtext not null / no defaultinternaluser-entered at intake Validated against the skill taxonomy; unknown values reject at intake (ERR-02/03[5])
prioritytext not null / routineinternaluser-entered Drives queue order; priority jobs pin above routine regardless of age
statustext (app constant, §6) not null / createdinternalsystem Lifecycle state; transitions are code-governed, not data-governed
source_systemtext nullable / no defaultinternalintegration (INT-3) Transitional pilot marker; removal trigger in §8
address / lat / lontext · decimal(9,6) not null / no defaultconfidentialuser-entered Service location: customer site, not technician position; distinct sensitivity class

Position · ReasonCode · Technician

FieldTypeNull / defaultSensitivitySourceDescription
Position.vehicle_id + observed_at text · timestamptz, composite PK not null / no defaultinternalintegration (INT-1) Natural key: readings are immutable facts; staleness computes from observed_at, never arrival time
Position.lat / londecimal(9,6) not null / no defaultpersonal-restricted, per classification[2] integration Vehicle reading, never a technician's assignment state: the disambiguation the data contract enforces (TERM-012[4])
Position.stale_flagboolean not null / falseinternalcalculated at adapter True past 60 seconds: the honesty bit the board must render
ReasonCode.code / meaningtext PK · text not null / no defaultinternalseed data (§6) RC-01…RC-06; a code in use retires in its list, never deletes
Technician.hr_id / name / certifications text PK · text · text not null / no defaultconfidentialintegration (Meridian HR) Read copy, one-hour freshness; the system of record is HR (§2); certifications gate suggestion eligibility (FR-013[5])

Agent export carries the schema as data, the consolidated DBML block beside these tables (excerpt):

Table assignment { event_id uuid [pk] job_id uuid [ref: > job.id, not null] technician_id text [ref: > technician.hr_id, not null] reason_code text [ref: > reason_code.code, null] note varchar(250) [null, note: 'check length <= 250'] created_at timestamptz [not null] }
§4

Relationships & Cardinality

mandatory 2 decisions1 evidence rule validators: every_relationship_has_bidirectional_cardinality_and_on_delete · polymorphic_references_are_justified_exceptions
RelationshipCardinality (both ways)On deleteNote
Job · Assignment one job holds zero-or-many assignment events; each event belongs to exactly one job restrict; jobs archive, never cascadeidentifying
Technician · Assignment one-to-zero-or-many / exactly-onerestrictnone
Technician · Position one-to-zero-or-many via vehicle mapping scheduled purge, not cascadenon-identifying
ReasonCode · Assignment zero-or-one / zero-or-many restrict; a code in use retires in its list, never deletesnone

No junction tables; no polymorphic references. Stated, so their absence is a fact and not a gap.

§5

Constraints & Invariants

mandatory 1 decision1 evidence rule validator: frd_rule_realizations_cite_both_ways

Invariants beyond keys, each in business terms and its enforcement form. The FRD owns the business rule; this section owns its storage realization; the two cite each other, neither restates.

Invariant (business terms)EnforcementHandshake
One active assignment per job partial unique index on assignments(job_id) where active FR-010[5] cites this row; this row cites FR-010
Override note never exceeds 250 characters check length(note) ≤ 250 FR-012 fit criterion[5]
Reason code required on the override path application-enforced; the rule spans the override flag enforcement split recorded, with reason
§6

Enumerations & Reference Data

mandatory 1 decision1 evidence rule validator: every_enum_list_has_owner_and_storage_decision
ListStorageOwner (adds values)Values
ReasonCodereference table, ships as seed data Product lead; additions are a product decision (open question OQ-2[5]) RC-01 … RC-06, meanings in the table
Job lifecycle statesapplication constant Engineering lead; states change with code, not configuration created · assigned · completed · archived

No other closed lists exist; stated.

§7

Indexing Strategy

mandatory 2 decisions1 evidence rule validators: every_index_row_cites_access_pattern · every_fk_indexed_or_exception_justified

Every index cites the access pattern it serves; "performance" is not a pattern. Volumetrics appear exactly where they drove a decision.

IndexAccess pattern servedTrade acknowledged
assignments(job_id) partial unique where active Idempotent acceptance (AC-010[5]; US-2 row AT-2[3]) none
positions(vehicle_id, observed_at desc) Latest-position reads at 400 rows/min peak (scale frame[1]) Write cost on an append-heavy table, seen and accepted; ~500k rows/month before purge drove this composite and the 30-day cadence (volumetric note[6])
assignments(technician_id, created_at) Day-view timeline (mobile flow[5]) none

All foreign keys indexed; no exceptions this project.

§8

Migration & Versioning

conditional · engaged: job authority moves at cutover 1 decision1 evidence rule validator: transitional_structures_carry_removal_triggers

Policy: expand-and-contract; breaking changes to consumer-visible structures owe the field-tools team 90 days notice (API surface[1]).

Transitional: named so temporary cannot become permanent jobs.source_system exists during pilot to mark scheduler-mastered rows; removal trigger: cutover day plus one verification cycle (Pilot cutover plan[7]).
§9

Open Questions

mandatory1 decision
QuestionOwnerAnswer byBlocks
Does assignment archival move to cold storage at year two of the seven-year retention? E. SandovalSep 15, 2026 The archival index decision only (lifecycle[1])

Omission note (how §8 renders on a greenfield project): "§8 Migration & Versioning omitted: pre-launch greenfield schema, no live consumers. Rationale recorded in adaptation event #2."

Refs

References & Package Contents

In this export package

package [5] Functional spec: Recommendation rules (FR ids, validation rules) ./frd-recommendation-rules.docx
package [6] Volumetric note: position growth and purge cadence ./analyses/position-volumetrics.html

In the Specira workspace

specira [1] Architecture: data chapter (system of record, lifecycle, contracts, scale) app.specira.ai/projects/dispatch-modernization/artifacts/architecture#data
specira [2] Security requirements: data protection classification app.specira.ai/projects/dispatch-modernization/artifacts/security-requirements#data-protection
specira [3] Story set: assignment recommendations (US-2, US-3 rows) app.specira.ai/projects/dispatch-modernization/artifacts/user-stories
specira [4] Glossary: governed terms (TERM ids) app.specira.ai/projects/dispatch-modernization/artifacts/glossary
specira [7] Decision: pilot cutover plan (job authority transfer) app.specira.ai/projects/dispatch-modernization/decisions/93
Generated by Specira · template data_model v2 (draft) · pack specira_default_delivery lineage 2a229c81…ffd0 · page 1 of 9