> ## Documentation Index
> Fetch the complete documentation index at: https://help.stralos.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Development setup

> Local setup notes for Stralos repositories

Each Stralos repository is independent and generally uses `pnpm`. Check each repo README before running service-specific setup.

## Node version

`stralos-shell` requires Node 24. The repository pins `24.19.0` in `.node-version`. Use a version manager that reads `.node-version` (for example `fnm` or `nodenv`) to match this exactly. The `package.json` engines field enforces `>=24 <25`.

## Local ports

| Repo | Purpose | Port |
| - | - | -: |
| `stralos-api-global` | Global data and auth | 3300 |
| `stralos-api-rates` | Rates | 3301 |
| `stralos-api-activities` | Activities | 3302 |
| `stralos-api-estimate` | Estimate | 3303 |
| `stralos-api-documents` | Document upload and AI pipeline | 3304 |
| `stralos-api-scheduler` | Programme and resource scheduling | 3305 |
| `stralos-api-assistant` | AI copilot assistant | 3307 |
| `stralos-shell` | Frontend shell | Vite dev server |

## API service commands

Most API services support:

```bash theme={null}
pnpm install
cp .env.example .env
pnpm db:migrate
pnpm dev
pnpm build
pnpm lint
pnpm build:lambda
```

`stralos-api-global` also needs DynamoDB Local for OTP and sessions:

```bash theme={null}
pnpm local:dynamodb
pnpm local:dynamodb:init
pnpm seed:auth
```

The `.env.example` sets `OTP_EXPOSE_GENERATED=true` by default. This causes `POST /auth/otp/request` to include the generated six-digit code in its JSON response, which is necessary for completing the login flow locally because SES email delivery is disabled (`SES_ENABLED=false`). See [Local OTP behaviour](https://help.stralos.app/api/authentication.md#local-otp-behaviour) for the response shape.

To exercise access-token refresh locally, set `ACCESS_TOKEN_TTL_SECONDS` to a whole number from `60` to `3600`. The default is `3600`; the Terraform development configuration uses `900` (15 minutes). See [User access token lifetime](https://help.stralos.app/internal/auth-token-architecture.md#user-access-token-lifetime).

`stralos-api-documents` also needs LocalStack and a worker:

```bash theme={null}
docker compose up -d
pnpm localstack:init
pnpm dev
pnpm dev:worker
pnpm test
```

## Assistant service setup

`stralos-api-assistant` requires Node.js **24.19.0** (pinned in `.node-version`) and `pnpm@11.10.0`. The Assistant API Lambda uses the `nodejs24.x` managed runtime.

```bash theme={null}
pnpm install
cp .env.example .env
pnpm db:migrate
pnpm dev
pnpm build
pnpm lint
pnpm test
```

The service is a member of the root `stralos` pnpm workspace. Start it from the suite root with stralos-local (`./stralos-local/stralos-local up assistant`) alongside the rest of the stack.

`.env.example` ships with `AI_PROVIDER=google` and `GOOGLE_MODEL_ID=gemini-3.6-flash`. The workspace's `scripts/setup-local-env.sh` fills `GOOGLE_API_KEY` from dev SSM (requires your stralos-dev AWS login). Without dev access, paste in a personal Gemini API key. Set `AI_PROVIDER=fixture` to run without any live model provider. See [AI copilot assistant service](https://help.stralos.app/internal/assistant-service.md) for the full configuration reference.

## Frontend commands

Frontend packages generally expose:

```bash theme={null}
pnpm install
pnpm type-check
pnpm lint
pnpm test
pnpm build
```

API packages generally use `pnpm build` for TypeScript checking rather than a separate `type-check` script.

## Shell API configuration

The shell's local API defaults work without copying `.env.example`. Override a variable only when a service runs somewhere other than its normal local port. Production builds use the serving origin as the terminal fallback when no explicit build-time, runtime, or support override is present.

Shell-specific variables and their local defaults:

| Variable | Local default | Service |
| - | - | - |
| `VITE_STRALOS_GLOBAL_API_URL` | `http://localhost:3300` | `stralos-api-global`. The legacy `VITE_STRALOS_API_URL` name is also accepted. |
| `VITE_STRALOS_ESTIMATE_API_URL` | `http://localhost:3303` | `stralos-api-estimate` |
| `VITE_STRALOS_DOCUMENTS_API_URL` | `http://localhost:3304` | `stralos-api-documents` |
| `VITE_STRALOS_ASSISTANT_API_URL` | `http://localhost:3307` | `stralos-api-assistant` (AI copilot). In a production build, falls through to the serving origin the same as every other module. |
| `VITE_STRALOS_BILLING_API_URL` | `http://localhost:3308` | `stralos-api-billing` (billing panel in Settings) |
| `VITE_STRALOS_ADMIN_API_URL` | `http://localhost:3306` | `stralos-admin-api` (Users panel in Settings). The legacy `VITE_ADMIN_API_URL` name is also accepted. |
| `VITE_STRALOS_LOGIN_API_URL` | `http://localhost:3400` | `stralos-api-login` — handoff redemption only. Consulted only under a dev server; a deployed build resolves from its own origin. |

See [Frontend architecture](https://help.stralos.app/internal/frontend-architecture.md#api-base-url-resolution) for the full precedence contract.

## Admin console

`stralos-admin-web` is a pnpm workspace member. Its `@stralos-co-nz/ui` dependency resolves from a sibling `stralos-ui` checkout rather than the registry, so you must run `pnpm install` from the workspace root — not from inside `stralos-admin-web` — and build the sibling packages in order before starting the dev server.

**Prerequisites**: `stralos-admin-api` running on port `3306` against the local `stralos_admin` database.

```bash theme={null}
cd <workspace-root>   # the directory containing stralos-admin-web, stralos-ui, and stralos-domain
pnpm install
pnpm --dir stralos-domain build   # domain types must be built first
pnpm --dir stralos-ui build       # ui is consumed from dist, not source
pnpm --dir stralos-admin-web dev  # serves http://localhost:5174
```

Run `pnpm --dir stralos-ui build` again after pulling `stralos-ui` — a stale `dist` folder looks clean to `git status` but renders components one release behind.

The workspace root `.npmrc` points `@stralos-co-nz` at GitHub Packages for other private API packages. A `read:packages` token is required for a full workspace install:

```bash theme={null}
echo '//npm.pkg.github.com/:_authToken=${GH_PACKAGES_TOKEN}' >> ~/.npmrc
export GH_PACKAGES_TOKEN=$(gh auth token)   # a PAT with read:packages scope
```

To point the console at a different admin API, set `VITE_ADMIN_API_URL` in a local `.env` file (copy `.env.example`). The default is `http://localhost:3306`.

Google sign-in also requires these four admin API settings in `stralos-admin-api/.env`:

```dotenv theme={null}
ADMIN_GOOGLE_CLIENT_ID=<local OAuth client id>
ADMIN_GOOGLE_CLIENT_SECRET=<local OAuth client secret>
ADMIN_GOOGLE_REDIRECT_URI=http://localhost:5174/auth/callback
ADMIN_GOOGLE_HOSTED_DOMAIN=<your Google Workspace domain>
```

Register `http://localhost:5174/auth/callback` as an authorised redirect URI on that Google OAuth client. When all four settings are absent, the API can start but the sign-in routes return `503`. A partial configuration is invalid and stops the admin API during startup, so supply the complete set together.

After `pnpm admin:bootstrap` on the admin API, sign in at `http://localhost:5174` with the bootstrapped operator's Google Workspace account. No password or TOTP enrolment is required; the first sign-in binds the Google account to the operator row.

## Rates service API configuration

The Rates API calls Global (to validate supplier ownership), Estimate, and
Activities (when resolving day-rate schedule line mappings). For each peer, set
the direct URL variable (`STRALOS_GLOBAL_URL`, `ESTIMATE_API_URL`,
`ACTIVITIES_API_URL`) or its `*_SSM_PARAMETER` companion naming the
service-discovery parameter. stralos-local sets the direct URLs for you. There is
no localhost fallback: when neither variable is set for a peer, the service
refuses with a configuration error rather than calling a hard-coded port. See
[Deployment — Peer API URL resolution](https://help.stralos.app/internal/deployment.md#peer-api-url-resolution).

## Activities feature API configuration

The Activities feature client uses three API services. Override their base URLs only when a service runs on a non-default port.

| Variable | Default | Purpose |
| - | - | - |
| `VITE_STRALOS_GLOBAL_API_URL` | `http://localhost:3300` | Setting-list items and rate categories. The legacy `VITE_STRALOS_API_URL` name is also accepted. |
| `VITE_STRALOS_ACTIVITIES_API_URL` | `http://localhost:3302` | Activities CRUD (activities and components). |
| `VITE_STRALOS_RATES_API_URL` | `http://localhost:3301` | Rate summaries and prices for the trench calculator. |

See [Frontend architecture](https://help.stralos.app/internal/frontend-architecture.md#api-base-url-resolution) for the full precedence contract.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.