Files
SigHej/Docs/ARCHITECTURE.md

98 lines
4.3 KiB
Markdown
Raw Normal View History

2026-05-12 18:21:25 +02:00
# Architecture — Social Proximity
## System Overview
Social Proximity er bygget som et minimal monorepo med tre separate komponenter:
```
┌────────────────────────────────────────────────────────┐
│ Mobile App (Flutter) │
│ │
│ BLE Scanner ──► Match Screen ──► "Say hello" nudge │
└───────────────────────┬────────────────────────────────┘
│ HTTPS + WebSocket
┌────────────────────────────────────────────────────────┐
│ Backend (FastAPI) │
│ │
│ Match Engine ──► Session Store (Redis) ──► DB (PG) │
└───────────┬────────────────────────────────────────────┘
│ Internal API
┌────────────────────────────────────────────────────────┐
│ Admin Dashboard (Next.js) │
│ │
│ Anonymised stats — pings, sessions, interest counts │
└────────────────────────────────────────────────────────┘
```
## Components
### Mobile App
- **Technology:** Flutter (Dart) — cross-platform Android + iOS
- **BLE library:** `flutter_blue_plus`
- **Responsibility:** BLE scanning and advertisement, interest profile, consent toggle, nudge display
- **Does NOT:** store data persistently, track location, communicate with other users directly
### Backend
- **Technology:** FastAPI (Python) + WebSockets
- **Session store:** Redis — ephemeral sessions, no long-term identity storage
- **Database:** PostgreSQL — anonymised aggregate stats only
- **Responsibility:** receive BLE advertisement tokens, match users, push nudge via WebSocket, aggregate stats
### Admin Dashboard
- **Technology:** Next.js (TypeScript)
- **Responsibility:** display anonymised platform stats — no PII, no user-level data
- **Access:** Internal only (no public-facing auth in MVP)
## Data Flow
### Happy path — two users nudged to talk
```
User A opens app, selects interests, enables "open to talk"
└─► App generates ephemeral BLE token
└─► App advertises token via BLE
└─► App registers token + interests with backend (POST /session)
User B nearby detects User A's BLE token
└─► App sends token to backend (POST /match)
└─► Backend checks: does B's interest list overlap with A's?
└─► If overlap + both consent: backend sends WebSocket nudge to both
"Someone nearby also works with DevOps and enjoys hardstyle"
└─► Users see nudge, put phones down, say hello
└─► Session expires automatically (Redis TTL: 2 hours)
```
### Privacy properties
- BLE tokens are ephemeral — regenerated every session
- Backend never stores exact location or movement history
- Interest matching happens server-side — apps never see each other's raw profile
- After session expiry, all session data is deleted from Redis
## Infrastructure
| Environment | Platform |
|---|---|
| Local dev | Docker Compose (backend + PostgreSQL + Redis) |
| Production | Azure Container Apps or Kubernetes (i80.dk) |
## Repository Structure
```
SigHej/
├── README.md
├── Docs/ ← Technical documentation (this folder)
├── backend/ ← FastAPI application
├── app/ ← Flutter mobile app
├── admin/ ← Next.js admin dashboard
└── docker-compose.yml
```
See individual docs for each component:
- [BACKEND.md](./BACKEND.md)
- [APP.md](./APP.md)
- [ADMIN.md](./ADMIN.md)
- [TESTING.md](./TESTING.md)
- [DECISIONS.md](./DECISIONS.md)