Skip to content

clean leaked framework logic - #16

Merged
cobraprojects merged 3 commits into
mainfrom
clean-leaked-framework-logic
May 1, 2026
Merged

cobraprojects merged 3 commits into
mainfrom
clean-leaked-framework-logic

Conversation

@cobraprojects

@cobraprojects cobraprojects commented May 1, 2026 •

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

Release Notes

  • New Features

    • Added runtime schema module generation for improved startup performance.
  • Chores

    • Streamlined database query APIs for better efficiency across frameworks.
    • Refactored schema initialization to reduce startup side effects.
    • Updated framework setup to support optimized schema preloading in development and test environments.

@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.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented May 1, 2026 •

Copy link
Copy Markdown

Warning

Rate limit exceeded

@cobraprojects has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 2 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 340d5463-388d-4131-bcc2-ba6c5b5b8ea3

📥 Commits

Reviewing files that changed from the base of the PR and between 328c078 and 5123589.

📒 Files selected for processing (4)
  • packages/adapter-next/src/config.ts
  • packages/cli/tests/authorization-registry.test.ts
  • packages/cli/tests/broadcast-registry.test.ts
  • packages/cli/tests/broadcast.test.ts
📝 Walkthrough

Walkthrough

The pull request refactors multiple framework blog applications (Next.js, Nuxt, SvelteKit) and the CLI/DB packages to eliminate static schema imports at module load time. Schema initialization is deferred to runtime via dynamic preloading in test runners and CLI processes. Models now use string identifiers instead of imported schema objects, and query builders use direct model methods rather than .query() chains.

Changes

Cohort / File(s) Summary
Model Definitions - Next.js
apps/blog-next/server/models/Post.ts, Category.ts, Tag.ts, User.ts
Removes ../db/schema.generated import to eliminate module-load side effects while keeping model definitions unchanged.
Model Definitions - Nuxt
apps/blog-nuxt/server/models/Post.ts, Category.ts, Tag.ts, User.ts
Replaces imported schema objects with string identifiers in defineModel calls (e.g., defineModel('posts', ...) instead of defineModel(posts, ...)), removing schema import dependency.
Model Definitions - SvelteKit
apps/blog-sveltekit/server/models/Post.ts, Category.ts, Tag.ts, User.ts
Removes ../db/schema.generated import to eliminate side effects during module loading; model definitions remain unchanged.
Query Builder Refactoring - Next.js
apps/blog-next/server/lib/blog.ts
Updates createUniqueSlug to call Model.whereLike(...) directly instead of Model.query().whereLike(...), preserving filter and retrieval logic.
Query Builder Refactoring - Nuxt
apps/blog-nuxt/server/lib/blog.ts
Replaces .query().with()/.query().orderBy() patterns with direct Model.with()/Model.orderBy() calls across all read operations; data shapes and logic unchanged.
Query Builder Refactoring - SvelteKit
apps/blog-sveltekit/src/lib/server/blog.ts
Removes .query() wrapper and uses direct model query methods (whereLike, with, orderBy) in slug lookups and read APIs.
Layout & Helper Type Annotations
apps/blog-next/app/layout.tsx
Removes ../db/schema.generated import and adds explicit Metadata type annotation to exported metadata constant.
Helper Module Updates
apps/blog-next/server/holo.ts, apps/blog-sveltekit/src/lib/server/holo.ts
Removes ../db/schema.generated import; createNextHoloHelpers()/createSvelteKitHoloHelpers() export remains unchanged.
Nitro Plugin Cleanup
apps/blog-nuxt/server/plugins/generated-schema.ts
Removes entire plugin body (schema import and empty defineNitroPlugin export), effectively deleting the file's functional content.
Test Logic Updates - All Frameworks
apps/blog-next/tests/blog-logic.mjs, apps/blog-nuxt/tests/blog-logic.mjs, apps/blog-sveltekit/tests/blog-logic.mjs
Changes eager-loaded relationship queries from Model.query().with(...) to Model.with(...), matching refactored query builder pattern.
Test Runners - Schema Preloading
apps/blog-next/tests/run.mjs, apps/blog-nuxt/tests/run.mjs, apps/blog-sveltekit/tests/run.mjs
Introduces createChildEnv() helper that dynamically appends --import=<schema.mjs> to NODE_OPTIONS when runtime schema file exists, replacing direct process.env inheritance.
CLI Project Discovery
packages/cli/src/project/discovery.ts
Adds early conditional dynamic import of generated schema module (when path exists) before running file collection and module discovery loops.
CLI Registry & Schema Extraction
packages/cli/src/project/registry.ts
Refactors registry loading from TypeScript module import to JSON file parsing; adds extraction of TableDefinition objects from generated schema for runtime artifact output.
CLI Shared Constants
packages/cli/src/project/shared.ts
Introduces new exported constant GENERATED_SCHEMA_RUNTIME_PATH pointing to .holo-js/generated/schema.mjs.
CLI Framework Scaffolding
packages/cli/src/project/scaffold/framework-renderers.ts
Removes static schema imports from generated framework helpers; adds preload logic to framework runner script to inject --import=<schema.mjs> into child process NODE_OPTIONS.
DB Schema Runtime Generation
packages/db/src/schema/generated.ts
Introduces renderGeneratedSchemaRuntimeModule variant alongside existing type-augmented module; runtime variant omits TypeScript augmentation and uses Object.freeze() for table exports.
DB & Adapter Exports
packages/db/src/index.ts, packages/db/src/schema/index.ts
Exports new renderGeneratedSchemaRuntimeModule function alongside existing schema helpers.
DB Schema Tests
packages/db/tests/generated-schema.test.ts
Adds test assertions validating runtime schema module includes correct imports and calls registerGeneratedTables(), while omitting TypeScript augmentation.
Adapter Next.js
packages/adapter-next/src/runtime.ts
Changes import path for initializeHolo and CreateHoloOptions from @holo-js/core/runtime to @holo-js/core.
CLI Test Assertions
packages/cli/tests/cli.test.ts
Inverts schema-access assertions: framework helper files now expected to not contain schema.generated substring instead of containing it.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • PR #13: Modifies CLI/framework scaffolding and generated-schema handling for registry and framework generation logic.
  • PR #4: Modifies CLI project discovery, registry loading, and scaffold wiring for schema initialization.
  • PR #12: Updates framework scaffolding and runner generation alongside CLI discovery and scaffold code changes.

Poem

🐰 No more static schema at startup's door,
Dynamic preloads open fresh runtime's floor.
Models speak in strings, queries dance direct—
Side effects erased, the code's more perfect! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'clean leaked framework logic' is vague and does not clearly describe the specific changes made in the pull request. The word 'leaked' is non-descriptive and does not convey meaningful information about what was cleaned or improved. Use a more specific, descriptive title that explains the actual changes, such as 'remove schema.generated imports and switch to runtime preloading' or 'decouple models from generated schema and use runtime schema loading'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch clean-leaked-framework-logic

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 21 minutes and 2 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/cli/tests/cli.test.ts (1)

642-643: ⚡ Quick win

Make the “no schema.generated” checks less brittle (match static import/require patterns).

Right now the test asserts the generated helper files contain no substring schema.generated. That can fail even when the leak you care about (static/module-load-time import of the schema artifact) is already fixed, because any incidental occurrence (comments/strings/paths unrelated to static imports) will break the test.

Prefer matching static import/require usage instead (e.g., import ... from '...schema.generated...' or require('...schema.generated...')) and asserting that those patterns are absent.

🛠️ Proposed adjustment (apply to all 3 occurrences)
-    expect(await readFile(join(projectRoot, 'server/holo.ts'), 'utf8')).not.toContain('schema.generated')
-    expect(await readFile(join(projectRoot, 'app/layout.tsx'), 'utf8')).not.toContain('schema.generated')
+    const staticSchemaImportPattern =
+      /(import\s+[^;]+?from\s+['"][^'"]*schema\.generated['"]|require\s*\(\s*['"][^'"]*schema\.generated['"])/m
+    expect(await readFile(join(projectRoot, 'server/holo.ts'), 'utf8')).not.toMatch(staticSchemaImportPattern)
+    expect(await readFile(join(projectRoot, 'app/layout.tsx'), 'utf8')).not.toMatch(staticSchemaImportPattern)
-    expect(await readFile(join(nextRoot, 'server/holo.ts'), 'utf8')).not.toContain('schema.generated')
-    expect(await readFile(join(nextRoot, 'app/layout.tsx'), 'utf8')).not.toContain('schema.generated')
+    expect(await readFile(join(nextRoot, 'server/holo.ts'), 'utf8')).not.toMatch(staticSchemaImportPattern)
+    expect(await readFile(join(nextRoot, 'app/layout.tsx'), 'utf8')).not.toMatch(staticSchemaImportPattern)
-    expect(await readFile(join(svelteRoot, 'src/lib/server/holo.ts'), 'utf8')).not.toContain('schema.generated')
+    expect(await readFile(join(svelteRoot, 'src/lib/server/holo.ts'), 'utf8')).not.toMatch(staticSchemaImportPattern)

Also applies to: 1432-1434, 1446-1447

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/tests/cli.test.ts` around lines 642 - 643, Replace the brittle
substring assertions that check server/holo.ts and app/layout.ts for
"schema.generated" with regex-based checks that only match static import/require
patterns (e.g., /import\s+[^;]+from\s+['"].*schema\.generated.*['"]/ and
/require\(\s*['"].*schema\.generated.*['"]\s*\)/); update the two expect calls
that read join(projectRoot, 'server/holo.ts') and join(projectRoot,
'app/layout.ts') (and the two other occurrences around the file) to assert that
those regexes do not match the file contents instead of using
not.toContain('schema.generated'), so incidental occurrences in comments/strings
won’t fail the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/cli/src/project/registry.ts`:
- Around line 80-88: The importProjectModule call in
renderGeneratedSchemaRuntimeArtifact loads the project's schema which registers
tables into the process-global registry and can leak state; to fix this snapshot
and restore the registry around the import (or clear it before import and
restore previous entries after), i.e. before calling importProjectModule take a
copy of the current registry state (using your registry API), clear the
registry, perform importProjectModule(projectRoot, schemaPath) and call
extractGeneratedSchemaTables(moduleValue) to get the tables without relying on
load-time side effects, then restore the registry to the snapped state so no
generated tables remain in the CLI process; update
renderGeneratedSchemaRuntimeArtifact to perform this
save/clear/import/extract/restore sequence.

---

Nitpick comments:
In `@packages/cli/tests/cli.test.ts`:
- Around line 642-643: Replace the brittle substring assertions that check
server/holo.ts and app/layout.ts for "schema.generated" with regex-based checks
that only match static import/require patterns (e.g.,
/import\s+[^;]+from\s+['"].*schema\.generated.*['"]/ and
/require\(\s*['"].*schema\.generated.*['"]\s*\)/); update the two expect calls
that read join(projectRoot, 'server/holo.ts') and join(projectRoot,
'app/layout.ts') (and the two other occurrences around the file) to assert that
those regexes do not match the file contents instead of using
not.toContain('schema.generated'), so incidental occurrences in comments/strings
won’t fail the test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 76f22dec-91c5-4063-a0e6-2f1861b4f782

📥 Commits

Reviewing files that changed from the base of the PR and between 4fcb1bc and 328c078.

📒 Files selected for processing (35)
  • apps/blog-next/app/layout.tsx
  • apps/blog-next/server/holo.ts
  • apps/blog-next/server/lib/blog.ts
  • apps/blog-next/server/models/Category.ts
  • apps/blog-next/server/models/Post.ts
  • apps/blog-next/server/models/Tag.ts
  • apps/blog-next/server/models/User.ts
  • apps/blog-next/tests/blog-logic.mjs
  • apps/blog-next/tests/run.mjs
  • apps/blog-nuxt/server/lib/blog.ts
  • apps/blog-nuxt/server/models/Category.ts
  • apps/blog-nuxt/server/models/Post.ts
  • apps/blog-nuxt/server/models/Tag.ts
  • apps/blog-nuxt/server/models/User.ts
  • apps/blog-nuxt/server/plugins/generated-schema.ts
  • apps/blog-nuxt/tests/blog-logic.mjs
  • apps/blog-nuxt/tests/run.mjs
  • apps/blog-sveltekit/server/models/Category.ts
  • apps/blog-sveltekit/server/models/Post.ts
  • apps/blog-sveltekit/server/models/Tag.ts
  • apps/blog-sveltekit/server/models/User.ts
  • apps/blog-sveltekit/src/lib/server/blog.ts
  • apps/blog-sveltekit/src/lib/server/holo.ts
  • apps/blog-sveltekit/tests/blog-logic.mjs
  • apps/blog-sveltekit/tests/run.mjs
  • packages/adapter-next/src/runtime.ts
  • packages/cli/src/project/discovery.ts
  • packages/cli/src/project/registry.ts
  • packages/cli/src/project/scaffold/framework-renderers.ts
  • packages/cli/src/project/shared.ts
  • packages/cli/tests/cli.test.ts
  • packages/db/src/index.ts
  • packages/db/src/schema/generated.ts
  • packages/db/src/schema/index.ts
  • packages/db/tests/generated-schema.test.ts
💤 Files with no reviewable changes (11)
  • apps/blog-next/server/models/Tag.ts
  • apps/blog-next/server/holo.ts
  • apps/blog-next/server/models/Category.ts
  • apps/blog-sveltekit/server/models/User.ts
  • apps/blog-sveltekit/src/lib/server/holo.ts
  • apps/blog-sveltekit/server/models/Post.ts
  • apps/blog-sveltekit/server/models/Category.ts
  • apps/blog-next/server/models/User.ts
  • apps/blog-nuxt/server/plugins/generated-schema.ts
  • apps/blog-sveltekit/server/models/Tag.ts
  • apps/blog-next/server/models/Post.ts

Comment on lines +80 to +88
async function renderGeneratedSchemaRuntimeArtifact(
projectRoot: string,
schemaEntry: string,
): Promise<string> {
const schemaPath = resolve(projectRoot, schemaEntry)
const moduleValue = await importProjectModule(projectRoot, schemaPath)
const tables = extractGeneratedSchemaTables(moduleValue)
return renderGeneratedSchemaRuntimeModule(tables)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid leaking generated tables into the CLI process.

importProjectModule(projectRoot, schemaPath) executes the schema module, and those generated schema modules register tables into the process-global registry on load. That means this artifact-generation step mutates shared DB state, so tables from one project/run can bleed into later work in the same process. Please clear/restore the registry around this import, or extract the exported tables without relying on the module’s load-time side effect.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/src/project/registry.ts` around lines 80 - 88, The
importProjectModule call in renderGeneratedSchemaRuntimeArtifact loads the
project's schema which registers tables into the process-global registry and can
leak state; to fix this snapshot and restore the registry around the import (or
clear it before import and restore previous entries after), i.e. before calling
importProjectModule take a copy of the current registry state (using your
registry API), clear the registry, perform importProjectModule(projectRoot,
schemaPath) and call extractGeneratedSchemaTables(moduleValue) to get the tables
without relying on load-time side effects, then restore the registry to the
snapped state so no generated tables remain in the CLI process; update
renderGeneratedSchemaRuntimeArtifact to perform this
save/clear/import/extract/restore sequence.

…t): The importProjectModule call does trigger registerGeneratedTables as a side effect of loading the generated schema module, which writes to globalThis.__holoGeneratedTables__. However, the CLI process never reads from that global map — extractGeneratedSchemaTables reads directly from the module's exports. The leaked state is inert and has no observable effect on CLI behavior. Adding snapshot/restore logic would be unnecessary complexity.

Finding 2 (brittle substring assertions in tests): The .not.toContain('schema.generated') assertions check scaffolded files whose content is fully controlled by the framework's code generators. A regex matching only import/require patterns would actually be weaker — it would miss other forms of leakage (dynamic imports, string paths, etc.). The current assertions are appropriately strict for their purpose.

- No changes needed.
- fix cli test
@cobraprojects
cobraprojects merged commit 54c1054 into main May 1, 2026
1 check passed
@cobraprojects
cobraprojects deleted the clean-leaked-framework-logic branch May 1, 2026 05:25
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