svc-tenders Dense Route Modules Map
Purpose
This note documents the densest route modules in svc-tenders after Cleanup Sprint 23:
- services/svc-tenders/src/routes/registerTenderDeclarationRoutes.ts
- services/svc-tenders/src/routes/registerAuctionDeclarationRoutes.ts
- services/svc-tenders/src/routes/registerKesRoutes.ts
The goal is route literacy:
- what endpoint clusters exist
- what gates they use
- what repository/support shape they depend on
- what remains mixed or unresolved
Labels used here:
VERIFIEDREALTRANSITIONALUNRESOLVED
registerTenderDeclarationRoutes.ts
Route module:
Input shape:
- dedicated repository input:
TenderDeclarationRepositoryPort- backed by services/svc-tenders/src/declaration/repository.ts
- support input:
TenderDeclarationRouteSupport
- shared shell input:
DeclarationEvidenceStorage
Endpoint clusters:
- Admin read
GET /admin/tenders/declarations/:id
Gate notes:
- auth required
- uses
canCheckTenderDeclaration(...) - this is broader visibility than the narrower mutation capabilities
- Draft authoring
POST /admin/tenders/declarations/draftsPUT /admin/tenders/declarations/:id/draft
Gate notes:
- auth required
- requires
tender:create-draft
- Readiness / declare transitions
POST /admin/tenders/declarations/:id/check-readinessPOST /admin/tenders/declarations/:id/mark-readyPOST /admin/tenders/declarations/:id/declare
Gate notes:
- readiness check uses the broader visibility/capability inspection path
- mark-ready requires
tender:mark-ready - declare requires
tender:declare canMarkTenderReady(...)andcanDeclareTender(...)enforce the declaration state-machine constraints
- Evidence surface
POST /admin/tenders/declarations/:id/evidence/uploadGET /admin/tenders/declarations/:id/evidenceGET /admin/tenders/declarations/:id/evidence/:evidenceId/download
Gate notes:
- upload requires auth and an existing declaration in
DRAFT - upload path uses declaration support + shared evidence storage
- evidence read/download use the broader
canCheckTenderDeclaration(...)visibility gate
Boundary notes:
VERIFIEDREAL- dedicated repository boundary is clean here
- shared upload/storage input is shell-owned infra, not repository ambiguity
registerAuctionDeclarationRoutes.ts
Route module:
Input shape:
- composed transitional repository input:
AuctionDeclarationRepositoryPort- composed in services/svc-tenders/src/server.ts
- mixes:
- declaration-owned methods from services/svc-tenders/src/declaration/repository.ts
- unresolved output-allocation methods from services/svc-tenders/src/repository/outputAllocations.ts
- support input:
AuctionDeclarationRouteSupport
- shared shell input:
DeclarationEvidenceStorage
Endpoint clusters:
- Output allocation admin surface
GET /admin/output-allocationsGET /admin/output-allocations/:idPOST /admin/output-allocationsPUT /admin/output-allocations/:id
Gate notes:
- auth required
- reads use
canCheckAuctionDeclaration(...) - writes require
auction:create-draft
- Admin read
GET /admin/auctions/declarations/:id
Gate notes:
- auth required
- uses
canCheckAuctionDeclaration(...)
- Evidence surface
POST /admin/auctions/declarations/:id/evidence/uploadGET /admin/auctions/declarations/:id/evidenceGET /admin/auctions/declarations/:id/evidence/:evidenceId/download
Gate notes:
- upload requires auth,
auction:create-draft, and existing declaration stateDRAFT - evidence read/download use the broader
canCheckAuctionDeclaration(...)gate
- Draft authoring
POST /admin/auctions/declarations/draftsPUT /admin/auctions/declarations/:id/draft
Gate notes:
- auth required
- requires
auction:create-draft
- Readiness / announce transitions
POST /admin/auctions/declarations/:id/check-readinessPOST /admin/auctions/declarations/:id/mark-readyPOST /admin/auctions/declarations/:id/declare
Gate notes:
- readiness check uses the broader declaration visibility path
- mark-ready requires
auction:mark-ready - final announce/declare requires
auction:declare canMarkReady(...)andcanDeclareAuction(...)enforce state-machine constraints
Boundary notes:
VERIFIEDTRANSITIONALUNRESOLVED- this is the densest remaining mixed route module because output allocations remain intentionally unresolved in ownership
registerKesRoutes.ts
Route module:
Input shape:
- transitional repository input:
KesRepositoryPort- backed by the mixed root services/svc-tenders/src/repository.ts
- support input:
KesRouteSupport- includes:
- auth helper
- parser helpers
- KYC boundary helper
- signature verification helper
Endpoint clusters:
- Case entry
POST /kes-orchestrator/cases
Gate notes:
- auth required
- primary write-side ingress into the KES surface
- Operator read / control-plane surface
GET /kes-orchestrator/casesGET /kes-orchestrator/control-planeGET /kes-orchestrator/cases/:idGET /kes-orchestrator/cases/:id/projectionGET /kes-orchestrator/process-mapGET /kes-orchestrator/suggestions
Gate notes:
- read-heavy cluster
- powered by transitional KES persistence hosted in the root repository
- Process-map mutation
PUT /kes-orchestrator/process-map
Gate notes:
- auth required
- does not add the extra signature/KYC ingress checks used by payment-sensitive actions
- Case / task / inspection actions
POST /kes-orchestrator/cases/:id/approve-landownerPOST /kes-orchestrator/cases/:id/publish-auctionPOST /kes-orchestrator/cases/:id/confirm-fundingPOST /kes-orchestrator/cases/:id/tasksPOST /kes-orchestrator/cases/:id/inspections
Gate notes:
- auth required
- lifecycle advancement cluster
- no extra KYC/signature ingress gates here
- Payment-sensitive actions
POST /kes-orchestrator/cases/:id/payments/requestPOST /kes-orchestrator/payments/:id/approvePOST /kes-orchestrator/payments/:id/settle
Gate notes:
- all require auth
- payment request additionally enforces:
ensureThirdPartyKycBoundary(...)verifyIncomingSignatureGate(...)
- payment approve/settle enforce:
verifyIncomingSignatureGate(...)
- Case closure
POST /kes-orchestrator/cases/:id/close
Gate notes:
- auth required
- terminal lifecycle action kept separate from the other action clusters
Boundary notes:
VERIFIEDREALTRANSITIONAL- KES route isolation is structurally good, but repository ownership is still transitional because persistence remains rooted in the mixed root repository
Current honest asymmetry
VERIFIED
The three dense modules are not symmetric, and that is correct:
- tender declaration is dense but repository-clean
- auction declaration is dense and still composition-mixed because of output allocations
- KES is dense because it combines:
- read/control-plane endpoints
- orchestrator action endpoints
- stricter ingress rules for payment-sensitive endpoints
Trying to normalize these into one pattern would hide the real topology.