Monorepo: die Flutter-App unter app/, das Backend unter supabase/, Werkzeuge im Root hinter einem Makefile.
Das tragende Konzept im Datenmodell ist die Gruppe. Sichtbarkeit hängt nicht an einer Beziehung zwischen zwei Konten, sondern an einer Gruppenmitgliedschaft: partner_groups plus partner_group_members, und jede Feature-Tabelle führt eine group_id. Row-Level-Security prüft gegen diese Mitgliedschaft — damit gilt dieselbe Regel für Chat, Galerie, Kalender und jedes spätere Modul, ohne dass jedes Modul eigene Rechtelogik bekommt.
Eine Ausnahme ist bewusst geblieben: die Schlüssel für die gerätebasierte Ende-zu-Ende-Verschlüsselung hängen weiter an der Zweierbeziehung, nicht an der Gruppe. Ein Schlüsseltausch ist Sache genau zweier Geräte; ihn auf eine Gruppe auszuweiten würde die Zusicherung aufweichen.
Das Backend ist eine selbst betriebene Supabase-Instanz mit 83 Tabellen. Fünf Edge Functions decken Push und Abrechnung ab; die JWT-Prüfung wird pro Funktion in der config.toml gesetzt, nicht pauschal abgeschaltet — die Webhooks von Apple und Google prüfen stattdessen ihre eigene Signatur.
Konfiguration kommt über --dart-define aus einer .env, die das Makefile lädt. Es liegen keine Secrets im Dart-Code und keine in der Dokumentation.