This val is a single HTTP app (main.http.ts) built with Hono. It serves both UI and API routes.
There are three UX surfaces:
/) for entry creation/admin) for live operations (draw/reset)/admin/manage) for prize pool CRUD and deeper inspectionid: string stable identifiername: string display nameid: stringname: stringemail: stringcreatedAt: ISO stringprizeIds: string[] selected prize IDsprizeId: stringprize: string denormalized nameentry: EntryannouncedAt: ISO stringRecord<string, WinnerRecord> keyed by prizeIdBlob keys:
devfest26_raffle_prizes_v1devfest26_raffle_entries_v2devfest26_raffle_winners_v2In-memory mirrors are maintained:
memoryPrizesmemoryEntriesmemoryWinnersReason: local/dev resilience and graceful behavior if blob reads fail.
Normalization functions (normalizeEntry, normalizeWinners) handle older payload shapes:
prizeIndexes converted to current prizeIdsprizeIdPOST /api/entries
{ name: string, email: string, prizeIds: string[] }All admin routes require ?key=<ADMIN_KEY>.
GET /api/admin/state
{ entriesCount, winners, prizes }POST /api/admin/draw
{ prizeId: string }POST /api/admin/reset
POST /api/admin/prizes
{ name: string }PATCH /api/admin/prizes/:prizeId
{ name: string }DELETE /api/admin/prizes/:prizeId
renderHome -> GET /renderAdminHome -> GET /adminrenderAdmin -> GET /admin/managehandleCreateEntry -> POST /api/entrieshandleDrawWinner -> POST /api/admin/drawhandleResetRaffle -> POST /api/admin/resethandleAddPrize -> POST /api/admin/prizeshandleRenamePrize -> PATCH /api/admin/prizes/:prizeIdhandleRemovePrize -> DELETE /api/admin/prizes/:prizeId401, key mismatch.?key=..., route may look like 404 even when real route works in browser.