4.3 KiB
4.3 KiB
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: