ZDDC/zddc/internal/handler/default-mdl.form.yaml
ZDDC d35809cfd8 feat(forms): cascade-driven filename composition + audit on row create
Schemas:
- default-mdl.form.yaml: declare the six readOnly audit fields
  (created_at/by, updated_at/by, revision, previous_sha) so the form
  UI renders them disabled. additionalProperties: false is preserved;
  WriteWithHistory strips any client-supplied values before validation.
- default-rsk.form.yaml: overhaul to reflect the new shape. Each row
  now carries the table-tracking components (originator/phase?/project/
  area?/discipline/type/sequence/suffix?) plus a server-assigned `row`
  field; type is enum-locked to RSK to mirror the cascade's locked: rule.
  Drops the old `id` field (D-001/R-001-style identifiers are now
  composed from the components and stored in the filename).
- default-ssr.form.yaml: append the six audit fields.

Handlers:
- serveFormCreateSSR routes the write through WriteWithHistory so
  audit fields are stamped on first create (revision=1, created_*=
  updated_*=request principal/now). ssr.yaml's identity stays the
  party folder name; no filename composition runs.
- serveFormCreateRollup now resolves the cascade at the row's parent
  folder and uses the matched records: entry's filename_format to
  compose the row filename from body fields. For RSK rows the rule
  carries row_field+row_scope_fields, so the server auto-assigns the
  next sequence (001, 002, ...) within the table-tracking group and
  injects it into the body before composition. Defaults from
  field_defaults: are injected where the client omitted them
  (type=RSK locks in via the locked: list). Falls back to the
  historical date+email naming only when no records: rule is in
  scope (covers deployments that override defaults.zddc.yaml without
  declaring their own records: entries).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 09:55:07 -05:00

136 lines
4.7 KiB
YAML

# Default row schema for a Master Deliverables List entry, served by
# zddc-server when no operator-supplied form.yaml exists at
# archive/<party>/mdl/.
#
# Properties cover every component of the ZDDC tracking-number model
# (zddc.varasys.io/reference.html#tracking-numbers) plus the standard
# MDL metadata (title, planned revision, planned date, status, owner,
# notes). The schema is intentionally permissive on the components
# (free-text strings, no regex / enum constraints) — projects choose
# their own conventions for originator codes, discipline vocabularies,
# etc., and a default that imposed a fixed set would just get in the
# way. Tightening per project is done via .zddc field_codes:, which
# the cascade resolves before the form is rendered.
#
# The six audit fields at the bottom are server-managed: clients must
# render them as read-only and never submit values for them.
# WriteWithHistory strips any client-supplied audit fields before
# schema validation and re-injects the authoritative values.
#
# To customize: drop your own form.yaml into archive/<party>/mdl/
# (the same directory as table.yaml). Tighten constraints with
# `enum:`, `pattern:`, `minLength:`, etc. Add fields and they'll
# appear in the row-edit form; add a matching column to table.yaml
# to surface the field in the table view too.
title: Deliverable
description: One planned or in-flight deliverable. The first eight fields are components of this row's tracking number; the rest are deliverable metadata.
schema:
type: object
required: [originator, project, discipline, type, sequence, title]
additionalProperties: false
properties:
# --- Tracking-number components (matches the reference doc's
# field definitions, in order). originator / project / discipline
# / type / sequence are the structural minimum; phase / area /
# suffix are optional and project-dependent.
originator:
type: string
title: Originator
description: Organizational unit responsible for this deliverable (e.g. ACME).
minLength: 1
phase:
type: string
title: Phase
description: Optional project phase code (e.g. ECI, EPC). Leave blank if your tracking-number schema doesn't use phases.
project:
type: string
title: Project
description: Project identifier, or your corporate placeholder (e.g. 000000) for non-project deliverables.
minLength: 1
area:
type: string
title: Area
description: Optional area / budget code (e.g. B02). Leave blank if unused.
discipline:
type: string
title: Discipline
description: Engineering or functional group code (EL, ME, CV, PM, ...).
minLength: 1
type:
type: string
title: Document type
description: Document category code within the discipline (SPC, DWG, RPT, ...).
minLength: 1
sequence:
type: string
title: Sequence
description: Zero-padded integer (0001, 0042, 2623). Stored as a string so leading zeros survive YAML.
minLength: 1
suffix:
type: string
title: Suffix
description: Optional structural-part suffix (-A for Appendix A, -01 for Sheet 1). Use only for parts of the SAME deliverable; separate documents get their own tracking number.
# --- Deliverable metadata.
title:
type: string
title: Deliverable title
minLength: 1
plannedRevision:
type: string
title: Planned revision
description: Issue revision label, e.g. A, B, IFR, IFC.
plannedDate:
type: string
title: Planned date
format: date
status:
type: string
title: Current status
enum: [DFT, IFR, IFA, IFC, AFC, AB]
owner:
type: string
title: Owner
description: Email or party name responsible for producing this row.
notes:
type: string
title: Notes
# --- Audit fields (server-managed; clients must not submit
# values). WriteWithHistory strips any client-supplied versions
# before validation and re-injects authoritative values.
created_at:
type: string
title: Created
format: date-time
readOnly: true
created_by:
type: string
title: Created by
format: email
readOnly: true
updated_at:
type: string
title: Updated
format: date-time
readOnly: true
updated_by:
type: string
title: Updated by
format: email
readOnly: true
revision:
type: integer
title: Revision
minimum: 1
readOnly: true
previous_sha:
type: string
title: Previous SHA
description: SHA-256 (first 8 hex chars) of the prior revision's bytes.
readOnly: true
ui:
notes:
ui:widget: textarea