UAT Phase 1 Findings
UAT Phase 1 Findings
MC: #10487
Date: 2026-05-02
Stage web: https://bilko-web-stage-dh4m46blja-lz.a.run.app
Stage API: https://bilko-api-stage-dh4m46blja-lz.a.run.app
Verdict: ACCEPT-WITH-FOLLOWUP
Methodology
Three-agent pure UAT discovery on Bilko stage environment (post-Kotlin migration, pre-Express deletion). No build work — observational only.
Team:
maria-santos — Real-user SMB persona walkthrough (mobile UX + time-to-first-invoice)
petter-graff — Architecture gap analysis (docs vs code vs schema)
angie-jones — Functional smoke per epic (INCOMPLETE — deferred to MC #10500)
Top P0 Findings (Blocking Go-Live)
1. Registration Fails — Dual Bug
Root causes:
DB ENUM type mismatch: Prisma migrations created PostgreSQL ENUM "UserRole" but Kotlin Flyway V1 declares VARCHAR(50) . Kotlin INSERT with string "owner" → PostgreSQL rejects with type error.
API field name mismatch: Web sends organizationName , Kotlin API expects orgName .
Impact: Zero users can register. Product completely inaccessible to new users.
Evidence:
curl -X POST https://bilko-api-stage-dh4m46blja-lz.a.run.app/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"test@test.ba","password":"test1234","fullName":"Test User","orgName":"Test DOO","country":"BA","baseCurrency":"BAM"}'
→ HTTP 500: {"error":"PSQLException: column \"role\" is of type \"UserRole\"
but expression is of type character varying","code":"INTERNAL_ERROR"}
Followup: MC #10494
2. Invoice Email Send — UI Only, No Dispatch
What: Invoice wizard Step 6 shows email compose fields (To, Subject, Message, "Send me a copy"). InvoiceService.sendInvoice() changes status to "sent" but does NOT send email . The emailData state is never passed to API.
Impact: Customer never receives invoice. User believes invoice was sent. Creates chargeback disputes and relationship damage when client claims "nisam dobio nista."
Evidence: apps/api/src/main/kotlin/no/alai/bilko/services/InvoiceService.kt — no email service injection in DI container. sendInvoice() returns success without SMTP call.
Followup: MC #10495 (Sprint 1 P0)
3. Dead UI Buttons — Receipt Scan + Attach
What:
"Skeniraj racun" button ( /expenses/new ) has no onClick handler. No camera access, no OCR, no file picker.
"Prikaci racun" (Paperclip) also has no onClick and no backing .
Impact: The mobile expense entry feature — marketed as a selling point — is non-functional. Field users will abandon immediately. RS/BA tax law requires receipt documentation for deductible expenses; without attachment capability, Bilko cannot support compliance.
Evidence:
apps/web/app/(dashboard)/expenses/new/page.tsx — button is styled