UAT Sign-Off: Drop — Fintech Payment App
UAT Sign-Off: Drop — Fintech Payment App
Project: Drop — Remittance + QR Payments Version: 0.5.0 Date: 2026-02-23 Author: John (AI Director) Status: Draft — Pending Alem Bašić (CEO) sign-off Reviewers: Alem Bašić (CEO)
Document History
| Version | Date | Author | Changes |
|---|---|---|---|
| 0.1 | 2026-02-23 | John | Initial UAT sign-off document — Phase 0.5 Security Hardening |
1. UAT Overview & Objectives
Release: Drop v0.5.0 — Phase 0.5 Security Hardening
UAT Period: TBD (before Phase 1 production launch)
UAT Environment: https://drop-staging.fly.dev/
Objectives:
- Confirm that all Phase 0.5 security hardening features match the agreed acceptance criteria
- Validate that all original MVP business flows (registration, login, remittance, QR payment) remain intact after security changes
- Verify that the pass-through model invariant is enforced: Drop NEVER holds customer funds
- Provide formal business sign-off by Alem Bašić (CEO) for production deployment
Scope of this UAT:
- Authentication module (registration, OTP, PIN, login) with security hardening
- Remittance flow (0.5% fee, 6 NOK corridors, mock BaaS)
- QR payment flow (1% fee, mock merchant, mock BaaS)
- Exchange rates API (6 corridors)
- Security features (rate limiting, CSRF, input validation, security headers)
- Database compliance checks (no balance column, no card_number/cvv)
Out of scope:
- BankID integration (Phase 2)
- Real BaaS payments (Phase 2)
- Real Sumsub KYC (Phase 2)
- Cards feature (Phase 3)
- Mobile native app (Phase 2)
2. Test Environment & Access
| Parameter | Value |
|---|---|
| UAT URL | https://drop-staging.fly.dev/ |
| Version deployed | v0.5.0 |
| Deployed on | TBD |
| Data state | Synthetic seed data only — no real user data (GDPR/NFR-D04 compliance) |
Test account credentials:
| Account | Password | Role | Use For | |
|---|---|---|---|---|
| Consumer (Amir) | [email protected] |
In Vaultwarden: "Drop UAT Consumer" | Consumer user (KYC approved) | Registration, login, remittance, QR payment |
| Merchant (Ahmet) | [email protected] |
In Vaultwarden: "Drop UAT Merchant" | Merchant user | Merchant registration, QR code generation |
| New user | Use fresh email | As specified in test steps | None (fresh) | End-to-end registration flow |
Support during UAT: Contact John (AI Director) via #drop-uat Slack channel on alai-talk.slack.com for environment issues.
3. UAT Participants
| Name | Title | Module Responsibility | Contact | Available Until |
|---|---|---|---|---|
| Alem Bašić | CEO / Product Owner | All modules — final sign-off | [email protected] | TBD |
| John | AI Director | Technical liaison — answers questions | MCP email / Slack | Continuous |
| Validator Agent | QA Agent (AI) | Automated pre-UAT verification | Mission Control | Continuous |
UAT Coordinator: John (AI Director) Engineering Liaison: John (AI Director) — available to answer questions during UAT window
4. Test Scenarios
Module: Authentication & Onboarding
Tester: Alem Bašić Priority: Critical
Scenario AUTH-001: Successful User Registration (3-step)
| Field | Value |
|---|---|
| Description | New user completes full registration: email + DOB → OTP → PIN. Tests the core onboarding business process. |
| Priority | Critical |
| Preconditions | Fresh email address; Norwegian phone (+47); age ≥ 18 |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Navigate to https://drop-staging.fly.dev/ | Landing page loads; "Registrer deg" button visible | ||
| 2 | Click "Registrer deg"; fill form with valid data (name, email, password ≥8 chars, Norwegian phone, DOB ≥ 18 years) | Form accepts input; submit button active | ||
| 3 | Submit registration form | OTP sent to phone; OTP input screen shown; no password hash in response | ||
| 4 | Enter correct 6-digit OTP | PIN setup screen shown | ||
| 5 | Enter and confirm 4-digit PIN | Account activated; redirected to dashboard; JWT httpOnly cookie set |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Alem Bašić | Date: _______________
Scenario AUTH-002: Under-18 Rejected
| Field | Value |
|---|---|
| Description | System rejects users under 18 years of age (Norwegian regulatory requirement, minimum age BankID) |
| Priority | Critical |
| Preconditions | Registration form accessible |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Navigate to registration form | Form accessible | ||
| 2 | Enter DOB indicating age < 18 years (e.g., born today minus 17 years) | |||
| 3 | Submit form | 422 error displayed; message "Du må være minst 18 år" (or equivalent); no account created |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Alem Bašić | Date: _______________
Scenario AUTH-003: Successful Login
| Field | Value |
|---|---|
| Description | Registered user logs in and accesses protected dashboard |
| Priority | Critical |
| Preconditions | Registered, OTP-verified, PIN-setup user account exists |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Navigate to https://drop-staging.fly.dev/login | Login form displayed | ||
| 2 | Enter valid email and password | |||
| 3 | Submit login | 200 response; JWT httpOnly cookie set; redirected to dashboard | ||
| 4 | Navigate to /api/auth/me |
200; user object returned (no password hash visible) |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Alem Bašić | Date: _______________
Scenario AUTH-004: Rate Limiting — Auth Endpoint
| Field | Value |
|---|---|
| Description | System blocks brute force login attempts with persistent rate limiting |
| Priority | Critical |
| Preconditions | None |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Make 10 rapid login attempts with wrong password | Each returns 401 | ||
| 2 | Make 11th login attempt | 429 Too Many Requests returned; rate limit message shown | ||
| 3 | Wait 1 minute and retry | Login attempt succeeds (if credentials correct) |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Alem Bašić | Date: _______________
Module: Remittance (Send Money)
Tester: Alem Bašić Priority: Critical
Scenario REM-001: Successful Remittance — NOK to RSD
| Field | Value |
|---|---|
| Description | KYC-approved user sends 1,000 NOK to Serbia. Tests core Drop remittance business process with correct fee calculation. |
| Priority | Critical |
| Preconditions | Logged-in user with KYC status = approved; valid recipient; mock BaaS configured |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Log in as consumer (Amir) | Dashboard visible; bank balance shown (mock) | ||
| 2 | Click "Send penger" (Send Money) | Remittance form shown | ||
| 3 | Select recipient; enter amount = 1,000 NOK; select currency = RSD | Fee displayed as 5 NOK (0.5%); recipient amount shown | ||
| 4 | Confirm and submit remittance | 201 created; transaction record created with status=completed; transaction appears in history | ||
| 5 | Navigate to Transaction History | Transaction shows: amount=1,000 NOK, fee=5 NOK, type=remittance, currency=RSD |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Alem Bašić | Date: _______________
Scenario REM-002: Insufficient Balance Rejected
| Field | Value |
|---|---|
| Description | System prevents remittance when user's bank balance is insufficient (pass-through model validation) |
| Priority | Critical |
| Preconditions | Logged-in user; mock balance set below remittance amount + fee |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Enter remittance amount exceeding available balance | |||
| 2 | Submit remittance | 402 "Insufficient balance" error; no transaction created; no money moved |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Alem Bašić | Date: _______________
Scenario REM-003: Exchange Rates Available
| Field | Value |
|---|---|
| Description | All 6 NOK corridors return current exchange rates |
| Priority | High |
| Preconditions | None (public endpoint) |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Navigate to /api/rates |
6 exchange rates returned (NOK→RSD, NOK→BAM, NOK→PKR, NOK→TRY, NOK→PLN, NOK→EUR) | ||
| 2 | Navigate to /api/rates/RSD |
Single NOK→RSD rate returned | ||
| 3 | Navigate to /api/rates/rsd (lowercase) |
Same result as step 2 (case insensitive) | ||
| 4 | Navigate to /api/rates/XXX |
404 Not Found |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Alem Bašić | Date: _______________
Module: QR Payments
Tester: Alem Bašić Priority: Critical
Scenario QR-001: Merchant Registration + QR Code Generation
| Field | Value |
|---|---|
| Description | User registers as merchant and receives unique QR code for accepting payments |
| Priority | Critical |
| Preconditions | Logged-in user |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Navigate to Merchant dashboard | Merchant registration form shown | ||
| 2 | Enter business_name and bank_account; submit | Merchant created with unique QR code value | ||
| 3 | Navigate to GET /api/merchants/me |
Merchant details + QR code returned |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Alem Bašić | Date: _______________
Scenario QR-002: Successful QR Payment
| Field | Value |
|---|---|
| Description | Consumer scans merchant QR code and completes payment with 1% merchant fee |
| Priority | Critical |
| Preconditions | Logged-in consumer (Amir) with KYC approved; registered merchant (Ahmet) |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Navigate to "Scan QR" screen | Camera/QR input shown | ||
| 2 | Enter valid merchantId; amount = 200 NOK | Fee displayed: 2 NOK (1%); merchant receives 200 NOK (gross) | ||
| 3 | Confirm payment | 201 created; transaction record with merchant_fee = 2 NOK | ||
| 4 | Check transaction history | QR payment appears with correct amounts |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Alem Bašić | Date: _______________
Module: Security & Compliance
Tester: Alem Bašić + Validator Agent Priority: Critical
Scenario SEC-001: No CVV or Card Number in Database
| Field | Value |
|---|---|
| Description | PCI-DSS compliance: Drop must never store full card numbers or CVV codes |
| Priority | Critical |
| Preconditions | Access to database schema |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Run db.test.ts compliance tests |
All pass: users table has NO balance column; cards table has NO card_number or cvv columns | ||
| 2 | Verify via GET /api/cards/[id] response |
Response contains last_four only; no full card number |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Validator Agent | Date: _______________
Scenario SEC-002: No Balance Column in Users Table
| Field | Value |
|---|---|
| Description | Pass-through model compliance: Drop must never store user balances |
| Priority | Critical |
| Preconditions | Database access |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Run db.test.ts assertion: users table schema check |
Test passes: no balance column exists in users table |
||
| 2 | Confirm balance shown on dashboard is read from mock BaaS AISP, not stored in Drop DB | Balance disappears when NEXT_PUBLIC_SERVICE_MODE=offline (no stored value) |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Validator Agent | Date: _______________
Scenario SEC-003: XSS and SQL Injection Rejected
| Field | Value |
|---|---|
| Description | Input validation rejects malicious payloads |
| Priority | Critical |
| Preconditions | Registration form accessible |
Test Steps:
| Step | Action | Expected Result | Actual Result | Status |
|---|---|---|---|---|
| 1 | Enter <script>alert(1)</script> as first name |
422 validation error; no script executed | ||
| 2 | Enter '; DROP TABLE users;-- as email |
422 validation error; users table intact | ||
| 3 | Enter 10,000 character password | 422 "Password too long" error | ||
| 4 | Enter Bosnian characters (š, đ, ć, č, ž) in name field | 201 created; name stored correctly with Unicode |
Overall Result: Pass / Fail / Blocked Notes: _______________ Tester: Validator Agent | Date: _______________
5. UAT Results Summary
| Module | Scenarios | Passed | Failed | Blocked | Pass Rate |
|---|---|---|---|---|---|
| Authentication & Onboarding | 4 | TBD | TBD | TBD | TBD% |
| Remittance | 3 | TBD | TBD | TBD | TBD% |
| QR Payments | 2 | TBD | TBD | TBD | TBD% |
| Security & Compliance | 3 | TBD | TBD | TBD | TBD% |
| Total | 12 | TBD | TBD | TBD | TBD% |
6. Defects Found During UAT
| # | Description | Module | Severity | Tester | Reported Date | Status | Resolution |
|---|---|---|---|---|---|---|---|
| — | No defects logged yet | — | — | — | — | — | — |
Defect tracking: Mission Control tasks + Slack #drop-bugs
7. Outstanding Issues & Risk Acceptance
Issues Deferred to Future Release
| # | Issue | Severity | Reason for Deferral | Fix Version | Risk Acceptance By |
|---|---|---|---|---|---|
| 1 | BankID SCA not integrated — DOB form validation only | Medium | Requires Finanstilsynet PISP/AISP registration (Phase 2) | v1.0.0 | Alem Bašić (CEO) |
| 2 | Sumsub KYC mocked — no real identity verification | Medium | Requires live Sumsub key + AML production config | v1.0.0 | Alem Bašić (CEO) |
| 3 | BaaS payments mocked — no real bank transactions | Medium | Requires SpareBank1 or Swan BaaS partnership (Phase 2) | v1.0.0 | Alem Bašić (CEO) |
| 4 | Cards feature absent | Low | Requires card partner; feature-flagged (Phase 3) | v2.0.0 | Alem Bašić (CEO) |
Workarounds in Place for Sign-Off
| Issue | Workaround | Acceptable for Production | Accepted By |
|---|---|---|---|
| Mock BaaS | NEXT_PUBLIC_SERVICE_MODE=mock; no real money movement |
Yes — for MVP/staging only; NOT for Phase 1 production | Alem Bašić (CEO) |
| Mock Sumsub KYC | kyc_status auto-approved in dev/staging |
Yes — for MVP/staging only | Alem Bašić (CEO) |
8. Go / No-Go Recommendation
Individual Recommendations
| Participant | Module | Recommendation | Conditions |
|---|---|---|---|
| Validator Agent | All (automated) | Go | All 12 AC-series and NF-AC-series tests passing |
| John (AI Director) | Technical | Go | Security audit score ≥ 80/100 post-Phase 0.5 hardening |
| Alem Bašić (CEO) | All | TBD | Pending CEO UAT execution |
Overall Recommendation
UAT Coordinator recommendation (John): Conditional Go
Rationale: Phase 0.5 delivers the security hardening required before BaaS partner discussions and Finanstilsynet submission. All MVP flows remain functional. Three medium-priority Phase 2 blockers (BankID, real BaaS, real KYC) are accepted as deferred. Production deployment of v0.5.0 is safe for staging-only use. Phase 1 production with real users requires BaaS partnership confirmation.
9. UAT Exit Criteria Verification
- All Critical scenarios executed (12 of 12)
- All High-priority scenarios executed
- Pass rate ≥ 100% for Critical scenarios
- All Critical defects resolved
- All High defects resolved or deferred with risk acceptance by Alem Bašić
- Outstanding issues documented and accepted (see Section 7)
- All UAT participants have completed their assigned scenarios
- UAT environment (drop-staging.fly.dev) matches production configuration (confirmed by John)
-
db.test.tscompliance checks pass — no balance, no card_number, no cvv columns - Playwright user-flows, full-flows, and input-chaos suites all green
Exit criteria met: TBD (pending UAT execution) Exceptions noted: Mock BaaS/KYC accepted as Phase 2 deferred items
10. Sign-Off Table
| Role | Name | Date | Decision | Conditions (if conditional) | Signature |
|---|---|---|---|---|---|
| Product Owner / AI Director | John | 2026-02-23 | Conditional Approve | Security audit score ≥ 80/100 | Approved (AI) |
| QA Lead (Validator Agent) | Validator Agent | TBD | TBD | All test suites green | |
| CEO / Business Stakeholder | Alem Bašić | TBD | TBD | CEO UAT walkthrough complete |
Conditions for Conditional Approval
| # | Condition | Owner | Due Date | Verified By |
|---|---|---|---|---|
| 1 | Security audit re-score ≥ 80/100 after Phase 0.5 hardening | John | Before Phase 1 launch | External pentest or AI security agent |
| 2 | All 12 UAT scenarios pass (100% critical pass rate) | Validator Agent | Before Phase 1 launch | Validator Agent |
| 3 | CEO UAT walkthrough completed | Alem Bašić | TBD | Alem Bašić |
| 4 | BaaS partner confirmed before Phase 1 user onboarding | Alem Bašić | Phase 2 kickoff | Legal + John |
Related Documents
Approval
| Role | Name | Date | Signature |
|---|---|---|---|
| Author | John (AI Director) | 2026-02-23 | Approved (AI) |
| QA Lead | Validator Agent | TBD | |
| CEO (Alem) | Alem Bašić | TBD |
No comments to display
No comments to display