1.8 KiB
Contract requests from WP-A (learner)
1. Feature factories and the auth service (apps/server/src/main.ts, @stc/contracts)
Problem. Phase 0 passes Feature[] to startServer, but ServerContext is built inside startServer, so a feature that needs ctx (every Phase 1 package exports xFeature(ctx)) cannot be listed. There is also no way for a feature to replace the anonymous AuthService.
Workaround in feat/learner (applied, small): startServer accepts FeatureEntry = Feature | ((ctx) => Feature & { auth?: AuthService }). Factories run after ctx exists (with ctx.jobs set right after they return, so factories must not use jobs synchronously), and a feature carrying auth replaces ctx.auth. The main entry lists learnerFeature.
Proposal. Move both into the contract:
export type FeatureFactory = (ctx: ServerContext) => Feature;
export interface Feature { /* … */ auth?: AuthService; migrationsDirs?: string[] }
and let startServer take Array<Feature | FeatureFactory>.
2. Migrations per package
migrate() only reads packages/db/migrations. The learner package exports migrationsDirs and, until Phase 2 wires it in, runs its own migrations lazily inside learnerFeature(ctx) through runMigrations(db, dirs), which uses the same schema_migrations table and file-name keys. When migrate() learns about migrationsDirs, the lazy call becomes a no-op; it can then be removed.
3. Package entry for the browser
@stc/feature-learner's index exports both learnerFeature (server) and learnerWeb/LessonView (browser). Bun's browser bundler tree-shakes the server half (checked), so one entry works. The web shell imports learnerWeb from @stc/feature-learner; the studio can import LessonView the same way.