Files
SigHej/Docs/ARCHITECTURE.md
Henrik Jess Nielsen 99e9b509a0
Some checks failed
Backend CI / test (push) Has been cancelled
Flutter CI / analyze-and-test (push) Has been cancelled
eksplicit mapping af envs
2026-05-12 18:21:25 +02:00

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: