Skip to content

Modernize the API runtime with Prisma 7 and automated updates#15

Merged
maotora merged 8 commits intomainfrom
codex/prisma7-modernization
Mar 17, 2026
Merged

Modernize the API runtime with Prisma 7 and automated updates#15
maotora merged 8 commits intomainfrom
codex/prisma7-modernization

Conversation

@maotora
Copy link
Contributor

@maotora maotora commented Mar 16, 2026

Summary

  • upgrade the project to Prisma 7 with a generated ESM client, @prisma/adapter-pg, and a single shared Prisma runtime
  • rebuild the database setup around a reproducible baseline migration and deterministic seed data for local development and CI
  • preserve public API compatibility by keeping both /v1 and /api, while cleaning up routes, request validation, search safety, logging, and cache behavior
  • add GitHub automation with CI validation and Dependabot update PRs

Key Changes

  • move the runtime to Node >=20.19.0, ESM, modern TypeScript config, flat ESLint config, and updated package scripts
  • replace duplicate Prisma client creation with a shared singleton in src/db/prisma.ts
  • migrate Prisma generation to prisma-client output under src/generated/prisma
  • replace the old migration history with a fresh baseline migration that recreates the schema plus the search_vector trigger-backed full-text index support
  • add deterministic seed data in prisma/seed.ts so tests and CI do not depend on an external pre-populated database
  • parameterize the search query to remove $queryRawUnsafe
  • mount the same router under both /v1 and /api, keeping /v1 canonical and /api as a compatibility alias
  • add collection filters for countryId, regionCode, districtCode, and wardCode
  • add request IDs, structured request logging, cache headers, Swagger/OpenAPI output, and updated README guidance
  • add .github/workflows/ci.yml and .github/dependabot.yml

Validation

  • pnpm build:ci
  • pnpm build
  • pnpm openapi:json
  • DATABASE_URL=postgresql://postgres@localhost:5432/locations_api NODE_ENV=test pnpm test:ci

Notes

  • public response envelopes remain unchanged: { data }, { data, pagination }, and { error }
  • /v1 is the canonical base path going forward, but /api remains available for compatibility
  • the main runtime-level change for maintainers is the new Node 20.19.0+ minimum and the Prisma 7 ESM client generation flow

@maotora maotora requested a review from AnoRebel March 16, 2026 15:24
@AnoRebel
Copy link
Member

Working on it, fixing the gaps.

- Remove unnecessary 'as const' assertion from mode: 'insensitive' in contains()
- Strip null bytes from search input before passing to plainto_tsquery
- Refactor search SQL to use a CTE so plainto_tsquery is evaluated once
- Move seed destructiveness warning to step 4 where db:seed is first introduced
String(q) avoids calling .replace() on an any-typed value from
req.validatedQuery, satisfying @typescript-eslint/no-unsafe-call
which is enabled via recommendedTypeChecked but was not disabled
in eslint.config.js.
…ibility

The 'as const' assertion is required so TypeScript narrows the string
literal to the QueryMode union expected by Prisma's StringNullableFilter.
Without it, mode is typed as plain 'string' which is not assignable.
Copy link
Member

@AnoRebel AnoRebel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review complete — all issues resolved, CI green.

Review findings:

  • SQL injection concern was a false positive — Prisma.sql tagged templates auto-parameterize all interpolated values
  • Tests already cover /v1 and /api paths, collection filters, search with special chars, compatibility headers, and Prisma singleton behavior

Fixes applied (3 commits):

  1. Search query hardening: null-byte stripping + CTE refactor so plainto_tsquery runs once
  2. ESLint no-unsafe-call fix: wrapped q with String() before .replace()
  3. Restored as const on mode: 'insensitive' for Prisma QueryMode type compatibility

Local verification: lint ✅ typecheck ✅ 20/20 tests ✅
CI verification: Node 20.19.0 ✅ Node 22 ✅

@maotora
Copy link
Contributor Author

maotora commented Mar 17, 2026

@AnoRebel thanks!

@maotora maotora merged commit eb278ed into main Mar 17, 2026
2 checks passed
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.

2 participants