Auctions Canonical Write Path
This document traces the real auction write paths that exist today.
It does not describe desired architecture. It describes current code reality.
Resolving locale, route permissions, and workspace projection.
Current scope: Guest
Category: 60_technical_specs | Version: v1.0.0
Owner: DOCUMENT_CUSTODIAN | Review cycle: 60 days
Approval authority: GOVERNANCE_ADMIN, COMPLIANCE_OFFICER
Documentation portal is read-only. Editing and mutation endpoints are disabled.
Kvary platform is originally created in Georgian. Where a Georgian version exists, Georgian is authoritative for platform UI, documentation, and legal interpretation.
Translations into other languages are provided for convenience. Some records may originate in other languages and carry their own source or legal locale for a specific flow, but where a Georgian version is available, the Georgian version prevails for platform-level wording and interpretation.
Metadata incomplete: Document ID, Version, Status, Owner Role, Last Review Date, Next Review Date, Change Log
This document traces the real auction write paths that exist today.
It does not describe desired architecture. It describes current code reality.
Labels:
VERIFIEDINFERREDUNVERIFIEDREALMIXEDUI-FIRSTMISSINGStatus:
VERIFIEDREALThis is the strongest real auction write path in the repo.
createAuctionDeclarationDraftsvc-tenders.
svc-tenders validates and authorizes the request.
POST /admin/auctions/declarations/draftscreateAuctionDeclarationDraftSchemacreateAuctionDeclarationDraftauction_declarationsauctions via upsertAuctionRegistryStateFromDeclarationsvc-tendersauctions row if state becomes publicupdateAuctionDeclarationDraft.
PUT /admin/auctions/declarations/:id/draft.
svc-tenders updates:
auction_declarationsauctions projection rowupdateAuctionDeclarationDraftmarkAuctionDeclarationReady.
POST /admin/auctions/declarations/:id/mark-ready.
svc-tenders:
auction_declarations.stateauctions.stateauction_declaration_events row with AUCTION_READY_FOR_ANNOUNCEMENTPOST /admin/auctions/declarations/:id/mark-readymarkAuctionDeclarationReady, insertAuctionDeclarationEventdeclareAuctionAnnouncement.
POST /admin/auctions/declarations/:id/declare.
svc-tenders:
auction_declarations.state = 'ANNOUNCED'auctions registry projection row to ANNOUNCEDauction_declaration_events row with AUCTION_DECLAREDPOST /admin/auctions/declarations/:id/declaredeclareAuction, upsertAuctionRegistryStateFromDeclaration, insertAuctionDeclarationEventVERIFIED
Inside repository methods, declaration state updates and registry projection updates happen inside one SQL transaction:
BEGINauctions rowCOMMITEvidence:
createAuctionDeclarationDraftupdateAuctionDeclarationDraftmarkAuctionDeclarationReadydeclareAuctionVERIFIED
Auction declaration transitions write to:
auction_declaration_eventsI did not verify:
kes_outbox_eventsSo the write path is durable and transactional, but auction eventing is currently best described as:
REALUNVERIFIED for auctions specificallyStatus:
VERIFIEDREALThis is the strongest real post-award auction mutation found.
repository.settleAuction(auctionId, winner).
settleAuctionauctions row with FOR UPDATEentitlement_idwinner_jsonstate = 'SETTLED'entitlement_id to linked tenders row when presentVERIFIED
I did not verify a public portal mutation path that reaches this method directly.
That means:
Status:
VERIFIEDMIXEDfetchAuctionsfetchAuctionPortalDetailproxyAuctionsJsonx-kvary-source: gateway-upstream-auctions-servicex-kvary-durability: service-readGET /auctions, GET /auctions/:idauctionsauction_declarationsIf upstream read fails or returns 404, the gateway falls back to the local engine:
Compatibility responses are now explicitly marked:
x-kvary-source: gateway-local-enginex-kvary-durability: compatibility-local-engineThe gateway list fallback now also returns:
projectionHealthy: falseIf the web cannot reach the API at all, it falls back to portal mocks:
getMockAuctionSummaries, getMockAuctionPortalDetailThis is not canonical.
Status:
VERIFIEDUI-FIRSTPlace Bid in apps/web/src/portal/components/AuctionDetailClient.tsxhandleBid() creates a LOCAL-* bid idappendSessionAuctionBid() writes bid state to browser sessionStorage
No durable service write occurs on the normal portal path.
Buy NowhandleBuyNow() calls recordSessionAuctionBuyNow()sessionStorage becomes the effective state sourceNo durable service write occurs on the normal portal path.
AuctionDetailClient and TransportWorkspaceClient subscribe to those session overlaysAgain, no durable backend orchestration write occurs on the normal portal path.
Status:
VERIFIEDMIXEDThese routes still exist under the public gateway surface:
POST /api/v1/auctions/createPOST /api/v1/auctions/:id/announcePOST /api/v1/auctions/:id/openPOST /api/v1/auctions/:id/bidsPOST /api/v1/auctions/:id/closePOST /api/v1/auctions/:id/awardPOST /api/v1/auctions/:id/settleEvidence:
These are not the canonical durable auction action backend. They execute against:
That engine uses:
This is compatibility behavior, not durable source-of-truth behavior.
VERIFIED
After durable declaration writes, read-back can happen through:
svc-tendersGET /auctions and GET /auctions/:id once the projected auction row is in a public stateThe key bridge is:
upsertAuctionRegistryStateFromDeclarationThat method materializes declaration snapshots into the auctions registry table used by public reads.
VERIFIED
After public bid / Buy Now / fulfillment interaction, read-back is mostly local:
overlayAuctionPortalItem()That is coherent UX, but not durable backend truth.