# Package Build System The monorepo uses a **hybrid build strategy** for `@alga-psa/*` packages under `packages/`. ## Two resolution modes | Mode | Resolved from | When | Used by | |---|---|---|---| | **Pre-built** | `packages//dist/` | Webpack aliases point to `dist/` | Next.js production build, dev server | | **Source-transpiled** | `packages//src/` | Listed in `transpilePackages` with aliases to `src/` | Next.js (for packages not yet flipped) | TypeScript type checking (`tsc --noEmit`) always resolves from `src/` via tsconfig paths, regardless of which mode a package is in. ## Pre-built packages These packages are compiled by `tsup` before `next build` runs. Webpack resolves their imports from `dist/` instead of compiling from source. **Currently flipped (8 packages):** - `clients`, `sla`, `assets`, `tags` (domain packages, CSS-free) - `types`, `core`, `validation`, `event-schemas` (leaf/horizontal packages) **Still source-transpiled:** `formatting` (deep subpath imports across many packages), `ui`, `billing`, `scheduling`, `tickets`, `projects`, `documents` (have CSS imports), `auth`, `integrations`, `notifications`, `users` (CE/EE complexity), and composition layers. ## Shared tsup preset All pre-built packages use a shared config at `packages/build-tools/tsup-preset.ts`: ```typescript import { defineConfig } from 'tsup'; import { makeConfig } from '../build-tools/tsup-preset'; export default defineConfig(makeConfig({ jsxEnabled: true, // for packages with .tsx files external: ['react'], // extra externals beyond @alga-psa/* addJsExtensions: true, // for packages imported by Node.js directly })); ``` ### Options - **`jsxEnabled`** — enables automatic JSX transform. Required for packages containing `.tsx` files (React components). - **`external`** — additional externals. `@alga-psa/*` and `@shared/*` are always external. With `bundle: false` this is mostly for documentation; imports are preserved as-is. - **`addJsExtensions`** — post-build rewrite adding `.js` extensions to relative imports. Required for packages imported directly by Node.js ESM (not via webpack). Currently only `event-schemas` (used by Temporal worker). ## How packages get built ### Local development `npm run dev` automatically runs `npx nx build-deps server` before starting the Next.js dev server. This builds all pre-built packages so their `dist/` directories are fresh. No manual setup needed after pulling. During a running dev session, if you edit source in a pre-built package, rebuild it manually: ```bash cd packages/ && npx tsup ``` Source-transpiled packages get hot-reloaded by Next.js automatically. ### CI / Docker builds All Dockerfiles and CI workflows use Nx to build packages before `next build`: ```bash npx nx build-deps server # builds all server dependencies (Dockerfiles) npx nx build server # builds deps + runs next build (CI) ``` The `build-deps` target is auto-generated by `@nx/next`. It runs `dependsOn: ["^build"]` for all server upstream packages, then exits (noop executor). This means: - Dependency ordering is handled automatically by Nx - No manual package list to maintain - New flipped packages are picked up automatically ### Argo production builds The Argo workflow uses `npx nx next:build server` in the `build-app-ee` step, which triggers `^build` for all dependencies. The `ee/server/Dockerfile` (pre-built artifacts) copies `./packages/` including `dist/` directories. ## How to flip a new package 1. Create `packages//tsup.config.ts` using the shared preset 2. Build: `cd packages/ && npx tsup` 3. Update `server/next.config.mjs`: - Change webpack alias from `packages//src` to `packages//dist` - Same for trailing-slash alias - Remove from `transpilePackages` array - Update Turbopack aliases if present 4. Update `packages//package.json`: change `"build"` script to `"tsup"` 5. Verify: `tsc --noEmit` passes (types still from src), `npm run build` succeeds (runtime from dist) **Do NOT change tsconfig paths** — types always resolve from `src/`. ## Packages that should stay source-transpiled | Package | Reason | |---|---| | `ui` | Heavy CSS integration (7 CSS imports), changes frequently | | `msp-composition` | Composition layer, imports from all verticals | | `client-portal-composition` | Same | | `ee-stubs` | Build-time CE/EE switching |