# @platform-modules/forms

## 0.3.0

### Minor Changes

- ee63372: Generate `uuid` and `createdAt`/`updatedAt` column defaults client-side so inserts work on SQLite/D1 as well as Postgres.

  `.defaultRandom()` and `.defaultNow()` declare a *database-side* default, and drizzle inlines that default's SQL into the INSERT. Under the SQLite dialect that emits `values (gen_random_uuid(), …, now())` — neither function exists in SQLite, so every insert into an affected table fails at runtime with `no such function`. On mod-cms, where D1 is the default database, that meant creating a content entry, a revision, a taxonomy term, a form submission, a field value or a translation was impossible; the audit insert failed the same way but is swallowed by `logAudit`, so audit logging silently did nothing.

  The columns now use `$defaultFn` alone. `$defaultFn` binds the value as a parameter from the runtime, which both dialects accept.

  `.defaultRandom().$defaultFn(…)` does **not** work — the SQL default takes precedence and the function never runs. `@platform-modules/i18n-content` carried that combination on `translationValue.id` and was still emitting `gen_random_uuid()`; it is corrected here.

  Hand-written DDL is unchanged, so Postgres columns keep their `DEFAULT gen_random_uuid()` / `DEFAULT now()` and any direct-SQL insert path behaves exactly as before. No package in this repo generates DDL from these schemas.

  One behavioral note at the seam: timestamps now come from the application clock rather than the database clock. Keyset pagination over `createdAt` assumes a monotonic clock, so a writer with backward clock skew can insert a row that sorts behind an already-served page boundary and is not returned by the listing.

### Patch Changes

- Updated dependencies [fd62ea1]
- Updated dependencies [1fd8651]
  - @platform-modules/util@0.4.0
  - @platform-modules/db@0.4.0

## 0.2.3

### Patch Changes

- Updated dependencies [df32439]
  - @platform-modules/db@0.3.0

## 0.2.2

### Patch Changes

- Updated dependencies [a708afa]
  - @platform-modules/util@0.3.0
  - @platform-modules/db@0.2.2

## 0.2.1

### Patch Changes

- Updated dependencies [7d474ec]
  - @platform-modules/util@0.2.0
  - @platform-modules/db@0.2.1

## 0.2.0

### Minor Changes

- 267d3fb: Add `formsTableSql()` — idempotent DDL helper emitting `CREATE TABLE IF NOT EXISTS form_submissions` plus the `(form_id, created_at DESC)` index, matching `schema.ts` exactly. Hosts provision schema per-statement-split on neon-http (same pattern as `commentsTableSql`).

## 0.1.0

### Minor Changes

- ed93ce1: New module `@platform-modules/forms` (L2) — typed form schema + validate-then-store pipeline behind a db-agnostic store seam + an anti-spam seam. Web-standard core, validator-agnostic (no Zod baked). Subpaths: `.` (defineForm + validateSubmission, import-light) · `./antispam` (honeypot + HMAC-signed time-trap + challenge seam) · `./store` (SubmissionStore contract + db reference adapter + recordSubmission). Validation is a Hard floor (drops undeclared keys, default per-field payload cap); anti-spam FLAGS not drops (data-loss floor); store reads are formId-scoped (IDOR floor).

### Patch Changes

- Updated dependencies [f895518]
- Updated dependencies [c80eaad]
- Updated dependencies [324de71]
  - @platform-modules/db@0.2.0
  - @platform-modules/util@0.1.0
