Skip to content

fix(acceptance): type-correct valid samples & negatives (date fields → real dates; type beats name) - #212

Merged
agjs merged 5 commits into
mainfrom
fix/acceptance-date-valid-value
Jul 29, 2026
Merged

fix(acceptance): type-correct valid samples & negatives (date fields → real dates; type beats name)#212
agjs merged 5 commits into
mainfrom
fix/acceptance-date-valid-value

Conversation

@agjs

@agjs agjs commented Jul 29, 2026

Copy link
Copy Markdown
Owner

The wall

Live deep-chain build (Organization→Project→Task) parked the Task slice: fast gate green, but the e2e acceptance timed out with task-form never hiding. The build's own note guessed 'transient socket hang up' — but the boundary state (form stays visible) said the create was failing.

Root cause

validValue (acceptance-spec.ts) had no case for date types, so a dueDate field got the generic "dueDate-2" sample. That passes UI Zod (z.string) and API TypeBox (t.String), but the service inserts it into a timestamptz column → Postgres throws → 500 → create fails → form never closes → 10s waitFor(hidden) times out → false park.

Confirmed at the live DB:

'dueDate-3'::timestamptz  → ERROR: invalid input syntax for type timestamp
'2024-06-15'::timestamptz → 2024-06-15 00:00:00+00   (accepted)

Fix

  • validValue returns "2024-06-15" for date/datetime/timestamp types (date-only → substring-safe for the row-cell toContainText shows assertion).
  • Explicit field TYPE now beats name heuristics, applied symmetrically to validValue and negativesFor via a shared isEmailField helper: a date- or number-typed field named like an email (emailVerifiedAt, emailCount) is not treated as an email — otherwise the positive sample / not-an-email negative feeds a non-date/number value into a date/number column and 500s (same false-park class).

Tests

Date/datetime/timestamp valid samples with a strict UTC round-trip that rejects normalized-impossible dates (e.g. 2024-02-31); the emailVerifiedAt precedence in both the valid sample and the negatives array; a genuine-email positive control; and a number-named-email (emailCount) case.

Validation

  • 4-model panel: PASS (round 5; earlier rounds tightened test coverage + the negativesFor symmetry, all real findings).
  • Live projtracker rebuild for full 3/3 green: in progress (will comment).

Full suite: typecheck / lint / format clean, 3193 green.

Follow-ups (filed, not blocking)

agjs added 5 commits July 29, 2026 08:48
…idValue)

Live deep-chain build (Organization→Project→Task) parked Task: fast gate green but
e2e acceptance timed out with the task-form never hiding — i.e. the create was
failing, not a transient hiccup as the build's own note guessed.

Root cause: validValue (acceptance-spec.ts) had no case for date/datetime/timestamp
types, so a dueDate field got the generic '${name}-${seed}' sample ('dueDate-2').
That passes the UI Zod (z.string) and API TypeBox (t.String), but the service inserts
it into a timestamptz column and Postgres throws 'invalid input syntax for type
timestamp with time zone' -> create 500s -> onSuccess/closeForm never fires -> form
stays visible -> 10s waitFor(hidden) times out -> false park.

Confirmed at the boundary against the live DB:
  'dueDate-3'::timestamptz  -> ERROR: invalid input syntax
  '2024-06-15'::timestamptz -> 2024-06-15 00:00:00+00 (accepted)

Fix: validValue returns '2024-06-15' for date/datetime/timestamp types. Date-only so it
stays a substring of whatever timestamp representation the row cell renders back (the
shows assertion is toContainText). Boolean fields were already fine (checkbox path).

Regression test added. typecheck/lint/format clean, 3193/3206 suite green.

Follow-ups (filed): empty-optional-date '' also 500s a timestamptz insert (generated
form should coerce '' -> undefined for optional date/number); e2e seed resilience to
transient socket hang-ups / vitest worker timeouts under load.
…panel r1 finding)

- Exercise date, datetime AND timestamp (production branch handles all three).
- Replace the weak !isNaN(new Date()) check, which accepts normalized-impossible dates
  (new Date('2024-02-31') rolls to 2024-03-02), with a strict UTC round-trip that rejects
  them. Self-checks the checker rejects '2024-02-31' and accepts '2024-06-15'.
…lue (panel r2 finding)

A date-typed field whose NAME matches the email heuristic (emailVerifiedAt, lastEmailSentAt)
was getting user@example.com because the email name-check ran before the date-type branch —
an email string 500s a timestamp-column insert, the same false-park class. Reordered so
explicit type checks (email/number/date) run first, then name-based heuristics for string
fields. Test covers emailVerifiedAt(timestamp) → real date, not an email.
…esFor (panel r3 finding)

3 reviewers converged: negativesFor still used f.type === 'email' || /email/i.test(name), so a
date/number field named like an email (emailVerifiedAt) got a 'not-an-email' negative. That value
reaches a timestamp/number column → 500 (not the expected 400/422) → false park — the same class
validValue was just fixed for. Extracted a shared isEmailField(field) helper (explicit type wins
over name; number/date types are never email) and used it in BOTH validValue and negativesFor so
they can never disagree. Test asserts the negatives array: emailVerifiedAt(timestamp) gets NO
not-an-email negative, a real email field DOES (positive control).
…ype-precedence, panel r4)

isEmailField also guards number types (emailCount type=number → number sample + negative-number
negative, never email). Added that case to the regression suite: numeric valid value (no '@'),
no not-an-email negative, and the '-1' number negative present.
@agjs
agjs merged commit 80846b8 into main Jul 29, 2026
8 checks passed
@agjs
agjs deleted the fix/acceptance-date-valid-value branch July 29, 2026 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant