Skip to content

Thread the app's Prisma client type through TypeInfo into hook context - #1214

Merged
borisno2 merged 1 commit into
mainfrom
claude/jolly-turing-p65lk0
Sep 6, 2026
Merged

Thread the app's Prisma client type through TypeInfo into hook context#1214
borisno2 merged 1 commit into
mainfrom
claude/jolly-turing-p65lk0

Conversation

@borisno2

@borisno2 borisno2 commented Sep 6, 2026

Copy link
Copy Markdown
Member

Summary

  • TypeInfo gains a prisma member (defaulted to the existing PrismaClientLike, so this is fully additive) carrying the consuming app's own generated Prisma client type.
  • Every list-level hook-args type (ResolveInputHookArgs, ValidateHookArgs, BeforeOperationHookArgs, AfterOperationHookArgs, BeforeTransactionHookArgs, AfterTransactionHookArgs) gains a TPrisma parameter and types context as StackContext<TPrisma>/AccessContext<TPrisma> instead of the unparameterised default. Hooks forwards it through to all of them.
  • Every field-level hook-args type (already parameterised over TTypeInfo) now types context as StackContext<TTypeInfo['prisma']>/AccessContext<TTypeInfo['prisma']>.
  • ListConfig<TTypeInfo> forwards TTypeInfo['prisma'] into Hooks, the same way it already forwards item and inputs.
  • The CLI generator (lists.ts) emits the new prisma member on each list's generated Lists.<List>.TypeInfo, pointing at the project's own generated PrismaClient — no opensaas.config.ts changes required downstream.

Before: context.db inside any hook resolved through AccessControlledDB<any> (a mapped type over keyof any that contributes no named property), so a hook's context was assignable to nothing app-specific — consumers needed context as unknown as Context to pass it into their own typed functions.

After: a hook authored the documented way (list<Lists.Post.TypeInfo>({ hooks: {...} })) gets a context keyed to the app's own Prisma client — context.db.<list> resolves to a real, named delegate, and context.db is assignable to the app's generated CustomDB with no cast.

Known, deliberately out-of-scope limitation: AccessControlledDB's catch-all & { [key: string]: any } index signature is unchanged by this fix, so a misspelled delegate name (context.db.typoedListName) still silently type-checks rather than failing to compile — closing that needs narrowing/removing that index signature, which is tracked separately under the Prisma 8 contract-keying migration (ADR-0052), not here. Covered by a dedicated test asserting this documented limitation.

Also found while verifying against a real example project (not touched by this PR, filed separately if warranted): a singleton list's generated .get() sugar and StackContext.session's Session | null are both pre-existing, unrelated structural gaps between core's generic context types and the generator's own narrowed Context/CustomDB — full Context/BaseContext assignability (as opposed to context.dbCustomDB) still needs a cast in those cases, orthogonal to the Prisma-client typing this issue is about.

Test plan

  • pnpm build across all 11 packages (core, cli, auth, ui, rag, storage/-s3/-vercel, tiptap, create-opensaas-app, docs)
  • pnpm test for core (1259 tests) and cli (384 tests, including 2 new)
  • New compile-time regression test (packages/cli/src/generator/types-hook-context.test.ts), built against core's real compiled types rather than a stub, asserting: context.db is assignable to the generated CustomDB with no cast, real per-list row types are resolved (not any), and the documented typo-permissiveness limitation
  • Extended types-large-schema.test.ts (Generated Context/CustomDB type hits TS2589 (excessively deep instantiation) once schema grows past ~7-8 lists #952's regression fixture) to also generate the Lists namespace and exercise a list-level and field-level hook reading context.db across 21 lists, confirming no TS2589 instantiation-depth regression
  • Manually verified end-to-end against examples/blog (pnpm generate && tsc --noEmit) with a throwaway hook consuming context.db.post/context.db.user and assigning context.db to the generated CustomDB
  • pnpm lint, pnpm manypkg fix, pnpm format
  • Changeset added (@opensaas/stack-core and @opensaas/stack-cli, minor)

Closes #1211

🤖 Generated with Claude Code

https://claude.ai/code/session_01UUfo5pf9kkNAYQ54X9EEhp


Generated by Claude Code

TypeInfo gains a `prisma` member (defaulted to PrismaClientLike, fully
additive) and every list/field hook-args type now types `context` as
StackContext<TTypeInfo['prisma']> / AccessContext<TTypeInfo['prisma']>
instead of the unparameterised default. Previously context.db resolved
through AccessControlledDB<any> - a mapped type over keyof any that
contributes no named property - so a hook's context was assignable to
nothing app-specific and consumers needed `context as unknown as Context`
to use it anywhere typed.

The CLI generator emits the new `prisma` member on each list's
Lists.<List>.TypeInfo, pointing at the project's own generated
PrismaClient, so no config changes are required downstream.

Adds a dedicated compile-time regression test (against core's real built
types, not a stub) proving context.db is now assignable to the generated
CustomDB with no cast and resolves real per-list row types, and extends
the #952 large-schema fixture to also generate the Lists namespace and
exercise list-level/field-level hooks reading context.db without
reintroducing TS2589.

Closes #1211

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UUfo5pf9kkNAYQ54X9EEhp
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@changeset-bot

changeset-bot Bot commented Sep 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: d7c3fbb

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@opensaas/stack-core Minor
@opensaas/stack-cli Minor
@opensaas/stack-auth Minor
@opensaas/stack-rag Minor
@opensaas/stack-storage Minor
@opensaas/stack-tiptap Minor
@opensaas/stack-ui Minor
@opensaas/stack-storage-s3 Minor
@opensaas/stack-storage-vercel Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Sep 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
stack-docs Ready Ready Preview Sep 6, 2026 11:17am UTC

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Core Package Coverage (./packages/core)

Status Category Percentage Covered / Total
🟢 Lines 94.4% (🎯 65%) 1756 / 1860
🟢 Statements 92.63% (🎯 65%) 1898 / 2049
🟢 Functions 97.53% (🎯 62%) 277 / 284
🟢 Branches 86.41% (🎯 50%) 1399 / 1619
File CoverageNo changed files found.
Generated in workflow #1995 for commit d7c3fbb by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for UI Package Coverage (./packages/ui)

Status Category Percentage Covered / Total
🔵 Lines 78.45% 244 / 311
🔵 Statements 77.95% 251 / 322
🔵 Functions 69.81% 74 / 106
🔵 Branches 66.94% 160 / 239
File CoverageNo changed files found.
Generated in workflow #1995 for commit d7c3fbb by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for CLI Package Coverage (./packages/cli)

Status Category Percentage Covered / Total
🔵 Lines 79.01% 1548 / 1959
🔵 Statements 78.82% 1616 / 2050
🔵 Functions 86.11% 217 / 252
🔵 Branches 69.66% 758 / 1088
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/cli/src/generator/lists.ts 98.52% 75% 100% 98.52% 139
Generated in workflow #1995 for commit d7c3fbb by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Auth Package Coverage (./packages/auth)

Status Category Percentage Covered / Total
🔵 Lines 99.49% 196 / 197
🔵 Statements 98.13% 211 / 215
🔵 Functions 100% 45 / 45
🔵 Branches 91.26% 188 / 206
File CoverageNo changed files found.
Generated in workflow #1995 for commit d7c3fbb by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Storage Package Coverage (./packages/storage)

Status Category Percentage Covered / Total
🔵 Lines 78.57% 220 / 280
🔵 Statements 80.06% 245 / 306
🔵 Functions 86.07% 68 / 79
🔵 Branches 75.88% 214 / 282
File CoverageNo changed files found.
Generated in workflow #1995 for commit d7c3fbb by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for RAG Package Coverage (./packages/rag)

Status Category Percentage Covered / Total
🔵 Lines 47.97% 355 / 740
🔵 Statements 48.14% 377 / 783
🔵 Functions 54.26% 70 / 129
🔵 Branches 42.55% 180 / 423
File CoverageNo changed files found.
Generated in workflow #1995 for commit d7c3fbb by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Storage S3 Package Coverage (./packages/storage-s3)

Status Category Percentage Covered / Total
🔵 Lines 100% 40 / 40
🔵 Statements 100% 40 / 40
🔵 Functions 100% 9 / 9
🔵 Branches 100% 19 / 19
File CoverageNo changed files found.
Generated in workflow #1995 for commit d7c3fbb by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Storage Vercel Package Coverage (./packages/storage-vercel)

Status Category Percentage Covered / Total
🔵 Lines 100% 68 / 68
🔵 Statements 100% 71 / 71
🔵 Functions 100% 15 / 15
🔵 Branches 97.87% 46 / 47
File CoverageNo changed files found.
Generated in workflow #1995 for commit d7c3fbb by the Vitest Coverage Report Action

@borisno2
borisno2 merged commit 11ea14a into main Sep 6, 2026
6 checks passed
@borisno2
borisno2 deleted the claude/jolly-turing-p65lk0 branch September 6, 2026 11:31
@github-actions github-actions Bot mentioned this pull request Sep 6, 2026
borisno2 pushed a commit that referenced this pull request Sep 7, 2026
Addresses a review finding on #1268: TypeInfo's new db member is
required, so an app that upgrades without re-running `opensaas
generate` sees a stale Lists.<List>.TypeInfo fail to type-check until
it regenerates — the same accepted trade-off #1214 made for the
prisma member. Calling it out explicitly rather than changing the fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtUdHuNi2yY4vRW2wBfyVN
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.

Hook args are not generic over the Prisma client, so a hook's context is untypeable in a consumer — AccessControlledDB<any> is assignable to nothing

2 participants