Files

72 lines
4.4 KiB
Markdown

### 📱 PERSON A — Web App (Customer-Facing)
#### Functional Requirements
- **WEB-FR-1**: User registration (email + password) with email verification
- **WEB-FR-2**: Login / logout
- **WEB-FR-3**: Password reset flow
- **WEB-FR-4**: Display the event's card offering — name, description, price, expiration date
- **WEB-FR-5**: Checkout flow via Stripe (EUR)
- _Open item: single card per order, or multiple?_
- **WEB-FR-6**: On confirmed payment (via Stripe webhook), trigger card/QR generation (calls shared backend)
- **WEB-FR-7**: Send confirmation email with QR code attached/embedded (via transactional email service)
- **WEB-FR-8**: "My Cards" account page — shows purchase history, card status (unused/used/expired), QR re-download button
- **WEB-FR-9**: Basic account settings page (update email/password)
#### Non-Functional Requirements
- **WEB-NFR-1**: HTTPS only
- **WEB-NFR-2**: GDPR-compliant — privacy policy, consent checkbox at registration, data retention/erasure process
- **WEB-NFR-3**: No raw card/payment data stored — Stripe handles PCI compliance, you only store payment references
- **WEB-NFR-4**: Responsive design (mobile browser support, since users will pull up emails on phones too, though the QR itself is scanned by the admin's phone, not theirs)
#### Open Items for This Side
1. Multi-card orders — yes/no, and if yes, does each card need a separate recipient email field?
2. Refund/cancellation flow — in scope for v1 or not?
3. Any requirement to resend the QR email if a user loses it (vs. just downloading from account page)?
---
### 📷 PERSON B — Android Scanner App (Admin-Facing)
#### Functional Requirements
- **APP-FR-1**: Single admin login (one hardcoded/managed admin role — no multi-account complexity)
- **APP-FR-2**: Camera-based QR scanning (use a standard library — e.g., ML Kit or ZXing)
- **APP-FR-3**: On scan, send token to backend validation endpoint
- **APP-FR-4**: Display result clearly and immediately:
- ✅ **Valid** → show card owner name + card type, mark as used
- ❌ **Already Used** → show when it was originally used
- ❌ **Expired** → show expiration date
- ❌ **Not Found** → invalid/forged code
- **APP-FR-5**: Local on-device scan log (timestamp + result) for admin's own reference during the event
- **APP-FR-6**: Manual entry fallback (in case camera/QR fails to scan — type in code manually)
#### Non-Functional Requirements
- **APP-NFR-1**: Requires internet connectivity to validate (confirm: acceptable, or do you need offline fallback?)
- **APP-NFR-2**: Fast response time — scan-to-result should feel instant (sub-1s ideally) since there may be a line of people
- **APP-NFR-3**: Simple, high-contrast UI readable in bright outdoor daylight or dark event lighting
- **APP-NFR-4**: Since it's single-admin/single-device, no need to handle concurrent scan conflicts — backend validation is still atomic, but app itself doesn't need sync logic
#### Open Items for This Side
1. **Offline fallback** — if there's no signal at the venue, what happens? Worth deciding now since it affects architecture (native online-only call vs. local cache + sync).
2. Does the admin need to _undo_ an accidental valid scan (e.g., mis-scan, wrong card)?
3. Any requirement to see a running count (e.g., "142 checked in") during the event?
---
### 🔗 SHARED — Backend Contract (Both of you depend on this)
This is the glue between your two apps — worth agreeing on before you start building independently, since a mismatch here is the most likely source of integration pain later.
- **API-1**: `POST /api/orders` — creates order, integrates Stripe checkout
- **API-2**: Stripe webhook handler — on payment success, generates Card record + signed QR token, triggers email
- **API-3**: `POST /api/cards/validate` — takes scanned token, returns `{status: valid|used|expired|not_found, owner_name, card_type, used_at?}`, atomically updates status if valid
- **API-4**: `GET /api/users/me/cards` — for the web app's "My Cards" page
- **API-5**: Shared **Card** data model: `id, unique_token (signed), user_id, card_type, status, purchased_at, expires_at, used_at`
- **API-6**: Auth — separate token/role for admin scanner vs. customer web sessions
**Recommendation:** whoever owns the backend (or whoever's building it jointly) should nail down the exact JSON shape of `API-3`'s response first, since that's the contract Person B's UI directly renders.