Auction Announcement / Declaration Flow v1
Scope
This implementation introduces the manual human-driven declaration path for auctions without rewriting the broader auction lifecycle. The source of truth is services/svc-tenders. services/api remains a compatibility/demo path.
Supported declaration states
DRAFTREADY_FOR_ANNOUNCEMENTANNOUNCED
Supported transitions in v1:
DRAFT -> READY_FOR_ANNOUNCEMENTREADY_FOR_ANNOUNCEMENT -> ANNOUNCED
Direct DRAFT -> ANNOUNCED is intentionally not supported.
Manual input model
The form/domain payload is grouped into:
- identity
- subject
- commercial terms
- timeline
- participation rules
- evidence references
- governance metadata
Evidence in v1 is reference-only. No file storage/upload orchestration is introduced.
Domain normalization
packages/core/auction/declaration.ts defines:
AuctionAnnouncementFormDataDeclareAuctionCommandAuctionAnnouncementValidationResultAuctionReadinessChecklistItemAuctionAnnouncementPreviewAuctionAnnouncedEvent- declaration guards:
canMarkReadycanDeclareAuction
The service normalizes the raw form payload before persistence or transition.
Validation layers
services/svc-tenders/src/validation.ts implements:
- field-level validation via zod
- business/readiness validation via
buildAuctionAnnouncementValidationResult - permission/governance shape validation via actor/capability checks
Readiness covers:
- identity completeness
- subject completeness
- commercial coherence
- bidding/delivery timeline coherence
- participation rule completeness
- evidence references present
- governance metadata present
- actor/capability presence
Persistence model
auction_declarations remains the workflow/declaration source of truth. It stores:
auction_declarationsauction_declaration_events
The declaration row keeps:
- JSONB form payload snapshot
- JSONB readiness snapshot
- JSONB preview snapshot
- JSONB declaration metadata
- state
- ready/declared actor + timestamps
auctions is the broader registry projection across internal lifecycle states. Declaration workflow now projects into auctions at three points:
- draft creation ->
DRAFT - mark ready ->
READY_FOR_ANNOUNCEMENT - declare ->
ANNOUNCED
Draft/ready registry rows intentionally preserve true missing values as null where the draft is still incomplete.
For v1 projection compatibility:
owner_stakeholder_idis sourced from explicitidentity.ownerStakeholderId- public subject linkage requires one real reference from
linkedAssetId | linkedLotId | linkedTenderId organizationIdremains declaration metadata onlyworkflowTemplateIdremains declaration metadata onlylinked_kes_contract_idstays null until a real KES/contract identifier existsminBidis temporarily projected frombasePrice
Public auction routes filter out internal-only states:
DRAFTREADY_FOR_ANNOUNCEMENT
Internal/admin auction routes expose the broader registry, including those internal states, behind the existing declaration capability gate.
Optional output allocation linkage
Output Allocation is an optional upstream commercial source in v1.
auction_declarations.allocation_idis nullable- direct declarations continue to work with no allocation selected
- allocation-backed declarations can later prefill subject/origin/quantity context without replacing the declaration workflow
- declaration readiness, mark-ready, and declare do not require allocation presence in v1
Event / audit shape
Two declaration events are currently recorded:
AUCTION_READY_FOR_ANNOUNCEMENTAUCTION_DECLARED
The declaration event includes:
auctionIdpreviousStatenewStatedeclaredBydeclaredAt- normalized snapshot
- linked evidence
rulesVersionintentIdsourceSystem
This is intentionally shaped so the same semantics can later feed outbox/KES integration.
Future KES mapping points
Later KES automation should map to the same semantics:
- form payload -> normalized declaration snapshot
- readiness check -> deterministic workflow gate
mark ready-> explicit state transitiondeclare-> explicit state transition + event emission
The intended future mapping is:
- KES action triggers the same normalized
DeclareAuctionCommand - service executes the same readiness/guard logic
- resulting declaration event can feed projections and hashable workflow snapshots
Deferred items
- dedicated web wizard
- gateway proxying for declaration endpoints
- full auction lifecycle naming cleanup
- file upload/storage for evidence
- smart-contract / KES automation execution