Skip to main content
packages/api is the composition root — the only package in the monorepo that’s actually a running server rather than a library. It has no index.ts; its entry points are app.ts (the Express app) and server.ts.

Composition

packages/api/src/application.ts
  policyRepository = new FilePolicyRepository(process.env.PARMANA_POLICY_DIR!)
  application = RuntimeFactory.create(
    businessTransactionRepository,   // from repositories.ts
    executionTrustRecordRepository,  // from repositories.ts
    policyRepository,
  )

packages/api/src/repositories.ts
  storage = StorageFactory.createFromEnvironment()   // PARMANA_STORAGE, default "memory"
  businessTransactionRepository = storage.businessTransactions
  executionTrustRecordRepository = storage.trustRecords
Every route handler imports the single application instance from application.ts — there’s exactly one ExecutionTrustApplication per process, module-scoped.

Routing

app.ts mounts eleven route modules under packages/api/src/routes/. See REST API Overview for the full endpoint table, and Verify / Receipt specifically for two mount paths that don’t match their filenames’ apparent intent (/verification, not /verify/:id; /receipt/latest, not /receipt/:id).

Error handling

packages/api/src/middleware/error-handler.ts is registered last, after all routes. It special-cases, in order: BusinessTransactionValidationError / PolicyValidationError / SignalValidationError400; PolicyNotFoundError404; DuplicateBusinessTransactionError409; any other RuntimeError (from @parmana/runtime) → error.status with { error, code }; anything else → logged to console.error and 500 { "error": "Internal Server Error" }.
This only runs for errors passed to Express’s next(error). Several routes (execute.ts, verify.ts, replay.ts, receipt.ts, policies.ts) return their own ad hoc { "error": string } bodies directly for request-shape validation failures, before errorHandler ever sees them. See REST API → Error Model for the full accounting of which shape you get from where.

BusinessTransactionMapper

packages/api/src/mappers/BusinessTransactionMapper.ts defines BusinessTransactionMapper.fromRequest(), intended to map a raw request body into an immutable BusinessTransaction (setting status: RECEIVED and createdAt: new Date()). It isn’t called anywhere — execute.ts passes req.body straight to application.execute() without going through this mapper.

REST API Overview

Every mounted endpoint.

Error Model

The full error-shape breakdown.

Authentication

Why there’s no auth middleware here yet.

runtime

What RuntimeFactory.create actually builds.