# maestro — development policy Maestro is the NestJS BFF between the Angular frontend and the gRPC services (pi-factory, in-factory) / platform-api. These rules come from code review and apply to every change; the same rules live in pi-factory and in-factory. ## Layering - Controllers are thin: decorators, body validation, one call into a service, response shape. Orchestration (multi-step calls, rollbacks, platform-api or gRPC round-trips) lives in a `*.service.ts`. Example: `platform-api/pipeline-tables.service.ts`. - One platform-api route per operation. If the platform already dispatches by pipeline type (batch vs CDC), do not branch on the type here — call the route that dispatches (e.g. `DELETE /pipeline/{id}/jobs` for table removal, never `DELETE /jobs/{id}` from maestro). ## Types - No `any` / `as any`. gRPC calls take the protospack request type exactly (`AddCdcTableRequest`, `MarkTableDeletedRequest`, ...); DTOs and interfaces are explicit classes/interfaces. Use `Record` or `unknown` (with narrowing) when a shape is genuinely open — never `any`. - Protospack payloads are built in one mapper per entity (e.g. `inputs/cdc-table.mapper.ts`), so a field that mirrors another (`CdcTable.name` == `table_name`) is derived in exactly one place. ## Pipeline type - Decide CDC vs batch with `src/utils/cdc.ts` (`isCdcPlugin`, `isCdcJob`, `isCdcPipeline`), never with inline `plugin.endsWith('_cdc')`, `!!x`, or the absence of some other data (e.g. "no run history ⇒ editable"). - The platform-api stamps `job.input.connector === 'cdc'` on CDC jobs; that is the authoritative discriminator once a pipeline exists. ## Dependencies - `@dadosfera/protospack-v2` is consumed from CodeArtifact, pinned to an exact version (`npm i @dadosfera/protospack-v2@ --save-exact`). A `file:` / tarball reference is for local development only and must never be committed. Note: `^3.40.0-beta.N` resolves to the stable `3.40.0` — prereleases must be pinned exactly. ## Commits and releases - Deploys are cut by semantic-release with the eslint preset: the commit title MUST start with `FIX:` (patch), `UPDATE:` or `FEAT:` (minor). A lowercase `feat(scope): ...` merges without producing a version, so the code never reaches stg/prd. - Pushing to `beta` deploys stg; `main` deploys prd. ## Tests - Every service method with a rollback path has a spec covering the happy path, the platform failure (rollback fires) and a rollback failure (does not mask the original error). Run `npx jest ` for a folder, `npx tsc --noEmit -p tsconfig.json` for types. - Several gRPC client configs read `process.env` at import time, so the full suite needs the service URLs set (any `0.0.0.0:` value works): `DUC_URL=0.0.0.0:50051 INFACTORY_URL=0.0.0.0:50052 PIFACTORY_URL=0.0.0.0:50053 npx jest`. A `Cannot read properties of undefined (reading 'startsWith')` at import is this, not a broken test.