docs(form-builder): API.md Form Builder (Public), SCHEMA v2.1, ARCH §10.4, BACKLOG
S2c Phase 8.
- API.md: new **Form Builder (Public)** section documenting all 6
public endpoints (GET schema + time-slots + sections; POST draft,
PUT save, POST submit) with request/response examples, error codes,
and the identity_match / schema_drift contracts. No PII-echo noted
explicitly.
- SCHEMA.md bumped to v2.1:
- changelog entry for S2c.
- form_submissions table gains schema_version_at_open +
identity_match_status columns; UNIQUE (form_schema_id,
idempotency_key) replaces the composite index; a new composite
index (form_schema_id, identity_match_status) landed for the
organiser "pending-match" dashboard.
- ARCH-FORM-BUILDER.md bumped to v1.3 with new §10.4 "Public
submission lifecycle — draft/save/submit split" documenting the
three-endpoint contract, idempotency, schema-drift detection,
access rules, the standardised error envelope, and the dependency
data sub-endpoints.
- BACKLOG.md adds:
- FORM-04 (grace_days configurable — current implementation still
uses the hard-coded 7-day window)
- DOC-01 (Scramble / OpenAPI generator for API.md to reduce the
docs-drift effort going forward).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Crewli — Core Database Schema
|
||||
|
||||
> Source: Design Document v1.3 — Section 3.5
|
||||
> **Version: 2.0** — Updated April 2026
|
||||
> **Version: 2.1** — Updated April 2026
|
||||
>
|
||||
> **Changelog:**
|
||||
>
|
||||
@@ -26,6 +26,15 @@
|
||||
> Removed minimum volunteer hours threshold concept. Removed hardcoded
|
||||
> motivation form step. Moved payment status from fixed admin field to
|
||||
> dynamic registration field.
|
||||
> - v2.1: Public Form Builder API completion (S2c). Added columns on
|
||||
> `form_submissions`: `identity_match_status` (null|pending|matched|none,
|
||||
> populated by `TriggerPersonIdentityMatchOnFormSubmit` per ARCH §31.1)
|
||||
> and `schema_version_at_open` (stamped at draft-create for drift
|
||||
> detection). Replaced the composite index on
|
||||
> `(form_schema_id, idempotency_key)` with a UNIQUE constraint so the
|
||||
> DB is the race-safe backstop behind application-level idempotency
|
||||
> replay. Full public API contract: `/dev-docs/ARCH-FORM-BUILDER.md`
|
||||
> §10.4.
|
||||
> - v2.0: Universal Form Builder replaces event-scoped registration EAV
|
||||
> (S1 + S2a + S2b landed). Full architecture:
|
||||
> `/dev-docs/ARCH-FORM-BUILDER.md` v1.2.
|
||||
@@ -2034,6 +2043,7 @@ that aggregates the user's submitted, non-test `form_submissions`.
|
||||
| `reviewed_at` | timestamp nullable | |
|
||||
| `review_notes` | text nullable | |
|
||||
| `submitted_at` | timestamp nullable | |
|
||||
| `schema_version_at_open` | int unsigned null | **v2.1** `form_schemas.version` at draft-create; compared against `schema_version_at_submit` for drift detection (ARCH §10.4) |
|
||||
| `schema_version_at_submit` | int unsigned null | `form_schemas.version` at submit time |
|
||||
| `schema_snapshot` | JSON nullable | Full snapshot when policy dictates (ARCH §4.6.1 shape) |
|
||||
| `is_test` | bool | default: false — excluded from reporting & retention |
|
||||
@@ -2042,14 +2052,15 @@ that aggregates the user's submitted, non-test `form_submissions`.
|
||||
| `first_interacted_at` | timestamp nullable | First field focus |
|
||||
| `submission_duration_seconds` | int unsigned null | opened_at → submitted_at |
|
||||
| `auto_save_count` | int unsigned | default: 0 |
|
||||
| `idempotency_key` | ULID nullable | Duplicate-submit guard |
|
||||
| `idempotency_key` | ULID nullable | Duplicate-submit guard — UNIQUE `(form_schema_id, idempotency_key)` since v2.1 |
|
||||
| `anonymised_at` | timestamp nullable | |
|
||||
| `identity_match_status` | string(20) null | **v2.1** null\|pending\|matched\|none — written by `TriggerPersonIdentityMatchOnFormSubmit` (ARCH §31.1) |
|
||||
| `search_index` | mediumText null | Concatenated text of text-type values; FULLTEXT-indexed on MySQL when supported |
|
||||
| `created_at`, `updated_at` | timestamps | |
|
||||
| `deleted_at` | timestamp nullable | Soft delete |
|
||||
|
||||
**Relations:** `belongsTo` schema, submittedBy / reviewedBy (User); `morphsTo` subject; `hasMany` values, section statuses, delegations
|
||||
**Indexes:** `(form_schema_id, status)`, `(subject_type, subject_id)`, `(submitted_by_user_id)`, `(form_schema_id, review_status)`, `(form_schema_id, idempotency_key)`, `FULLTEXT(search_index)` (MySQL/InnoDB — best-effort, skipped gracefully on SQLite)
|
||||
**Indexes:** `(form_schema_id, status)`, `(subject_type, subject_id)`, `(submitted_by_user_id)`, `(form_schema_id, review_status)`, **UNIQUE** `(form_schema_id, idempotency_key)` (v2.1; replaced the non-unique composite index from v2.0), `(form_schema_id, identity_match_status)` (v2.1), `FULLTEXT(search_index)` (MySQL/InnoDB — best-effort, skipped gracefully on SQLite)
|
||||
**Events fired:** `FormSubmissionCreated`, `FormSubmissionDraftUpdated`, `FormSubmissionSubmitted`, `FormSubmissionReviewed`, `FormSubmissionSectionSubmitted`, `FormSubmissionSectionReviewed`, `FormSubmissionAnonymised`, `FormSubmissionArchived`, `FormSubmissionDeleted`
|
||||
**Soft delete:** yes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user