# 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/<pkg>/dist/` | Webpack aliases point to `dist/` | Next.js production build, dev server |
| **Source-transpiled** | `packages/<pkg>/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/<pkg> && 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/<pkg>/tsup.config.ts` using the shared preset
2. Build: `cd packages/<pkg> && npx tsup`
3. Update `server/next.config.mjs`:
   - Change webpack alias from `packages/<pkg>/src` to `packages/<pkg>/dist`
   - Same for trailing-slash alias
   - Remove from `transpilePackages` array
   - Update Turbopack aliases if present
4. Update `packages/<pkg>/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 |
