You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every one of those starts cold, and the pnpm --filter @shared/types build prefix is hand-copied into five scripts (typecheck, test, build, dev:backend, dev:frontend) — the build order lives in string concatenation instead of in the compiler. The scaffolding for the real fix is already half-present: shared/tsconfig.json is composite: true, and both backend and frontend already declare references: [{ path: "../shared" }]. What is missing is a root solution file, composite on the projects that can carry it, and a typecheck script that actually uses build mode.
Scope:tsconfig.json, tsconfig.build.json (new, if a separate solution file is cleaner than reusing root), shared/tsconfig.json, backend/tsconfig.json, frontend/tsconfig.json, package.json
Depends on:#15 — land after CI enforces typecheck, so the change is validated by a green pipeline rather than by assertion
Checklist
Add composite: true to backend/tsconfig.json; leave frontend non-composite (TS5053 — noEmit and composite are mutually exclusive, and the frontend genuinely wants noEmit)
Add a root solution config with "files": [] and "references" to shared, backend, and frontend, so build order is expressed once, in the compiler, rather than five times in npm scripts
Decide and record whether the root paths mapping "@shared/types": ["./shared/index.ts"] stays. It is compatible with project references — TypeScript redirects an import that resolves into a referenced composite project to that project's declaration output — but it means two resolution mechanisms coexist (paths at compile time, the workspace symlink plus exports.types at runtime). Recommendation: keep it (smaller change, preserves go-to-definition landing on source), and prove it works from cold rather than assuming
Replace the four-command typecheck script with build mode. Verify empirically which form TypeScript 5.9.3 accepts — tsc -b --noEmit was historically rejected as TS5094 and support was added later, so test it rather than trusting either this plan or memory. If -b --noEmit is unavailable, plain tsc -b is an acceptable substitute: it emits exactly the artifacts build needs anyway
Keep the services/pdf-service leg as its own explicit invocation and leave a one-line comment saying why it is outside the solution — the next reader will otherwise "fix" it by folding it in and break the isolated Vercel deploy
Remove the now-redundant pnpm --filter @shared/types build prefixes from typecheck, test, and build once references make them unnecessary. Leave dev:backend / dev:frontend alone unless watch mode is verified end to end — those exist so a cold dev has shared/dist present, and breaking hot reload to save a string is a bad trade
verify: from a genuinely cold tree (rm -rf shared/dist backend/dist **/*.tsbuildinfo), one typecheck command typechecks all three workspaces in dependency order and exits 0
verify: the second consecutive run is measurably faster than the first — record both wall-clock numbers in the issue. This is the entire point of the task; if the numbers are the same, incrementality is not actually on
verify: a deliberate type error introduced in shared/index.ts fails both the backend and frontend legs — this proves the reference graph is wired, not just the paths alias
verify: a deliberate type error in backend/src fails, and one in services/pdf-service/api still fails — the pdf-service leg must not be silently dropped while restructuring
verify: build still produces a working backend/dist/server.js and frontend/dist SPA, test stays green with unchanged counts, and dev still hot-reloads a shared/ edit through to both backend and frontend
Priority: Low · Phase 12 task 20 of the maintainer’s migration plan.
Root
typecheckis four sequential compilations plus a manual pre-build:Every one of those starts cold, and the
pnpm --filter @shared/types buildprefix is hand-copied into five scripts (typecheck,test,build,dev:backend,dev:frontend) — the build order lives in string concatenation instead of in the compiler. The scaffolding for the real fix is already half-present:shared/tsconfig.jsoniscomposite: true, and bothbackendandfrontendalready declarereferences: [{ path: "../shared" }]. What is missing is a root solution file,compositeon the projects that can carry it, and atypecheckscript that actually uses build mode.Scope:
tsconfig.json,tsconfig.build.json(new, if a separate solution file is cleaner than reusing root),shared/tsconfig.json,backend/tsconfig.json,frontend/tsconfig.json,package.jsonDepends on: #15 — land after CI enforces typecheck, so the change is validated by a green pipeline rather than by assertion
Checklist
composite: truetobackend/tsconfig.json; leavefrontendnon-composite (TS5053 —noEmitandcompositeare mutually exclusive, and the frontend genuinely wantsnoEmit)"files": []and"references"toshared,backend, andfrontend, so build order is expressed once, in the compiler, rather than five times in npm scriptspathsmapping"@shared/types": ["./shared/index.ts"]stays. It is compatible with project references — TypeScript redirects an import that resolves into a referenced composite project to that project's declaration output — but it means two resolution mechanisms coexist (pathsat compile time, the workspace symlink plusexports.typesat runtime). Recommendation: keep it (smaller change, preserves go-to-definition landing on source), and prove it works from cold rather than assumingtypecheckscript with build mode. Verify empirically which form TypeScript 5.9.3 accepts —tsc -b --noEmitwas historically rejected as TS5094 and support was added later, so test it rather than trusting either this plan or memory. If-b --noEmitis unavailable, plaintsc -bis an acceptable substitute: it emits exactly the artifactsbuildneeds anywayservices/pdf-serviceleg as its own explicit invocation and leave a one-line comment saying why it is outside the solution — the next reader will otherwise "fix" it by folding it in and break the isolated Vercel deploypnpm --filter @shared/types buildprefixes fromtypecheck,test, andbuildonce references make them unnecessary. Leavedev:backend/dev:frontendalone unless watch mode is verified end to end — those exist so a colddevhasshared/distpresent, and breaking hot reload to save a string is a bad traderm -rf shared/dist backend/dist **/*.tsbuildinfo), onetypecheckcommand typechecks all three workspaces in dependency order and exits 0shared/index.tsfails both the backend and frontend legs — this proves the reference graph is wired, not just thepathsaliasbackend/srcfails, and one inservices/pdf-service/apistill fails — the pdf-service leg must not be silently dropped while restructuringbuildstill produces a workingbackend/dist/server.jsandfrontend/distSPA,teststays green with unchanged counts, anddevstill hot-reloads ashared/edit through to both backend and frontendPriority: Low · Phase 12 task 20 of the maintainer’s migration plan.