Twenty days. Sixty-seven commits. One working product.

Blood went from “I need to understand my blood test” to v1.23.2 in three weeks. This post covers where we are, what’s next, what technical debt I’m carrying intentionally, and what success looks like six months from now.

Current State: v1.23.2

Code:

  • 5,800 lines of code (frontend + backend)
  • 67 commits
  • 17 unit tests + regression tests + E2E tests
  • 0 critical security vulnerabilities

Infrastructure:

  • AWS eu-west-3 (Paris)
  • CloudFront CDN (test + prod)
  • Lambda (Python 3.12)
  • S3 (frontend hosting + job state)
  • API Gateway (throttled: burst 30, rate 10/s)

Costs:

  • €22/month during development (includes testing overhead)
  • Projected €30-50/month at 1,000 tests/month
  • AI costs: ~€0.003 per test (Bedrock Nova 2 Lite)

Features Complete:

  • PDF upload (drag-drop + click-to-browse)
  • Password-protected PDF support
  • AI analysis (extraction + outlier explanation + conclusion)
  • Results visualization (range bars, donut charts, trend lines)
  • IndexedDB storage (persistent across sessions)
  • Test history (list, delete, navigate)
  • Trends page (worsening/improving/stable classification)
  • Manual entry mode (JSON paste or form)
  • Privacy notice (full GDPR compliance)
  • Consent banner (AI as recommended option)
  • Feedback widget (Discord notifications)
  • Mobile responsive (iOS Safari + Android Chrome tested)
  • tinycount analytics (fire-and-forget, privacy-respecting)

The Backlog: What’s Next

Phase 1: Launch Readiness (June 2026)

ItemPriorityStatus
Deploy race fixHIGH[ ] Split HTML + asset sync into atomic operation
Rate limiting (WAF)HIGH[ ] AWS WAF rule: 100 req/5min per IP
Log retention enforcementMEDIUM[~] Need aws logs put-retention-policy per-env
Semantic version tagMEDIUM[ ] git tag v1.0.0 on main

Phase 2: UX Polish (June-July 2026)

ItemPriorityStatus
BYOK flow redesignMEDIUM[~] File-optional, prompt-first experience
Canonicalize imported markersMEDIUM[ ] Ensure trends match for manual entries
Accessibility auditLOW[ ] WCAG 2.1 AA compliance
Dark modeLOW[ ] User preference toggle

Phase 3: Growth Features (Q3 2026)

ItemPriorityStatus
Google Drive syncHIGH[ ] Cross-device storage (Phase 2)
Multi-language (NL/FR)MEDIUM[ ] Belgian market requirement
Compare modeLOW[ ] Side-by-side two tests
Health context profileMEDIUM[ ] Medications, conditions, goals
Next test planningLOW[ ] AI suggests markers to re-check

Phase 4: Monetization (Q4 2026)

ItemPriorityStatus
Soft gate (3 free tests)HIGH[x] Counter implemented, not enforced
Payment integrationMEDIUM[ ] Stripe or Paddle
Paid tier featuresMEDIUM[ ] Unlimited tests, cloud backup, trends export
B2B pricingLOW[ ] Whitelabel for labs

Technical Debt Inventory

Some debt is intentional. Some is accidental. Here’s the list:

Intentional Debt (Will Refactor Later)

  1. Frontend state management: Currently using Svelte stores. Might migrate to runes-only pattern once Svelte 5 ecosystem matures.
  2. Test coverage: 17 backend tests, minimal frontend tests. Adequate for MVP, needs expansion before scale.
  3. Error messages: User-facing errors are generic (“Analysis failed”). Should be more specific without leaking implementation details.

Accidental Debt (Should Fix Soon)

  1. Deploy race condition: Two overlapping pipelines can leave index.html pointing to deleted JS assets. Fix: merge HTML + asset sync into one aws s3 sync call.
  2. Log retention: CloudWatch log groups auto-created by Lambda can’t have retention set via CFN without import. Fix: run aws logs put-retention-policy --retention-in-days 90 per-environment.
  3. Untracked benchmark scripts: scripts/benchmark_*.py files not committed. Either commit or delete.

Lessons Learned

What Went Well

  1. Constraints enabled speed: “Privacy by architecture” eliminated entire classes of decisions (no database design, no auth system).
  2. Async job pattern: Beat the 30-second API Gateway timeout cleanly. Reusable pattern for any slow AI workflow.
  3. Bedrock Nova 2 Lite: Right balance of cost, speed, and EU residency.
  4. Svelte 5: Small bundles, fast dev loop, no runtime bloat.
  5. GitLab CI/CD: Auto-deploy to test on every commit caught bugs early.

What I’d Do Differently

  1. Mobile testing earlier: Waited until users reported problems. Should’ve tested on real devices from day one.
  2. Progress indicator sooner: Infinite spinner was a known issue. Fixed it after first user complaint instead of anticipating it.
  3. Benchmark earlier: Almost shipped with nova_direct extraction. Would’ve caught the duplicate marker issue with earlier benchmarking.
  4. Log retention from start: Anonymized telemetry is clean, but should’ve set retention policy before first log written.

Success Criteria (6 Months Out)

December 2026 targets:

MetricTargetCurrent
Monthly active users1,000~50 (beta)
Tests processed/month5,000~200 (beta)
Error rate<1%0.3%
p95 latency<30s34s
Revenue€5,000/month€0 (free beta)
NPS>40Not measured yet

Qualitative goals:

  • Users recommend Blood to friends unprompted
  • At least one lab partnership inquiry
  • DevLog series drives meaningful traffic to insightlab.be
  • Zero security incidents or data breaches

The Philosophy Holds

Three principles guided every decision:

  1. Privacy by Architecture: No server-side storage. No accounts. No cookies. IndexedDB only.
  2. EU Data Residency: Everything in eu-west-3. AWS DPA for GDPR Art. 9 compliance.
  3. AI as Translator: Explains context, not prescriptions. Amplifies human judgment.

These weren’t constraints that slowed us down. They were the product.

What’s Next

Post-launch priorities:

  1. Rate limiting — Before any public sharing beyond closed beta
  2. Google Drive sync — Most requested feature (cross-device access)
  3. Multi-language — Dutch and French for Belgian market
  4. Payment integration — Freemium model: 3 free tests, then paid

And I’ll keep writing DevLogs. Next series might cover:

  • Scaling to 10,000 users/month
  • Internationalization patterns
  • Payment integration without compromising privacy
  • Lab partnership technical requirements

This is post #6 (final) in the Blood Development Log series. Read post #5 → | Series index →

Blood is built by DGTL bv. Privacy-first. EU-hosted. AI-powered.

🀄