Skip to content

feat(codegen-ts)!: derive native uuid[]/text[] from isArray; drop uuid_array/text_array dbColumnType values (phase 1)#118

Closed
dmealing wants to merge 1 commit into
mainfrom
feat/dbcoltype-phase1-ts
Closed

feat(codegen-ts)!: derive native uuid[]/text[] from isArray; drop uuid_array/text_array dbColumnType values (phase 1)#118
dmealing wants to merge 1 commit into
mainfrom
feat/dbcoltype-phase1-ts

Conversation

@dmealing

@dmealing dmealing commented Jun 30, 2026

Copy link
Copy Markdown
Member

dbColumnType slim-and-derive — Phase 1 (TypeScript + migrate-ts)

Applies the project's derive-don't-declare principle (ADR-0023) to the @dbColumnType escape hatch. The array-ness of a column already lives on the field's isArray axis, so native Postgres arrays are derived, not declared. Breaking metamodel-vocabulary change, scoped to the pre-1.0 consolidation window.

Per the design spec (docs/superpowers/specs/2026-06-29-dbcolumntype-slim-and-derive-design.md), this PR is only the TS port + migrate-ts. Other ports and the shared fixtures/ corpora are coordinated separately.

The change

  • Vocab (metadata/db-constants.ts): removed uuid_array + text_array from DB_COLUMN_TYPE_VALUES + DB_COLUMN_TYPE_LEGAL_SUBTYPES. The loader now rejects both (ERR_BAD_ATTR_VALUE). Constants stay exported. Kept uuid / jsonb / timestamp_with_tz (the timestamp_with_tz default-flip is Phase 2).
  • migrate-ts (canonical DDL): subtypeToSqlType now derives native arrays from isArrayfield.string isArray → text[], field.uuid isArray → uuid[] — via a small arrayElementSqlType helper; dropped the retired uuid_array/text_array overrides. Scalar field.uuiduuid, no-maxLength field.stringtext (unchanged).
  • Description text left unchanged on purpose. The @dbColumnType attr description is carried verbatim in two shared cross-port fixtures (fixtures/registry-conformance/expected-registry.json, fixtures/metamodel-docs/expected/). Those are coordinated separately, so this PR does not edit the description (the loader-level value-set enforcement is in db-constants.ts, independent of the doc text). A follow-up alongside the other ports can refresh the description + those fixtures.

What TS already did vs the field.uuid[] question

  • field.uuid scalar was already handled → uuid() column (not a gap, contrary to the worst case the brief flagged).
  • field.uuid + isArray already emits uuid() + .array() (= uuid[]) via the column-mapper's scalar-array path (uuid is neither object nor map), and field.string + isArray already emits text[]. No column-mapper change was needed — added explicit test coverage to lock it in.
  • field.string no-maxLengthtext, with maxLengthvarchar(N): already correct, confirmed.
  • The only real fix was in migrate-ts, where native arrays were only reachable through the now-removed *_array overrides — isArray was never consulted. Now derived.

Test evidence

  • Targeted unit suites green: metadata attr-schema-validate (incl. new uuid_array/text_arrayERR_BAD_ATTR_VALUE cases) + db-definition-completeness; codegen-ts column-mapper (new field.uuid/field.string isArray → uuid[]/text[]); migrate-ts expected-schema (derived arrays, scalar uuid/text, removed-value rejection). Plus the registry-conformance + metamodel-docs byte-gates stay green (description left unchanged). 131/131 across those 6 suites.
  • typecheck clean for metadata / codegen-ts / migrate-ts; pre-push CI-parity build+typecheck gate passed.
  • Canonical schema.postgres.sql is unchanged — no persistence fixture exercises native arrays, so removing the overrides produces no diff in the committed canonical schema.

Part of dbColumnType slim-and-derive Phase 1.

🤖 Generated with Claude Code

…d_array/text_array dbColumnType values (phase 1)

dbColumnType slim-and-derive Phase 1 (TS port + migrate-ts). Applies the
project's derive-don't-declare principle (ADR-0023) to the @dbColumnType escape
hatch: the array-ness of a column already lives on the field's isArray axis, so
native Postgres arrays are DERIVED, never declared.

- metadata: remove uuid_array/text_array from the legal @dbColumnType value-set
  (DB_COLUMN_TYPE_VALUES + DB_COLUMN_TYPE_LEGAL_SUBTYPES). Both now fail the
  loader (ERR_BAD_ATTR_VALUE). Constants kept exported. Keeps uuid/jsonb/
  timestamp_with_tz (timestamp_with_tz default flip is Phase 2). The shared
  attr-description text (registry-conformance + metamodel-docs fixtures) is left
  unchanged — those cross-port fixtures are coordinated separately.
- migrate-ts: derive native text[]/uuid[] from isArray on field.string/
  field.uuid in subtypeToSqlType; drop the retired array overrides. Scalar
  field.uuid -> uuid, no-maxLength field.string -> text (unchanged).
- codegen-ts: field.uuid scalar already maps to uuid(); field.uuid + isArray and
  field.string + isArray already emit .array() via the scalar-array path -> no
  column-mapper change needed; added explicit coverage. field.uuid was NOT a gap.

Tests: targeted unit suites green (metadata attr-schema-validate + db-definition-
completeness, codegen-ts column-mapper, migrate-ts expected-schema) plus the
registry-conformance + metamodel-docs byte-gates; typecheck clean for
metadata/codegen-ts/migrate-ts. No persistence fixture uses native arrays, so the
committed canonical schema.postgres.sql is unchanged.

Part of #dbcoltype-phase1

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuZWKnWzYGVnESijL7uuky
@dmealing

Copy link
Copy Markdown
Member Author

Folded into the integrated Phase-1 PR (feat/dbcolumntype-slim-derive) which merges all five ports atomically — that's the one that lands. Keeping this open for per-port review history.

@dmealing

Copy link
Copy Markdown
Member Author

Landed via the integrated Phase-1 PR #121 (squash-merged to main).

@dmealing dmealing closed this Jun 30, 2026
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