Skip to content

MOD-320: Project structure#242

Closed
omegascorp wants to merge 9 commits into
mainfrom
project-structure
Closed

MOD-320: Project structure#242
omegascorp wants to merge 9 commits into
mainfrom
project-structure

Conversation

@omegascorp
Copy link
Copy Markdown
Collaborator

@omegascorp omegascorp commented Apr 9, 2026

File-based auto-loading for modules and migrations

Summary

Adds convention-based auto-discovery of modules and migrations from the file system, so you don't need to manually wire everything into startApp()
The CLI (modelence dev / modelence build) scans /modules/ and /migrations/, generates a TypeScript entry wrapper with static imports, and feeds it to tsx/tsup
Fully backward compatible — existing startApp({ modules: [...], migrations: [...] }) works unchanged, auto-discovered items are merged in

Convention

src/server/
  app.ts
  modules/
    <name>/
      stores/        # one default export per file
      queries/       # filename → method key (e.g. getAll.ts → <name>.getAll)
      mutations/     # same as queries
      crons/         # filename → cron alias
      routes/        # one default export per file
      index.ts       # optional: configSchema, rateLimits, channels
  migrations/
    0001-initial-schema.ts   # default export: { version, description, handler }
    0002-add-indexes.ts

How it works

Before launching dev/build, the CLI scans the file system and generates .modelence/generated/autoModules.ts (static imports + setAutoLoadedModules/setAutoLoadedMigrations calls) and .modelence/generated/entry.ts (imports autoModules then user's app.ts)
entry.ts becomes the actual entry point for tsx (dev) and tsup (build)
startApp merges auto-loaded modules/migrations with any explicitly passed ones
Duplicate module names or migration versions throw at startup


Note

Medium Risk
Introduces a new code-generation + startup path that changes dev/build entrypoints and merges additional modules/migrations at runtime; failures in scanning, name/version collisions, or generated imports could break app startup/builds.

Overview
Adds a file-based auto-loading system: the CLI now scans <serverDir>/modules and <serverDir>/migrations, generates .modelence/generated/autoModules.ts + .modelence/generated/entry.ts, and uses the generated entry as the dev (tsx watch) and build (tsup) entrypoint.

startApp() now merges auto-discovered modules/migrations with explicitly provided ones, validates duplicate module names and duplicate migration versions, and sorts migrations by version before running.

Also generates an optional typed client helper at .modelence/generated/clientModules.ts (and attempts to add a @modelence/modules tsconfig path alias), and updates deployment to use the built server filename instead of a hardcoded app.mjs.

Reviewed by Cursor Bugbot for commit 73c7793. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread packages/modelence/src/app/index.ts Outdated
Comment thread packages/modelence/src/bin/scan.ts
@omegascorp omegascorp changed the title Project structure MOD-320: Project structure Apr 10, 2026
Comment thread packages/modelence/src/bin/scan.ts
Comment thread packages/modelence/src/bin/scan.ts Outdated
Copy link
Copy Markdown
Contributor

@artahian artahian left a comment

Choose a reason for hiding this comment

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

Structure looks good - only remaining question is how do client modules handle this. Leaving this in a comment state until we figure it out.


seen.set(baseName, path.join(dirPath, entry.name));
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Scanner crashes on .d.ts files in module folders

Low Severity

The scanFolder function matches .d.ts files because path.extname('types.d.ts') returns '.ts'. This produces a baseName of 'types.d', which fails the VALID_MODULE_NAME regex due to the dot, throwing a confusing error telling the user the filename is an invalid JS identifier. TypeScript declaration files (.d.ts) are common and valid in any directory; the scanner could silently skip them instead of crashing.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3d1e96a. Configure here.

@omegascorp
Copy link
Copy Markdown
Collaborator Author

@artahian, after many attempts, client modules are working as expected. Demo is here: modelence/examples#28

@omegascorp omegascorp requested a review from artahian April 14, 2026 17:43
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ff14ab5. Configure here.

Comment thread packages/modelence/src/bin/scan.ts
Copy link
Copy Markdown
Contributor

@artahian artahian left a comment

Choose a reason for hiding this comment

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

So it seems like there is no way to avoid generating types manually?

Do you think we should just keep the explicit imports but add an automated/lint check based on scanning so if you add something but forget to add it shows a warning for the App Builder?

Since this makes the type checking so complicated, I'm starting to doubt whether the structure has to be implicit like this or we should still have the same structure but with explicit imports.

@omegascorp
Copy link
Copy Markdown
Collaborator Author

We can actually avoid generating anything and just add ESLint rules to project tempalte

@omegascorp
Copy link
Copy Markdown
Collaborator Author

Closing for now since we decided to chagne the direction

@omegascorp omegascorp closed this Apr 27, 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.

2 participants