Files
maestro/CLAUDE.md
T

2.9 KiB

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<string, T> 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@<version> --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 <path> 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:<port> 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.