Open Tech Debt + Followups
Open Tech Debt + Followups
Context: Post-Sprint 0 landscape (2026-05-02)
Sprint program: Bilko stage UAT + bug-fix sprint
Active Followup MCs
MC #10500 — angie-jones Functional Smoke Re-run
Priority: M
Status: OPEN
Owner: TBD
Context: AC1 from UAT Phase 1 (MC #10487) was incomplete. Evidence file /tmp/bilko-uat-bugs-10487.json = 2 bytes ({}). No HAR files, no screenshots, no functional coverage per epic.
Scope:
- Re-run functional smoke test on stage with ALL 8 epics
- Capture evidence per epic: screenshot + HAR + reproduction steps
- Test AFTER Sprint 0 lands (MC #10494) so login works
- Output: structured JSON with ≥8 entries
8 epics to test:
- Registration + org creation (now fixed — verify success flow)
- Login + JWT token refresh
- Invoice creation + PDV calculation
- Expense recording + category assignment
- Bank CSV import + auto-match
- Chart of Accounts CRUD
- P&L report generation
- Multi-currency invoice with exchange rate lock
Acceptance criteria:
bilko-uat-bugs-RERUN.jsonwith structured findings (epic_name, urls_tested, screenshots[], har_files[], repro_steps[])- HAR files saved to
/tmp/bilko-uat-har-<epic_name>.har - Screenshots saved to
/tmp/bilko-uat-screenshot-<epic_name>-<step>.png
Blocker: Sprint 0 must land first (registration must work to proceed past login).
MC #10502 — PROD CUTOVER (Kotlin to Prod)
Priority: H
Status: OPEN
Category: BLOCKER
Context: TD-3 per DEPLOY-MAP.md. Prod bilko-api Cloud Run service is STILL running Express container (digest sha256:2986d8b0..., port 4000). Stage is Kotlin-safe. Cutover blocked.
Scope:
- Verify stage Kotlin
bilko/api:stage-ab7d50dis production-ready (Sprint 0 landed, registration works, no regression) - Audit prod Cloud SQL instance
bilko-dbschema state (Flyway version, jmbg/oib columns from V3, ENUM types) - Tag production-ready image:
docker tag bilko/api:stage-ab7d50d bilko/api:prod-<sha> - Deploy to prod
bilko-apiCloud Run service - Smoke test prod
/api/v1/health+ registration endpoint - Monitor for 24h (error rate, latency p95)
- Document rollback procedure (Cloud Run traffic split to previous Express revision)
Blockers before cutover:
- Sprint 1 SEF decision (CEO choice: real integration vs honest banner) — cannot go to prod with stub if legal risk unacceptable
- Invoice email send (Sprint 1) — cannot market "send invoice" if email doesn't work
- TD-2 resolution (
postgres-socket-factory+ IAM auth) — MC #10240 (currently open)
Risk: Prod still on Express means any bug fix in Kotlin (e.g., registration fix #10494) does NOT reach prod users.
MC #10504 — .gcloudignore Optimization
Priority: M
Status: OPEN
Parent: MC #10498 (Arch roadmap)
Context: Cloud Build web deploy uploads 492MB (includes apps/api/build/, .gradle/, all node_modules/). Upload step times out on slow connections (3+ minutes).
Scope:
- Add to
.gcloudignore:apps/api/build/ apps/api/.gradle/ **/node_modules/ **/.next/ **/dist/ **/.turbo/ - Test local:
gcloud meta list-files-for-upload(dry-run to see filtered file list) - Verify upload size reduction: target <100MB
- PR + merge
- Verify next Cloud Build web deploy upload time <30s
Acceptance criteria:
- Cloud Build upload step duration <30s (down from 180s)
- Build still succeeds (no missing files causing build failures)
Tracked Tech Debt (DEPLOY-MAP.md)
TD-2: Cloud SQL Public IP, No SSL/IAM Auth
MC: #10240 (open)
Severity: MEDIUM (stage), BLOCKER (prod)
Current state:
- Stage DB
bilko-staging-dballows connections from0.0.0.0/0 requireSsl=falsein connection string- Direct TCP to public IP
35.228.33.112:5432 - Password-based auth (secret in env var)
Risk:
- Credential rotation requires redeploy
- No certificate pinning
- Network traffic unencrypted
Required for prod:
- Implement
cloud-sql-socket-factoryinbuild.gradle.kts - Switch to Cloud SQL IAM database authentication (service account-based)
- Remove public IP, use private VPC peering OR Cloud SQL Auth Proxy
Reference: ADR-023-postgresql-on-cloud-sql.md (exists, drives implementation)
TD-3: PROD Still on Express
MC: #10502 (see above)
Severity: BLOCKER
Pre-Existing Blueprint Violations (Score 61/100)
Source: BUILD-BLUEPRINT.md audit 2026-04-29
MEDIUM Violations (3)
1. Package Naming x2
What: Two packages violate ALAI package naming standard (@alai/<name>):
@bilko/api-types(should be@alai/bilko-api-types)@bilko/database(should be@alai/bilko-database)
Impact: Cannot publish to ALAI npm registry (npm.alai.no) without rename.
Blocker for: Multi-repo code sharing (if Bilko utilities needed in other products).
Fix effort: Low (rename in package.json + update imports).
2. Dockerfile Base Image (Chainguard vs Distroless)
What: apps/web/Dockerfile uses cgr.dev/chainguard/node:latest-dev (resolved MC #10442 CVE fix). ALAI standard is gcr.io/distroless/nodejs.
Rationale for deviation: Chainguard swap was emergency CVE-2026-4878 mitigation. Distroless base had unpatched vulnerability at time of fix.
Status: Acceptable deviation (ADR-022 or inline justification should document this).
Action: No immediate change needed, but document rationale in apps/web/Dockerfile comment.
Known Unimplemented Features (From UAT)
1. Email Verification Flow (US-001 AC1-2)
Scope: Registration issues JWT immediately without email verification.
Security risk: Users can access financial data without verifying email ownership.
Required:
- Send verification email on registration (token link)
GET /auth/verify-email?token=<token>endpoint- UI confirmation page
- Block sensitive actions until verified (e.g., invoice send, bank connection)
Priority: P1 (security + compliance)
2. Automated Overdue Invoice Detection (US-012 AC2)
Scope: No scheduler exists to flip invoice status to overdue when due_date < NOW().
Impact: Users never see overdue invoices unless status set manually via API.
Required:
- Cloud Scheduler job (daily at 06:00 UTC)
- Kotlin endpoint
POST /internal/invoices/check-overdue(internal-only, auth bypass) - Query invoices where
status = 'sent' AND due_date < NOW()→ update status tooverdue - Optional: send overdue notification email
Priority: P1 (core workflow)
3. Serbian CoA Seeding (US-001 AC4, US-030 AC1)
Scope: CountryService.seedChartOfAccounts() exists but not called from registration.
Impact: New orgs have empty chart of accounts.
Fix: Add function call in AuthService.register() after org creation.
Priority: P1 (user onboarding)
4. Multi-Org Support (US-004)
Scope: Each user has single organizationId. No switcher.
Impact: Accountants managing multiple companies must log out/in with different emails.
Required:
user_organizationsjunction tableGET /users/me/organizations,POST /users/me/switch-organization- Org switcher dropdown in top-bar
Priority: P1 (SMB accountant use case)
5. Real SEF Integration (US-011)
Scope: Stub sefId (SEF-STUB-<id>) issued, no real efaktura.gov.rs HTTP.
Legal risk: Serbian e-invoicing law mandates real submission.
Decision pending: CEO choice (real integration vs honest banner).
Priority: P0 (legal compliance) or DEFERRED (if banner chosen)
Post-Sprint 0 Metrics
Completed Work (2026-05-02)
- 3 PRs merged: #39 (Express deletion), #40 (Sprint 0 P0), #41 (Dockerfile fix)
- 2 P0 bugs fixed: Registration ENUM + field contract
- 141 files deleted: Express backend removal
- 1 regression resolved: Web Dockerfile COPY reference
Open Bilko MCs (Post-Cleanup)
Total: 45 MCs remaining (down from 69 pre-cleanup, per MC #10300 sweep)
By priority:
- H: 8 (includes #10495, #10502)
- M: 22 (includes #10496, #10498, #10500, #10504)
- L: 15 (includes #10497)
By status:
- Open: 42
- In-progress: 3
- Blocked: 0 (after CEO triage)
References
MCs:
- MC #10487 — UAT Phase 1 (discovery)
- MC #10493 — Express deletion (DONE)
- MC #10494 — Sprint 0 P0 (DONE)
- MC #10495 — Sprint 1 (OPEN)
- MC #10496 — Sprint 2 (OPEN)
- MC #10497 — Sprint 3 (OPEN)
- MC #10498 — Arch roadmap (OPEN)
- MC #10500 — angie-jones re-run (OPEN)
- MC #10502 — PROD CUTOVER (OPEN, BLOCKER)
- MC #10504 — .gcloudignore (OPEN)
- MC #10240 — postgres-socket-factory (OPEN, TD-2)
Docs:
- DEPLOY-MAP.md — Cloud Run inventory + TD tracking
- BUILD-BLUEPRINT.md — Package standards + violations
- USER-STORIES.md — Acceptance criteria source
- ADR-023 — PostgreSQL on Cloud SQL (IAM auth guidance)
Evidence:
/tmp/bilko-uat-ux-10487.md(maria-santos UX report)/tmp/bilko-uat-gap-10487.md(petter-graff architecture gaps)
Bilko repo: https://github.com/johnatbasicas/bilko
No comments to display
No comments to display