fix(timeline): harden curator event precision field
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 2m51s
CI / OCR Service Tests (pull_request) Successful in 24s
CI / Backend Unit Tests (pull_request) Successful in 4m35s
CI / fail2ban Regex (pull_request) Successful in 47s
CI / Semgrep Security Scan (pull_request) Successful in 23s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m7s
SDD Gate / RTM Check (pull_request) Successful in 13s
SDD Gate / Contract Validate (pull_request) Successful in 22s
SDD Gate / Constitution Impact (pull_request) Successful in 17s

- Validate the submitted precision against the DatePrecision allow-list in
  parseEventForm (falls back to DAY) so an untrusted token can't flow into
  the request body — symmetric with the existing `type` narrowing.
- Parameterize the precision input name via DatePrecisionField's new
  precisionInputName prop; the timeline form now submits `precision` instead
  of the misleading document-domain `metaDatePrecision`. Document form keeps
  the default, so its behaviour is unchanged.
- Capture EventTypeSelect's onchange into EventForm's `type` state so it no
  longer goes stale (the submitted value was already correct via the hidden
  input; this keeps the local state in sync).

Addresses PR #832 review (#781).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-13 23:22:11 +02:00
parent 9f17c4538f
commit cd5649b96e
4 changed files with 51 additions and 6 deletions

View File

@@ -16,7 +16,9 @@ import type { DatePrecision } from '$lib/shared/utils/documentDate';
* Exposed (shared contract — both WhoWhenSection and EventForm depend on it):
* - dateIso, precision, endDateIso — $bindable; the parent's binding IS the
* state (no redundant $state mirror).
* - dateInputName / endDateInputName — names of the hidden ISO inputs.
* - dateInputName / endDateInputName / precisionInputName — submitted field
* names; defaults match the document form (`metaDatePrecision`), the timeline
* form overrides precisionInputName to `precision`.
* - initialDateIso / suggestedDateIso — seeding inputs (see onMount + $effect).
* - dateTestId / precisionTestId / endDateInnerTestId — forwarded data-testid
* attributes so existing WhoWhenSection selectors survive the extraction.
@@ -28,6 +30,7 @@ let {
endDateIso = $bindable(''),
dateInputName = 'documentDate',
endDateInputName = 'metaDateEnd',
precisionInputName = 'metaDatePrecision',
initialDateIso = '',
suggestedDateIso = '',
dateLabel = m.form_label_date(),
@@ -41,6 +44,7 @@ let {
endDateIso?: string;
dateInputName?: string;
endDateInputName?: string;
precisionInputName?: string;
initialDateIso?: string;
suggestedDateIso?: string;
dateLabel?: string;
@@ -145,7 +149,7 @@ $effect(() => {
</label>
<select
id="{dateInputName}Precision"
name="metaDatePrecision"
name={precisionInputName}
bind:value={precision}
class="block min-h-[48px] w-full rounded border border-line px-2 py-3 text-sm shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring"
>