Skip to content

feat!: migrate to pnpm workspaces monorepo with Aurora DSQL and Drizzle ORM#126

Draft
konokenj wants to merge 13 commits intomainfrom
dev/v3
Draft

feat!: migrate to pnpm workspaces monorepo with Aurora DSQL and Drizzle ORM#126
konokenj wants to merge 13 commits intomainfrom
dev/v3

Conversation

@konokenj
Copy link
Contributor

WIP: pnpm workspaces monorepo + Aurora DSQL + Drizzle ORM migration.

Closes #98, closes #91.

See .kiro/specs/pnpm-workspaces/plan.md for full design.

konokenj added 13 commits March 20, 2026 20:47
…le ORM

Replace the single-package npm project with a pnpm workspaces monorepo,
migrate from Aurora Serverless v2 + Prisma to Aurora DSQL + Drizzle ORM,
and replace ESLint + Prettier with oxlint + oxfmt.

Architecture:
- apps/webapp (Next.js), apps/async-job (Lambda), apps/cdk (CDK infra)
- packages/db (Drizzle schema, DSQL client, migration runner)
- packages/shared-types (job payload Zod schemas)

Database:
- Aurora DSQL with IAM auth (no VPC, no NAT, no Bastion)
- Drizzle ORM with relations() for joins (no FK, DSQL constraint)
- Custom migration runner: hash verification, 1 DDL/tx, DSQL SQL validation
- dsql-migrator CDK Construct: Docker Lambda + CDK Trigger for deploy-time migration

Tooling:
- oxlint with type-aware linting (oxlint-tsgolint) replaces ESLint + tsc --noEmit
- oxfmt with .oxfmtrc.json matching original .prettierrc (singleQuote, printWidth 120)
- shamefully-hoist removed; missing implicit deps made explicit

Docker:
- All Dockerfiles use pnpm install (no --filter) for strict mode compatibility
- esbuild bundles to .mjs (Lambda ESM requirement)
- IgnoreMode.DOCKER on all Docker assets to read root .dockerignore
- Verified: all 3 images build and respond to Lambda RIE invocations

Refs: #98, #91, discussion #94
…gration

- Fix client.ts: use Proxy for lazy db singleton to prevent crash when
  getPool is imported without DSQL_ENDPOINT set (e.g. migration CLI)
- Fix migrate script: add --env-file=.env to load DSQL credentials
- Document VPC ENI cleanup workaround in migration guide for v2→v3
  update scenario where Lambda ENIs block security group deletion
Replace the flat checklist with 8 incremental stages (12a-12h):
static checks → build → local Docker build → local migration →
local dev server e2e → cdk deploy → deployed e2e → Lambda migration.

Each stage catches a different class of bugs that later stages cannot
surface efficiently. Documents known issues (VPC ENI cleanup) at the
stage where they manifest.
…heck

- Add drizzle-kit as devDependency with drizzle.config.ts
- Add check-dsql-compat.ts validator (runs after generate)
- Add 'generate' pnpm script: drizzle-kit generate && check
- Initialize drizzle-kit snapshot from existing 0001_initial.sql
- Document schema change workflow in AGENTS.md
check-dsql-compat.ts now auto-fixes:
- statement-breakpoint → blank lines (runner splits on \n\n)
- CREATE INDEX → CREATE INDEX ASYNC
- Removes REFERENCES / FOREIGN KEY lines

Still errors on unfixable patterns: ALTER COLUMN TYPE, DROP COLUMN, SERIAL.
The existing migrate.ts had hash-based verification that broke on
formatter changes, lacked validation for most DSQL-incompatible ALTER
TABLE patterns, and did not support .ts/.mjs batch migrations.

- Extract pure functions (transform/validate/validateStatement) into
  dsql-compat.ts; check-dsql-compat.ts becomes a thin CLI wrapper
- Remove hash verification from _migrations table (name-based skip)
- Add validation for SET/DROP NOT NULL, SET/DROP DEFAULT, DROP
  CONSTRAINT, TRUNCATE
- Fix REFERENCES removal to preserve column definitions (strip only
  the REFERENCES clause, not the entire line)
- Fix statement-breakpoint replacement to produce blank lines (\n\n)
  for correct statement splitting
- Add .ts/.mjs migration support (export default async function)
- Update CDK Construct to memorySize 2048 / timeout 15min
- Add unit tests (43) and DSQL integration tests (16 passed, 2
  skipped due to oxlint no-restricted-syntax not yet supported)
- Colocate tests with source files (foo.test.ts next to foo.ts)
- Add packages/db/README.md with usage, constraints, and caveats
- Update AGENTS.md with ALTER TABLE constraints, unfixable error
  workflow, and test colocation convention
v3 introduces four simultaneous breaking changes (DSQL, Drizzle, pnpm,
oxlint) but the decision rationale was scattered across internal planning
documents. This commit creates public-facing documentation that records
intent — not just what changed, but why — so future maintainers and AI
agents can reproduce or re-derive the same decisions.

- Move DESIGN_PRINCIPLES.md from design/ to repo root, remove design/ dir
- Create docs/v3.0.0/design.md: motivation, target architecture, key
  design decisions with intent for each technology choice
- Create docs/v3.0.0/adr.md: three ADRs (DSQL+Drizzle+migrator, pnpm
  workspaces, oxlint+oxfmt) in Nygard format with rejected alternatives
- Create docs/v3.0.0/migration-prompt.md: phased migration meta-prompt
  for AI agents with checkpoints and data-loss safeguards, replacing the
  previous v3-pnpm-workspaces-prompt.md
- Add Japanese translations (*.ja.md) for all three documents
- Update DESIGN_PRINCIPLES.md: replace "ADRs are not used yet" with
  versioned docs/ convention, add Migration guides section with
  BREAKING CHANGE footer convention
- Update README.md path reference
Merge information from implementation plans (plan.md, drizzle-dsql-migrator-plan.md)
into the permanent documentation before the plans are deleted.

- Split adr.ja.md into 3 individual ADR files (adr-001, adr-002, adr-003)
  to match the convention that each ADR is an immutable, self-contained record
- Rewrite design.ja.md as implementation specification that references ADRs
  for motivation/rationale, eliminating duplicated content between the two
- Add DSQL DDL constraints, SQL transform rules, connection pattern, test
  design, and ESM Proxy rationale to design doc (from plan.md sources)
- Fix v2 problem descriptions: job.Dockerfile existed but package.json was
  shared; NAT Instance was t4g.nano (~$3/mo) not ~$30; add Aurora Serverless
  v2 operational issues (cold start, scheduled job keep-alive, retry cost)
- Add "Major version process" section to DESIGN_PRINCIPLES.md defining the
  artifact flow: research → ADR → design doc → implementation plan → code →
  migration prompt, with explicit committed/not-committed distinction
- Move drizzle-dsql-migrator-plan.md to .kiro/specs/
Review v3 docs (ADRs, design doc, DESIGN_PRINCIPLES.md, migration-prompt)
against implementation code, DSQL official docs, and v2 codebase.

Fixes:
- ADR-001 Context: v2 used serverlessV2MinCapacity: 0 (auto-pause), not
  0.5 ACU minimum billing. Rewrite to describe auto-pause limitations
  (cold start, scheduled jobs preventing pause)
- ADR-001 Decision: add drizzle-kit migrate SERIAL PRIMARY KEY
  incompatibility (dialect.ts uses SERIAL for its migrations table)
- ADR-001 Consequences: inline DDL constraint summary for
  self-containedness (previously required reading design doc)
- design.ja.md: document globalThis singleton for Next.js hot-reload
  connection leak prevention (was only documenting Proxy for ESM)
- DESIGN_PRINCIPLES.md: add [.lang] suffix to artifact path conventions
  to match actual .ja.md files, fix broken migration-prompt link

Cleanup:
- Remove implementation plans (.kiro/specs/) — all content verified as
  transferred to ADRs and design doc
- Remove English doc drafts (adr.md, design.md, migration-prompt.md) —
  superseded by .ja.md versions
Enable all default plugins (eslint, typescript, unicorn, oxc) that were
previously dropped when plugins field was explicitly set, plus react,
jsx-a11y, import, and vitest for broader coverage.

Key changes:
- oxlintrc.json: add 7 new plugins, enable import/no-cycle for circular
  dependency detection, disable rules incompatible with project (React 17
  JSX transform, ES2022 target, side-effect imports)
- Fix lint violations caught by new plugins: unnecessary template literal,
  missing html lang attribute, label-control association for a11y
- Fix lint:ci ignore-pattern mismatch in apps/cdk
- Add inline oxlint-disable for intentional test.skip and assertion-free
  integration tests
- README: add Agentic Coding section with DSQL skill install and
  oxlint/oxfmt post-write hook recommendation
…ric flow

The migration prompt is a meta-prompt that an AI coding agent reads to
migrate a user's v2 codebase to v3. The previous version had several
issues that could lead agents to make mistakes or miss critical steps.

Key changes:
- Remove v3 kit code details per documentation policy (agent has v3 copy)
- Add "files to copy vs files to transform" section so the agent knows
  which files need user-specific conversion
- Use schema.prisma as primary data source for schema conversion instead
  of pg_dump output (structured model definitions are easier to analyze)
- Merge pnpm migration + monorepo restructuring + linter into one phase
  (pnpm-workspace.yaml references apps/*/packages/* so dirs must exist
  before pnpm install; linter catches DSQL-incompatible imports early)
- Add dev DSQL cluster verification step using scripts/dsql.sh before
  touching production database
- Add user-specific analysis steps: custom code inventory, VPC-dependent
  constructs identification, CI/CD pipeline npm/npx cleanup
- Fix phase numbering (1-based, 5 phases) and CDK deploy count (2 required
  deploys in Phase 5, not 4)
- Clarify .npmrc must not be created (strict mode is pnpm default)
- Replace tsc --noEmit with oxlint typeCheck (oxlintrc.json has typeAware)
- Remove redundant "breaking changes reference" section (duplicated phases)
- Consolidate agent behavioral rules at the top with data loss warning
Static checks (lint, build, tsc) alone cannot catch runtime failures such as
ESM module eager evaluation, .env loading issues, and Docker path resolution
problems — all of which were discovered during v3 implementation (documented
in .kiro/specs plan.md task 12).

Add Phase 4-3 with progressive verification stages:
- 4-3a: lint → build (static checks)
- 4-3b: local Docker image build + docker run artifact inspection
- 4-3c: local migration execution against real DSQL cluster
- 4-3d: local dev server + browser verification

Also fix Phase 3 checkpoint ordering to lint → build (detect DSQL
incompatible patterns before attempting build).
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.

pnpm workspaces でモノレポ化 Use Aurora DSQL instead of Aurora Serverless v2

1 participant