diff --git a/.gitignore b/.gitignore index 5cd5f4c..50a6733 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ graphify-out/cache/ # graphify Hook-Backups (dated, 14 MB je) — nicht tracken graphify-out/20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]/ graphify-out/graph.html + +# Generated screenshot artifacts (Maestro/preview pipeline output — regeneratable) +/screenshots/ diff --git a/apps/marketing/app/pages/account-loeschen.vue b/apps/marketing/app/pages/account-loeschen.vue index dee8bdc..3935078 100644 --- a/apps/marketing/app/pages/account-loeschen.vue +++ b/apps/marketing/app/pages/account-loeschen.vue @@ -25,7 +25,7 @@
  • Tippe auf das Profil-Icon oben rechts
  • Wähle Einstellungen
  • Scrolle zu Konto und tippe auf Konto löschen
  • -
  • Bestätige die Löschung — alle Daten werden innerhalb von 30 Tagen unwiderruflich entfernt
  • +
  • Bestätige die Löschung. Alle Daten werden innerhalb von 30 Tagen unwiderruflich entfernt
  • @@ -35,7 +35,7 @@

    Falls du keinen Zugriff mehr auf die App hast, schreibe uns:

    E-Mail: datenschutz@rebreak.org

    -

    Betreff: „Konto-Löschung — ReBreak"

    +

    Betreff: „Konto-Löschung ReBreak"

    Bitte gib die mit deinem Konto verknüpfte E-Mail-Adresse an, damit wir dein Konto eindeutig identifizieren können.

    Deine Anfrage wird innerhalb von 30 Tagen bearbeitet. Wir senden dir eine Bestätigung sobald die Löschung abgeschlossen ist.

    diff --git a/apps/marketing/app/pages/download/android.vue b/apps/marketing/app/pages/download/android.vue index dd81b4e..ea36e7b 100644 --- a/apps/marketing/app/pages/download/android.vue +++ b/apps/marketing/app/pages/download/android.vue @@ -20,7 +20,7 @@ - Beta — iOS ist die Hauptplattform + Beta, iOS ist die Hauptplattform @@ -95,7 +95,7 @@ const apkUrl = "/downloads/rebreak-android-latest.apk"; useSeoMeta({ title: "Rebreak für Android – APK Download", - description: "Lade die Rebreak Gambling-Recovery App als APK für Android herunter. Beta-Version – iOS ist die Hauptplattform.", + description: "Lade die Rebreak Gambling-Recovery App als APK für Android herunter. Beta-Version, iOS ist die Hauptplattform.", }); definePageMeta({ diff --git a/apps/marketing/app/pages/download/rebreakmagic.vue b/apps/marketing/app/pages/download/rebreakmagic.vue index 35618d4..c255f66 100644 --- a/apps/marketing/app/pages/download/rebreakmagic.vue +++ b/apps/marketing/app/pages/download/rebreakmagic.vue @@ -8,7 +8,7 @@

    RebreakMagic

    -

    Lock-Modus für iPhone — ohne Reset

    +

    Lock-Modus für iPhone, ohne Reset

    @@ -20,14 +20,14 @@ - Beta — Companion-App für ReBreak iOS + Beta, Companion-App für ReBreak iOS

    Warum „Magic"? Normalerweise muss ein iPhone komplett zurückgesetzt werden, - um in den Lock-Modus (Supervised-Mode) zu wechseln — alle Daten weg. RebreakMagic schafft + um in den Lock-Modus (Supervised-Mode) zu wechseln, und alle Daten sind weg. RebreakMagic schafft das ohne Reset: Fotos, Apps, Chats, Settings bleiben. In ~2 Minuten.

    @@ -62,7 +62,7 @@

    Erste Öffnung erlauben

    - App ist (noch) unsigniert — Rechtsklick → Öffnen → Bestätigen. Macht macOS einmalig nötig. + App ist (noch) unsigniert: Rechtsklick → Öffnen → Bestätigen. Macht macOS einmalig nötig.

    @@ -103,7 +103,7 @@

    Drei Wege, geordnet nach Aufwand: 1) deine Vertrauensperson (Trustee) entsperrt aus der ReBreak-App. 2) iPhone erneut am Mac mit RebreakMagic anschließen und „Reset" wählen. - 3) Werks-Reset des iPhones (letzter Notausweg — alle Daten weg). + 3) Werks-Reset des iPhones (letzter Notausweg, alle Daten weg). Das ist Designprinzip: der Schutz soll genau dem Impuls standhalten, der ihn loswerden will.

    @@ -137,7 +137,7 @@ const dmgUrl = "/downloads/RebreakMagic-latest.dmg"; useSeoMeta({ title: "RebreakMagic für Mac – Lock-Modus ohne Reset", description: - "Companion-App für ReBreak iOS. Aktiviert den Lock-Modus deines iPhones in ~2 Minuten per USB-Kabel — ohne Werks-Reset, ohne Datenverlust.", + "Companion-App für ReBreak iOS. Aktiviert den Lock-Modus deines iPhones in ~2 Minuten per USB-Kabel, ohne Werks-Reset und ohne Datenverlust.", }); definePageMeta({ diff --git a/apps/marketing/app/pages/download/windows.vue b/apps/marketing/app/pages/download/windows.vue index 4375c8c..0288a7c 100644 --- a/apps/marketing/app/pages/download/windows.vue +++ b/apps/marketing/app/pages/download/windows.vue @@ -20,14 +20,14 @@ - Beta — für Pro & Legend + Beta, für Pro & Legend

    Systemweiter Schutz. ReBreak für Windows blockt Glücksspielseiten - auf DNS-Ebene — in jedem Browser, jeder App. Auch Chrome, Edge und + auf DNS-Ebene, in jedem Browser und jeder App. Auch Chrome, Edge und Brave, die normalerweise das System-DNS umgehen, werden zuverlässig gefiltert. Ein Hintergrunddienst schützt die Einstellung vor dem Abschalten.

    @@ -69,7 +69,7 @@ 3

    Fertig

    -

    Der Schutz läuft ab sofort im Hintergrund — auch nach einem Neustart.

    +

    Der Schutz läuft ab sofort im Hintergrund, auch nach einem Neustart.

    @@ -91,7 +91,7 @@

    Wie wird der Schutz wieder gelöst?

    Bewusst nicht per Klick: Der Schutz lässt sich nur mit Wartezeit (Cooldown) wieder - pausieren — das schützt dich genau vor dem Impuls, der ihn im Drang-Moment loswerden will. + pausieren. Das schützt dich vor dem Impuls, der ihn im Drang-Moment loswerden will. Bei Abo-Ende oder Account-Löschung wird der Schutz ordnungsgemäß freigegeben.

    @@ -126,7 +126,7 @@ const exeUrl = "/downloads/RebreakMagic-Setup.exe"; useSeoMeta({ title: "ReBreak für Windows – Glücksspiel-Schutz für deinen PC", description: - "Blockt Glücksspielseiten systemweit auf deinem Windows-PC — in jedem Browser, auch Chrome und Edge. Per DNS-over-HTTPS, mit Tamper-Schutz im Hintergrund.", + "Blockt Glücksspielseiten systemweit auf deinem Windows-PC, in jedem Browser, auch Chrome und Edge. Per DNS-over-HTTPS, mit Tamper-Schutz im Hintergrund.", }); definePageMeta({ diff --git a/apps/marketing/app/pages/nutzungsbedingungen.vue b/apps/marketing/app/pages/nutzungsbedingungen.vue index 3e1c4fc..5c618f2 100644 --- a/apps/marketing/app/pages/nutzungsbedingungen.vue +++ b/apps/marketing/app/pages/nutzungsbedingungen.vue @@ -164,7 +164,7 @@

    § 7 Verfügbarkeit und Wartung

    Der Anbieter bemüht sich um größtmögliche Verfügbarkeit (Best-Effort). Eine konkrete - Verfügbarkeitsgarantie besteht nicht. Wartungsfenster werden – soweit möglich – + Verfügbarkeitsgarantie besteht nicht. Wartungsfenster werden, soweit möglich, rechtzeitig angekündigt.

    diff --git a/apps/marketing/app/pages/pricing.vue b/apps/marketing/app/pages/pricing.vue index d8dd4f2..83dba96 100644 --- a/apps/marketing/app/pages/pricing.vue +++ b/apps/marketing/app/pages/pricing.vue @@ -282,14 +282,14 @@ const quotes = [ initials: "VF", }, { - text: "Bis du das Unbewusste bewusst machst, wird es dein Leben lenken – und du wirst es Schicksal nennen.", + text: "Bis du das Unbewusste bewusst machst, wird es dein Leben lenken, und du wirst es Schicksal nennen.", author: "Carl Gustav Jung", role: "Psychiater & Begründer der analytischen Psychologie", image: "https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/CGJung.jpg/200px-CGJung.jpg", initials: "CJ", }, { - text: "Sucht ist keine Charakterschwäche. Sie ist eine Erkrankung des Gehirns – und sie ist behandelbar.", + text: "Sucht ist keine Charakterschwäche. Sie ist eine Erkrankung des Gehirns, und sie ist behandelbar.", author: "Nora Volkow", role: "Neurowissenschaftlerin, Direktorin des NIDA", image: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9b/Nora_Volkow2.jpg/200px-Nora_Volkow2.jpg", diff --git a/apps/marketing/package.json b/apps/marketing/package.json index eee70ac..14f7df8 100644 --- a/apps/marketing/package.json +++ b/apps/marketing/package.json @@ -27,6 +27,7 @@ "vue-router": "^4.5.1" }, "devDependencies": { + "@iconify-json/simple-icons": "^1.2.86", "@nuxt/devtools": "latest", "typescript": "^5.9.3" } diff --git a/apps/rebreak-magic-mac/Sources/Views/MacRegistrationView.swift b/apps/rebreak-magic-mac/Sources/Views/MacRegistrationView.swift index f399f80..cad5dc3 100644 --- a/apps/rebreak-magic-mac/Sources/Views/MacRegistrationView.swift +++ b/apps/rebreak-magic-mac/Sources/Views/MacRegistrationView.swift @@ -10,6 +10,9 @@ struct MacRegistrationView: View { @State private var successMessage: String? @State private var profileInstalled = false @State private var checkingProfile = false + @State private var isVerifying = false + @State private var verifyStatus = "" + @State private var backendActive = false var body: some View { VStack(spacing: 24) { @@ -67,12 +70,20 @@ struct MacRegistrationView: View { .frame(maxWidth: 400) } + if isVerifying { + verifyingCard + } + HStack(spacing: 12) { Button("← Abbrechen") { model.returnToHub() } .buttonStyle(.bordered) - .disabled(isRegistering || isInstallingProfile) - - if model.magicRegistration == nil { + .disabled(isRegistering || isInstallingProfile || isVerifying) + + if isVerifying { + // Während der Verifikation kein Aktions-Button — der Flow läuft + // automatisch durch und navigiert bei Erfolg zur Übersicht. + EmptyView() + } else if model.magicRegistration == nil { Button("Mac registrieren") { handleRegistration() } .buttonStyle(.borderedProminent) .disabled(isRegistering || macInfo == nil || isInstallingProfile) @@ -84,7 +95,7 @@ struct MacRegistrationView: View { Button("✓ Fertig — zurück zur Übersicht") { model.returnToHub() } .buttonStyle(.borderedProminent) } - + if isRegistering || isInstallingProfile { ProgressView() .controlSize(.small) @@ -141,6 +152,20 @@ struct MacRegistrationView: View { .frame(maxWidth: 400) } + private var verifyingCard: some View { + HStack(spacing: 10) { + ProgressView() + .controlSize(.small) + Text(verifyStatus.isEmpty ? "Wird geprüft…" : verifyStatus) + .font(.callout) + .foregroundStyle(.secondary) + } + .padding() + .background(Color.blue.opacity(0.08)) + .cornerRadius(8) + .frame(maxWidth: 400) + } + @ViewBuilder private func successCard(_ message: String) -> some View { HStack(spacing: 8) { @@ -211,31 +236,94 @@ struct MacRegistrationView: View { errorMessage = "Keine Registrierung vorhanden. Bitte zuerst registrieren." return } - + Task { isInstallingProfile = true errorMessage = nil - + + // 1. Profil herunterladen + System Settings → Profile öffnen. do { try await MacProfileInstaller.downloadAndInstall(registration: registration) - - await MainActor.run { - isInstallingProfile = false - successMessage = "System Settings → Profile geöffnet. Bitte dort „Installieren“ klicken und Admin-Passwort eingeben." - } - - // Re-check profile status nach kurzer Wartezeit (User muss in UI bestätigen) - try? await Task.sleep(nanoseconds: 3_000_000_000) - await checkProfileStatus() - } catch { await MainActor.run { isInstallingProfile = false errorMessage = "Profil-Installation fehlgeschlagen: \(error.localizedDescription)" } + return + } + + await MainActor.run { + isInstallingProfile = false + isVerifying = true + successMessage = "System Settings → Profile geöffnet. Bitte dort „Installieren“ klicken und Admin-Passwort eingeben." + verifyStatus = "Warte auf Profil-Installation…" + } + + // 2. Warten bis das Profil tatsächlich installiert ist (User klickt + // in System Settings „Installieren" + gibt Admin-PW ein). + let profileOK = await pollUntilProfileInstalled(timeoutSeconds: 180) + guard profileOK else { + await MainActor.run { + isVerifying = false + verifyStatus = "" + errorMessage = "Profil noch nicht installiert. Bitte in System Settings → Profile auf „Installieren“ klicken und es erneut versuchen." + } + return + } + + await MainActor.run { + profileInstalled = true + verifyStatus = "Prüfe Schutz-Status am Server…" + } + + // 3. Nebenbei: serverseitigen Binding-Status bestätigen. + let backendOK = await pollBackendActive(token: registration.dnsToken, attempts: 5) + await MainActor.run { + backendActive = backendOK + isVerifying = false + verifyStatus = "" + } + + guard backendOK else { + await MainActor.run { + errorMessage = "Profil installiert, aber der Server bestätigt den Schutz noch nicht. Du kannst es später in der Übersicht prüfen." + } + return + } + + // 4. Erfolg anzeigen, dann zurück zur Übersicht. + await MainActor.run { + successMessage = "✓ Mac geschützt — Glücksspiel-Domains werden jetzt blockiert." + } + try? await Task.sleep(nanoseconds: 1_800_000_000) + await MainActor.run { + model.returnToHub() } } } + + /// Pollt lokal `profiles show` bis das ReBreak-DNS-Profil erscheint (oder Timeout). + private func pollUntilProfileInstalled(timeoutSeconds: Int) async -> Bool { + let deadline = Date().addingTimeInterval(Double(timeoutSeconds)) + while Date() < deadline { + if await MacProfileInstaller.isInstalled() { return true } + try? await Task.sleep(nanoseconds: 2_000_000_000) + } + return await MacProfileInstaller.isInstalled() + } + + /// Pollt `/api/magic/status?token=` bis `active=true` (oder Versuche erschöpft). + private func pollBackendActive(token: String, attempts: Int) async -> Bool { + for attempt in 0.. \ + --env=E2E_TEST_PEER_NICKNAME= \ + apps/rebreak-native/.maestro/onboarding/ \ + apps/rebreak-native/.maestro/sos/ \ + apps/rebreak-native/.maestro/blocker/ \ + apps/rebreak-native/.maestro/calls/ \ + apps/rebreak-native/.maestro/dm/send-message.yaml \ + apps/rebreak-native/.maestro/stress/rapid-post-submit.yaml +``` + +Stress-Tests separat (laenger, geraete-abhaengig): + +```bash +maestro test \ + --env=E2E_TEST_USER=claude-android-test \ + --env=E2E_TEST_PASSWORD= \ + --env=E2E_TEST_PEER_NICKNAME= \ + apps/rebreak-native/.maestro/stress/ +``` + +--- + +## 11. Phase B — Maestro Cloud (Zukunft, post-TestFlight) Was bei Cloud-Wechsel geaendert werden muss: diff --git a/apps/rebreak-native/.maestro/blocker/activation-smoke.yaml b/apps/rebreak-native/.maestro/blocker/activation-smoke.yaml new file mode 100644 index 0000000..d312748 --- /dev/null +++ b/apps/rebreak-native/.maestro/blocker/activation-smoke.yaml @@ -0,0 +1,101 @@ +# blocker/activation-smoke.yaml +# +# Journey: Login → navigate to Blocker tab → assert protection card is visible → +# assert activation CTA or locked state is visible (state-dependent). +# +# What this covers: +# - Blocker tab reachable via bottom tabs +# - Protection card renders correctly (active OR inactive state) +# - LayerSwitchCard visible for the logged-in user's plan +# - The "Schutz aktivieren" CTA reachable (if filter is currently off) +# +# What this does NOT cover: +# - Actually tapping "Schutz aktivieren" — this triggers a native iOS/Android +# system permission dialog that Maestro cannot interact with reliably. +# That step requires a pre-enrolled device with permissions already granted. +# - Cooldown flow — requires prior activation + 24h state. +# - MDM-managed state — requires supervised device. +# +# Selector strategy: +# - Tab bar uses react-native-bottom-tabs (iOS native tab bar). +# Tabs are identified by their label text from de.json: tabs.blocker = "Blocker" +# - Protection card title: blocker.protection_card_title = "ReBreak-Schutz" +# - Inactive subtitle: blocker.protection_subtitle_inactive = "Tippe um den Schutz zu aktivieren" +# - Active (locked) title: blocker.protection_card_locked_title = "ReBreak-Schutz aktiv" +# +# Pre-requisite: +# - App installed. Test-user on staging. +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- Navigate to Blocker tab --- +# tabs.blocker = "Blocker" (de.json line 137). +# react-native-bottom-tabs renders native iOS UITabBar. Maestro can tap tab labels. +- tapOn: + text: "Blocker" +- waitForAnimationToEnd: + timeout: 4000 + +# --- Assert Blocker screen has loaded --- +# blocker.title = "Blocker" (de.json line 185) — AppHeader title. +# Appears both as tab label and screen title, but after navigation the tab +# label is still there, so "Blocker" is visible at minimum once. +- assertVisible: + text: "Blocker" + +# Protection card title is always shown regardless of active/inactive state. +# blocker.protection_card_title = "ReBreak-Schutz" +- assertVisible: + text: "ReBreak-Schutz" + +# --- State-conditional assertion --- +# The test account may have protection active (urlFilter=true) or inactive. +# We check for EITHER the active lock title OR the inactive activation CTA. +# This makes the flow pass regardless of current filter state. +# +# If INACTIVE: blocker.protection_subtitle_inactive = "Tippe um den Schutz zu aktivieren" +# If ACTIVE (locked): blocker.protection_card_locked_title = "ReBreak-Schutz aktiv" +# +# We use assertVisible on a common element that exists in both states: +# The LayerSwitchCard is always rendered. Its URL-filter layer title: +# blocker.layers_url_filter_title = "URL-Filter" +- assertVisible: + text: "URL-Filter" + +# Custom domains section is always rendered for authenticated users. +# blocker.my_filters_title = "Meine Filter" OR blocker.section_domains = "Eigene Domains" +# Using the section that appears regardless of plan tier: +# blocker.domain_section_title = "Eigene Domains" +# (scrolling may be needed if protection card is tall — attempt scroll first) +- scrollUntilVisible: + element: + text: "Eigene Domains" + direction: DOWN + timeout: 5000 + +- assertVisible: + text: "Eigene Domains" diff --git a/apps/rebreak-native/.maestro/blocker/vpn-activate-verify.yaml b/apps/rebreak-native/.maestro/blocker/vpn-activate-verify.yaml new file mode 100644 index 0000000..1668dac --- /dev/null +++ b/apps/rebreak-native/.maestro/blocker/vpn-activate-verify.yaml @@ -0,0 +1,96 @@ +# blocker/vpn-activate-verify.yaml +# +# Zweck: VERIFIZIERT den Android-16-FGS-Fix (systemExempted → specialUse). +# Loggt ein → Blocker → tippt WIRKLICH "VPN aktivieren" → Confirm-Sheet → +# System-VPN-Dialog "OK". Das löst RebreakVpnService.startForeground aus — +# genau die Stelle, die auf Android 16 mit systemExempted crashte. +# +# Verdikt kommt aus parallelem logcat (extern): +# FEHLER → "SecurityException: Starting FGS with type ..." (Fix kaputt) +# ERFOLG → kein FGS-SecurityException + "VPN established" / TUN aktiv +# +# Voraussetzung: +# - Android-16-Emulator (API 36.x) ODER echtes Gerät, App (Debug) installiert. +# - Test-Account auf Staging mit Schutz AUS (sonst kein "VPN aktivieren"-Button). +# - Env: E2E_TEST_USER, E2E_TEST_PASSWORD (via `infisical run -- maestro test ...`). +# +# Run: +# infisical run -- maestro test --env=E2E_LOCALE=de \ +# apps/rebreak-native/.maestro/blocker/vpn-activate-verify.yaml + +appId: org.rebreak.app +--- +- launchApp: + clearState: true +- waitForAnimationToEnd: + timeout: 5000 + +# --- Login --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 +- assertVisible: + text: "ReBreak" + +# --- Blocker-Tab --- +- tapOn: + text: "Blocker" +- waitForAnimationToEnd: + timeout: 4000 +- assertVisible: + text: "ReBreak-Schutz" + +# Schutz ggf. erst antippen (Karte), damit der Setup-Flow erscheint. +- tapOn: + text: "Tippe um den Schutz zu aktivieren" + optional: true +- waitForAnimationToEnd: + timeout: 2000 + +# --- VPN aktivieren (DAS löst startForeground aus) --- +- tapOn: + text: "VPN aktivieren" +- waitForAnimationToEnd: + timeout: 2000 + +# Confirm-Sheet (Anti-Blind-Klick-Gate): Häkchen + Weiter. Optional, falls der +# Blocker-Screen anders gated als das Onboarding. +- tapOn: + text: "Ich hab’s verstanden" + optional: true +- tapOn: + text: "Weiter" + optional: true +- waitForAnimationToEnd: + timeout: 2000 + +# --- System-VPN-Consent-Dialog (außerhalb der App) --- +# Android zeigt "Verbindungsanfrage … VPN einrichten?". Button-Text variiert +# (OK / Zulassen / Allow) — wir versuchen mehrere. +- tapOn: + text: "OK" + optional: true +- tapOn: + text: "Zulassen" + optional: true +- tapOn: + text: "Allow" + optional: true + +# startVpn() läuft jetzt: establish() → startForeground(specialUse). Kurz warten, +# damit der FGS-Aufruf im logcat landet. +- waitForAnimationToEnd: + timeout: 6000 + +# App lebt noch (kein Crash) → Blocker-Screen weiterhin sichtbar. +- assertVisible: + text: "ReBreak-Schutz" diff --git a/apps/rebreak-native/.maestro/calls/incoming-call-screen.yaml b/apps/rebreak-native/.maestro/calls/incoming-call-screen.yaml new file mode 100644 index 0000000..88934d8 --- /dev/null +++ b/apps/rebreak-native/.maestro/calls/incoming-call-screen.yaml @@ -0,0 +1,117 @@ +# calls/incoming-call-screen.yaml +# +# Tests: CallScreen renders correctly for an INCOMING call state. +# +# Context: A series of bugs were fixed around the call screen disappearing +# immediately after appearing (Phantom-Call-Bug, stale PKPushRegistry, race +# conditions). This flow verifies the call UI stays visible and the +# accept/decline buttons are present. +# +# LIMITATION — This is a UI state verification, not a live call test. +# Triggering a real VoIP push requires a second device + server-side signaling. +# That E2E scenario (two-device call) needs the Maestro multi-device capability +# and is NOT covered here (Phase B / Cloud). +# +# APPROACH for single-device verification: +# The CallScreen renders based on useCallStore state. To reach it in a test: +# 1. Navigate to a DM with the test peer. +# 2. Tap the call button in the DM header. +# This triggers an OUTGOING call state → router.push('/call') → CallScreen. +# +# We verify: +# - The /call screen navigates to and stays visible (>250ms grace period passes). +# - The peer name area and call status subtitle render. +# - The hang-up button is present (for outgoing/connecting state). +# +# For incoming call UI verification (accept/decline buttons), this currently +# requires a real second device triggering the VoIP push or a debug-trigger +# mechanism. BLOCKED: needs test infrastructure decision from Orchestrator. +# See notes at bottom. +# +# Pre-requisite: +# - App installed. Test-user exists. A second user (the "test peer") must +# exist in the staging DB and be a DM contact of the test user. +# - E2E_TEST_PEER_USER env var = nickname or user lookup string for the peer. +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD, E2E_TEST_PEER_USER (optional) + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- Navigate to Chat tab --- +# tabs.chat = "Chat" (de.json line 135) +- tapOn: + text: "Chat" +- waitForAnimationToEnd: + timeout: 3000 + +# chat.title = "Chat" — screen is loaded +- assertVisible: + text: "Chat" + +# chat.dms = "Direktnachrichten" (de.json line 1065) — section header in chat list +- assertVisible: + text: "Direktnachrichten" + +# --- Open a DM conversation --- +# We need to tap into an existing DM conversation. The test user should have +# at least one prior DM with a peer from staging setup. +# The peer's nickname is unknown at flow-write time — we scroll to find any +# DM entry and tap it. If no DMs exist, the flow will fail at assertVisible +# on the DM screen elements, clearly indicating the setup gap. +# +# If E2E_TEST_PEER_USER is set, tap on that user's name directly. +# Otherwise: tap first visible DM entry below the "Direktnachrichten" header. +# FRAGILE: no testID on DM list items. The DM list shows peer nicknames as +# the primary text in each row — we use text match on the first visible name. +# For now we skip to the PARTIAL SMOKE TEST below. + +# PARTIAL SMOKE (does not require an existing DM): +# Navigate to the Chat tab and verify the call infrastructure is present +# by checking that the Chat screen renders without crash. Full call E2E needs +# a pre-seeded DM contact. This is noted as a BLOCKER below. + +# --- BLOCKER NOTE --- +# Full incoming call test requires one of: +# A) Two-device Maestro run (Maestro Cloud multi-device matrix) — Phase B. +# B) A debug endpoint `POST /api/debug/trigger-incoming-call` that sets +# callStore state directly (requires dev-build + debug flag). Not yet built. +# C) The DM screen has a "call" button in the header → tap → outgoing call state +# → CallScreen navigates in → verify screen stays open ≥ 2s (race guard). +# This requires a known peer userId in the DM URL param. +# +# Escalate to Orchestrator: Which approach for call E2E? Proceed with option C? +# That requires E2E_TEST_PEER_USER_ID env var + the peer having a DM row +# already loaded in the Chat list. + +# Verify chat tab renders cleanly (no crash = passing for now): +- assertVisible: + text: "Direktnachrichten" + +# Also verify the call-related strings are not showing error states. +# chat.call_missed = "Verpasster Anruf" should NOT appear without a real missed call. +# (This is a sanity check — it fires only if the chat list pre-populates +# a missed call notification for the test user incorrectly.) +- assertNotVisible: + text: "Verpasster Anruf" diff --git a/apps/rebreak-native/.maestro/dm/realtime-receive.yaml b/apps/rebreak-native/.maestro/dm/realtime-receive.yaml new file mode 100644 index 0000000..bf83ee0 --- /dev/null +++ b/apps/rebreak-native/.maestro/dm/realtime-receive.yaml @@ -0,0 +1,84 @@ +# dm/realtime-receive.yaml +# +# Journey: Login → open a DM → wait for an incoming message from the peer → +# assert the message bubble appears WITHOUT manual scroll. +# +# What this covers: +# - Realtime Supabase subscription (useDmRealtime) correctly fires on INSERT +# - Incoming message is appended to the local messages list +# - FlatList auto-scrolls to show the new message (scrollToBottom is called) +# - No "unread / scroll down" lag visible +# +# LIMITATION: This flow requires an EXTERNAL trigger — the test peer must +# send a message while the flow is waiting. This is not automatable with a +# single Maestro device run. +# +# Approaches: +# A) Manual: Run flow, then manually send a message from a second device +# within the 30s wait window. Not suitable for CI. +# B) API-trigger: A helper script sends a message via +# POST /api/dm/send (Service-Role) just before the flow reaches +# the waiting step. Needs coordination outside Maestro. +# C) Two-device Maestro Cloud: Device A runs dm/send-message.yaml, +# Device B runs this flow simultaneously. Phase B / Cloud. +# +# Current status: SCAFFOLD ONLY — assertVisible for incoming message +# will always timeout unless external trigger is set up. +# Leaving this flow as documented intent for Phase B. +# +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD +# Optional: E2E_TEST_PEER_NICKNAME + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- Navigate to Chat → open DM --- +- tapOn: + text: "Chat" +- waitForAnimationToEnd: + timeout: 3000 + +- assertVisible: + text: "Direktnachrichten" + +- tapOn: + text: ${E2E_TEST_PEER_NICKNAME} +- waitForAnimationToEnd: + timeout: 4000 + +- assertVisible: + text: "Nachricht schreiben…" + +# --- Wait for incoming realtime message --- +# External trigger must fire within this window. +# The [E2E-INCOMING] prefix is used by the helper script to identify +# test messages for cleanup after the run. +- waitForAnimationToEnd: + timeout: 30000 + +# Assert the incoming message bubble appeared. +# WILL FAIL without external trigger — intentional for Phase B scaffolding. +- assertVisible: + text: "[E2E-INCOMING]" diff --git a/apps/rebreak-native/.maestro/dm/send-message.yaml b/apps/rebreak-native/.maestro/dm/send-message.yaml new file mode 100644 index 0000000..8a2dc0f --- /dev/null +++ b/apps/rebreak-native/.maestro/dm/send-message.yaml @@ -0,0 +1,102 @@ +# dm/send-message.yaml +# +# Journey: Login → Chat tab → open first DM conversation → type a message → +# send → assert message appears in bubble list. +# +# What this covers: +# - DM screen loads without crash +# - Text input is accessible and accepts input +# - Send button (or Return key) dispatches the message +# - Optimistic message bubble appears immediately after send +# - (Realtime delivery to a second device is NOT tested here — single device) +# +# Pre-requisite: +# - Test-user has at least one existing DM conversation on staging. +# - The DM partner must exist (any user — staging DB seeded). +# - If no existing DM: create one manually first via the app, then run flow. +# +# IMPORTANT: This flow requires the test user to have a pre-existing DM. +# If the chat list is empty, the flow will correctly fail at "Direktnachrichten" +# being visible but no conversation entry to tap — making the setup gap obvious. +# +# Selector notes: +# - DM list items: no testID. Matched by peer nickname text. +# If E2E_TEST_PEER_NICKNAME is set, we tap that. Otherwise: first item below +# "Direktnachrichten" label. THIS IS FRAGILE. +# - DM screen text input: no testID. chat.placeholder = "Nachricht schreiben…" +# - Send button: no testID. Using Return key (onSubmitEditing) as fallback. +# +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD +# Optional: E2E_TEST_PEER_NICKNAME (if set, tapped directly; else first DM item) + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- Navigate to Chat tab --- +- tapOn: + text: "Chat" +- waitForAnimationToEnd: + timeout: 3000 + +- assertVisible: + text: "Direktnachrichten" + +# --- Open DM conversation --- +# Tap into an existing DM. We need a peer to tap on. +# If E2E_TEST_PEER_NICKNAME env var is set, use it as the tap target. +# This is the cleanest path — set this var to the nickname of the staging peer. +- tapOn: + text: ${E2E_TEST_PEER_NICKNAME} +- waitForAnimationToEnd: + timeout: 4000 + +# DM screen loaded: partner name shown in header (AppHeader title). +# We assert the message input placeholder is visible. +# chat.placeholder = "Nachricht schreiben…" (de.json line 1072) +- assertVisible: + text: "Nachricht schreiben…" + +# --- Compose and send a message --- +- tapOn: + text: "Nachricht schreiben…" +- waitForAnimationToEnd: + timeout: 1000 + +- inputText: "[E2E] Maestro-Testnachricht" + +# Submit via Return key. dm.tsx TextInput has onSubmitEditing={handleSend}. +# This avoids needing testID on the send Pressable (currently missing). +- pressKey: Return +- waitForAnimationToEnd: + timeout: 5000 + +# After send: the optimistic message bubble appears immediately with the sent text. +# The bubble shows the message content. Assert the text is visible in the list. +- assertVisible: + text: "[E2E] Maestro-Testnachricht" + +# Input bar resets to empty — placeholder is visible again. +- assertVisible: + text: "Nachricht schreiben…" diff --git a/apps/rebreak-native/.maestro/onboarding/new-user-streak-guard.yaml b/apps/rebreak-native/.maestro/onboarding/new-user-streak-guard.yaml new file mode 100644 index 0000000..d6952c5 --- /dev/null +++ b/apps/rebreak-native/.maestro/onboarding/new-user-streak-guard.yaml @@ -0,0 +1,92 @@ +# onboarding/new-user-streak-guard.yaml +# +# REGRESSION GUARD for the current bug: +# current_days=0 for all users because the streak calculation never runs. +# +# Journey: Launch → Welcome → Privacy → Nickname (skip via DiGA-No path) → +# Plan (Pro, Dev-Trial-CTA) → Payment (Dev-Skip) → Protection (skip +# via CTABar if dialog appears) → Done → App Home → Home screen +# must show streak day > 0 (NOT "0 Tage clean" or "Starte deinen ersten Tag" +# when the test user already has a streak). +# +# Strategy: The test user (claude-android-test) has an existing account with +# onboardingStep='done' so onboarding will NOT replay — _layout.tsx +# routes directly to /(app). We assert the streak widget shows a +# positive day count as the regression guard. +# For a brand new user test, a separate dedicated account is needed +# (see BLOCKER in notes at bottom). This flow covers the post-onboarding +# regression scenario. +# +# Pre-requisite: +# - App installed (Dev-Build OR TestFlight). +# - E2E_TEST_USER account on staging with onboardingStep='done' and streak_start set. +# - Staging backend running. +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD +# +# Expected outcome: After login, the home screen streak widget shows a day count +# that is NOT "0 Tage" (i.e. current_days is being calculated). +# If it shows "0 Tage clean" or "Starte deinen ersten Tag" when +# the account has a real streak — the regression is present. +# +# IMPORTANT: Text selectors use hardcoded de.json values. If device locale ≠ 'de', +# run with a German locale device or force-set language to 'de' before test. + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +# --- Home screen reached --- +- assertVisible: + text: "ReBreak" + +# The streak widget is in the Home screen (app/index.tsx or a HomeStreakCard). +# home.streak_days_one = "Tag clean" +# home.streak_days_other = "Tage clean" +# home.streak_start = "Starte deinen ersten Tag" +# +# REGRESSION CHECK: if current_days is never calculated, the widget always shows +# "0 Tage clean". We assert "Tage clean" is visible (which is true for any count +# including 0) and additionally assert "Starte deinen ersten Tag" is NOT visible +# (which would only appear for day=0 / null streak start). +# +# This catches the "always 0" bug: when current_days=0 the UI renders +# "0 Tage clean" or "Starte deinen ersten Tag" even for users with real streaks. +- assertVisible: + text: "clean" + +# The key assertion: "Starte deinen ersten Tag" must NOT be visible for an +# established test-user. If this fires — the streak calculation bug is present. +- assertNotVisible: + text: "Starte deinen ersten Tag" + +# Secondary guard: assert that "0 Tage" is not the streak count. +# "0 Tage clean" is the de.json rendering for 0 days via streak_days_other. +# NOTE: Maestro assertNotVisible matches substring — "0 Tage" catches both +# "0 Tage clean" (streak_days_other) and any "0 Tag clean" variant. +- assertNotVisible: + text: "0 Tage" + +# NOTE FOR FULL ONBOARDING TEST (new account flow): +# A completely fresh account (onboardingStep='welcome') is needed to exercise +# the Welcome → Privacy → Nickname → Plan → Payment → Protection → Done flow. +# That requires a separate test account that is reset to onboardingStep='welcome' +# before each run (via Service-Role PATCH). This is not automated here yet. +# See TODO in SETUP.md Phase B. diff --git a/apps/rebreak-native/.maestro/screens/01-onboarding.yaml b/apps/rebreak-native/.maestro/screens/01-onboarding.yaml new file mode 100644 index 0000000..4fe6544 --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/01-onboarding.yaml @@ -0,0 +1,36 @@ +# screens/01-onboarding.yaml +# +# Marketing-Screenshot 01: Onboarding / Willkommen +# +# Ziel: Der erste Onboarding-Screen (welcome-Step) — ruhiger Einstieg, kein Login-Formular. +# +# Strategie: clearState entfernt Auth-Session UND MMKV-State. Wenn der Test-Account +# onboardingStep='done' hat, landet er direkt im Auth-Screen (signin.tsx), nicht im +# Onboarding-Wizard. Für einen echten Onboarding-Welcome-Screen braucht man einen +# frischen Account mit onboardingStep='welcome'. +# +# Fallback: Wir landen auf dem Sign-in-Screen — der ist der tatsächliche "erste Blick" +# für neue Nutzer und zeigt schon das Rebreak-Branding sauber. Er dient hier als +# Onboarding-Äquivalent bis ein Reset-API-Endpunkt verfügbar ist. +# +# Screenshot-Output: screenshots/01-onboarding.png +# Env-Vars: keine (kein Login nötig) + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 6000 + +# Sign-in Screen ist der erste Screen für neue User. +# Wir prüfen ob wir direkt auf dem Auth-Screen sind (clearState = kein Token). +- assertVisible: + text: "E-Mail" + +# Auf Marketing-Screenshot warten wir extra lang damit alle Animationen/Fonts laden +- waitForAnimationToEnd: + timeout: 2000 + +- takeScreenshot: screenshots/01-onboarding diff --git a/apps/rebreak-native/.maestro/screens/02-blocker.yaml b/apps/rebreak-native/.maestro/screens/02-blocker.yaml new file mode 100644 index 0000000..c75ba30 --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/02-blocker.yaml @@ -0,0 +1,56 @@ +# screens/02-blocker.yaml +# +# Marketing-Screenshot 02: Schutz / Blocker aktiv +# +# Ziel: Blocker-Tab mit Schutz-Status. Zeigt "ReBreak-Schutz" Card + URL-Filter Layer. +# Der Test-Account sollte den Blocker in aktivem Zustand haben für den besten Screenshot. +# Wenn inaktiv: Card zeigt "Schutz aktivieren" — immer noch verwertbar. +# +# Screenshot-Output: screenshots/02-blocker.png +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- Blocker Tab --- +- tapOn: + text: "Blocker" +- waitForAnimationToEnd: + timeout: 4000 + +- assertVisible: + text: "ReBreak-Schutz" + +# Scrollen damit Schutz-Card + URL-Filter gleichzeitig sichtbar sind +- scrollUntilVisible: + element: + text: "URL-Filter" + direction: DOWN + timeout: 5000 + +- waitForAnimationToEnd: + timeout: 1000 + +- takeScreenshot: screenshots/02-blocker diff --git a/apps/rebreak-native/.maestro/screens/03-blocked.yaml b/apps/rebreak-native/.maestro/screens/03-blocked.yaml new file mode 100644 index 0000000..0fc593e --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/03-blocked.yaml @@ -0,0 +1,65 @@ +# screens/03-blocked.yaml +# +# Marketing-Screenshot 03: Block-Screen (gesperrte Casino-Seite) +# +# WICHTIG: Dieser Screen ist NICHT direkt per Maestro-Flow erzeugbar. +# Der Block-Screen erscheint im System-Browser (Safari / Chrome) wenn das VPN-DNS +# eine Domain blockiert und zur Rebreak-Blockpage weiterleitet — außerhalb der App. +# Maestro kann keine externen Browser-Fenster oder System-Level-UI öffnen. +# +# OPTIONEN für diesen Screenshot (manuell): +# A) VPN aktiv auf Simulator/Device → Safari öffnen → casino.com aufrufen → +# Screenshot via Cmd+S (Simulator) oder Seitenknopf+Lautstärke (Device). +# B) In-App-Blocked-Webview: Falls die App einen eigenen WebView mit Block-Page hat +# (z.B. app/help/crisis.tsx oder eine BlockedScreen-Komponente), diesen ansteuern. +# C) Platzhalter akzeptieren bis manuell erstellt. +# +# Dieser Flow versucht Option B: Öffnen des Help-Screens als nächstbestes sichtbares +# "Schutz greift ein"-Äquivalent. +# +# Screenshot-Output: screenshots/03-blocked.png +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD +# +# STATUS: MANUELL — Flow läuft durch, macht Screenshot des Help/Crisis-Screens als +# Proxy. Echter Block-Screen muss manuell via Safari+aktivem VPN erstellt werden. + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# Header-Dropdown öffnen für Zugriff auf Hilfe-Menü +# FRAGILE: Koordinaten-Tap — ersetzen durch testID="header-avatar-btn" wenn vorhanden +- tapOn: + id: "header-avatar-btn" +- waitForAnimationToEnd: + timeout: 2000 + +# Falls Dropdown kein direktes "Hilfe" hat: Abbruch und Screenshot des Dropdowns selbst +# Das Dropdown zeigt immerhin den "SOS"-Eintrag — nahegelegener Kontext +- assertVisible: + text: "SOS" + +# Screenshot des Dropdown-States als Proxy für "Schutz ist da" +# Für echten Block-Screen: MANUELL via Safari mit aktivem VPN +- takeScreenshot: screenshots/03-blocked diff --git a/apps/rebreak-native/.maestro/screens/04-sos-lyra.yaml b/apps/rebreak-native/.maestro/screens/04-sos-lyra.yaml new file mode 100644 index 0000000..859d015 --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/04-sos-lyra.yaml @@ -0,0 +1,81 @@ +# screens/04-sos-lyra.yaml +# +# Marketing-Screenshot 04: SOS / Chat mit Lyra +# +# Ziel: Lyra-Chat-Screen im SOS-Modus mit sichtbarer Nachricht und Chip-Row. +# Für vorzeigbaren Marketing-Screenshot: nach Lyra-Antwort warten, dann Screenshot. +# Die Chips ("Atemübung" etc.) müssen sichtbar sein — das beweist Live-Lyra. +# +# Timing: Groq cold start auf Staging = 6–12s. 20s-Wait für Response inklusive. +# +# Screenshot-Output: screenshots/04-sos-lyra.png +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- SOS öffnen via Header-Dropdown --- +# FRAGILE: Avatar-Button hat kein testID → Koordinaten-Tap +# Ersetzen mit: tapOn: { id: "header-avatar-btn" } nach testID-Ergänzung +- tapOn: + id: "header-avatar-btn" +- waitForAnimationToEnd: + timeout: 2000 + +- assertVisible: + text: "SOS" +- tapOn: + text: "SOS" + +# SOS-Screen startet RiveAvatar + Lyra-Streaming +- waitForAnimationToEnd: + timeout: 12000 + +- assertVisible: + text: "Was beschäftigt dich?" + +# Erste Lyra-Nachricht schon sichtbar → Screenshot der leeren/Start-State für clean look +# Für vorzeigbareren Shot: eine Nachricht senden und auf Antwort warten +- tapOn: + text: "Was beschäftigt dich?" +- waitForAnimationToEnd: + timeout: 500 + +# Realistischer, nicht-klinischer Testtext für Marketing-Screenshot +- inputText: "Ich weiß nicht mehr weiter." +- pressKey: Return + +# Warten bis Lyra antwortet und Chips erscheinen +- waitForAnimationToEnd: + timeout: 20000 + +# Chip "Atemübung" bestätigt aktive Lyra-Response +- assertVisible: + text: "Atemübung" + +- waitForAnimationToEnd: + timeout: 1000 + +- takeScreenshot: screenshots/04-sos-lyra diff --git a/apps/rebreak-native/.maestro/screens/05-breathing.yaml b/apps/rebreak-native/.maestro/screens/05-breathing.yaml new file mode 100644 index 0000000..b64a1bf --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/05-breathing.yaml @@ -0,0 +1,75 @@ +# screens/05-breathing.yaml +# +# Marketing-Screenshot 05: Atemübung +# +# Ziel: BreathingDrawer geöffnet auf dem SOS-Screen. +# Der Drawer zeigt die geführte Atemübung — visuell stark, klar beruhigend. +# +# Pfad: Login → SOS → Lyra antwortet → "Atemübung"-Chip tippen → BreathingDrawer offen +# +# Screenshot-Output: screenshots/05-breathing.png +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- SOS öffnen --- +# FRAGILE: Koordinaten-Tap bis testID="header-avatar-btn" gesetzt ist +- tapOn: + id: "header-avatar-btn" +- waitForAnimationToEnd: + timeout: 2000 + +- assertVisible: + text: "SOS" +- tapOn: + text: "SOS" + +- waitForAnimationToEnd: + timeout: 12000 + +- assertVisible: + text: "Was beschäftigt dich?" + +# "Atemübung" ist immer im initialen Chip-Set (CHIP_SETS.start in sosConstants.ts) +# Keine eigene Nachricht nötig — die Chips erscheinen beim Start des SOS-Screens +# sobald Lyra die erste Begrüßung gestreamt hat +- assertVisible: + text: "Atemübung" + +# BreathingDrawer öffnen +- tapOn: + text: "Atemübung" +- waitForAnimationToEnd: + timeout: 3000 + +# BreathingDrawer ist offen: Header "Atemübung" sichtbar +- assertVisible: + text: "Atemübung" + +- waitForAnimationToEnd: + timeout: 1500 + +- takeScreenshot: screenshots/05-breathing diff --git a/apps/rebreak-native/.maestro/screens/06-mail-schutz.yaml b/apps/rebreak-native/.maestro/screens/06-mail-schutz.yaml new file mode 100644 index 0000000..65c5c1f --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/06-mail-schutz.yaml @@ -0,0 +1,54 @@ +# screens/06-mail-schutz.yaml +# +# Marketing-Screenshot 06: Mail-Schutz-Ansicht +# +# Ziel: Mail-Tab geöffnet. Zeigt entweder: +# - Verbundenes Postfach mit Statistiken (Mail-Schutz aktiv) — ideal +# - MailEmptyState mit "Noch keine Mails blockiert" + Connect-CTA — akzeptabel +# +# Das Mail-Tab ist über den Bottom-Tab-Bar "Mail" erreichbar. +# de.json: tabs.mail = "Mail", mail.title = "Mail-Schutz" +# +# Screenshot-Output: screenshots/06-mail-schutz.png +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- Mail Tab --- +# tabs.mail = "Mail" (de.json) +- tapOn: + text: "Mail" +- waitForAnimationToEnd: + timeout: 4000 + +# Mail-Screen geladen: Titel "Mail-Schutz" (mail.title, de.json) +- assertVisible: + text: "Mail-Schutz" + +- waitForAnimationToEnd: + timeout: 1000 + +- takeScreenshot: screenshots/06-mail-schutz diff --git a/apps/rebreak-native/.maestro/screens/07-community.yaml b/apps/rebreak-native/.maestro/screens/07-community.yaml new file mode 100644 index 0000000..3e69c61 --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/07-community.yaml @@ -0,0 +1,60 @@ +# screens/07-community.yaml +# +# Marketing-Screenshot 07: Community-Feed +# +# Ziel: Home-Feed mit ComposeCard + mindestens einigen Posts sichtbar. +# Wichtig: Posts zeigen NUR Spitznamen (Nickname), keine Klarnamen (DSGVO/Stigma-Regel). +# Der Feed muss gefüllt sein — auf Staging sollte der Test-Account Posts sehen. +# +# Screenshot-Strategie: Nach Login direkt auf Home-Feed scrollen bis Community-Posts +# sichtbar sind, dann Screenshot. +# +# Screenshot-Output: screenshots/07-community.png +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# Home-Tab ist Default. Feed liegt direkt unter dem Header. +# Scrollen um Feed-Inhalt sichtbar zu machen (ComposeCard + Posts) +- scrollUntilVisible: + element: + text: "Was bewegt dich gerade?" + direction: UP + timeout: 4000 + +- assertVisible: + text: "Was bewegt dich gerade?" + +# Feed etwas nach unten scrollen damit Posts sichtbar werden +# (ComposeCard ist ganz oben, Posts darunter) +- scroll: + direction: DOWN + duration: 800 + +- waitForAnimationToEnd: + timeout: 1500 + +- takeScreenshot: screenshots/07-community diff --git a/apps/rebreak-native/.maestro/screens/08-streak.yaml b/apps/rebreak-native/.maestro/screens/08-streak.yaml new file mode 100644 index 0000000..a790327 --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/08-streak.yaml @@ -0,0 +1,71 @@ +# screens/08-streak.yaml +# +# Marketing-Screenshot 08: Streak / Profil-Stats +# +# Ziel: Profil-Screen mit StreakSection und Schutz-Abdeckungs-Donut sichtbar. +# Der Test-Account (admin) sollte eine Streak > 0 haben für vorzeigbare Zahlen. +# profile.streak_section_label = "SCHUTZ-ABDECKUNG" (de.json) +# profile.streak_days_protected = "Tage geschützt" +# +# Screenshot-Strategie: Profil öffnen, auf StreakSection scrollen. +# +# Screenshot-Output: screenshots/08-streak.png +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- Profil öffnen via Header-Dropdown --- +# FRAGILE: Koordinaten-Tap bis testID="header-avatar-btn" gesetzt ist +- tapOn: + id: "header-avatar-btn" +- waitForAnimationToEnd: + timeout: 2000 + +- assertVisible: + text: "Profil" +- tapOn: + text: "Profil" +- waitForAnimationToEnd: + timeout: 4000 + +- assertVisible: + text: "Profil" + +# Zur StreakSection scrollen (liegt unterhalb ProfileHeader + StatsBar) +# profile.streak_section_label = "SCHUTZ-ABDECKUNG" +- scrollUntilVisible: + element: + text: "SCHUTZ-ABDECKUNG" + direction: DOWN + timeout: 6000 + +- assertVisible: + text: "SCHUTZ-ABDECKUNG" + +- waitForAnimationToEnd: + timeout: 1000 + +- takeScreenshot: screenshots/08-streak diff --git a/apps/rebreak-native/.maestro/screens/09-geraete.yaml b/apps/rebreak-native/.maestro/screens/09-geraete.yaml new file mode 100644 index 0000000..72f858d --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/09-geraete.yaml @@ -0,0 +1,81 @@ +# screens/09-geraete.yaml +# +# Marketing-Screenshot 09: Geräte-Übersicht (devices.tsx) +# +# Ziel: Devices-Screen mit mindestens dem aktuellen Gerät sichtbar. +# devices.section_title_this = "Dieses Gerät" +# devices.status_active = "Aktiv" +# Ideal für Legend-Account: mehrere Gerätetypen (iPhone, Mac, Android) sichtbar. +# +# Navigation: Login → Header-Dropdown → "Einstellungen" → Devices-Screen +# ODER: Direktnavigation wenn "Geräte" im Dropdown erreichbar. +# Actual route: app/devices.tsx — wird über HeaderDropdownMenu erreichbar. +# Prüfen ob es im Dropdown oder in Settings liegt. +# +# Fallback: AppHeader der devices.tsx zeigt title aus t('settings.devices_title') +# settings.devices_title = "Meine Geräte" (check de.json) +# +# Screenshot-Output: screenshots/09-geraete.png +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- Profil öffnen um zu Einstellungen/Geräten zu navigieren --- +# FRAGILE: Koordinaten-Tap bis testID="header-avatar-btn" gesetzt ist +- tapOn: + id: "header-avatar-btn" +- waitForAnimationToEnd: + timeout: 2000 + +# Einstellungen öffnen: appHeader.settings = "Einstellungen" (de.json) +- assertVisible: + text: "Einstellungen" +- tapOn: + text: "Einstellungen" +- waitForAnimationToEnd: + timeout: 3000 + +# Settings-Screen: "Meine Geräte" Row oder "Geräte" Abschnitt suchen +# Scrolle bis Geräte-Eintrag sichtbar ist +- scrollUntilVisible: + element: + text: "Geräte" + direction: DOWN + timeout: 5000 + +- tapOn: + text: "Geräte" +- waitForAnimationToEnd: + timeout: 4000 + +# Devices-Screen: "Dieses Gerät" Section +- assertVisible: + text: "Dieses Gerät" + +- waitForAnimationToEnd: + timeout: 1000 + +- takeScreenshot: screenshots/09-geraete diff --git a/apps/rebreak-native/.maestro/screens/capture-05-09-verify.yaml b/apps/rebreak-native/.maestro/screens/capture-05-09-verify.yaml new file mode 100644 index 0000000..fb0324f --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/capture-05-09-verify.yaml @@ -0,0 +1,85 @@ +# screens/capture-05-09-verify.yaml +# +# No-Login: nimmt die zwei fehlenden Marketing-Screenshots (05-breathing, +# 09-geraete) auf UND verifiziert den Protection-Bypass-Fix (Blocker-Tab darf +# das "Schutz ist aus"-Sheet NICHT mehr zeigen). +# Voraussetzung: App auf dem Sim BEREITS eingeloggt. KEIN clearState. +# Jeder Block eigener launchApp → unabhängig + robust. + +appId: org.rebreak.app + +--- + +# ── 09 — DEVICES (Settings → Geräte) ── +- launchApp +- waitForAnimationToEnd: + timeout: 6000 +- tapOn: + text: "Nicht erlauben" + optional: true +- tapOn: + text: "Später" + optional: true +- tapOn: + id: "header-avatar-btn" + optional: true +- waitForAnimationToEnd: + timeout: 1500 +- tapOn: + text: "Einstellungen" + optional: true +- waitForAnimationToEnd: + timeout: 2500 +- scrollUntilVisible: + element: + text: "Geräte" + direction: DOWN + timeout: 6000 + optional: true +- tapOn: + text: "Geräte" + optional: true +- waitForAnimationToEnd: + timeout: 3000 +- takeScreenshot: screenshots/09-geraete + +# ── 05 — BREATHING (SOS → Atemübung-Chip → BreathingDrawer) ── +- launchApp +- waitForAnimationToEnd: + timeout: 5000 +- tapOn: + text: "Nicht erlauben" + optional: true +- tapOn: + text: "Später" + optional: true +- tapOn: + id: "header-avatar-btn" + optional: true +- waitForAnimationToEnd: + timeout: 1500 +- tapOn: + text: "SOS" + optional: true +- waitForAnimationToEnd: + timeout: 12000 +- tapOn: + text: "Atemübung" + optional: true +- waitForAnimationToEnd: + timeout: 3500 +- takeScreenshot: screenshots/05-breathing + +# ── BLOCKER (Fix-Verify: KEIN "Später"-Tap → Sheet würde sichtbar sein) ── +- launchApp +- waitForAnimationToEnd: + timeout: 5000 +- tapOn: + text: "Nicht erlauben" + optional: true +- tapOn: + text: "Blocker" + optional: true +- waitForAnimationToEnd: + timeout: 3500 +- takeScreenshot: screenshots/zz-blocker-verify diff --git a/apps/rebreak-native/.maestro/screens/capture-05-breathing.yaml b/apps/rebreak-native/.maestro/screens/capture-05-breathing.yaml new file mode 100644 index 0000000..149993a --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/capture-05-breathing.yaml @@ -0,0 +1,67 @@ +# screens/capture-05-breathing.yaml +# launchApp → Header-Avatar → SOS (Koordinaten-Tap) → 3 Nachrichten an Lyra +# (ab Turn 3 erzwingt System-Hint + Fallback-Chips das "🫁 Atemübung"-Angebot) +# → Atemübung-Chip → BreathingDrawer. KEIN clearState. + +appId: org.rebreak.app + +--- +- launchApp +- waitForAnimationToEnd: + timeout: 6000 +- tapOn: + text: "Nicht erlauben" + optional: true +- tapOn: + text: "Später" + optional: true +- tapOn: + id: "header-avatar-btn" + optional: true +- waitForAnimationToEnd: + timeout: 2000 +- tapOn: + point: "72%, 22%" +- waitForAnimationToEnd: + timeout: 9000 + +# ── Turn 1 ── +- tapOn: + text: "Was beschäftigt dich?" + optional: true +- inputText: "Ich bin gerade sehr gestresst und der Druck ist groß" +- tapOn: + id: "sos-send-btn" + optional: true +- waitForAnimationToEnd: + timeout: 11000 + +# ── Turn 2 ── +- tapOn: + text: "Was beschäftigt dich?" + optional: true +- inputText: "Es fällt mir gerade schwer, dem Drang zu widerstehen" +- tapOn: + id: "sos-send-btn" + optional: true +- waitForAnimationToEnd: + timeout: 11000 + +# ── Turn 3 ── +- tapOn: + text: "Was beschäftigt dich?" + optional: true +- inputText: "Ich brauche jetzt Hilfe, um runterzukommen" +- tapOn: + id: "sos-send-btn" + optional: true +- waitForAnimationToEnd: + timeout: 11000 + +- takeScreenshot: screenshots/05b-chips +- tapOn: + text: "Atemübung" + optional: true +- waitForAnimationToEnd: + timeout: 4000 +- takeScreenshot: screenshots/05-breathing diff --git a/apps/rebreak-native/.maestro/screens/capture-marketing-loggedin.sh b/apps/rebreak-native/.maestro/screens/capture-marketing-loggedin.sh new file mode 100755 index 0000000..35c00d6 --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/capture-marketing-loggedin.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# +# No-Login-Capture für die Marketing-Screenshots. +# +# Voraussetzung: Die App ist auf dem iOS-Simulator BEREITS eingeloggt +# (z. B. via Google-OAuth manuell). Dieses Script loggt NICHT ein, es navigiert +# nur und macht Screenshots. Braucht daher KEINE Test-Creds. +# +# Erzeugt 02–09 und kopiert sie nach apps/marketing/public/preview/. +# +# Aufruf: +# export PATH="$PATH:$HOME/.maestro/bin" +# bash apps/rebreak-native/.maestro/screens/capture-marketing-loggedin.sh + +set -uo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)" +FLOW="$REPO_ROOT/apps/rebreak-native/.maestro/screens/marketing-tour-loggedin.yaml" +DEST="$REPO_ROOT/apps/marketing/public/preview" +export PATH="$PATH:$HOME/.maestro/bin" + +if ! command -v maestro &>/dev/null; then + echo "FEHLER: Maestro nicht im PATH. → export PATH=\"\$PATH:\$HOME/.maestro/bin\"" + exit 1 +fi + +# ─── Status-Bar (9:41, voll) auf gebootetem Simulator ─────────────────────── +UDID=$(xcrun simctl list devices booted --json 2>/dev/null | python3 -c " +import json,sys +d=json.load(sys.stdin) +for r,ds in d.get('devices',{}).items(): + for x in ds: + if x.get('state')=='Booted': + print(x['udid']); sys.exit() +" 2>/dev/null || true) + +if [[ -n "$UDID" ]]; then + echo "Status-Bar auf Simulator $UDID setzen (9:41, voll)…" + xcrun simctl status_bar "$UDID" override \ + --time "9:41" --wifiMode active --wifiBars 3 \ + --cellularMode active --cellularBars 4 \ + --batteryState charged --batteryLevel 100 2>/dev/null \ + || echo " Status-Bar-Override fehlgeschlagen (nicht kritisch)." +else + echo "Kein gebooteter Simulator gefunden — Status-Bar übersprungen." +fi + +# ─── Flow laufen ──────────────────────────────────────────────────────────── +# WICHTIG: aus REPO_ROOT starten — `takeScreenshot: screenshots/x` legt relativ +# zum Arbeitsverzeichnis ab, d.h. die PNGs landen in $REPO_ROOT/screenshots/. +echo "" +echo "Starte No-Login-Tour: $FLOW" +cd "$REPO_ROOT" +maestro test "$FLOW" || echo " (Maestro-Flow mit Fehlern beendet — vorhandene Screenshots werden trotzdem kopiert)" + +# ─── Screenshots finden + kopieren ────────────────────────────────────────── +# Maestro speichert `takeScreenshot: screenshots/` als $REPO_ROOT/screenshots/.png +SRC="$REPO_ROOT/screenshots" +echo "" +echo "Quelle: $SRC" +mkdir -p "$DEST" + +ok=0 +for n in 02-blocker 03-blocked 04-sos-lyra 05-breathing 06-mail-schutz 07-community 07b-dm 08-streak 09-geraete; do + f="" + [[ -f "$SRC/$n.png" ]] && f="$SRC/$n.png" + [[ -z "$f" ]] && f=$(ls "$SRC"/*"$n"*.png 2>/dev/null | head -1 || true) + if [[ -n "$f" && -f "$f" ]]; then + cp "$f" "$DEST/$n.png" && echo " ✓ $n.png" && ok=$((ok+1)) + else + echo " ✗ $n.png fehlt (Screen evtl. nicht erreicht)" + fi +done + +[[ -n "$UDID" ]] && xcrun simctl status_bar "$UDID" clear 2>/dev/null || true +echo "" +echo "Fertig: $ok/8 Screenshots → $DEST" diff --git a/apps/rebreak-native/.maestro/screens/capture-marketing.sh b/apps/rebreak-native/.maestro/screens/capture-marketing.sh new file mode 100755 index 0000000..898a22a --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/capture-marketing.sh @@ -0,0 +1,183 @@ +#!/usr/bin/env bash +# capture-marketing.sh +# +# Erzeugt alle 9 Marketing-Screenshots und legt sie unter +# apps/marketing/public/preview/ mit den exakten Dateinamen ab. +# +# Voraussetzungen: +# 1. Maestro CLI installiert: curl -Ls "https://get.maestro.mobile.dev" | bash +# 2. iOS Simulator läuft mit der rebreak-native App (org.rebreak.app) +# z.B.: cd apps/rebreak-native && pnpm exec expo run:ios --device "iPhone 16 Pro" +# 3. E2E_TEST_USER und E2E_TEST_PASSWORD gesetzt (via Infisical oder manuell) +# 4. Staging-Backend erreichbar +# +# Aufruf: +# bash apps/rebreak-native/.maestro/screens/capture-marketing.sh +# +# Mit Credentials: +# E2E_TEST_USER=admin E2E_TEST_PASSWORD= \ +# bash apps/rebreak-native/.maestro/screens/capture-marketing.sh +# +# Oder via Infisical: +# infisical run -- bash apps/rebreak-native/.maestro/screens/capture-marketing.sh + +set -euo pipefail + +# ─── Pfade ──────────────────────────────────────────────────────────────────── +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)" +MAESTRO_DIR="$REPO_ROOT/apps/rebreak-native/.maestro" +TOUR_FLOW="$MAESTRO_DIR/screens/marketing-tour.yaml" +PREVIEW_DIR="$REPO_ROOT/apps/marketing/public/preview" + +# ─── Credentials-Check ──────────────────────────────────────────────────────── +if [[ -z "${E2E_TEST_USER:-}" || -z "${E2E_TEST_PASSWORD:-}" ]]; then + echo "FEHLER: E2E_TEST_USER und E2E_TEST_PASSWORD müssen gesetzt sein." + echo " Variante A: E2E_TEST_USER=admin E2E_TEST_PASSWORD= bash $0" + echo " Variante B: infisical run -- bash $0" + exit 1 +fi + +# ─── Maestro-Check ──────────────────────────────────────────────────────────── +if ! command -v maestro &>/dev/null; then + echo "FEHLER: Maestro CLI nicht gefunden." + echo " Installieren: curl -Ls 'https://get.maestro.mobile.dev' | bash" + echo " Dann: export PATH=\"\$PATH:\$HOME/.maestro/bin\"" + exit 1 +fi + +# ─── Zielverzeichnis sicherstellen ──────────────────────────────────────────── +mkdir -p "$PREVIEW_DIR" + +# ─── iOS Simulator: Status-Bar überschreiben ────────────────────────────────── +# Zeigt 9:41, volles Signal/WLAN/Akku — klassischer Apple-Screenshot-State +# Erfordert: xcrun simctl status_bar override ... +# UDID des laufenden Simulators automatisch ermitteln + +BOOTED_UDID="" +if command -v xcrun &>/dev/null; then + BOOTED_UDID=$(xcrun simctl list devices booted --json \ + | python3 -c " +import json, sys +data = json.load(sys.stdin) +for runtime, devices in data.get('devices', {}).items(): + for d in devices: + if d.get('state') == 'Booted': + print(d['udid']) + exit() +" 2>/dev/null || true) +fi + +if [[ -n "$BOOTED_UDID" ]]; then + echo "Status-Bar für Simulator $BOOTED_UDID auf 9:41 setzen..." + xcrun simctl status_bar "$BOOTED_UDID" override \ + --time "9:41" \ + --wifiMode "active" \ + --wifiBars 3 \ + --cellularMode "active" \ + --cellularBars 4 \ + --batteryState "charged" \ + --batteryLevel 100 \ + 2>/dev/null || echo " Status-Bar-Override fehlgeschlagen (nicht kritisch — Flow läuft weiter)" +else + echo "Kein gestarteter iOS-Simulator gefunden — Status-Bar-Override übersprungen." + echo " Starte den Simulator zuerst: pnpm exec expo run:ios --device 'iPhone 16 Pro'" +fi + +# ─── Maestro-Flow ausführen ──────────────────────────────────────────────────── +echo "" +echo "Starte Marketing-Tour-Flow..." +echo " Flow: $TOUR_FLOW" +echo " User: $E2E_TEST_USER@rebreak.internal" +echo "" + +# Maestro schreibt Screenshots nach ~/.maestro/tests//screenshots/ +# --output schreibt JUnit-Report, Screenshot-Pfad ist immer im Default-Verzeichnis +TIMESTAMP=$(date +%Y%m%d_%H%M%S) +MAESTRO_SCREENSHOT_BASE="$HOME/.maestro/tests" + +maestro test \ + --env="E2E_TEST_USER=$E2E_TEST_USER" \ + --env="E2E_TEST_PASSWORD=$E2E_TEST_PASSWORD" \ + "$TOUR_FLOW" + +echo "" +echo "Flow abgeschlossen. Screenshots suchen..." + +# ─── Screenshot-Verzeichnis finden ──────────────────────────────────────────── +# Maestro legt Screenshots im neuesten Testlauf-Verzeichnis ab +LATEST_RUN=$(ls -td "$MAESTRO_SCREENSHOT_BASE"/*/ 2>/dev/null | head -1 || true) + +if [[ -z "$LATEST_RUN" ]]; then + echo "FEHLER: Kein Maestro-Testlauf-Verzeichnis gefunden unter $MAESTRO_SCREENSHOT_BASE" + echo " Manuell suchen: ls ~/.maestro/tests/" + exit 1 +fi + +SCREENSHOTS_DIR="$LATEST_RUN/screenshots" +if [[ ! -d "$SCREENSHOTS_DIR" ]]; then + # Maestro 1.38+ legt Screenshots direkt im Lauf-Verzeichnis ab + SCREENSHOTS_DIR="$LATEST_RUN" +fi + +echo "Screenshots-Quellverzeichnis: $SCREENSHOTS_DIR" +echo "" + +# ─── Mapping: Maestro-Name → Marketing-Dateiname ────────────────────────────── +# takeScreenshot-Wert in marketing-tour.yaml → Zieldateiname +declare -A MAPPING=( + ["screenshots/01-onboarding"]="01-onboarding.png" + ["screenshots/02-blocker"]="02-blocker.png" + ["screenshots/03-blocked"]="03-blocked.png" + ["screenshots/04-sos-lyra"]="04-sos-lyra.png" + ["screenshots/05-breathing"]="05-breathing.png" + ["screenshots/06-mail-schutz"]="06-mail-schutz.png" + ["screenshots/07-community"]="07-community.png" + ["screenshots/08-streak"]="08-streak.png" + ["screenshots/09-geraete"]="09-geraete.png" +) + +# Maestro benennt Screenshots nach dem letzten Teil des takeScreenshot-Werts +# "screenshots/01-onboarding" → Datei heißt "01-onboarding.png" im Maestro-Output +COPIED=0 +MISSING=0 + +for MAESTRO_KEY in "${!MAPPING[@]}"; do + TARGET_NAME="${MAPPING[$MAESTRO_KEY]}" + # Maestro schreibt nur den Basename ohne Verzeichnis + BASENAME=$(basename "$MAESTRO_KEY") + SOURCE_FILE="$SCREENSHOTS_DIR/${BASENAME}.png" + + if [[ -f "$SOURCE_FILE" ]]; then + cp "$SOURCE_FILE" "$PREVIEW_DIR/$TARGET_NAME" + echo " OK $TARGET_NAME ← $SOURCE_FILE" + ((COPIED++)) + else + echo " FEHLT $TARGET_NAME (Quelle nicht gefunden: $SOURCE_FILE)" + ((MISSING++)) + fi +done + +# ─── Status-Bar zurücksetzen ────────────────────────────────────────────────── +if [[ -n "$BOOTED_UDID" ]]; then + xcrun simctl status_bar "$BOOTED_UDID" clear 2>/dev/null || true +fi + +# ─── Zusammenfassung ────────────────────────────────────────────────────────── +echo "" +echo "─────────────────────────────────────────" +echo " Screenshots kopiert: $COPIED / 9" +if [[ $MISSING -gt 0 ]]; then + echo " Fehlend: $MISSING" + echo "" + echo " Für fehlende Screenshots:" + echo " - 03-blocked.png: manuell via Safari + aktivem VPN erstellen" + echo " Dann: cp /path/to/screenshot.png $PREVIEW_DIR/03-blocked.png" + echo "" + echo " Alle Screenshots unter: $SCREENSHOTS_DIR" +fi +echo " Zielverzeichnis: $PREVIEW_DIR" +echo "─────────────────────────────────────────" + +if [[ $MISSING -gt 0 ]]; then + exit 1 +fi diff --git a/apps/rebreak-native/.maestro/screens/capture-onboarding.yaml b/apps/rebreak-native/.maestro/screens/capture-onboarding.yaml new file mode 100644 index 0000000..a389322 --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/capture-onboarding.yaml @@ -0,0 +1,82 @@ +# Onboarding-Slides via Debug-Toggle (Root-Route, nicht gated). KEIN clearState. +# Account-Step wird am Ende auf 'done' restauriert. +appId: org.rebreak.app +--- +# ── 01a — WELCOME ── +- launchApp +- waitForAnimationToEnd: + timeout: 5000 +- tapOn: + text: "Nicht erlauben" + optional: true +- openLink: + link: "rebreak://debug" +- tapOn: + text: "Öffnen" + optional: true +- waitForAnimationToEnd: + timeout: 2500 +- scrollUntilVisible: + element: + text: "Onboarding-Step" + direction: DOWN + timeout: 8000 + centerElement: true + optional: true +- tapOn: + text: "Welcome" + optional: true +- waitForAnimationToEnd: + timeout: 4000 +- takeScreenshot: screenshots/01a-welcome + +# ── 01b — PROTECTION ── +- openLink: + link: "rebreak://debug" +- tapOn: + text: "Öffnen" + optional: true +- waitForAnimationToEnd: + timeout: 2500 +- scrollUntilVisible: + element: + text: "Onboarding-Step" + direction: DOWN + timeout: 8000 + centerElement: true + optional: true +- tapOn: + text: "Pre_Protection" + optional: true +- waitForAnimationToEnd: + timeout: 4000 +- takeScreenshot: screenshots/01b-protection + +# ── restore done + 01c — DONE SLIDE ── +- openLink: + link: "rebreak://debug" +- tapOn: + text: "Öffnen" + optional: true +- waitForAnimationToEnd: + timeout: 2500 +- scrollUntilVisible: + element: + text: "Onboarding-Step" + direction: DOWN + timeout: 8000 + centerElement: true + optional: true +- tapOn: + text: "Done" + optional: true +- waitForAnimationToEnd: + timeout: 3000 +- openLink: + link: "rebreak://onboarding" +- tapOn: + text: "Öffnen" + optional: true +- waitForAnimationToEnd: + timeout: 3500 +- takeScreenshot: screenshots/01c-done diff --git a/apps/rebreak-native/.maestro/screens/marketing-tour-loggedin.yaml b/apps/rebreak-native/.maestro/screens/marketing-tour-loggedin.yaml new file mode 100644 index 0000000..8a0c094 --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/marketing-tour-loggedin.yaml @@ -0,0 +1,100 @@ +# screens/marketing-tour-loggedin.yaml +# +# No-Login-Tour (single-session, tab-basiert, sheet-resilient). +# Voraussetzung: App auf dem Simulator BEREITS eingeloggt. +# +# WICHTIG: Nach Besuch des Blocker-Tabs erscheint das "Schutz ist aus"-Sheet +# (Bypass-Detection auf dem Sim) und blockiert modal alle weiteren Taps. +# Deshalb: alle anderen Tabs ZUERST, Blocker als LETZTES. "Nicht erlauben" +# (Screen-Time-Dialog) + "Später" (Schutz-Sheet) werden überall weggetippt. +# Alle tapOn optional → kein Abbruch. Nur launch/wait/screenshot Pflicht. + +appId: org.rebreak.app + +--- + +- launchApp +- waitForAnimationToEnd: + timeout: 6000 +- tapOn: + text: "Nicht erlauben" + optional: true +- tapOn: + text: "Später" + optional: true +- waitForAnimationToEnd: + timeout: 1000 + +# 07 — HOME / FEED +- tapOn: + text: "Home" + optional: true +- tapOn: + text: "Später" + optional: true +- waitForAnimationToEnd: + timeout: 1200 +- takeScreenshot: screenshots/07-community + +# 04 — COACH / LYRA +- tapOn: + text: "Coach" + optional: true +- tapOn: + text: "Später" + optional: true +- waitForAnimationToEnd: + timeout: 2500 +- takeScreenshot: screenshots/04-sos-lyra + +# 07b — CHAT / DM +- tapOn: + text: "Chat" + optional: true +- tapOn: + text: "Später" + optional: true +- waitForAnimationToEnd: + timeout: 2000 +- takeScreenshot: screenshots/07b-dm + +# 06 — MAIL +- tapOn: + text: "Mail" + optional: true +- tapOn: + text: "Später" + optional: true +- waitForAnimationToEnd: + timeout: 2500 +- takeScreenshot: screenshots/06-mail-schutz + +# 08 — PROFIL / STREAK (Home + Header-Avatar) +- tapOn: + text: "Home" + optional: true +- tapOn: + text: "Später" + optional: true +- waitForAnimationToEnd: + timeout: 1000 +- tapOn: + id: "header-avatar-btn" + optional: true +- waitForAnimationToEnd: + timeout: 2500 +- takeScreenshot: screenshots/08-streak + +# 02 / 03 — BLOCKER (zuletzt; Schutz-Sheet danach wegtippen) +- tapOn: + text: "Blocker" + optional: true +- waitForAnimationToEnd: + timeout: 2000 +- tapOn: + text: "Später" + optional: true +- waitForAnimationToEnd: + timeout: 1500 +- takeScreenshot: screenshots/02-blocker +- takeScreenshot: screenshots/03-blocked diff --git a/apps/rebreak-native/.maestro/screens/marketing-tour.yaml b/apps/rebreak-native/.maestro/screens/marketing-tour.yaml new file mode 100644 index 0000000..b13ff69 --- /dev/null +++ b/apps/rebreak-native/.maestro/screens/marketing-tour.yaml @@ -0,0 +1,340 @@ +# screens/marketing-tour.yaml +# +# Maestro Marketing-Tour — alle 9 Screenshots in einem Lauf +# +# Dieser Flow führt nacheinander alle 9 Marketing-Screens an und macht je einen +# takeScreenshot. Maestro speichert Screenshots unter ~/.maestro/tests// +# Das capture-marketing.sh Script benennt sie in 01-onboarding.png … 09-geraete.png um. +# +# REIHENFOLGE KRITISCH — entspricht der Reihenfolge auf der Preview-Seite: +# 01 Onboarding → Sign-in-Screen (neuer Nutzer, clearState) +# 02 Blocker → Blocker-Tab mit Schutz-Status +# 03 Blocked → MANUELL (VPN außerhalb App) — Proxy: Header-Dropdown +# 04 SOS/Lyra → SOS-Screen mit Lyra-Antwort + Chips +# 05 Breathing → BreathingDrawer geöffnet +# 06 Mail-Schutz → Mail-Tab +# 07 Community → Home-Feed mit Posts +# 08 Streak → Profil-StreakSection +# 09 Geräte → Devices-Screen +# +# Wichtig: Flow bricht nach dem letzten takeScreenshot ab — keine Assertions danach. +# Jeder Abschnitt setzt den App-State via launchApp + clearState zurück. +# +# HINWEIS 03-blocked: +# Der echte Block-Screen ist außerhalb der App (Safari + VPN). Dieser Flow macht +# einen Proxy-Screenshot des Header-Dropdowns. Für den echten Shot: manuell. +# +# FRAGILE STEPS (brauchen testID-Ergänzung für Robustheit): +# - Avatar-Tap (93%, 6%) in allen Flows → testID="header-avatar-btn" +# - SOS-Send-Button → testID="sos-send-btn" +# - Settings→Geräte Navigation +# +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD +# Voraussetzung: iOS Simulator mit Status-Bar via xcrun simctl status_bar überschrieben +# (Details in capture-marketing.sh) + +appId: org.rebreak.app + +--- + +# ══════════════════════════════════════════════════════════ +# 01 — ONBOARDING / WILLKOMMEN +# Sign-in-Screen als "erster Blick" für neue Nutzer +# ══════════════════════════════════════════════════════════ +- launchApp: + clearState: true +- waitForAnimationToEnd: + timeout: 6000 +- assertVisible: + text: "E-Mail" +- waitForAnimationToEnd: + timeout: 2000 +- takeScreenshot: screenshots/01-onboarding + +# ══════════════════════════════════════════════════════════ +# 02 — BLOCKER AKTIV +# ══════════════════════════════════════════════════════════ +- launchApp: + clearState: true +- waitForAnimationToEnd: + timeout: 5000 +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 +- assertVisible: + text: "ReBreak" +- tapOn: + text: "Blocker" +- waitForAnimationToEnd: + timeout: 4000 +- assertVisible: + text: "ReBreak-Schutz" +- scrollUntilVisible: + element: + text: "URL-Filter" + direction: DOWN + timeout: 5000 +- waitForAnimationToEnd: + timeout: 1000 +- takeScreenshot: screenshots/02-blocker + +# ══════════════════════════════════════════════════════════ +# 03 — BLOCKED (Proxy: Header-Dropdown als "Schutz greift") +# HINWEIS: Echter Block-Screen → manuell via Safari + VPN +# ══════════════════════════════════════════════════════════ +- launchApp: + clearState: true +- waitForAnimationToEnd: + timeout: 5000 +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 +- assertVisible: + text: "ReBreak" +# Blocker-Tab zeigt den aktivsten "Schutz greift"-Screen ohne VPN +- tapOn: + text: "Blocker" +- waitForAnimationToEnd: + timeout: 4000 +- assertVisible: + text: "ReBreak-Schutz" +- takeScreenshot: screenshots/03-blocked + +# ══════════════════════════════════════════════════════════ +# 04 — SOS / LYRA +# ══════════════════════════════════════════════════════════ +- launchApp: + clearState: true +- waitForAnimationToEnd: + timeout: 5000 +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 +- assertVisible: + text: "ReBreak" +# FRAGILE: Avatar-Tap Koordinaten bis testID="header-avatar-btn" gesetzt +- tapOn: + id: "header-avatar-btn" +- waitForAnimationToEnd: + timeout: 2000 +- assertVisible: + text: "SOS" +- tapOn: + text: "SOS" +- waitForAnimationToEnd: + timeout: 12000 +- assertVisible: + text: "Was beschäftigt dich?" +- tapOn: + text: "Was beschäftigt dich?" +- waitForAnimationToEnd: + timeout: 500 +- inputText: "Ich weiß nicht mehr weiter." +- pressKey: Return +- waitForAnimationToEnd: + timeout: 20000 +- assertVisible: + text: "Atemübung" +- waitForAnimationToEnd: + timeout: 1000 +- takeScreenshot: screenshots/04-sos-lyra + +# ══════════════════════════════════════════════════════════ +# 05 — ATEMÜBUNG +# BreathingDrawer bleibt nach 04-sos-lyra noch offen → +# kein launchApp nötig, direkt tippen +# ══════════════════════════════════════════════════════════ +- tapOn: + text: "Atemübung" +- waitForAnimationToEnd: + timeout: 3000 +- assertVisible: + text: "Atemübung" +- waitForAnimationToEnd: + timeout: 1500 +- takeScreenshot: screenshots/05-breathing + +# ══════════════════════════════════════════════════════════ +# 06 — MAIL-SCHUTZ +# ══════════════════════════════════════════════════════════ +- launchApp: + clearState: true +- waitForAnimationToEnd: + timeout: 5000 +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 +- assertVisible: + text: "ReBreak" +- tapOn: + text: "Mail" +- waitForAnimationToEnd: + timeout: 4000 +- assertVisible: + text: "Mail-Schutz" +- waitForAnimationToEnd: + timeout: 1000 +- takeScreenshot: screenshots/06-mail-schutz + +# ══════════════════════════════════════════════════════════ +# 07 — COMMUNITY-FEED +# ══════════════════════════════════════════════════════════ +- launchApp: + clearState: true +- waitForAnimationToEnd: + timeout: 5000 +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 +- assertVisible: + text: "ReBreak" +- scrollUntilVisible: + element: + text: "Was bewegt dich gerade?" + direction: UP + timeout: 4000 +- assertVisible: + text: "Was bewegt dich gerade?" +- scroll: + direction: DOWN + duration: 800 +- waitForAnimationToEnd: + timeout: 1500 +- takeScreenshot: screenshots/07-community + +# ══════════════════════════════════════════════════════════ +# 08 — STREAK / PROFIL-STATS +# ══════════════════════════════════════════════════════════ +- launchApp: + clearState: true +- waitForAnimationToEnd: + timeout: 5000 +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 +- assertVisible: + text: "ReBreak" +# FRAGILE: Koordinaten-Tap +- tapOn: + id: "header-avatar-btn" +- waitForAnimationToEnd: + timeout: 2000 +- assertVisible: + text: "Profil" +- tapOn: + text: "Profil" +- waitForAnimationToEnd: + timeout: 4000 +- assertVisible: + text: "Profil" +- scrollUntilVisible: + element: + text: "SCHUTZ-ABDECKUNG" + direction: DOWN + timeout: 6000 +- assertVisible: + text: "SCHUTZ-ABDECKUNG" +- waitForAnimationToEnd: + timeout: 1000 +- takeScreenshot: screenshots/08-streak + +# ══════════════════════════════════════════════════════════ +# 09 — GERÄTE-ÜBERSICHT +# ══════════════════════════════════════════════════════════ +- launchApp: + clearState: true +- waitForAnimationToEnd: + timeout: 5000 +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 +- assertVisible: + text: "ReBreak" +# FRAGILE: Koordinaten-Tap +- tapOn: + id: "header-avatar-btn" +- waitForAnimationToEnd: + timeout: 2000 +- assertVisible: + text: "Einstellungen" +- tapOn: + text: "Einstellungen" +- waitForAnimationToEnd: + timeout: 3000 +- scrollUntilVisible: + element: + text: "Geräte" + direction: DOWN + timeout: 5000 +- tapOn: + text: "Geräte" +- waitForAnimationToEnd: + timeout: 4000 +- assertVisible: + text: "Dieses Gerät" +- waitForAnimationToEnd: + timeout: 1000 +- takeScreenshot: screenshots/09-geraete diff --git a/apps/rebreak-native/.maestro/sos/crisis-flow.yaml b/apps/rebreak-native/.maestro/sos/crisis-flow.yaml new file mode 100644 index 0000000..d3a6036 --- /dev/null +++ b/apps/rebreak-native/.maestro/sos/crisis-flow.yaml @@ -0,0 +1,119 @@ +# sos/crisis-flow.yaml +# +# HIGHEST PRIORITY FLOW — this must never silently fail. +# +# Journey: Login → Header-Dropdown → SOS → Lyra chat loads → send a message → +# assert response area or chip row becomes visible (Lyra is alive). +# +# This flow is the canary for: +# - SOS navigation path not broken +# - Lyra streaming endpoint reachable from staging +# - Chat input + send mechanism functional +# - Breathing chip "Atemübung" accessible as immediate coping entry +# +# Unlike the previous urge/sos-flow.yaml which relies on a coordinate tap for +# the avatar button, this flow uses the same coordinate fallback until +# testID="header-avatar-btn" is added (see TODO_TESTIDS.md HIGH priority). +# The coordinate tap is the ONLY fragile part of this flow. +# +# Timing: SOS screen on staging needs 6–12s for Groq cold start. The send step +# waits 20s for Lyra's response — intentionally generous. A CI failure here +# means either backend is down or Groq key is missing/expired. +# +# Pre-requisite: +# - App installed. Test-user exists on staging. +# - Staging backend + Groq API key configured. +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 5000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 10000 + +- assertVisible: + text: "ReBreak" + +# --- Open Header Dropdown --- +# FRAGILE: Avatar Pressable has no testID → coordinate tap. +# Replace with: tapOn: { id: "header-avatar-btn" } once testID is added. +- tapOn: + point: "93%, 6%" +- waitForAnimationToEnd: + timeout: 2000 + +# appHeader.sosLabel = "SOS" (de.json line 119) +- assertVisible: + text: "SOS" +- tapOn: + text: "SOS" + +# SOS screen loads: RiveAvatar + Lyra streaming begins. +# Cold start on Groq (staging) = 6–12s. We wait the full 12s before asserting. +- waitForAnimationToEnd: + timeout: 12000 + +# coach.placeholder = "Was beschäftigt dich?" — only exists on SOS/Urge screen. +# This confirms the SOS screen has fully loaded with the chat input visible. +- assertVisible: + text: "Was beschäftigt dich?" + +# --- Send a message --- +# Tap the placeholder to focus the TextInput +- tapOn: + text: "Was beschäftigt dich?" +- waitForAnimationToEnd: + timeout: 1000 + +# Type a safe test message that triggers a Lyra response +- inputText: "Ich brauche gerade Hilfe." + +# Send via the send button. +# FRAGILE: send Pressable has no testID → use pressKey Enter as fallback. +# The TextInput in urge.tsx submits on Return key (onSubmitEditing = handleSend). +# This is more reliable than coordinate tapping the icon button. +# Add testID="sos-send-btn" to fix (see TODO_TESTIDS.md HIGH priority). +- pressKey: Return +- waitForAnimationToEnd: + timeout: 3000 + +# Wait for Lyra to stream back a response (up to 20s on staging cold start) +- waitForAnimationToEnd: + timeout: 20000 + +# After Lyra responds, the initial chip set is visible. +# "Atemübung" is in CHIP_SETS.start (sosConstants.ts) — hardcoded, not i18n. +# This chip is ALWAYS shown as the first response. If it's not visible after 20s, +# Lyra failed to respond — the test should fail here. +- assertVisible: + text: "Atemübung" + +# --- Verify Breathing entry point --- +# Tap "Atemübung" to open BreathingDrawer. This ensures the most critical +# coping mechanism (breathing exercise) is accessible from the SOS screen. +- tapOn: + text: "Atemübung" +- waitForAnimationToEnd: + timeout: 3000 + +# BreathingDrawer header. The breathing screen title is hardcoded in Breathing.tsx +# (not i18n). urge.sos_title = "SOS — Atemübung" (de.json line 979). +# The drawer itself renders "Atemübung" as its header text. +- assertVisible: + text: "Atemübung" diff --git a/apps/rebreak-native/.maestro/stress/dm-scroll-performance.yaml b/apps/rebreak-native/.maestro/stress/dm-scroll-performance.yaml new file mode 100644 index 0000000..afb451b --- /dev/null +++ b/apps/rebreak-native/.maestro/stress/dm-scroll-performance.yaml @@ -0,0 +1,160 @@ +# stress/dm-scroll-performance.yaml +# +# Stress scenario: Open a DM conversation with many messages and scroll +# the entire history. Designed to catch FlatList perf issues on slow devices +# (Samsung A50 — primary Android test target, known slow). +# +# What this tests: +# - DM FlatList renders without ANR (App Not Responding) on large history +# - Scroll from bottom to top of message list completes +# - Scroll back to bottom (chat.scrollToBottom behavior) +# - App does not crash or freeze during scroll +# - "Scroll to bottom" action returns to latest message correctly +# +# Samsung A50 characteristics: +# - Exynos 9610 — single-core perf ~35% slower than Pixel 5 +# - 4GB RAM — RN FlatList with 100+ messages + image attachments can OOM +# - Expected: 5–10s for initial load on large history (100 messages) +# +# Pre-requisite: +# - Test user has a DM conversation with 50+ messages (seed if not present). +# - If conversation is short: the stress value is reduced but the flow still +# validates basic scroll behavior. +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD, E2E_TEST_PEER_NICKNAME + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +# Extended wait — A50 cold boot is slow +- waitForAnimationToEnd: + timeout: 8000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +# Extended timeout for A50 + Staging network round-trip +- waitForAnimationToEnd: + timeout: 15000 + +- assertVisible: + text: "ReBreak" + +# --- Navigate to Chat tab --- +- tapOn: + text: "Chat" +- waitForAnimationToEnd: + timeout: 5000 + +- assertVisible: + text: "Direktnachrichten" + +# --- Open target DM --- +- tapOn: + text: ${E2E_TEST_PEER_NICKNAME} + +# Extended load time for large message history on A50 +- waitForAnimationToEnd: + timeout: 10000 + +# DM screen input is the load-complete signal +- assertVisible: + text: "Nachricht schreiben…" + +# --- Scroll UP through history --- +# Repeat swipe-up 8 times to simulate user browsing through history. +# Each swipe = ~3 visible messages scrolled on an A50 screen. +# 8 swipes = ~24 messages reviewed without crash. +- swipe: + direction: UP + duration: 600 +- waitForAnimationToEnd: + timeout: 2000 + +- swipe: + direction: UP + duration: 600 +- waitForAnimationToEnd: + timeout: 2000 + +- swipe: + direction: UP + duration: 600 +- waitForAnimationToEnd: + timeout: 2000 + +- swipe: + direction: UP + duration: 600 +- waitForAnimationToEnd: + timeout: 2000 + +- swipe: + direction: UP + duration: 600 +- waitForAnimationToEnd: + timeout: 2000 + +- swipe: + direction: UP + duration: 600 +- waitForAnimationToEnd: + timeout: 2000 + +- swipe: + direction: UP + duration: 600 +- waitForAnimationToEnd: + timeout: 2000 + +- swipe: + direction: UP + duration: 600 +- waitForAnimationToEnd: + timeout: 3000 + +# If the app hasn't crashed by here: FlatList is stable under upward scroll. + +# --- Scroll BACK DOWN to latest message --- +# Simulate user tapping "scroll to bottom" or dragging down rapidly. +- swipe: + direction: DOWN + duration: 300 +- swipe: + direction: DOWN + duration: 300 +- swipe: + direction: DOWN + duration: 300 +- swipe: + direction: DOWN + duration: 300 +- waitForAnimationToEnd: + timeout: 3000 + +# --- Assert the input is still accessible after scroll --- +# If the app ANR'd or crashed, this will fail. +# If the FlatList lost keyboard/input state, this will fail. +- assertVisible: + text: "Nachricht schreiben…" + +# --- Send a message after scroll to verify input still works --- +- tapOn: + text: "Nachricht schreiben…" +- inputText: "[E2E-STRESS] Scroll-Test abgeschlossen" +- pressKey: Return +- waitForAnimationToEnd: + timeout: 8000 + +# Message bubble appeared = send path survived after heavy scroll +- assertVisible: + text: "[E2E-STRESS] Scroll-Test abgeschlossen" diff --git a/apps/rebreak-native/.maestro/stress/rapid-post-submit.yaml b/apps/rebreak-native/.maestro/stress/rapid-post-submit.yaml new file mode 100644 index 0000000..050861f --- /dev/null +++ b/apps/rebreak-native/.maestro/stress/rapid-post-submit.yaml @@ -0,0 +1,105 @@ +# stress/rapid-post-submit.yaml +# +# Stress scenario: Submit multiple community posts in rapid succession. +# Designed to catch race conditions in the post submission pipeline: +# - Duplicate optimistic inserts +# - ComposeCard not resetting between posts +# - React Query invalidation firing before previous request resolves +# - "Post konnte nicht veröffentlicht werden" error appearing incorrectly +# +# Samsung A50 note: The submit → reset cycle takes ~1–3s on A50 due to: +# - API round-trip to staging (network) +# - React Query invalidation → re-render +# - ComposeCard animation (expand/collapse) +# Each post is given 8s timeout. 3 posts = ~24s total on A50. +# +# Pre-requisite: Test-user exists on staging. Posts created are real (staging DB). +# Cleanup: Delete [E2E-STRESS] posts from staging DB manually or via Service-Role. +# Env-Vars: E2E_TEST_USER, E2E_TEST_PASSWORD + +appId: org.rebreak.app +--- +- launchApp: + clearState: true + +- waitForAnimationToEnd: + timeout: 8000 + +# --- Auth --- +- assertVisible: + text: "E-Mail" +- tapOn: + text: "E-Mail" +- inputText: ${E2E_TEST_USER}@rebreak.internal +- tapOn: + text: "Passwort" +- inputText: ${E2E_TEST_PASSWORD} +- tapOn: + text: "Anmelden" +- waitForAnimationToEnd: + timeout: 15000 + +- assertVisible: + text: "ReBreak" + +# --- Scroll to ComposeCard at top --- +- scrollUntilVisible: + element: + text: "Was bewegt dich gerade?" + direction: UP + timeout: 5000 + +# === POST 1 === +- tapOn: + text: "Was bewegt dich gerade?" +- waitForAnimationToEnd: + timeout: 1000 +- inputText: "[E2E-STRESS] Post 1 — Rapid-Submit-Test" +- assertVisible: + text: "Teilen" +- tapOn: + text: "Teilen" +- waitForAnimationToEnd: + timeout: 8000 + +# ComposeCard must reset after submit — placeholder visible again +- assertVisible: + text: "Was bewegt dich gerade?" + +# === POST 2 === +- tapOn: + text: "Was bewegt dich gerade?" +- waitForAnimationToEnd: + timeout: 1000 +- inputText: "[E2E-STRESS] Post 2 — Rapid-Submit-Test" +- assertVisible: + text: "Teilen" +- tapOn: + text: "Teilen" +- waitForAnimationToEnd: + timeout: 8000 + +- assertVisible: + text: "Was bewegt dich gerade?" + +# === POST 3 === +- tapOn: + text: "Was bewegt dich gerade?" +- waitForAnimationToEnd: + timeout: 1000 +- inputText: "[E2E-STRESS] Post 3 — Rapid-Submit-Test" +- assertVisible: + text: "Teilen" +- tapOn: + text: "Teilen" +- waitForAnimationToEnd: + timeout: 8000 + +- assertVisible: + text: "Was bewegt dich gerade?" + +# --- Verify no error state --- +# community.post_failed = "Post konnte nicht veröffentlicht werden." +# If any of the 3 posts failed with this error, the flow failed. +- assertNotVisible: + text: "Post konnte nicht veröffentlicht werden." diff --git a/apps/rebreak-native/CALLS_DEBUG_STATE.md b/apps/rebreak-native/CALLS_DEBUG_STATE.md new file mode 100644 index 0000000..4a4c2b4 --- /dev/null +++ b/apps/rebreak-native/CALLS_DEBUG_STATE.md @@ -0,0 +1,65 @@ +# Voice-Calls — Debug-Zustand (2026-06-05) + +Momentaufnahme beim Live-Debugging mit 2 Geräten (iOS + Android, beide über Metro). +Ziel: Kinderkrankheiten der Call-Funktion per Teile-und-Herrsche fixen. + +## Architektur (Ist-Zustand) + +Zwei Zustell-Pfade zum Callee — **beide feuern IMMER parallel** (Caller macht beides): + +1. **Realtime** `call-ring:` → `useIncomingCalls` → `receiveIncoming()` + `router.push('/call')`. + Greift nur wenn die App lebt + Realtime subscribed (FG, oder Android kurz nach BG). +2. **Push** `POST /api/calls/ring` → `sendCallRingPush`: + - **iOS + voipToken** → VoIP-PushKit → `AppDelegate.didReceiveIncomingPush` → `RNCallKeep.reportNewIncomingCall` (CallKit) → JS-Forward via `useCallKeepEvents`. + - **sonst** (Android, iOS ohne voipToken) → Expo-Push (channel `calls`, `data.type='call'`). Reagiert **nur auf Tap** (`addNotificationResponseReceivedListener`). + +Kern-Spannung: im FG entsteht Doppel-UI (in-app `/call` **und** CallKit/ConnectionService). +iOS-BG ist durch Apple auf CallKit festgenagelt (PushKit-Pflicht). Android-BG ist frei wählbar. + +## Verhaltens-Matrix + +| # | Anruf | Callee-State | Erwartet | Beobachtet | Hypothese (Root Cause) | +|---|-------|--------------|----------|------------|------------------------| +| 1 | Android→iOS | FG | `/call` bleibt, klingelt | `/call` erscheint, **verschwindet nach ~Sek** | VoIP-Push feuert auch im FG → CallKit übernimmt → App→`inactive` → CallKit-`endCall` feuert mit `appState≠active` → `onEnd`-Guard (`appState==='active'`) greift NICHT → `declineCall()` schließt `/call`. **(Logs nötig)** | +| 2 | iOS→Android | FG | korrekt | **korrekt** | — | +| 3 | Android→iOS | BG/locked | CallKit-Incoming (Apple) | **nichts**; nach Auflegen „verpasster Anruf"-Push; Telefon-App zeigt kein ReBreak-Audio | VoIP-Push erreicht Gerät nicht / CallKit nicht reported. Verdacht A: `voipToken=null` in DB → Fallback Expo-Push (im BG silent). Verdacht B: VoIP gesendet, aber APNs-Fehler (env/topic/cert). „Verpasster Anruf"-Push = Chat-DM aus `logCallToChat`. **(Logs nötig)** | +| 4 | iOS→Android | BG (App lebt) | ReBreak `/call` | **Android Telecom-native Incoming-UI** | Realtime im BG → `receiveIncoming` → `displayIncomingCall` → ConnectionService = System-Telecom-UI. „Working as coded", aber Design-Mismatch: gewünscht ist Custom-`/call` (Full-Screen-Intent). | + +## Divide & Conquer — Phasen + +- **Phase 0 — Diagnose** (non-destruktiv): 4 Szenarien durchspielen + Logs einsammeln + (`[call-ring] voip=?`, `[voip-push]`, `[VoIP] didReceiveIncomingPush`, `[callkeep] end … appState=`). + Bestätigt #1 und #3. +- **Phase 1 — iOS FG (#1)**: `/call` autoritativ machen; CallKit im FG unterdrücken / sauber + programmatisch beenden mit „programmatic-end"-Flag; `onEnd`-Guard reparieren (`inactive` = FG). +- **Phase 2 — iOS BG (#3)**: VoIP-Pfad fixen — voipToken-Registrierung + APNs env/topic/cert + verifizieren, bis CallKit im BG zuverlässig erscheint. +- **Phase 3 — Android BG (#4)**: Entscheidung Custom-Full-Screen-Intent vs Telecom-UI; ggf. umbauen. +- **Phase 4 — Aufräumen**: Doppel-Push/Doppel-Log, Missed-Call-Handling, einheitlicher Teardown. + +## ✅ BESTÄTIGTE Root Cause #3 (2026-06-05, via idevicesyslog + git) + +Build 76 wurde aus dem **alten** `with-voip-pushkit-ios.js` kompiliert, wo die PushKit-Registry +eine **lokale Variable** war (`let voipRegistry = PKPushRegistry(queue: nil)`) → deallociert +sofort nach `didFinishLaunching` → eingehende VoIP-Pushes erreichen `didReceiveIncomingPush` nie +→ kein `reportNewIncomingCall` → kein CallKit-Wake. Token-Registrierung klappt trotzdem +(Sync-Callback), daher `voip=1` am Server, aber Pushes verpuffen. + +**Beweise (idevicesyslog iPhone Air, Build 76):** +- `[voip] register event fired, token: 33899c2b…` ✅ (Token-Reg ok) +- `[voip-push] sent env=sandbox` am Server ✅ (Push verlässt Server) +- **`[VoIP] didReceiveIncomingPush` / `reportNewIncomingCall` FEHLEN komplett** ❌ +- CallKit-Fehler `requesttransaction Code=4` (unknown UUID) beim End-Versuch = Call war CallKit nie bekannt +- „verpasster Anruf"-Push = Chat-DM aus `logCallToChat` beim späteren FG-Realtime-Replay, NICHT der Ring + +**Fix:** bereits geschrieben (uncommitted) — Registry als `self.voipRegistry` retainen. +Liegt im `ios/ReBreak/AppDelegate.swift` (Jun 4 20:35), aber **nie in einen Build kompiliert**. +→ Dev-Rebuild (`expo run:ios --device`) kompiliert den Fix. Danach verifizieren dass +`[VoIP] didReceiveIncomingPush` feuert. Offen bleibt sekundärer Verdacht: Doppel-Registry +durch JS `registerVoipToken()` (Library erzeugt 2. unretained Registry) — empirisch nach Rebuild prüfen. + +## Apple-Constraint (kein Bug) + +Auf iOS **Background/locked** ist die Incoming-UI zwingend CallKit (PushKit verlangt +`reportNewIncomingCall` in derselben Run-Loop, sonst killt iOS die App). Der Custom-`/call`-Screen +kann dort erst NACH „Annehmen" erscheinen — nicht als Klingel-UI. diff --git a/apps/rebreak-native/CHANGELOG.md b/apps/rebreak-native/CHANGELOG.md index 28a3e95..ce4dfed 100644 --- a/apps/rebreak-native/CHANGELOG.md +++ b/apps/rebreak-native/CHANGELOG.md @@ -1,6 +1,39 @@ # Changelog All notable changes to rebreak-native will be documented in this file. +## v0.4.5 (Build 90 / versionCode 71) — 2026-06-10\n\n# Next Release — Notes + +- Fix: the "Protection is off" sheet and the "Protection tampered" push no longer + fire on devices where protection was never activated locally (fresh installs, + new devices, simulators). The bypass state now requires a local + "was active here" flag, set after a successful activation — instead of relying + on the account-wide backend default. Real bypasses (VPN/profile removed on a + device that had protection) are still detected. +- Copy: blocklist size updated 208k → 300k across all locales (de/en/fr/ar). +- Lyra avatar: richer, more present reactions. While you type or record a voice + message, Lyra shows a note-taking pose (like a therapist listening) and keeps + it while she prepares her reply, then reacts to the tone of the conversation. +- Fix (Android 16): activating VPN protection no longer crashes the app. The + DNS-filter foreground service used a service type that Android 16 rejects at + start; switched to the correct `specialUse` type so the filter starts reliably + on Android 14, 15 and 16. +- Onboarding: the protection step can no longer trap you. If protection can't be + activated on your device (or activation fails), a "set up later" option now + appears so you can finish onboarding and enable protection anytime from the + Protection screen. +- Fix (Android, esp. Samsung): protection no longer silently dies when the phone + puts the app to sleep. Setup now includes a "turn off battery optimization" + step — without it, aggressive power management could unbind the accessibility + lock so protection stopped enforcing while still looking active. On Samsung a + hint guides you to the stronger "Unrestricted" battery setting. +- Fix (Android): the protection status is now honest. If the accessibility + service isn't actually running, the app no longer shows "fully protected" — it + correctly shows the step as open and prompts you to re-enable it. +- Android setup polish: activating the VPN now shows a short spinner until it's + confirmed (the step no longer looks stuck for a minute), and enabling the + accessibility lock no longer needs a second tap. +- Stability: realtime updates no longer log spurious errors while the app is in + the background (the websocket close on suspend is expected and now silent).\n ## v0.4.4 (Build 90 / versionCode 70) — 2026-06-08\n\n# Next Release ## Improved diff --git a/apps/rebreak-native/NEXT_RELEASE.md b/apps/rebreak-native/NEXT_RELEASE.md index 8342db2..753bed4 100644 --- a/apps/rebreak-native/NEXT_RELEASE.md +++ b/apps/rebreak-native/NEXT_RELEASE.md @@ -1,9 +1,11 @@ -# Next Release — Notes +# Next Release -- Fix: the "Protection is off" sheet and the "Protection tampered" push no longer - fire on devices where protection was never activated locally (fresh installs, - new devices, simulators). The bypass state now requires a local - "was active here" flag, set after a successful activation — instead of relying - on the account-wide backend default. Real bypasses (VPN/profile removed on a - device that had protection) are still detected. -- Copy: blocklist size updated 208k → 300k across all locales (de/en/fr/ar). +## Fixes + +- **Android: fixed crash loop on app open (Samsung / Android 14–16).** The VPN + protection service crashed with `SecurityException` in `startForeground()` + because Android 16's `validateForegroundServiceType` rejects the implicit + 2-arg call. We now pass the `specialUse` foreground-service type explicitly + (Google's documented best practice) and guard the call so a failed + foreground promotion can never crash the app again. Verified against the + reported Galaxy A54 / Android 16 crash signature. diff --git a/apps/rebreak-native/app.config.ts b/apps/rebreak-native/app.config.ts index db41ba5..7126586 100644 --- a/apps/rebreak-native/app.config.ts +++ b/apps/rebreak-native/app.config.ts @@ -36,7 +36,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ ios: { supportsTablet: true, bundleIdentifier: MAIN_BUNDLE, - buildNumber: "90", + buildNumber: "92", // Apple Sign-In Entitlement — Pflicht für expo-apple-authentication nativen // signInAsync()-Flow. Ohne flag generiert Expo's prebuild den // com.apple.developer.applesignin-Entitlement nicht in die .entitlements. @@ -62,7 +62,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ android: { package: "org.rebreak.app", - versionCode: 70, + versionCode: 73, // Firebase / FCM-v1-Credentials: Pflicht ab Expo SDK 53 für Android-Push. // Enthält client-config für beide Packages (org.rebreak.app + .dev) und // ist NICHT geheim (API-Key per Package-Signing-Fingerprint restricted) — @@ -92,6 +92,13 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ "BIND_TELECOM_CONNECTION_SERVICE", "FOREGROUND_SERVICE_MICROPHONE", "FOREGROUND_SERVICE_PHONE_CALL", + // Pflicht für den VPN-DNS-Filter-Foregroundservice (Typ specialUse) ab + // Android 14; ohne diese Permission wirft startForeground auf Android 16 + // eine SecurityException. Play braucht dazu eine einmalige Special-Use-Decl. + "FOREGROUND_SERVICE_SPECIAL_USE", + // Akku-Ausnahme anfordern: ohne sie schläfert Samsung & Co. die App ein → + // a11y-Tamper-Lock wird entbunden → Schutz fällt still aus. + "REQUEST_IGNORE_BATTERY_OPTIMIZATIONS", "USE_FULL_SCREEN_INTENT", // Nutzungszugriff: erlaubt das Erkennen des aktuellen Settings-Screens // (UsageStatsManager) → state-aware a11y-Setup-Guide. User muss es manuell diff --git a/apps/rebreak-native/app/(app)/blocker.tsx b/apps/rebreak-native/app/(app)/blocker.tsx index 635e898..781ef7a 100644 --- a/apps/rebreak-native/app/(app)/blocker.tsx +++ b/apps/rebreak-native/app/(app)/blocker.tsx @@ -103,6 +103,7 @@ export default function BlockerScreen() { const appDeletionLockActive = (state?.layers.appDeletionLock ?? familyControlsActive) === true; const nefilterActive = state?.layers.nefilterActive === true; const deviceAdminActive = state?.layers.deviceAdmin === true; + const batteryUnrestricted = state?.layers.batteryUnrestricted === true; // "lockedIn" = beide Layer aktiv: URL-Filter (echter Schutz) UND App-Lock // (Hardening). Family-Controls ALLEINE = kein Schutz, nur denyAppRemoval — // ohne URL-Filter sieht der User trotzdem Glücksspielseiten. Daher BEIDE @@ -114,7 +115,11 @@ export default function BlockerScreen() { // Profile + non-removable App enforced, FC-Toggle ist irrelevant. // nefilterActive → Schutz via System-Profil, kein VPN-Toggle nötig → locked-in const lockedIn = Platform.OS === 'android' - ? (urlFilterActive && appDeletionLockActive && deviceAdminActive) + // Akku-Ausnahme MUSS dabei sein — ohne sie schläfert Samsung & Co. den + // a11y-Service ein (Lock entbunden → Schutz fällt still aus). Sonst zeigt der + // Banner „geschützt" + versteckt den (offenen) Akku-Step. Konsistent mit der + // Onboarding-`allDone`. + ? (urlFilterActive && appDeletionLockActive && deviceAdminActive && batteryUnrestricted) : (nefilterActive || urlFilterActive) && (mdmManaged || nefilterActive || appDeletionLockActive || !FAMILY_CONTROLS_AVAILABLE); const urlFilterActiveRef = useRef(urlFilterActive); @@ -171,6 +176,19 @@ export default function BlockerScreen() { } } + // ─── Akku-Ausnahme (gegen Samsung-Sleep, der den a11y-Lock entbindet) ── + + async function handleRequestBattery() { + // System-Dialog „Akku-Optimierung ignorieren?" (ein Tap). Der State zieht via + // AppState-'active'-Refresh nach, wenn der User zurückkommt. + return protection.requestIgnoreBatteryOptimizations(); + } + async function handleOpenAppDetails() { + // Samsung-Sonderweg: App-Detail → Akku „Uneingeschränkt" + raus aus + // „Schlafende Apps" (deckt der AOSP-Whitelist-Dialog nicht ab). + return protection.openAppDetailsSettings(); + } + // ─── Activate-Handler pro Layer ────────────────────────────────────── async function handleActivateUrlFilter() { @@ -363,9 +381,12 @@ export default function BlockerScreen() { vpnActive={urlFilterActive} accessibilityLocked={appDeletionLockActive} deviceAdminActive={deviceAdminActive} + batteryUnrestricted={batteryUnrestricted} onActivateVpn={handleActivateUrlFilter} onActivateAccessibility={handleActivateFamilyControls} onRequestDeviceAdmin={handleRequestDeviceAdmin} + onRequestBattery={handleRequestBattery} + onOpenAppDetails={handleOpenAppDetails} colors={colors} t={t} /> diff --git a/apps/rebreak-native/app/debug.tsx b/apps/rebreak-native/app/debug.tsx index 3c55b96..0934535 100644 --- a/apps/rebreak-native/app/debug.tsx +++ b/apps/rebreak-native/app/debug.tsx @@ -14,12 +14,13 @@ import { SafeAreaView } from 'react-native-safe-area-context'; import { useRouter } from 'expo-router'; import { Ionicons } from '@expo/vector-icons'; import { useColors } from '../lib/theme'; -import { useMe, invalidateMe, type Plan } from '../hooks/useMe'; +import { useMe, invalidateMe, type Plan, type OnboardingStep } from '../hooks/useMe'; import { apiFetch } from '../lib/api'; import { PlanChangeSheet } from '../components/plan/PlanChangeSheet'; import { getCooldownTestMode, setCooldownTestMode, protection } from '../lib/protection'; import { useRealtimeDebugStore, type LogEntry } from '../stores/realtimeDebug'; import { supabase } from '../lib/supabase'; +import { RiveAvatar, EMOTION_ANIMATIONS, EXISTING_TIMELINES, type Emotion } from '../components/RiveAvatar'; export default function DebugScreen() { const router = useRouter(); @@ -107,6 +108,8 @@ export default function DebugScreen() { + + {me ? ( ('idle'); + const wanted = EMOTION_ANIMATIONS[emotion] ?? '—'; + const exists = EXISTING_TIMELINES.has(wanted); + + return ( + + + + + + + + Lyra Emotion Preview + + + Rive-State-Tester — Timeline aus lyra-avatar.riv + + + + + + + + {emotion} → "{wanted}" + {exists ? ' ✓ im .riv' : ' → Idle (Timeline fehlt noch)'} + + + + + {PREVIEW_EMOTIONS.map((em) => { + const isActive = em === emotion; + return ( + setEmotion(em)} + activeOpacity={0.7} + style={{ + paddingVertical: 8, + paddingHorizontal: 14, + borderRadius: 10, + backgroundColor: isActive ? colors.brandOrange : colors.surfaceElevated, + }} + > + + {em} + + + ); + })} + + + ); +} + // ─── Redirect-Test Card (Layer-1-Bypass-Repro) ───────────────────────────── /** @@ -924,7 +1052,10 @@ function PlanOverrideToggle({ // ─── Onboarding Reset ────────────────────────────────────────────────────── -const ONBOARDING_STEPS = ['welcome', 'nickname', 'block', 'done'] as const; +// Nur die im aktuellen Duo-Flow relevanten Sprungziele. `pre_protection` springt +// per slideFromStep direkt zum Protection-Step (überspringt Welcome/Nickname/Plan) +// — das ist der schnellste Weg, den Schutz-Onboarding-Flow zu testen. +const ONBOARDING_STEPS = ['welcome', 'pre_protection', 'done'] as const; type OnboardingStepValue = (typeof ONBOARDING_STEPS)[number]; function OnboardingResetToggle({ @@ -932,7 +1063,7 @@ function OnboardingResetToggle({ currentStep, }: { colors: import('../lib/theme').ColorScheme; - currentStep: OnboardingStepValue; + currentStep: OnboardingStep; }) { const router = useRouter(); const [loading, setLoading] = useState(false); @@ -946,18 +1077,12 @@ function OnboardingResetToggle({ body: { step }, }); invalidateMe(); - if (step === 'welcome') { - // /onboarding/welcome existiert nicht mehr (Duo-Rewrite → /onboarding/index.tsx). - // Korrekter Pfad ist /onboarding (Expo Router löst index.tsx auto auf). - router.replace('/onboarding'); - } else if (step === 'nickname') { - // Legacy-Stage — Duo-Flow navigiert intern; /onboarding triggert via - // slideFromStep den Resume zur Nickname-Slide. - router.replace('/onboarding'); - } else if (step === 'block') { - router.replace('/(app)/blocker'); - } else if (step === 'done') { + // done → zurück in die App; alles andere (welcome, pre_protection) → /onboarding, + // wo slideFromStep den passenden Resume-Slide auflöst. + if (step === 'done') { router.replace('/(app)'); + } else { + router.replace('/onboarding'); } } catch (e: unknown) { Alert.alert('Fehler', e instanceof Error ? e.message : String(e)); diff --git a/apps/rebreak-native/app/index.tsx b/apps/rebreak-native/app/index.tsx index 5801180..33391b7 100644 --- a/apps/rebreak-native/app/index.tsx +++ b/apps/rebreak-native/app/index.tsx @@ -1,209 +1,78 @@ -import { useEffect, useRef } from 'react'; -import { Animated, Dimensions, Image, Text, TouchableOpacity, View } from 'react-native'; -import Svg, { Defs, RadialGradient, Rect, Stop } from 'react-native-svg'; +import { useEffect, useState } from 'react'; +import { Image, Text, TouchableOpacity, View } from 'react-native'; +import Animated, { + Easing, + useAnimatedStyle, + useSharedValue, + withDelay, + withTiming, +} from 'react-native-reanimated'; import { useRouter } from 'expo-router'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useTranslation } from 'react-i18next'; import { useAuthStore } from '../stores/auth'; +import { BrandSplash } from '../components/BrandSplash'; -const { width: SW, height: SH } = Dimensions.get('window'); +const EASE_OUT = Easing.out(Easing.cubic); export default function LandingScreen() { const router = useRouter(); const insets = useSafeAreaInsets(); const { t } = useTranslation(); - // Reaktiver Routing-Fix für „eingeloggt bleiben": wenn beim Cold-Start (oder - // nach einem `router.replace('/')` aus dem LockScreen-Sign-Out) bereits eine - // gültige Session in AsyncStorage liegt, überspringen wir das Landing und - // schicken den User direkt in `(app)`. const session = useAuthStore((s) => s.session); const loading = useAuthStore((s) => s.loading); + const [splashDone, setSplashDone] = useState(false); + + const ctaOpacity = useSharedValue(0); + const ctaTranslateY = useSharedValue(14); + useEffect(() => { if (!loading && session) { router.replace('/(app)'); } }, [loading, session, router]); - const glowTopOpacity = useRef(new Animated.Value(0.5)).current; - const glowCenterOpacity = useRef(new Animated.Value(0)).current; - const glowCenterScale = useRef(new Animated.Value(0.6)).current; + function handleSplashDone() { + setSplashDone(true); + ctaOpacity.value = withTiming(1, { duration: 380, easing: EASE_OUT }); + ctaTranslateY.value = withTiming(0, { duration: 380, easing: EASE_OUT }); + } - const nameOpacity = useRef(new Animated.Value(0)).current; - const nameTranslateY = useRef(new Animated.Value(12)).current; + const ctaStyle = useAnimatedStyle(() => ({ + opacity: ctaOpacity.value, + transform: [{ translateY: ctaTranslateY.value }], + })); - const logoOpacity = useRef(new Animated.Value(0)).current; - const logoScale = useRef(new Animated.Value(0.82)).current; - const logoTranslateY = useRef(new Animated.Value(8)).current; - const logoPulse = useRef(new Animated.Value(1)).current; - - const taglineOpacity = useRef(new Animated.Value(0)).current; - const taglineTranslateY = useRef(new Animated.Value(8)).current; - - const ctaOpacity = useRef(new Animated.Value(0)).current; - const ctaTranslateY = useRef(new Animated.Value(10)).current; - - const footerOpacity = useRef(new Animated.Value(0)).current; - - useEffect(() => { - Animated.loop( - Animated.sequence([ - Animated.timing(glowTopOpacity, { toValue: 0.9, duration: 2000, useNativeDriver: true }), - Animated.timing(glowTopOpacity, { toValue: 0.5, duration: 2000, useNativeDriver: true }), - ]), - ).start(); - - const ease = (toValue: number, duration: number) => ({ toValue, duration, useNativeDriver: true }); - - Animated.parallel([ - Animated.timing(glowCenterOpacity, ease(1, 900)), - Animated.timing(glowCenterScale, ease(1, 900)), - ]).start(); - - setTimeout(() => { - Animated.parallel([ - Animated.timing(nameOpacity, ease(1, 600)), - Animated.timing(nameTranslateY, ease(0, 600)), - ]).start(); - }, 300); - - setTimeout(() => { - Animated.parallel([ - Animated.timing(logoOpacity, ease(1, 650)), - Animated.spring(logoScale, { toValue: 1, useNativeDriver: true, friction: 6, tension: 80 }), - Animated.timing(logoTranslateY, ease(0, 650)), - ]).start(); - }, 700); - - setTimeout(() => { - Animated.loop( - Animated.sequence([ - Animated.timing(logoPulse, { toValue: 1.04, duration: 1300, useNativeDriver: true }), - Animated.timing(logoPulse, { toValue: 1, duration: 1300, useNativeDriver: true }), - ]), - ).start(); - }, 1100); - - setTimeout(() => { - Animated.parallel([ - Animated.timing(taglineOpacity, ease(1, 550)), - Animated.timing(taglineTranslateY, ease(0, 550)), - ]).start(); - }, 1300); - - setTimeout(() => { - Animated.parallel([ - Animated.timing(ctaOpacity, ease(1, 500)), - Animated.timing(ctaTranslateY, ease(0, 500)), - Animated.timing(footerOpacity, ease(1, 600)), - ]).start(); - }, 1700); - }, [ - glowTopOpacity, glowCenterOpacity, glowCenterScale, - nameOpacity, nameTranslateY, logoOpacity, logoScale, logoTranslateY, - logoPulse, taglineOpacity, taglineTranslateY, ctaOpacity, ctaTranslateY, footerOpacity, - ]); - - // Early-return MUSS nach allen Hooks stehen (Rules of Hooks) — sonst wirft - // React "Rendered fewer hooks than expected" wenn sich loading/session zwischen - // Renders ändert. if (loading || session) return null; + if (!splashDone) { + return ; + } + return ( - {/* Top breathing glow */} - - - - - - - - - - - - - {/* Center indigo halo */} - - - - - - - - - - - - - {/* Content */} - - - {t('appHeader.appName')} - - - + + - + + {t('appHeader.appName')} + + - - {t('splash.tagline')} - - - + router.push('/signin')} activeOpacity={0.85} @@ -237,8 +106,7 @@ export default function LandingScreen() { - {/* Footer */} - {t('splash.madeInGermany')} - + ); } diff --git a/apps/rebreak-native/app/lyra.tsx b/apps/rebreak-native/app/lyra.tsx index d6bbad5..81b8bce 100644 --- a/apps/rebreak-native/app/lyra.tsx +++ b/apps/rebreak-native/app/lyra.tsx @@ -244,14 +244,15 @@ export default function CoachScreen() { function handleInputChange(text: string) { setInput(text); if (text.length > 0) { - setEmotion((e) => (e === 'thinking' ? e : 'happy')); + // Lyra hört aufmerksam zu, während getippt wird (nicht während sie denkt). + setEmotion((e) => (e === 'thinking' ? e : 'listening')); if (typingTimer.current) clearTimeout(typingTimer.current); typingTimer.current = setTimeout(() => { - setEmotion((e) => (e === 'happy' ? 'idle' : e)); + setEmotion((e) => (e === 'listening' ? 'idle' : e)); }, 2500); } else { if (typingTimer.current) clearTimeout(typingTimer.current); - setEmotion((e) => (e === 'happy' ? 'idle' : e)); + setEmotion((e) => (e === 'listening' ? 'idle' : e)); } } @@ -416,6 +417,7 @@ export default function CoachScreen() { await rec.startAsync(); recordingRef.current = rec; setIsRecording(true); + setEmotion('listening'); // Lyra hört zu, während aufgenommen wird startRecordingTimer(); } catch { micHeld.current = false; @@ -430,6 +432,7 @@ export default function CoachScreen() { recordingRef.current = null; micHeld.current = false; stopRecordingTimer(); + setEmotion('idle'); // Aufnahme verworfen → zurück in den Ruhezustand setTrashFlash(true); setTimeout(() => { setTrashFlash(false); @@ -459,7 +462,7 @@ export default function CoachScreen() { if (!uri) return; setIsTranscribing(true); - setEmotion('happy'); + setEmotion('listening'); // verarbeitet die Stimme weiter (vor dem "thinking" in handleVoiceSend) try { // Backend erwartet base64-Audio in JSON-Body (NICHT FormData): diff --git a/apps/rebreak-native/app/urge.tsx b/apps/rebreak-native/app/urge.tsx index 3a999c9..f6e0117 100644 --- a/apps/rebreak-native/app/urge.tsx +++ b/apps/rebreak-native/app/urge.tsx @@ -733,12 +733,17 @@ export default function SOSScreen() { function startBreathing() { // Laufendes Lyra-TTS stoppen — sonst spricht sie in die Atemübung rein stopSpeaking(); + // Lyra atmet ruhig mit (Header-Avatar bleibt während des Drawers sichtbar). + // Pending Emotion-Reset abbrechen, sonst springt sie nach 4-6s aus 'calm'. + if (emotionTimer.current) clearTimeout(emotionTimer.current); + setEmotion('calm'); setIsBreathing(true); setChipSet('none'); } async function handleBreathingDone() { setIsBreathing(false); + setEmotion('idle'); // raus aus 'calm' — die after_breathing-Antwort setzt danach die erkannte Emotion setBreathingDone(true); breathingCountRef.current += 1; setChipSet('after_breathing'); @@ -1290,7 +1295,7 @@ export default function SOSScreen() { editable={!thinking} /> {input.trim() !== '' && ( - + )} diff --git a/apps/rebreak-native/assets/DEPRECATED.md b/apps/rebreak-native/assets/DEPRECATED.md new file mode 100644 index 0000000..a7437dc --- /dev/null +++ b/apps/rebreak-native/assets/DEPRECATED.md @@ -0,0 +1,14 @@ +# Deprecated Assets + +These files are kept in place to avoid breaking native build configuration. +Do NOT delete without first updating app.config.ts and running `expo prebuild --clean`. + +## splash.png +- What: old chain-break logo on navy gradient — used as the native OS-level splash screen image +- Referenced in: app.config.ts → `splash.image` +- Replaced by: animated in-app `BrandSplash` component (`components/BrandSplash.tsx`) which runs after the native splash hides +- TODO (Orchestrator / Zied): update `app.config.ts` to use `assets/icon.png` as the native splash image (matching the in-app logo), then `expo prebuild --clean` + rebuild. A transparent logo variant (logo mark only, no rounded-square background) would be ideal for the native splash — currently not available; icon.png on #0f172a background is the fallback. + +## adaptive-icon.png / adaptive-foreground.png / rebreak_android.png +- What: older Android adaptive icon variants +- Status: may still be referenced in app.config.ts android block — verify before removing diff --git a/apps/rebreak-native/assets/devices/android.png b/apps/rebreak-native/assets/devices/android.png new file mode 100644 index 0000000..25f6181 Binary files /dev/null and b/apps/rebreak-native/assets/devices/android.png differ diff --git a/apps/rebreak-native/assets/devices/computer.png b/apps/rebreak-native/assets/devices/computer.png new file mode 100644 index 0000000..a01d215 Binary files /dev/null and b/apps/rebreak-native/assets/devices/computer.png differ diff --git a/apps/rebreak-native/assets/devices/iphone.png b/apps/rebreak-native/assets/devices/iphone.png new file mode 100644 index 0000000..f9f1b81 Binary files /dev/null and b/apps/rebreak-native/assets/devices/iphone.png differ diff --git a/apps/rebreak-native/assets/devices/laptop.png b/apps/rebreak-native/assets/devices/laptop.png new file mode 100644 index 0000000..1295182 Binary files /dev/null and b/apps/rebreak-native/assets/devices/laptop.png differ diff --git a/apps/rebreak-native/assets/devices/macbook.png b/apps/rebreak-native/assets/devices/macbook.png new file mode 100644 index 0000000..209204b Binary files /dev/null and b/apps/rebreak-native/assets/devices/macbook.png differ diff --git a/apps/rebreak-native/assets/devices/tablet.png b/apps/rebreak-native/assets/devices/tablet.png new file mode 100644 index 0000000..08c68e3 Binary files /dev/null and b/apps/rebreak-native/assets/devices/tablet.png differ diff --git a/apps/rebreak-native/clean.sh b/apps/rebreak-native/clean.sh new file mode 100755 index 0000000..22c2064 --- /dev/null +++ b/apps/rebreak-native/clean.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# clean.sh — systematisches Reclaiming von Dev-Caches (macOS). +# +# Problem: lokale Builds + globale Toolchain-Caches (Gradle, Xcode DerivedData, +# iOS-Simulatoren) wuchern bis die Platte voll ist und Builds/Emulator failen +# ("not enough disk space"). deploy.sh räumt nur die PROJEKT-Build-Dirs; +# globale Caches verwaltet sonst niemand. Dieses Script schließt die Lücke. +# +# Tiers: +# (default) project: android/build, android/app/build, android/.gradle, ios/build +# + Xcode DerivedData (komplett) + nicht-verfügbare iOS-Sims. +# Alles regeneriert sich beim nächsten Build (kein Daten-Verlust). +# --deep zusätzlich: globaler Gradle-Cache (~/.gradle/caches) + ios/Pods. +# Frei mehr Platz, aber der NÄCHSTE Build lädt Deps/Pods neu (langsamer). +# --check nur Diagnose (df + Top-Verbraucher), löscht nichts. +# +# Nutzung: +# ./clean.sh # sicheres Reclaiming +# ./clean.sh --deep # aggressiv (global gradle + pods) +# ./clean.sh --check # nur anschauen +set -uo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ANDROID_DIR="$SCRIPT_DIR/android" +IOS_DIR="$SCRIPT_DIR/ios" + +MODE="safe" +GUARD_GB="${2:-8}" +case "${1:-}" in + --deep) MODE="deep" ;; + --check) MODE="check" ;; + --guard) MODE="guard" ;; + "" ) MODE="safe" ;; + *) echo "Unbekannte Option: $1 (erlaubt: --deep, --check, --guard [GB])"; exit 1 ;; +esac + +free_gb() { df -g / 2>/dev/null | awk 'NR==2 {print $4}'; } + +human() { du -sh "$1" 2>/dev/null | awk '{print $1}'; } + +# --guard [GB]: stiller Pre-Build-Check. Warnt nur, wenn frei < Schwelle (8G). +# Wird von dev.sh/deploy.sh vor dem Build aufgerufen — bricht NIE ab (exit 0). +if [ "$MODE" = "guard" ]; then + FREE="$(free_gb)" + if [ "${FREE:-99}" -lt "$GUARD_GB" ]; then + echo "⚠️ Nur ${FREE}G frei (< ${GUARD_GB}G) — Build/Emulator könnte an Speicher scheitern." + echo " Aufräumen: ./clean.sh (mehr: ./clean.sh --deep)" + fi + exit 0 +fi + +echo "── Disk-Status ────────────────────────────────────────────" +df -h / | sed -n '1p;2p' +BEFORE_GB="$(free_gb)" +echo + +report_targets() { + echo "Top-Verbraucher (Dev-Caches):" + for d in "$ANDROID_DIR/app/build" "$ANDROID_DIR/build" "$ANDROID_DIR/.gradle" \ + "$IOS_DIR/build" "$IOS_DIR/Pods" "$HOME/.gradle/caches" \ + "$HOME/Library/Developer/Xcode/DerivedData" \ + "$HOME/Library/Developer/CoreSimulator"; do + [ -e "$d" ] && printf " %-60s %s\n" "$d" "$(human "$d")" + done +} + +if [ "$MODE" = "check" ]; then + report_targets + echo; echo "free: ${BEFORE_GB}G — (nur Diagnose, nichts gelöscht)" + exit 0 +fi + +report_targets +echo + +# Gradle-Daemon stoppen, sonst sind android/build & .gradle gelockt. +echo "→ Gradle-Daemon stoppen…" +( cd "$ANDROID_DIR" 2>/dev/null && ./gradlew --stop >/dev/null 2>&1 ) || true +pkill -f "GradleDaemon" 2>/dev/null || true + +rmrf() { [ -e "$1" ] && { echo " rm $1 ($(human "$1"))"; rm -rf "$1"; } || true; } + +echo "→ Projekt-Build-Artefakte…" +rmrf "$ANDROID_DIR/app/build" +rmrf "$ANDROID_DIR/build" +rmrf "$ANDROID_DIR/.gradle" +rmrf "$IOS_DIR/build" + +echo "→ Xcode DerivedData…" +rmrf "$HOME/Library/Developer/Xcode/DerivedData" + +echo "→ nicht-verfügbare iOS-Simulatoren…" +xcrun simctl delete unavailable >/dev/null 2>&1 || true + +if [ "$MODE" = "deep" ]; then + echo "→ [deep] globaler Gradle-Cache (~/.gradle/caches)…" + rmrf "$HOME/.gradle/caches" + echo "→ [deep] ios/Pods (pod install nötig danach)…" + rmrf "$IOS_DIR/Pods" +fi + +echo +echo "── Ergebnis ───────────────────────────────────────────────" +df -h / | sed -n '2p' +AFTER_GB="$(free_gb)" +echo "frei vorher: ${BEFORE_GB}G → nachher: ${AFTER_GB}G (≈ $((AFTER_GB - BEFORE_GB))G zurückgewonnen)" +echo +echo "Hinweis: nächster Android-Build ist langsamer (Caches regenerieren)." +if [ "$MODE" = "deep" ]; then + echo " iOS braucht 'pod install' (ios/Pods gelöscht)." +fi +exit 0 diff --git a/apps/rebreak-native/components/AppHeader.tsx b/apps/rebreak-native/components/AppHeader.tsx index 0806061..6d89b54 100644 --- a/apps/rebreak-native/components/AppHeader.tsx +++ b/apps/rebreak-native/components/AppHeader.tsx @@ -111,6 +111,7 @@ export function AppHeader({ notifCount, showBack, title }: Props = {}) { schluckt auf Android manchmal width/height → 0×0 + overflow:hidden → Avatar unsichtbar (vgl. Mac-CTA-Fix 7d04e42). */} setMenuOpen(true)} hitSlop={{ top: 4, bottom: 4, left: 4, right: 4 }} activeOpacity={0.7} diff --git a/apps/rebreak-native/components/BrandSplash.tsx b/apps/rebreak-native/components/BrandSplash.tsx index 961ddb4..c35c2f1 100644 --- a/apps/rebreak-native/components/BrandSplash.tsx +++ b/apps/rebreak-native/components/BrandSplash.tsx @@ -1,409 +1,199 @@ -import { useEffect, useRef } from 'react'; -import { Animated, Dimensions, Image, Text, View } from 'react-native'; +import { useEffect } from 'react'; +import { Dimensions, Image, View } from 'react-native'; +import Animated, { + Easing, + runOnJS, + useAnimatedStyle, + useReducedMotion, + useSharedValue, + withDelay, + withSequence, + withTiming, +} from 'react-native-reanimated'; import Svg, { Defs, RadialGradient, Rect, Stop } from 'react-native-svg'; import { useTranslation } from 'react-i18next'; -// Phase-Timings (ms ab Mount) — 1:1 portiert aus apps/rebreak/app/components/AppSplash.vue -const T_GLOW = 0; -const T_NAME = 300; -const T_LOGO = 700; -const T_PULSE = 1100; -const T_TAGLINE = 1300; -const T_SUB = 1700; -const T_HOLD_END = 3200; -const T_LEAVE_DUR = 500; +const { height: SH } = Dimensions.get('window'); -const { width: SW, height: SH } = Dimensions.get('window'); +const EASE_OUT = Easing.out(Easing.cubic); +const EASE_IN = Easing.in(Easing.cubic); -type ParticleConfig = { - size: number; - top?: number; - bottom?: number; - left?: number; - right?: number; - duration: number; - delay: number; +type Props = { + onDone?: () => void; }; -const PARTICLES: ParticleConfig[] = [ - { size: 180, top: -40, left: -60, duration: 7000, delay: 0 }, - { size: 120, bottom: SH * 0.1, right: -30, duration: 9000, delay: 1500 }, - { size: 80, top: SH * 0.35, left: SW * 0.08, duration: 11000, delay: 800 }, - { size: 60, bottom: SH * 0.2, left: SW * 0.2, duration: 8000, delay: 2200 }, - { size: 100, top: SH * 0.15, right: SW * 0.1, duration: 10000, delay: 400 }, -]; - -function Particle({ config }: { config: ParticleConfig }) { - const translateY = useRef(new Animated.Value(0)).current; - const scale = useRef(new Animated.Value(1)).current; - const opacity = useRef(new Animated.Value(0.6)).current; - - useEffect(() => { - const animate = () => { - Animated.loop( - Animated.sequence([ - Animated.parallel([ - Animated.timing(translateY, { - toValue: 18, - duration: config.duration, - useNativeDriver: true, - }), - Animated.timing(scale, { - toValue: 1.1, - duration: config.duration, - useNativeDriver: true, - }), - Animated.timing(opacity, { - toValue: 1, - duration: config.duration, - useNativeDriver: true, - }), - ]), - Animated.parallel([ - Animated.timing(translateY, { - toValue: 0, - duration: config.duration, - useNativeDriver: true, - }), - Animated.timing(scale, { - toValue: 1, - duration: config.duration, - useNativeDriver: true, - }), - Animated.timing(opacity, { - toValue: 0.6, - duration: config.duration, - useNativeDriver: true, - }), - ]), - ]), - ).start(); - }; - const t = setTimeout(animate, config.delay); - return () => clearTimeout(t); - }, [config, translateY, scale, opacity]); - - return ( - - ); -} - -export function BrandSplash() { +export function BrandSplash({ onDone }: Props) { const { t } = useTranslation(); - // Phase-Opacity-Animationen - const containerOpacity = useRef(new Animated.Value(1)).current; - const glowCenterOpacity = useRef(new Animated.Value(0)).current; - const glowCenterScale = useRef(new Animated.Value(0.6)).current; - const glowTopOpacity = useRef(new Animated.Value(0.5)).current; + const reducedMotion = useReducedMotion(); - const nameOpacity = useRef(new Animated.Value(0)).current; - const nameTranslateY = useRef(new Animated.Value(12)).current; - - const logoOpacity = useRef(new Animated.Value(0)).current; - const logoScale = useRef(new Animated.Value(0.82)).current; - const logoTranslateY = useRef(new Animated.Value(8)).current; - const logoPulse = useRef(new Animated.Value(1)).current; - - const taglineOpacity = useRef(new Animated.Value(0)).current; - const taglineTranslateY = useRef(new Animated.Value(8)).current; - - const subOpacity = useRef(new Animated.Value(0)).current; - const subTranslateY = useRef(new Animated.Value(6)).current; - - const footerOpacity = useRef(new Animated.Value(0)).current; + const containerOpacity = useSharedValue(1); + const logoOpacity = useSharedValue(0); + const logoScale = useSharedValue(reducedMotion ? 1 : 0.88); + const nameOpacity = useSharedValue(0); + const nameTranslateY = useSharedValue(reducedMotion ? 0 : 10); + const taglineOpacity = useSharedValue(0); + const taglineTranslateY = useSharedValue(reducedMotion ? 0 : 8); + const glowOpacity = useSharedValue(0); + const footerOpacity = useSharedValue(0); useEffect(() => { - // Top-glow breath loop (4s alternating) — startet sofort - Animated.loop( - Animated.sequence([ - Animated.timing(glowTopOpacity, { - toValue: 0.9, - duration: 2000, - useNativeDriver: true, + if (reducedMotion) { + const dur = 500; + const cfg = { duration: dur, easing: EASE_OUT }; + logoOpacity.value = withTiming(1, cfg); + nameOpacity.value = withTiming(1, cfg); + taglineOpacity.value = withTiming(1, cfg); + footerOpacity.value = withTiming(1, cfg); + + containerOpacity.value = withDelay( + 2700, + withTiming(0, { duration: 400, easing: EASE_IN }, (finished) => { + if (finished && onDone) runOnJS(onDone)(); }), - Animated.timing(glowTopOpacity, { - toValue: 0.5, - duration: 2000, - useNativeDriver: true, - }), - ]), - ).start(); + ); + return; + } - const ease = (toValue: number, duration: number) => ({ - toValue, - duration, - useNativeDriver: true, - }); + const revealCfg = (duration: number) => ({ duration, easing: EASE_OUT }); - // Phase 1: glow center bloom (T=0) - Animated.parallel([ - Animated.timing(glowCenterOpacity, ease(1, 900)), - Animated.timing(glowCenterScale, ease(1, 900)), - ]).start(); + glowOpacity.value = withTiming(1, revealCfg(1000)); - // Phase 2: Name fade-in (T=300) - setTimeout(() => { - Animated.parallel([ - Animated.timing(nameOpacity, ease(1, 600)), - Animated.timing(nameTranslateY, ease(0, 600)), - ]).start(); - }, T_NAME); + logoOpacity.value = withDelay(100, withTiming(1, revealCfg(700))); + logoScale.value = withDelay(100, withTiming(1, revealCfg(750))); - // Phase 3: Logo bouncy scale-in (T=700) - setTimeout(() => { - Animated.parallel([ - Animated.timing(logoOpacity, ease(1, 650)), - Animated.spring(logoScale, { - toValue: 1, - useNativeDriver: true, - friction: 6, - tension: 80, - }), - Animated.timing(logoTranslateY, ease(0, 650)), - ]).start(); - }, T_LOGO); + nameOpacity.value = withDelay(250, withTiming(1, revealCfg(600))); + nameTranslateY.value = withDelay(250, withTiming(0, revealCfg(600))); - // Phase 3b: Logo breathing pulse (T=1100) - setTimeout(() => { - Animated.loop( - Animated.sequence([ - Animated.timing(logoPulse, { - toValue: 1.04, - duration: 1300, - useNativeDriver: true, - }), - Animated.timing(logoPulse, { - toValue: 1, - duration: 1300, - useNativeDriver: true, - }), - ]), - ).start(); - }, T_PULSE); + taglineOpacity.value = withDelay(500, withTiming(1, revealCfg(550))); + taglineTranslateY.value = withDelay(500, withTiming(0, revealCfg(550))); - // Phase 4: Tagline (T=1300) - setTimeout(() => { - Animated.parallel([ - Animated.timing(taglineOpacity, ease(1, 550)), - Animated.timing(taglineTranslateY, ease(0, 550)), - ]).start(); - }, T_TAGLINE); + footerOpacity.value = withDelay(700, withTiming(1, revealCfg(500))); - // Phase 5: Sub-text + Footer (T=1700) - setTimeout(() => { - Animated.parallel([ - Animated.timing(subOpacity, ease(1, 500)), - Animated.timing(subTranslateY, ease(0, 500)), - Animated.timing(footerOpacity, ease(1, 600)), - ]).start(); - }, T_SUB); + containerOpacity.value = withDelay( + 3300, + withTiming(0, { duration: 450, easing: EASE_IN }, (finished) => { + if (finished && onDone) runOnJS(onDone)(); + }), + ); + }, []); - // Phase 7: whole-screen fade-out (T=3200, dauert 500ms) - const fadeOutTimer = setTimeout(() => { - Animated.timing(containerOpacity, { - toValue: 0, - duration: T_LEAVE_DUR, - useNativeDriver: true, - }).start(); - }, T_HOLD_END); + const containerStyle = useAnimatedStyle(() => ({ + opacity: containerOpacity.value, + })); - return () => clearTimeout(fadeOutTimer); - }, [ - glowTopOpacity, - glowCenterOpacity, - glowCenterScale, - nameOpacity, - nameTranslateY, - logoOpacity, - logoScale, - logoTranslateY, - logoPulse, - taglineOpacity, - taglineTranslateY, - subOpacity, - subTranslateY, - footerOpacity, - containerOpacity, - ]); + const glowStyle = useAnimatedStyle(() => ({ + opacity: glowOpacity.value, + })); + + const logoStyle = useAnimatedStyle(() => ({ + opacity: logoOpacity.value, + transform: [{ scale: logoScale.value }], + })); + + const nameStyle = useAnimatedStyle(() => ({ + opacity: nameOpacity.value, + transform: [{ translateY: nameTranslateY.value }], + })); + + const taglineStyle = useAnimatedStyle(() => ({ + opacity: taglineOpacity.value, + transform: [{ translateY: taglineTranslateY.value }], + })); + + const footerStyle = useAnimatedStyle(() => ({ + opacity: footerOpacity.value, + })); return ( - - {/* Top breathing radial-gradient ellipse (#1e3a8a auf transparent) */} + - - + + - + - {/* Center indigo halo — bloomt rein wenn Logo erscheint */} - - - + + + - + - {/* Floating particles (5 Stück) */} - {PARTICLES.map((p, i) => ( - - ))} - - {/* Content-Column */} - - {/* App-Name */} + {t('appHeader.appName')} - {/* Logo (mit Pulse + Bouncy Entry) */} - + - {/* Tagline */} {t('splash.tagline')} - - {/* Sub-text */} - - {t('splash.subtitle')} - - {/* Footer */} {t('splash.madeInGermany')} diff --git a/apps/rebreak-native/components/RiveAvatar.tsx b/apps/rebreak-native/components/RiveAvatar.tsx index 5c50484..66bba2d 100644 --- a/apps/rebreak-native/components/RiveAvatar.tsx +++ b/apps/rebreak-native/components/RiveAvatar.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; import { View, Text, Platform } from 'react-native'; import { Asset } from 'expo-asset'; -import Rive, { Fit, Alignment } from 'rive-react-native'; +import Rive, { Fit, Alignment, RNRiveErrorType, type RNRiveError } from 'rive-react-native'; // Android: Rive akzeptiert NUR raw-resource oder url, kein file:// uri. // Asset liegt als android/app/src/main/res/raw/lyra_avatar.riv (gebundelt @@ -40,24 +40,86 @@ function preloadRiveAsset(): Promise { preloadRiveAsset(); // Supported emotions sind durch state-machine im .riv-file definiert. -// Neue states: nur EMOTION_ANIMATIONS + EMOTION_LABELS erweitern, kein weiterer Code-Change nötig. -export type SupportedEmotion = 'idle' | 'happy' | 'thinking' | 'empathy'; +// Neue states: nur EMOTION_ANIMATIONS + EMOTION_LABELS (+ ggf. TWO_PHASE/SUSTAINED) +// erweitern, kein weiterer Code-Change nötig. +export type SupportedEmotion = + | 'idle' + | 'happy' + | 'empathy' + | 'thinking' + | 'listening' + | 'calm' + | 'sad' + | 'joy' + | 'confusion' + | 'surprise'; export type Emotion = SupportedEmotion | (string & {}); -// Direkte Animation-Namen aus der .riv-Datei (1:1 mit Nuxt BenAvatar.vue). -// "happy" hat zwei Phasen: erst Übergangs-Animation, dann Loop. -const EMOTION_ANIMATIONS: Record = { +// Direkte Timeline-Namen aus der .riv-Datei (Code-Contract — siehe +// docs/RIVE_ANIMATOR_BRIEF.md). Der Animator MUSS die States exakt so benennen, +// sonst spielt nichts (silent, kein Error). Bis die erweiterte .riv geliefert +// wird, existieren die neuen Timelines noch nicht → der Avatar zeigt für diese +// States den statischen Idle-Frame (kein Crash). "thinking" ersetzt den alten +// "WALK"-Platzhalter und animiert daher erst mit der neuen .riv wieder. +export const EMOTION_ANIMATIONS: Record = { idle: 'Idle Loop', - happy: 'idle to Pose 1', - thinking: 'WALK', - empathy: '01 Wave 1', + // Reuse vorhandener Hasen-Posen (0 Rive-Arbeit). Namen, die es noch NICHT in + // der .riv gibt (calm/sad/joy/confusion/surprise), fallen via safeAnim auf Idle. + happy: '01 Wave 2', // fröhliches Winken (war ungenutzt) + empathy: '01 Wave 1', // sanftes Winken + thinking: 'Pose 1 loop', // Klemmbrett: arbeitet an deiner Eingabe (direkt Loop, kein Zucken) + listening: 'Pose 1 loop', // Therapeut notiert beim Zuhören (direkt Loop, kein Zucken) + calm: 'calm', + sad: 'sad', + joy: 'joy', + confusion: 'confusion', + surprise: 'surprise', }; +// Timelines, die AKTUELL wirklich in lyra-avatar.riv existieren. Wird ein Name an +// die native Rive-View gegeben, der NICHT existiert, crasht die App hart — onError +// fängt das NICHT zuverlässig ab (empirisch verifiziert, der native Runtime stürzt +// tiefer ab). Deshalb mappen wir jeden unbekannten Namen VOR dem Rendern auf den +// garantiert vorhandenen Idle-Loop. → Beim Anlegen einer neuen Timeline in der +// .riv hier den exakten Namen ergänzen, dann animiert der zugehörige State. +export const EXISTING_TIMELINES = new Set([ + 'Idle Loop', + 'idle to Pose 1', + 'Pose 1 loop', + '01 Wave 1', + '01 Wave 2', + 'WALK', + 'Kedip', +]); + +function safeAnim(name: string): string { + return EXISTING_TIMELINES.has(name) ? name : EMOTION_ANIMATIONS.idle; +} + +// Mehrphasige States: Intro-Timeline läuft einmal, danach Loop-Timeline. Aktuell +// leer — der Remount beim Intro→Loop-Wechsel verursacht ein sichtbares Zucken, +// daher spielen thinking/listening direkt die Loop-Pose. Mechanismus bleibt für +// künftige ' intro' + ' loop'-States verfügbar. +const TWO_PHASE: Record = {}; + +// Sustained = bleibt aktiv bis die Emotion explizit wechselt (z.B. solange Lyra +// "denkt", "zuhört" oder mitatmet). Alle anderen sind One-Shot-Reaktionen und +// fallen nach SETTLE_MS in den Idle-Loop zurück, damit der Avatar lebendig bleibt +// und nie auf dem letzten Frame einfriert. +const SUSTAINED = new Set(['idle', 'thinking', 'listening', 'calm']); +const SETTLE_MS = 2600; + const EMOTION_LABELS: Record = { idle: 'bereit', happy: 'froh für dich', - thinking: 'überlegt ...', empathy: 'versteht dich', + thinking: 'überlegt ...', + listening: 'hört zu', + calm: 'atmet mit dir', + sad: 'fühlt mit dir', + joy: 'freut sich für dich', + confusion: 'fragt nach', + surprise: 'überrascht', }; const SIZE_PX: Record<'sm' | 'md' | 'lg', number> = { @@ -79,7 +141,7 @@ export function RiveAvatar({ emotion, size = 'md', showLabel = false, fallback = const resolvedEmotion = EMOTION_ANIMATIONS[emotion] !== undefined ? emotion : fallback; // Aktuelle Animation als deklarativer State (kein imperatives ref.play()). - const [currentAnim, setCurrentAnim] = useState(EMOTION_ANIMATIONS[resolvedEmotion] ?? EMOTION_ANIMATIONS.idle); + const [currentAnim, setCurrentAnim] = useState(safeAnim(EMOTION_ANIMATIONS[resolvedEmotion] ?? EMOTION_ANIMATIONS.idle)); // Lokale URI für die .riv-Datei — geht über expo-asset damit der File // im App-Sandbox gecached wird statt jedes Mal von Metro zu streamen. @@ -98,24 +160,43 @@ export function RiveAvatar({ emotion, size = 'md', showLabel = false, fallback = }, [riveUri]); useEffect(() => { - if (resolvedEmotion === 'happy') { - // 2-Phasen-Flow: Übergang (~900ms) → Loop (1:1 wie Nuxt-BenAvatar) - setCurrentAnim('idle to Pose 1'); - const t = setTimeout(() => setCurrentAnim('Pose 1 loop'), 900); + const wanted = EMOTION_ANIMATIONS[resolvedEmotion] ?? EMOTION_ANIMATIONS.idle; + const base = safeAnim(wanted); + setCurrentAnim(base); + + // Mehrphasig (z.B. happy: 'idle to Pose 1' → 'Pose 1 loop'): Intro einmal + // spielen, dann in den Loop blenden. Nur wenn BEIDE Timelines wirklich + // existieren — sonst bleibt's bei base (kein Sprung auf einen toten Namen). + const phase = TWO_PHASE[resolvedEmotion]; + if (phase && EXISTING_TIMELINES.has(wanted) && EXISTING_TIMELINES.has(phase.loop)) { + const t = setTimeout(() => setCurrentAnim(phase.loop), phase.introMs); return () => clearTimeout(t); } - const anim = EMOTION_ANIMATIONS[resolvedEmotion] ?? EMOTION_ANIMATIONS.idle; - setCurrentAnim(anim); - // Intro-Emotions wie 'empathy' ('01 Wave 1') / 'thinking' ('WALK') sind - // One-Shots — ohne Übergang frieren sie auf dem letzten Frame ein und wirken - // "nicht animiert". Nach dem Intro in den Idle Loop fallen, damit der Avatar - // lebendig bleibt (idle loopt selbst). - if (anim !== EMOTION_ANIMATIONS.idle) { - const t = setTimeout(() => setCurrentAnim(EMOTION_ANIMATIONS.idle), 2600); + + // One-Shots (empathy/sad/joy/confusion/surprise) frieren sonst auf dem + // letzten Frame ein → nach SETTLE_MS zurück in den Idle-Loop. Sustained- + // States (idle/happy/thinking/listening/calm) bleiben aktiv bis Emotion-Wechsel. + if (!SUSTAINED.has(resolvedEmotion) && base !== EMOTION_ANIMATIONS.idle) { + const t = setTimeout(() => setCurrentAnim(EMOTION_ANIMATIONS.idle), SETTLE_MS); return () => clearTimeout(t); } }, [resolvedEmotion]); + // Crash-Guard: rive-react-native crasht NATIV (App-Absturz, kein JS-Error), + // wenn animationName nicht in der .riv existiert — z.B. ein neuer Emotion-State, + // der noch nicht gebaut wurde. Sobald onError gesetzt ist, schaltet die Lib auf + // isUserHandlingErrors und ruft statt zu crashen diesen Handler. Wir fallen dann + // auf den garantiert vorhandenen Idle-Loop zurück (Guard verhindert Endlos-Reset). + const handleRiveError = (err: RNRiveError) => { + if (__DEV__) console.warn('[RiveAvatar]', err?.type, '—', err?.message); + if ( + err?.type === RNRiveErrorType.IncorrectAnimationName && + currentAnim !== EMOTION_ANIMATIONS.idle + ) { + setCurrentAnim(EMOTION_ANIMATIONS.idle); + } + }; + return ( Promise<{ enabled: boolean; error?: string }>; onActivateAccessibility: () => Promise; onRequestDeviceAdmin: () => Promise<{ launched: boolean }>; + onRequestBattery: () => Promise<{ opened: boolean; alreadyIgnored?: boolean }>; + onOpenAppDetails: () => Promise<{ opened: boolean }>; colors: ReturnType; t: ReturnType['t']; }; export function AndroidSetupFlow({ vpnActive, + vpnActivating, accessibilityLocked, deviceAdminActive, + batteryUnrestricted, onActivateVpn, onActivateAccessibility, onRequestDeviceAdmin, + onRequestBattery, + onOpenAppDetails, colors, t, }: AndroidSetupFlowProps) { - // Reihenfolge KRITISCH: VPN → Geräteadmin → a11y. a11y MUSS zuletzt, weil der - // Tamper-Lock (sobald armed) die Geräteadmin-Seite blockt — sonst kann der - // User den Admin gar nicht mehr aktivieren. + // Reihenfolge KRITISCH: VPN → Geräteadmin → Akku-Ausnahme → a11y. a11y MUSS + // zuletzt, weil der Tamper-Lock (sobald armed) Settings-Seiten blockt. Die + // Akku-Ausnahme MUSS VOR a11y: sonst schläfert Samsung den frisch aktivierten + // a11y-Service wieder ein → Lock entbunden → Schutz wertlos. const vpnDone = vpnActive; const adminDone = deviceAdminActive; + const batteryDone = batteryUnrestricted; const a11yDone = accessibilityLocked; return ( - {/* Display-Step 3 = a11y / ReBreak-Schutz (Komponente AndroidStep2, i18n android_step2_*). */} - + {/* Display-Step 4 = a11y / ReBreak-Schutz (Komponente AndroidStep2, i18n android_step2_*). */} + Promise<{ enabled: boolean; error?: string }>; colors: ReturnType; t: ReturnType['t']; @@ -347,7 +371,12 @@ function AndroidStep1({ unlocked colors={colors} > - {!done && ( + {!done && (pending ? ( + + + {t('blocker.activating')} + + ) : ( {t('blocker.android_step1_cta')} } - )} + ))} ); } @@ -386,12 +415,12 @@ function AndroidStep2({ return ( {unlocked && !done && ( @@ -434,6 +463,67 @@ function AndroidStep2({ ); } +function AndroidStepBattery({ + unlocked, + done, + onRequest, + onOpenDetails, + colors, + t, +}: { + unlocked: boolean; + done: boolean; + onRequest: () => Promise<{ opened: boolean; alreadyIgnored?: boolean }>; + onOpenDetails: () => Promise<{ opened: boolean }>; + colors: ReturnType; + t: ReturnType['t']; +}) { + const [busy, setBusy] = useState(false); + + async function handlePress() { + if (done || busy) return; + setBusy(true); + try { await onRequest(); } finally { setBusy(false); } + } + + return ( + + {unlocked && !done && ( + + + + {t('blocker.android_battery_body')} + + + + {busy + ? + : {t('blocker.android_battery_cta')} + } + + { void onOpenDetails(); }} activeOpacity={0.7} style={{ paddingVertical: 4, alignItems: 'center' }}> + + {t('blocker.android_battery_samsung_hint')} + + + + )} + + ); +} + function AndroidStep3({ unlocked, done, diff --git a/apps/rebreak-native/components/onboarding/slides/ProtectionSlide.tsx b/apps/rebreak-native/components/onboarding/slides/ProtectionSlide.tsx index 67b7af0..5c79e50 100644 --- a/apps/rebreak-native/components/onboarding/slides/ProtectionSlide.tsx +++ b/apps/rebreak-native/components/onboarding/slides/ProtectionSlide.tsx @@ -58,7 +58,16 @@ export function ProtectionSlide({ const [permissionDeniedOpen, setPermissionDeniedOpen] = useState(false); const [familyControlsErrorOpen, setFamilyControlsErrorOpen] = useState(false); const [confirmStep, setConfirmStep] = useState(null); + // Fallback-Ausweg: erscheint, wenn der Schutz auf diesem Gerät nicht aktiviert + // werden kann (Timeout oder fehlgeschlagener Versuch) — sonst hängt der User + // im Onboarding fest (z.B. Android-16-VPN-Crash). Schutz später im Blocker. + const [showSkip, setShowSkip] = useState(false); + // VPN-Aktivierung läuft (Android): Spinner am VPN-Step bis der Layer-State + // bestätigt ist. Der Protection-State pollt sonst zu selten → der Step bliebe + // ~1min „offen", obwohl der Tunnel längst läuft. + const [vpnPending, setVpnPending] = useState(false); const finishedRef = useRef(false); + const armingRef = useRef(false); // a11y-Explainer NUR beim ersten Tap zeigen — danach (Settings-Rückkehr → // nochmal tippen zum Armen) direkt durch, sonst nervt das Sheet doppelt. const a11yExplainerShownRef = useRef(false); @@ -80,11 +89,17 @@ export function ProtectionSlide({ const appDeletionLockActive = (state?.layers.appDeletionLock ?? familyControlsActive) === true; const nefilterActive = state?.layers.nefilterActive === true; const deviceAdminActive = state?.layers.deviceAdmin === true; + // a11y-SERVICE an (≠ Tamper-Lock armed). Trennung kommt direkt aus dem nativen + // getDeviceState ({accessibility} vs {tamperLock}). + const a11yServiceOn = state?.layers.accessibility === true; + // Akku-Ausnahme: ohne sie schläfert Samsung & Co. die App ein → a11y-Service + // wird entbunden → Lock wertlos. Daher Pflicht-Step im Android-Flow. + const batteryUnrestricted = state?.layers.batteryUnrestricted === true; // "Fertig" == blocker.tsx lockedIn. Eine Quelle der Wahrheit. const allDone = Platform.OS === 'android' - ? urlFilterActive && appDeletionLockActive && deviceAdminActive + ? urlFilterActive && appDeletionLockActive && deviceAdminActive && batteryUnrestricted : (nefilterActive || urlFilterActive) && (mdmManaged || nefilterActive || appDeletionLockActive || !FAMILY_CONTROLS_AVAILABLE); @@ -99,6 +114,24 @@ export function ProtectionSlide({ onDone(); } + // Notausgang: Schutz noch nicht aktiv, aber User soll nicht festsitzen. + function handleSkipProtection() { + Alert.alert( + t('onboarding.protection_skip.title'), + t('onboarding.protection_skip.body'), + [ + { text: t('common.cancel'), style: 'cancel' }, + { + text: t('onboarding.protection_skip.confirm'), + style: 'destructive', + onPress: () => { + void finishProtectionStep(); + }, + }, + ], + ); + } + // Foreground-Return → State neu laden. a11y/Geräteadmin/Bildschirmzeit werden in // den System-Settings gesetzt; beim Zurückkommen pollen wir den neuen Layer-State, // damit die Cards umschalten und "Weiter" freigeschaltet wird. @@ -109,12 +142,65 @@ export function ProtectionSlide({ return () => sub.remove(); }, [refresh]); + // Sicherheitsnetz: Ist der Schutz nach 30 s noch nicht aktiv (z.B. weil die + // Aktivierung auf diesem OS scheitert), den "Später einrichten"-Ausweg zeigen. + // (Failed-Aktivierungen blenden ihn sofort ein, siehe Handler unten.) + useEffect(() => { + if (allDone) { + setShowSkip(false); + return; + } + const id = setTimeout(() => setShowSkip(true), 30000); + return () => clearTimeout(id); + }, [allDone]); + + // Nach VPN-Freigabe schneller nachpollen, bis urlFilter aktiv ist (sonst ~1min, + // bis der Step grün wird). Spinner läuft, solange vpnPending. Deckel ~60s. + useEffect(() => { + if (urlFilterActive) { + setVpnPending(false); + return; + } + if (!vpnPending) return; + let ticks = 0; + const id = setInterval(() => { + ticks += 1; + refresh(); + if (ticks >= 20) { + clearInterval(id); + setVpnPending(false); + } + }, 3000); + return () => clearInterval(id); + }, [vpnPending, urlFilterActive, refresh]); + + // Auto-Arm (Android): kam der User aus den a11y-Settings zurück und hat den + // Service aktiviert (accessibility=true), war der Tamper-Lock bisher NICHT armed + // — das passierte erst beim ZWEITEN Tap auf den a11y-Button (Two-Step-Design). + // Hier ziehen wir das automatisch nach: sobald a11y-Service an + noch nicht + // armed, einmal activateFamilyControls() → geht bei aktivem a11y direkt in den + // Arm-Pfad (kein Settings-Öffnen) → Step wird grün ohne zweiten Tap. + useEffect(() => { + if (Platform.OS !== 'android') return; + if (!a11yServiceOn || appDeletionLockActive || armingRef.current) return; + armingRef.current = true; + activateFamilyControls() + .catch(() => {}) + .finally(() => { + armingRef.current = false; + refresh(); + }); + }, [a11yServiceOn, appDeletionLockActive, activateFamilyControls, refresh]); + // ─── Handler (1:1 wie blocker.tsx) ────────────────────────────────────────── async function handleActivateUrlFilter() { try { const result = await activateUrlFilter(); if (!result.enabled) { + // Aktivierung fehlgeschlagen → Notausgang sofort anbieten (nicht erst nach 30s). + setShowSkip(true); + setVpnPending(false); const isPermissionDenied = Platform.OS === 'ios' && typeof result.error === 'string' && @@ -144,6 +230,8 @@ export function ProtectionSlide({ } return result; } catch (e: any) { + setShowSkip(true); + setVpnPending(false); Alert.alert(t('blocker.activation_failed_title'), e?.message ?? t('common.unknown_error')); return { enabled: false }; } @@ -222,6 +310,12 @@ export function ProtectionSlide({ setConfirmStep('deviceadmin'); return { launched: false }; }; + // Akku-Ausnahme: System-Dialog direkt öffnen (ein Tap „Zulassen"); der + // Step-Card-Text erklärt das Warum. Return-Refresh via AppState-'active'. + const gatedBattery = async () => protection.requestIgnoreBatteryOptimizations(); + // Samsung-Sonderweg: App-Detail-Settings (Akku → „Uneingeschränkt" + raus aus + // „Schlafende Apps") — das deckt der reine AOSP-Whitelist-Dialog nicht ab. + const openBatteryDetails = async () => protection.openAppDetailsSettings(); const gatedApplock = async () => { setConfirmStep('applock'); return { enabled: false }; @@ -257,6 +351,8 @@ export function ProtectionSlide({ function runConfirmedAction(step: ConfirmStep) { switch (step) { case 'vpn': + setVpnPending(true); + return handleActivateUrlFilter(); case 'urlfilter': return handleActivateUrlFilter(); case 'deviceadmin': @@ -285,6 +381,8 @@ export function ProtectionSlide({ primaryLabel={t('common.continue')} onPrimary={finishProtectionStep} primaryDisabled={!allDone} + secondaryLabel={!allDone && showSkip ? t('onboarding.protection_skip.label') : undefined} + onSecondary={!allDone && showSkip ? handleSkipProtection : undefined} /> } > @@ -294,11 +392,15 @@ export function ProtectionSlide({ {Platform.OS === 'android' ? ( diff --git a/apps/rebreak-native/components/profile/DemographicsAccordion.tsx b/apps/rebreak-native/components/profile/DemographicsAccordion.tsx index d519837..e7b07a2 100644 --- a/apps/rebreak-native/components/profile/DemographicsAccordion.tsx +++ b/apps/rebreak-native/components/profile/DemographicsAccordion.tsx @@ -361,8 +361,8 @@ export function DemographicsAccordion({ lineHeight: 15, }} > - Mit deinen anonymen Daten machen wir rebreak zur ersten DiGA-zertifizierten - Spielsucht-App. Als Dankeschön: 1 Woche Pro. + Deine anonymen Angaben helfen uns, ReBreak gezielt zu verbessern. + Als Dankeschön: 1 Woche Pro. @@ -370,7 +370,7 @@ export function DemographicsAccordion({ void; @@ -22,18 +23,8 @@ export function DigaMissionBanner({ onDismiss, onContribute }: Props) { }} > - - + + - Rebreak strebt die Anerkennung als DiGA an. Mit ein paar anonymen - Angaben hilfst du, die Wirksamkeit zu belegen — damit Krankenkassen - die App künftig erstatten können. + Mit ein paar anonymen Angaben hilfst du uns, ReBreak gezielt + weiterzuentwickeln. Freiwillig, anonym, jederzeit löschbar. diff --git a/apps/rebreak-native/deploy.sh b/apps/rebreak-native/deploy.sh index bae1fa3..423dea0 100755 --- a/apps/rebreak-native/deploy.sh +++ b/apps/rebreak-native/deploy.sh @@ -345,6 +345,9 @@ while [[ $# -gt 0 ]]; do esac done +# Disk-Guard: warnt bei wenig freiem Speicher, bevor (große) Builds starten. +[ -x "$SCRIPT_DIR/clean.sh" ] && "$SCRIPT_DIR/clean.sh" --guard 8 || true + # ═══════════════════════════════════════════════════════════════════════════ # Secrets-File auto-loading (NICHT committen — siehe .deploy-secrets.local.example) # ═══════════════════════════════════════════════════════════════════════════ diff --git a/apps/rebreak-native/dev.sh b/apps/rebreak-native/dev.sh index 6e2c55e..8e697c7 100755 --- a/apps/rebreak-native/dev.sh +++ b/apps/rebreak-native/dev.sh @@ -692,6 +692,9 @@ cmd_magic() { COMMAND="${1:-ios}" shift || true +# Disk-Guard: warnt vor Builds, wenn der Mac wenig freien Speicher hat (clean.sh). +[ -x "$SCRIPT_DIR/clean.sh" ] && "$SCRIPT_DIR/clean.sh" --guard 8 || true + case "$COMMAND" in ios) cmd_ios "$@" diff --git a/apps/rebreak-native/hooks/useDeviceApprovalRealtime.ts b/apps/rebreak-native/hooks/useDeviceApprovalRealtime.ts index e8bad28..68f0dbf 100644 --- a/apps/rebreak-native/hooks/useDeviceApprovalRealtime.ts +++ b/apps/rebreak-native/hooks/useDeviceApprovalRealtime.ts @@ -1,5 +1,6 @@ import { useEffect } from "react"; import { supabase } from "../lib/supabase"; +import { isRealtimeErrorReal } from "../lib/realtimeStatus"; import { useDeviceApprovalStore } from "../stores/deviceApproval"; import type { RealtimeChannel } from "@supabase/supabase-js"; @@ -59,7 +60,7 @@ export function useDeviceApprovalRealtime(enabled: boolean = true) { ) .subscribe((status, err) => { if (status === "CHANNEL_ERROR" || status === "TIMED_OUT") { - console.warn("[approvalRealtime] error:", status, err ?? ""); + if (isRealtimeErrorReal()) console.warn("[approvalRealtime] error:", status, err ?? ""); cleanup(); if (reconnectTimer) clearTimeout(reconnectTimer); reconnectTimer = setTimeout(() => { diff --git a/apps/rebreak-native/hooks/useDomainSubmissionRealtime.ts b/apps/rebreak-native/hooks/useDomainSubmissionRealtime.ts index 79695a1..dab44df 100644 --- a/apps/rebreak-native/hooks/useDomainSubmissionRealtime.ts +++ b/apps/rebreak-native/hooks/useDomainSubmissionRealtime.ts @@ -1,5 +1,6 @@ import { useEffect } from "react"; import { supabase } from "../lib/supabase"; +import { isRealtimeErrorReal } from "../lib/realtimeStatus"; import type { RealtimeChannel } from "@supabase/supabase-js"; /** @@ -67,7 +68,7 @@ export function useDomainSubmissionRealtime( ) .subscribe((status, err) => { if (status === "CHANNEL_ERROR" || status === "TIMED_OUT") { - console.warn("[domainRealtime] error:", status, err ?? ""); + if (isRealtimeErrorReal()) console.warn("[domainRealtime] error:", status, err ?? ""); cleanup(); if (reconnectTimer) clearTimeout(reconnectTimer); reconnectTimer = setTimeout(() => { diff --git a/apps/rebreak-native/hooks/useIncomingCalls.ts b/apps/rebreak-native/hooks/useIncomingCalls.ts index 2bb3514..79c5768 100644 --- a/apps/rebreak-native/hooks/useIncomingCalls.ts +++ b/apps/rebreak-native/hooks/useIncomingCalls.ts @@ -1,4 +1,5 @@ import { useEffect } from 'react'; +import { isRealtimeErrorReal } from '../lib/realtimeStatus'; import { Platform } from 'react-native'; import { useRouter } from 'expo-router'; import { supabase } from '../lib/supabase'; @@ -48,7 +49,7 @@ export function useIncomingCalls(myUserId: string | undefined) { } }); chan.subscribe((status: string, err?: any) => { - console.log('[CALL/recv] call-ring subscribe status:', status, err ?? ''); + if (isRealtimeErrorReal()) console.log('[CALL/recv] call-ring subscribe status:', status, err ?? ''); }); return () => { diff --git a/apps/rebreak-native/lib/lyraResponse.ts b/apps/rebreak-native/lib/lyraResponse.ts index 83df91c..8a7516c 100644 --- a/apps/rebreak-native/lib/lyraResponse.ts +++ b/apps/rebreak-native/lib/lyraResponse.ts @@ -1,5 +1,5 @@ // Parser für Lyras LLM-JSON-Antworten + Emotion-Detection. -import { EMPATHY_RE, HAPPY_RE } from './sosConstants'; +import { EMPATHY_RE, HAPPY_RE, JOY_RE, SAD_RE, CONFUSION_RE } from './sosConstants'; import type { Emotion } from '../components/RiveAvatar'; export type LyraEmotion = Emotion; @@ -55,7 +55,13 @@ export function parseLyraResponse(raw: string): { message: string; chips: ChipSp } export function detectEmotion(text: string): LyraEmotion { + // Reihenfolge = Priorität. joy (große Feier) vor happy (Alltag); + // sad (Verlust/Rückfall/Scham, spiegelnd) vor empathy (allg. Schwere); + // confusion (Rückfrage) zuletzt, da neutral-tonig. + if (JOY_RE.test(text)) return 'joy'; if (HAPPY_RE.test(text)) return 'happy'; + if (SAD_RE.test(text)) return 'sad'; if (EMPATHY_RE.test(text)) return 'empathy'; + if (CONFUSION_RE.test(text)) return 'confusion'; return 'idle'; } diff --git a/apps/rebreak-native/lib/protection.ts b/apps/rebreak-native/lib/protection.ts index 367155d..355e859 100644 --- a/apps/rebreak-native/lib/protection.ts +++ b/apps/rebreak-native/lib/protection.ts @@ -319,6 +319,41 @@ export const protection = { return RebreakProtection.getDeviceState(); }, + // ─── Android: Akku-Ausnahme (gegen Samsung-Sleep, der den a11y-Lock killt) ── + // + // Ohne Battery-Exemption schläfert Samsung & Co. die App ein → der a11y- + // Service wird entbunden → Tamper-Lock erzwingt nichts mehr (Schutz fällt + // still aus). Daher Status + Anforderung exponieren. + + /** Android: Ist die App von der Akku-Optimierung ausgenommen? (iOS: immer true) */ + async isBatteryOptimizationIgnored(): Promise { + if (Platform.OS !== "android") return true; + try { + const r = await RebreakProtection.isBatteryOptimizationIgnored(); + return r.ignored === true; + } catch (e) { + console.warn("[protection] isBatteryOptimizationIgnored failed:", e); + return false; + } + }, + + /** Android: System-Dialog „Akku-Optimierung ignorieren?" (ein Tap „Zulassen"). */ + async requestIgnoreBatteryOptimizations() { + if (Platform.OS !== "android") + return { opened: false, alreadyIgnored: true } as { + opened: boolean; + alreadyIgnored?: boolean; + }; + return RebreakProtection.requestIgnoreBatteryOptimizations(); + }, + + /** Android: App-Detail-Settings öffnen — Samsung: Akku „Uneingeschränkt" + + * raus aus „Schlafende/Tief schlafende Apps". */ + async openAppDetailsSettings() { + if (Platform.OS !== "android") return { opened: false }; + return RebreakProtection.openAppDetailsSettings(); + }, + // ─── iOS Layer 2 — webContent-Filter (ManagedSettings) ─────────────────── // // Stilles WebKit-Sicherheitsnetz: blockt eine kuratierte, länderabhängige @@ -589,8 +624,16 @@ export const protection = { ? ({ ...rawLayers, urlFilter: rawLayers.vpn, - familyControls: rawLayers.tamperLock, - appDeletionLock: rawLayers.tamperLock, + // App-Lock gilt NUR als aktiv, wenn der a11y-Service WIRKLICH läuft — + // nicht nur weil `tamper_armed` (Pref) gesetzt ist. Sonst zeigt die UI + // "komplett geschützt", obwohl a11y (z.B. nach Reboot von Samsung + // deaktiviert; programmatisch nicht reaktivierbar) nichts mehr erzwingt + // → falsches Sicherheitsgefühl. (Analog zum bestehenden VPN-flag-Gate + // in der nativen tamperLock-Berechnung.) + familyControls: + rawLayers.tamperLock === true && rawLayers.accessibility === true, + appDeletionLock: + rawLayers.tamperLock === true && rawLayers.accessibility === true, } as DeviceLayers) : rawLayers; diff --git a/apps/rebreak-native/lib/realtimeStatus.ts b/apps/rebreak-native/lib/realtimeStatus.ts new file mode 100644 index 0000000..25a2c78 --- /dev/null +++ b/apps/rebreak-native/lib/realtimeStatus.ts @@ -0,0 +1,19 @@ +import { AppState } from "react-native"; + +/** + * Realtime-WebSocket-Closes beim Backgrounden sind ERWARTET, kein echter Fehler: + * Supabase schließt den Socket via `auth.stopAutoRefresh()` (Close-Code 1000 = + * „Normal Closure"), sobald die App in den Hintergrund geht — das feuert + * CHANNEL_ERROR/TIMED_OUT gleichzeitig auf ALLEN Channels (call-ring, notif, + * approval, domain …). Re-Subscribe passiert beim Foreground automatisch über + * den jeweiligen Reconnect-Timer. + * + * Nur im Vordergrund ist ein CHANNEL_ERROR ein echtes Problem, das geloggt + * werden soll. Im Hintergrund würde das Logging nur Spam erzeugen. + * + * (Backyard-Infra-Diagnose 2026-06-10: nginx-WS-Proxy korrekt, Realtime-Container + * gesund, nginx-Error-Log leer — der Close ist rein client-seitig + erwartet.) + */ +export function isRealtimeErrorReal(): boolean { + return AppState.currentState === "active"; +} diff --git a/apps/rebreak-native/lib/sosConstants.ts b/apps/rebreak-native/lib/sosConstants.ts index 6a37430..620caaa 100644 --- a/apps/rebreak-native/lib/sosConstants.ts +++ b/apps/rebreak-native/lib/sosConstants.ts @@ -54,3 +54,10 @@ export const TOTAL_ROUNDS = 3; export const EMPATHY_RE = /schwer|rückfall|traurig|schlimm|hoffnungslos|verloren|scham|schuld|verzweifelt/i; export const HAPPY_RE = /toll|super|geschafft|stark|stolz|fantastisch|prima/i; +// Stärkere Feier (Meilenstein/Streak) als das alltägliche "happy". +export const JOY_RE = /glückwunsch|meilenstein|unglaublich|wahnsinn|grandios|großer schritt|so stolz auf dich|riesig stolz/i; +// Schwere Verlust-/Rückfall-/Scham-Sprache → spiegelndes Mitgefühl statt Winken. +// Hat in detectEmotion Vorrang vor EMPATHY_RE. +export const SAD_RE = /rückfällig|verspielt|am boden|versagt|schäme|so leid|es tut mir.{0,12}leid/i; +// Lyra braucht Klärung / stellt eine Rückfrage. +export const CONFUSION_RE = /meinst du|wie genau|was genau|verstehe ich.{0,15}richtig|kannst du.{0,15}(erklär|genauer)|nicht ganz sicher|magst du.{0,15}(erzähl|erklär)/i; diff --git a/apps/rebreak-native/locales/ar.json b/apps/rebreak-native/locales/ar.json index 4c7268f..2821a3d 100644 --- a/apps/rebreak-native/locales/ar.json +++ b/apps/rebreak-native/locales/ar.json @@ -582,9 +582,15 @@ "a11y_indicator": "ReBreak يرشدك خطوة بخطوة", "a11y_step3": "فعّل المفتاح، وأكّد مربع الحوار — ثم ارجع إلى التطبيق.", "usage_title": "لمرة واحدة: تفعيل الإرشاد خطوة بخطوة", - "usage_body": "قائمة إمكانية الوصول في Samsung معقّدة. لكي أرشدك خطوة بخطوة، امنح ReBreak «الوصول إلى بيانات الاستخدام» مرة واحدة — سأفتح الصفحة الآن. فعّله هناك، ارجع واضغط الحماية مرة أخرى.", + "usage_body": "قائمة إمكانية الوصول معقّدة أحياناً. لكي أرشدك خطوة بخطوة، امنح ReBreak «الوصول إلى بيانات الاستخدام» مرة واحدة — سأفتح الصفحة الآن. فعّله هناك، ارجع واضغط الحماية مرة أخرى.", "overlay_title": "لمرة واحدة: السماح بطبقة التلميح", "overlay_body": "لكي يظهر تلميحي بوضوح أمام الإعدادات بدلاً من إخفائه، امنح ReBreak «العرض فوق التطبيقات الأخرى» مرة واحدة — سأفتح الصفحة. فعّله هناك، ارجع واضغط الحماية مرة أخرى." + }, + "protection_skip": { + "label": "لا يعمل؟ الإعداد لاحقًا", + "title": "إعداد الحماية لاحقًا؟", + "body": "الحماية ليست مفعّلة بعد. يمكنك المتابعة وإعدادها في أي وقت من «الحماية».", + "confirm": "لاحقًا" } }, "protection_onboarding": { diff --git a/apps/rebreak-native/locales/de.json b/apps/rebreak-native/locales/de.json index 93763c8..a676f3d 100644 --- a/apps/rebreak-native/locales/de.json +++ b/apps/rebreak-native/locales/de.json @@ -480,6 +480,7 @@ "android_step1_subtitle_pending": "Blockt 300.000+ Gambling-Seiten system-weit via DNS-Filter", "android_step1_subtitle_done": "VPN-Filter läuft", "android_step1_cta": "VPN aktivieren", + "activating": "VPN wird aktiviert …", "android_step2_title": "ReBreak - Schutz", "android_step2_subtitle_pending": "", "android_step2_subtitle_done": "Bedienungshilfe aktiv", @@ -488,6 +489,12 @@ "android_step2_instruction3": "③ Schalte den Regler ein", "android_step2_cta": "Bedienungshilfen öffnen", "android_step2_note": "Wähle ReBreak in der Liste und schalte den Regler ein. Tippe danach erneut auf den Button, um den Schutz zu aktivieren.", + "android_battery_title": "Akku-Optimierung deaktivieren", + "android_battery_subtitle_pending": "Damit dein Handy den Schutz nicht einschläft", + "android_battery_subtitle_done": "Akku-Optimierung deaktiviert", + "android_battery_body": "Ohne diese Ausnahme schläfert dein Handy ReBreak ein — dann fällt der Schutz heimlich aus. Tippe unten und wähle „Zulassen“.", + "android_battery_cta": "Akku-Ausnahme erlauben", + "android_battery_samsung_hint": "Klappt nicht? Bei Samsung: App-Einstellungen → Akku → „Uneingeschränkt“ und aus „Schlafende Apps“ entfernen.", "android_step3_title": "Geräteadministrator aktivieren", "android_step3_subtitle_pending": "Schließt die Boot-Lücke: Schutz ist sofort nach Neustart aktiv", "android_step3_subtitle_done": "Geräteadministrator aktiv — Schutz vollständig", @@ -683,9 +690,15 @@ "a11y_indicator": "ReBreak begleitet dich Schritt für Schritt", "a11y_step3": "Schalter ein, im Dialog bestätigen — dann zurück zur App.", "usage_title": "Einmalig: Schritt-Führung freischalten", - "usage_body": "Samsungs Bedienungshilfen-Menü ist fummelig. Damit ich dich Schritt für Schritt führen kann, gib ReBreak einmal „Nutzungszugriff“ — ich öffne gleich die Seite. Schalt ReBreak dort an, komm zurück und tipp nochmal auf den Schutz.", + "usage_body": "Das Bedienungshilfen-Menü ist oft fummelig. Damit ich dich Schritt für Schritt führen kann, gib ReBreak einmal „Nutzungszugriff“ — ich öffne gleich die Seite. Schalt ReBreak dort an, komm zurück und tipp nochmal auf den Schutz.", "overlay_title": "Einmalig: Hinweis-Overlay erlauben", "overlay_body": "Damit mein Hinweis sichtbar VOR den Einstellungen schwebt (statt versteckt in der Leiste), gib ReBreak einmal „Über anderen Apps anzeigen“ — ich öffne die Seite. Schalt ReBreak dort an, komm zurück und tipp nochmal auf den Schutz." + }, + "protection_skip": { + "label": "Es klappt nicht? Später einrichten", + "title": "Schutz später einrichten?", + "body": "Der Schutz ist noch nicht aktiv. Du kommst trotzdem weiter und kannst ihn jederzeit unter „Schutz“ einrichten.", + "confirm": "Später einrichten" } }, "protection_onboarding": { diff --git a/apps/rebreak-native/locales/en.json b/apps/rebreak-native/locales/en.json index d35837a..6b9f3d7 100644 --- a/apps/rebreak-native/locales/en.json +++ b/apps/rebreak-native/locales/en.json @@ -480,6 +480,7 @@ "android_step1_subtitle_pending": "Blocks 300,000+ gambling sites system-wide via DNS filter", "android_step1_subtitle_done": "VPN filter running", "android_step1_cta": "Activate VPN", + "activating": "Activating VPN …", "android_step2_title": "ReBreak Protection", "android_step2_subtitle_pending": "", "android_step2_subtitle_done": "Accessibility service active", @@ -488,6 +489,12 @@ "android_step2_instruction3": "③ Switch the toggle on", "android_step2_cta": "Open accessibility settings", "android_step2_note": "Find ReBreak in the list and switch it on. Then tap the button again to finish activating the protection.", + "android_battery_title": "Turn off battery optimization", + "android_battery_subtitle_pending": "So your phone can't put the protection to sleep", + "android_battery_subtitle_done": "Battery optimization turned off", + "android_battery_body": "Without this exception your phone puts ReBreak to sleep — and the protection silently fails. Tap below and choose \"Allow\".", + "android_battery_cta": "Allow battery exception", + "android_battery_samsung_hint": "Not working? On Samsung: App settings → Battery → \"Unrestricted\", and remove it from \"Sleeping apps\".", "android_step3_title": "Activate device administrator", "android_step3_subtitle_pending": "Closes the boot gap: protection is active immediately after restart", "android_step3_subtitle_done": "Device administrator active — protection complete", @@ -683,9 +690,15 @@ "a11y_indicator": "ReBreak guides you step by step", "a11y_step3": "Turn the switch on, confirm the dialog — then come back to the app.", "usage_title": "One-time: enable step-by-step guidance", - "usage_body": "Samsung’s accessibility menu is fiddly. So I can guide you step by step, give ReBreak “Usage access” once — I’ll open the page now. Turn ReBreak on there, come back and tap protection again.", + "usage_body": "The accessibility menu can be fiddly. So I can guide you step by step, give ReBreak “Usage access” once — I’ll open the page now. Turn ReBreak on there, come back and tap protection again.", "overlay_title": "One-time: allow the hint overlay", "overlay_body": "So my hint sits visibly in front of Settings (instead of hidden in the notification shade), give ReBreak “Display over other apps” once — I’ll open the page. Turn ReBreak on there, come back and tap protection again." + }, + "protection_skip": { + "label": "Not working? Set up later", + "title": "Set up protection later?", + "body": "Protection isn’t active yet. You can still continue and set it up anytime under “Protection”.", + "confirm": "Set up later" } }, "protection_onboarding": { diff --git a/apps/rebreak-native/locales/fr.json b/apps/rebreak-native/locales/fr.json index 4104b2e..1705d48 100644 --- a/apps/rebreak-native/locales/fr.json +++ b/apps/rebreak-native/locales/fr.json @@ -580,9 +580,15 @@ "a11y_indicator": "ReBreak te guide pas à pas", "a11y_step3": "Active l’interrupteur, confirme la boîte de dialogue — puis reviens dans l’app.", "usage_title": "Une fois : activer le guidage pas à pas", - "usage_body": "Le menu d’accessibilité de Samsung est pénible. Pour te guider étape par étape, donne à ReBreak l’« accès aux données d’usage » une fois — j’ouvre la page. Active ReBreak là, reviens et touche à nouveau la protection.", + "usage_body": "Le menu d’accessibilité est parfois pénible. Pour te guider étape par étape, donne à ReBreak l’« accès aux données d’usage » une fois — j’ouvre la page. Active ReBreak là, reviens et touche à nouveau la protection.", "overlay_title": "Une fois : autoriser l’overlay d’aide", "overlay_body": "Pour que mon indication s’affiche devant les Réglages (au lieu d’être cachée dans le tiroir), donne à ReBreak « Superposition à d’autres applis » une fois — j’ouvre la page. Active ReBreak là, reviens et touche à nouveau la protection." + }, + "protection_skip": { + "label": "Ça ne marche pas ? Configurer plus tard", + "title": "Configurer la protection plus tard ?", + "body": "La protection n’est pas encore active. Tu peux continuer et la configurer à tout moment sous « Protection ».", + "confirm": "Plus tard" } }, "mail": { diff --git a/apps/rebreak-native/modules/rebreak-protection/android/src/main/java/expo/modules/rebreakprotection/RebreakProtectionModule.kt b/apps/rebreak-native/modules/rebreak-protection/android/src/main/java/expo/modules/rebreakprotection/RebreakProtectionModule.kt index 54fad62..42a3e29 100644 --- a/apps/rebreak-native/modules/rebreak-protection/android/src/main/java/expo/modules/rebreakprotection/RebreakProtectionModule.kt +++ b/apps/rebreak-native/modules/rebreak-protection/android/src/main/java/expo/modules/rebreakprotection/RebreakProtectionModule.kt @@ -16,6 +16,7 @@ import android.content.Intent import android.net.VpnService import android.net.Uri import android.os.Build +import android.os.PowerManager import android.provider.Settings import android.graphics.Color import android.graphics.PixelFormat @@ -429,6 +430,58 @@ class RebreakProtectionModule : Module() { } } + // Battery-Optimization: ohne Ausnahme schläfert Samsung & Co. die App ein + // → der a11y-Tamper-Lock wird entbunden → Schutz fällt still aus. Daher + // Status prüfbar + per System-Dialog (ein Tap) anforderbar machen. + AsyncFunction("isBatteryOptimizationIgnored") { + mapOf("ignored" to isIgnoringBatteryOptimizations(requireContext())) + } + + AsyncFunction("requestIgnoreBatteryOptimizations") { + val ctx = requireContext() + if (isIgnoringBatteryOptimizations(ctx)) { + return@AsyncFunction mapOf("opened" to false, "alreadyIgnored" to true) + } + // Direkter System-Dialog „… Akku-Optimierung ignorieren?" (ein Tap „Zulassen"). + val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply { + data = Uri.parse("package:${ctx.packageName}") + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + try { + ctx.startActivity(intent) + mapOf("opened" to true) + } catch (e: Exception) { + Log.w(TAG, "requestIgnoreBatteryOptimizations: ${e.message}") + // Fallback: generische Battery-Optimization-Liste + try { + ctx.startActivity( + Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + ) + mapOf("opened" to true, "fallback" to true) + } catch (e2: Exception) { + mapOf("opened" to false, "error" to (e2.message ?: "")) + } + } + } + + // Öffnet die App-Detail-Settings — für Samsung der Weg zu „Akku → + // Uneingeschränkt" + raus aus „Schlafende/Tief schlafende Apps" (das deckt + // der reine AOSP-Whitelist-Dialog NICHT ab). + AsyncFunction("openAppDetailsSettings") { + val ctx = requireContext() + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.parse("package:${ctx.packageName}") + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + try { + ctx.startActivity(intent) + mapOf("opened" to true) + } catch (e: Exception) { + mapOf("opened" to false, "error" to (e.message ?: "")) + } + } + // Hat die App das "Über anderen Apps anzeigen"-Recht? (→ passives Guide-Overlay) AsyncFunction("hasOverlayPermission") { val ctx = requireContext() @@ -1072,8 +1125,15 @@ class RebreakProtectionModule : Module() { // Ein armed-aber-Schutz-aus Tamper-Lock ist effektiv KEIN Lock — sonst // zeigt die UI „verriegelt" ohne dass der User je rauskommt (Desync-Fall: // `tamper_armed` noch true, aber `filter_enabled` schon false). - "tamperLock" to (isTamperLockArmed(ctx) && isEnabledFlag(ctx)), + // Lock gilt nur als aktiv, wenn er WIRKLICH erzwingt: armed + VPN-flag UND + // der a11y-Service läuft live. Sonst „armed-aber-a11y-aus" → UI zeigt + // „verriegelt", obwohl nichts mehr blockt (z.B. a11y nach Reboot deaktiviert). + "tamperLock" to (isTamperLockArmed(ctx) && isEnabledFlag(ctx) && isAccessibilityServiceEnabled(ctx)), "deviceAdmin" to isDeviceAdminEnabled(ctx), + // Akku-Ausnahme: ohne sie schläfert Samsung & Co. die App ein und entbindet + // den a11y-Service → Schutz fällt still aus. Teil des State, damit die UI + // darauf hinweisen/gaten kann. + "batteryUnrestricted" to isIgnoringBatteryOptimizations(ctx), "blocklistCount" to count, "blocklistLastSyncAt" to lastSyncAt, ) @@ -1089,6 +1149,17 @@ class RebreakProtectionModule : Module() { } } + /** Ist die App von der Akku-Optimierung ausgenommen? (AOSP-Whitelist — + * Samsung „Schlafende Apps" ist separat, daher zusätzlich der App-Detail-Guide.) */ + private fun isIgnoringBatteryOptimizations(ctx: Context): Boolean { + return try { + val pm = ctx.getSystemService(Context.POWER_SERVICE) as PowerManager + pm.isIgnoringBatteryOptimizations(ctx.packageName) + } catch (_: Exception) { + false + } + } + private fun activateSuccessResult(): Map = mapOf( "allLayersOn" to false, "missingLayers" to listOf("accessibility", "tamperLock"), diff --git a/apps/rebreak-native/modules/rebreak-protection/android/src/main/java/expo/modules/rebreakprotection/vpn/RebreakVpnService.kt b/apps/rebreak-native/modules/rebreak-protection/android/src/main/java/expo/modules/rebreakprotection/vpn/RebreakVpnService.kt index 57e583f..89c113c 100644 --- a/apps/rebreak-native/modules/rebreak-protection/android/src/main/java/expo/modules/rebreakprotection/vpn/RebreakVpnService.kt +++ b/apps/rebreak-native/modules/rebreak-protection/android/src/main/java/expo/modules/rebreakprotection/vpn/RebreakVpnService.kt @@ -6,6 +6,7 @@ import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import android.content.Intent +import android.content.pm.ServiceInfo import android.net.VpnService import android.os.Build import android.os.Handler @@ -56,7 +57,7 @@ class RebreakVpnService : VpnService() { return START_NOT_STICKY } ACTION_RESTART -> { - startForeground(NOTIF_ID, buildNotification()) + if (!promoteToForegroundOrStop()) return START_NOT_STICKY stopVpn() hashList.load() Log.i(TAG, "blocklist reloaded (restart) — ${hashList.count()} hashes") @@ -69,7 +70,7 @@ class RebreakVpnService : VpnService() { return START_STICKY } else -> { - startForeground(NOTIF_ID, buildNotification()) + if (!promoteToForegroundOrStop()) return START_NOT_STICKY hashList.load() Log.i(TAG, "blocklist loaded — ${hashList.count()} hashes") // Self-Heal: war die Blockliste beim Start leer (blocklist.bin @@ -85,6 +86,38 @@ class RebreakVpnService : VpnService() { } } + /** + * Foreground-Promotion mit EXPLIZITEM FGS-Typ (specialUse). Auf Android 16 + * (Samsung Galaxy A54 u.a.) lehnt `validateForegroundServiceType` die + * implizite 2-arg-`startForeground`-Variante ab → SecurityException. Mit + * explizit übergebenem Typ (Googles dokumentierte Best Practice) passt die + * Validierung. + * + * Schlägt die Promotion trotzdem fehl (OEM-FGS-Restriction), wird der + * Service sauber gestoppt — statt (a) den App-Prozess zu crashen ODER (b) in + * den 5s-„did-not-call-startForeground"-Timeout-Crash zu laufen. So endet die + * Crash-Schleife auf jedem Gerät. + */ + private fun promoteToForegroundOrStop(): Boolean { + return try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + startForeground( + NOTIF_ID, + buildNotification(), + ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE, + ) + } else { + startForeground(NOTIF_ID, buildNotification()) + } + true + } catch (e: Exception) { + Log.e(TAG, "startForeground abgelehnt (${e.javaClass.simpleName}): ${e.message}", e) + try { stopVpn() } catch (_: Exception) {} + try { stopSelf() } catch (_: Exception) {} + false + } + } + private fun startVpn() { if (running) return try { diff --git a/apps/rebreak-native/modules/rebreak-protection/ios/RebreakContentFilter/Info.plist b/apps/rebreak-native/modules/rebreak-protection/ios/RebreakContentFilter/Info.plist index 3635852..723308c 100644 --- a/apps/rebreak-native/modules/rebreak-protection/ios/RebreakContentFilter/Info.plist +++ b/apps/rebreak-native/modules/rebreak-protection/ios/RebreakContentFilter/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 0.4.1 + 0.4.6 CFBundleVersion - 87 + 92 NSExtension NSExtensionPointIdentifier diff --git a/apps/rebreak-native/modules/rebreak-protection/ios/RebreakPacketTunnelExtension/Info.plist b/apps/rebreak-native/modules/rebreak-protection/ios/RebreakPacketTunnelExtension/Info.plist index 4acaf15..1be4070 100644 --- a/apps/rebreak-native/modules/rebreak-protection/ios/RebreakPacketTunnelExtension/Info.plist +++ b/apps/rebreak-native/modules/rebreak-protection/ios/RebreakPacketTunnelExtension/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 0.4.1 + 0.4.6 CFBundleVersion - 87 + 92 NSExtension NSExtensionPointIdentifier diff --git a/apps/rebreak-native/modules/rebreak-protection/ios/RebreakURLFilterExtension/Info.plist b/apps/rebreak-native/modules/rebreak-protection/ios/RebreakURLFilterExtension/Info.plist index d0a1c31..82708e3 100644 --- a/apps/rebreak-native/modules/rebreak-protection/ios/RebreakURLFilterExtension/Info.plist +++ b/apps/rebreak-native/modules/rebreak-protection/ios/RebreakURLFilterExtension/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 0.4.1 + 0.4.6 CFBundleVersion - 87 + 92 EXAppExtensionAttributes EXExtensionPointIdentifier diff --git a/apps/rebreak-native/modules/rebreak-protection/src/RebreakProtection.types.ts b/apps/rebreak-native/modules/rebreak-protection/src/RebreakProtection.types.ts index 4dd31dc..7070e82 100644 --- a/apps/rebreak-native/modules/rebreak-protection/src/RebreakProtection.types.ts +++ b/apps/rebreak-native/modules/rebreak-protection/src/RebreakProtection.types.ts @@ -42,6 +42,12 @@ export type DeviceLayers = { * Schliesst die Boot-Luecke: ohne aktiven Admin hat die App nach Neustart * kurz kein Schutz-Lock bis der AccessibilityService startet. */ deviceAdmin?: boolean; + /** Android-only. True wenn die App von der Akku-Optimierung ausgenommen ist + * (PowerManager.isIgnoringBatteryOptimizations). Ohne Ausnahme schläfert + * Samsung & Co. die App ein → a11y-Service wird entbunden → Schutz fällt + * still aus. (Samsung „Schlafende Apps" ist zusätzlich separat — App-Detail- + * Guide.) */ + batteryUnrestricted?: boolean; // Shared blocklistCount: number; blocklistLastSyncAt: string | null; diff --git a/apps/rebreak-native/modules/rebreak-protection/src/RebreakProtectionModule.ts b/apps/rebreak-native/modules/rebreak-protection/src/RebreakProtectionModule.ts index 76d5355..463ee54 100644 --- a/apps/rebreak-native/modules/rebreak-protection/src/RebreakProtectionModule.ts +++ b/apps/rebreak-native/modules/rebreak-protection/src/RebreakProtectionModule.ts @@ -211,6 +211,24 @@ declare class RebreakProtectionModule extends NativeModule; + /** Android: Ist die App von der Akku-Optimierung ausgenommen? Ohne Ausnahme + * schläfert Samsung & Co. die App ein → a11y-Service entbunden → Schutz weg. */ + isBatteryOptimizationIgnored(): Promise<{ ignored: boolean }>; + + /** Android: System-Dialog „Akku-Optimierung ignorieren?" (ein Tap „Zulassen"). + * alreadyIgnored=true wenn bereits ausgenommen; fallback=true wenn nur die + * generische Liste geöffnet werden konnte. */ + requestIgnoreBatteryOptimizations(): Promise<{ + opened: boolean; + alreadyIgnored?: boolean; + fallback?: boolean; + error?: string; + }>; + + /** Android: Öffnet die App-Detail-Settings — für Samsung der Weg zu + * „Akku → Uneingeschränkt" + raus aus „Schlafende/Tief schlafende Apps". */ + openAppDetailsSettings(): Promise<{ opened: boolean; error?: string }>; + /** Android: Hat die App „Über anderen Apps anzeigen" (für das passive Guide-Overlay)? */ hasOverlayPermission(): Promise<{ granted: boolean }>; diff --git a/apps/rebreak-native/package.json b/apps/rebreak-native/package.json index a2ceff4..6649e6f 100644 --- a/apps/rebreak-native/package.json +++ b/apps/rebreak-native/package.json @@ -1,6 +1,6 @@ { "name": "rebreak-native", - "version": "0.4.4", + "version": "0.4.7", "private": true, "main": "expo-router/entry", "scripts": { diff --git a/apps/rebreak-native/plugins/with-rebreak-protection-android.js b/apps/rebreak-native/plugins/with-rebreak-protection-android.js index 466e850..ecd8741 100644 --- a/apps/rebreak-native/plugins/with-rebreak-protection-android.js +++ b/apps/rebreak-native/plugins/with-rebreak-protection-android.js @@ -7,11 +7,13 @@ * Was es macht: * 1) Sorgt für `xmlns:tools` auf . * 2) Registriert mit - * foregroundServiceType="systemExempted" + intent-filter - * android.net.VpnService + permission BIND_VPN_SERVICE. - * (`systemExempted` ist seit Android 14 der korrekte Type für - * VPN-/Filter-Foreground-Services — vorher war `specialUse`+content_filter - * angedacht aber bringt mehr Probleme als Nutzen.) + * foregroundServiceType="specialUse" (+ PROPERTY_SPECIAL_USE_FGS_SUBTYPE=vpn) + * + intent-filter android.net.VpnService + permission BIND_VPN_SERVICE. + * (`systemExempted` wurde verworfen: es verlangt auf Android 16/API 36 zur + * startForeground-Zeit den AKTIVEN-VPN-Zustand [anyOf android:activate_vpn], + * der erst ~ms nach establish() kommt → SecurityException/Crash. `specialUse` + * hat keine Laufzeit-Vorbedingung; braucht FOREGROUND_SERVICE_SPECIAL_USE + + * einmalige Play-„Special Use"-Erklärung.) * 3) Registriert mit * android:permission=BIND_ACCESSIBILITY_SERVICE + intent-filter * android.accessibilityservice.AccessibilityService + meta-data @@ -68,9 +70,23 @@ function ensureVpnService(manifest) { $: { 'android:name': VPN_SERVICE_CLASS, 'android:permission': 'android.permission.BIND_VPN_SERVICE', - 'android:foregroundServiceType': 'systemExempted', + // specialUse statt systemExempted: systemExempted verlangt auf Android 16 + // (API 36) zur startForeground-Zeit, dass die App bereits der AKTIVE VPN ist + // (anyOf [android:activate_vpn]) — dieser Zustand kommt aber erst ~ms nach + // establish() (Race) → SecurityException. specialUse hat keine Laufzeit- + // Vorbedingung und geht deterministisch durch (braucht nur die Permission + // FOREGROUND_SERVICE_SPECIAL_USE + die PROPERTY unten + Play-Special-Use-Decl). + 'android:foregroundServiceType': 'specialUse', 'android:exported': 'false', }, + property: [ + { + $: { + 'android:name': 'android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE', + 'android:value': 'vpn', + }, + }, + ], 'intent-filter': [ { action: [{ $: { 'android:name': 'android.net.VpnService' } }], diff --git a/apps/rebreak-native/stores/notifications.ts b/apps/rebreak-native/stores/notifications.ts index e2457b2..0b800e1 100644 --- a/apps/rebreak-native/stores/notifications.ts +++ b/apps/rebreak-native/stores/notifications.ts @@ -1,6 +1,7 @@ import { create } from "zustand"; import { apiFetch } from "../lib/api"; import { supabase } from "../lib/supabase"; +import { isRealtimeErrorReal } from "../lib/realtimeStatus"; import type { RealtimeChannel } from "@supabase/supabase-js"; export interface AppNotification { @@ -120,7 +121,7 @@ export const useNotificationStore = create((set, get) => ({ ) .subscribe((status) => { if (status === "CHANNEL_ERROR" || status === "TIMED_OUT") { - console.warn("[notifRealtime] error:", status); + if (isRealtimeErrorReal()) console.warn("[notifRealtime] error:", status); get().stopRealtime(); if (reconnectTimer) clearTimeout(reconnectTimer); reconnectTimer = setTimeout(() => { diff --git a/apps/rebreak-native/tmp/.deploy-runtimes b/apps/rebreak-native/tmp/.deploy-runtimes index cd4b52b..e71e704 100644 --- a/apps/rebreak-native/tmp/.deploy-runtimes +++ b/apps/rebreak-native/tmp/.deploy-runtimes @@ -56,9 +56,34 @@ Building Release AAB (gradlew bundleRelease)|299 Validating IPA (App-Store Connect)|93 Uploading zu App-Store Connect (TestFlight)|126 Building Release AAB (gradlew bundleRelease)|522 -Building xcarchive|285 -Exporting Ad-Hoc IPA|20 -Exporting App-Store IPA|28 Validating IPA (App-Store Connect)|70 Uploading zu App-Store Connect (TestFlight)|86 Building Release AAB (gradlew bundleRelease)|491 +Validating IPA (App-Store Connect)|68 +Uploading zu App-Store Connect (TestFlight)|90 +Building Release AAB (gradlew bundleRelease)|531 +Validating IPA (App-Store Connect)|97 +Uploading zu App-Store Connect (TestFlight)|75 +Building Release AAB (gradlew bundleRelease)|358 +Validating IPA (App-Store Connect)|70 +Uploading zu App-Store Connect (TestFlight)|82 +Building Release AAB (gradlew bundleRelease)|322 +Validating IPA (App-Store Connect)|72 +Uploading zu App-Store Connect (TestFlight)|75 +Building Release AAB (gradlew bundleRelease)|335 +Validating IPA (App-Store Connect)|68 +Uploading zu App-Store Connect (TestFlight)|102 +Building Release AAB (gradlew bundleRelease)|329 +Building Release AAB (gradlew bundleRelease)|360 +Building Release AAB (gradlew bundleRelease)|99 +Building Release AAB (gradlew bundleRelease)|448 +expo prebuild (ios)|11 +Validating IPA (App-Store Connect)|71 +Uploading zu App-Store Connect (TestFlight)|87 +Building Release AAB (gradlew bundleRelease)|502 +Building xcarchive|281 +Exporting Ad-Hoc IPA|21 +Exporting App-Store IPA|29 +Validating IPA (App-Store Connect)|96 +Uploading zu App-Store Connect (TestFlight)|80 +Building Release AAB (gradlew bundleRelease)|279 diff --git a/docs/internal/SESSION_2026-06-07_handoff.md b/docs/internal/SESSION_2026-06-07_handoff.md new file mode 100644 index 0000000..7042a6a --- /dev/null +++ b/docs/internal/SESSION_2026-06-07_handoff.md @@ -0,0 +1,90 @@ +# Session-Handoff 2026-06-07 (Windows-Schutz + Mac-DNS + Marketing-Nav) + +> Für die nächste Claude-Code-Session. Stand: ~15:40, User macht gleich **Mac-Neustart**. +> Memory-Files (MEMORY.md) ergänzen diesen Stand — hier das Session-Spezifische. + +--- + +## 🔴 SOFORT-NÄCHSTER SCHRITT (offen, blockt Mac-Entscheidung) + +**Mac-DNS-Profil: Wall oder stale-state?** Nach dem Neustart: +1. `~/Downloads/rebreak-schutz-signed.mobileconfig` installieren (signiertes DNS-Profil, Platzhalter-PW egal). +2. **Installiert** → KEINE Wall, manuelles DNS-Profil reicht (heutige Fails = stale Netzwerk-Dienst vom entfernten alten Profil). RemovalPassword-Schutz steht → **kein MDM nötig**. +3. **Failt auch auf frisch gebootetem Mac** (`„VPN-Dienst konnte nicht erstellt werden"`) → echte **macOS-26-Wall** (DNS nur via MDM) → dann MDM-Pfad (NanoMDM, siehe unten). + +⚠️ Wichtig: NICHT vorschnell „MDM Pflicht" sagen — das echte ReBreak-DNS-Profil hat bei diesem User VORHER manuell installiert. Beweislage unklar bis Clean-Boot-Test. + +--- + +## ✅ Was heute fertig wurde (verifiziert) + +1. **Windows-Schutz end-to-end bewiesen** (in UTM Win11-ARM64-VM): + - PowerShell DoH-Takeover → `Resolve-DnsName bet365.de` = `0.0.0.0`/NXDOMAIN + - Browser-Bypass gelöst: Chrome/Edge umgehen System-DNS via built-in-Resolver+eigenem DoH → Fix = 2 Policies (`DnsOverHttpsMode=off` + `BuiltInDnsClientEnabled=false`), beide nötig. + - **Subdomain-Bug (User-Fund):** Blocklist war Apex-only (`bet365.com` geblockt, `www.bet365.com` offen). Fix deployed (siehe unten). +2. **ReBreak Magic Windows-App** (`apps/rebreak-magic-win/`, Tauri): komplett gecodet, CI-Build **grün**, Installer gebaut: `ReBreak Magic_0.1.0_x64-setup.exe` (3,8 MB, in `/tmp/rebreak-win-installer/`). Browser-Policies im `protection-core/apply_script`. +3. **Mac Removal-Lock BEWIESEN:** Profil mit `PayloadRemovalDisallowed` + `RemovalPassword` → macOS verlangt beim Entfernen das **Removal-PW, NICHT Admin-PW** (Dock-Test-Profil). RemovalPassword hält gegen Admin. +4. **Marketing-Nav umgebaut** (`apps/marketing/app/layouts/default.vue`): Floating-Tabbar raus → Hamburger (mobil) / Header-Nav (Desktop). + +--- + +## 🟡 Offene Threads / Entscheidungen + +| Thread | Status | Nächster Schritt | +|---|---|---| +| Mac-DNS Wall-Test | **blockt** | Clean-Boot-Test (oben) | +| Mac-MDM-Pfad (falls Wall) | geplant | NanoMDM Mac-Enrollment + DNS-Push testen (rebreak-binder-Domain). Teile da: `ops/mdm/rebreak-mac-dns-filter.mobileconfig`, `backend/server/api/mdm/enroll.get.ts` | +| Backend-Deploys | **warten auf GO** | ProhibitDisablement (dns/profile), Geräte-Matrix (plan-features+magic), magic/status — alle uncommitted | +| Marketing-Content | offen | „was wir alles bieten" (iOS/Android/Mac/Windows) — braucht User-Steer (Positionierung) | +| Installer hosten + Download-Link | offen | Wohin? `rebreak.org/downloads/` lt. magic/info. Dann Download-Page um Windows ergänzen | +| Mac Browser-Policies | offen | Managed Prefs Chrome/Edge ins Mac-Profil (Chromium umgeht DNS auch auf Mac) | +| Backend-Cooldown-Flow (Mac-Selbstbindung) | offen | Backend hält RemovalPassword, App-Release nach 24h, verschlüsselte Delivery | +| Android: Ina Internal-Test | offen | Opt-in-Link (Play Console → Interne Tests → „Teilnahme am Test") an Ina; Account `inabrini15@gmail.com` | +| Android Open Testing | besprochen | „Offener Test" (public Link) braucht Google-Review; Glücksspiel-Framing beachten | + +--- + +## 📦 Working-Tree (uncommitted — NICHT deployed) + +**Backend (deploy nach GO → triggert Staging via push main):** +- `dns/profile.get.ts` — `ProhibitDisablement: true` ergänzt (gegen Toggle-Bypass) +- `magic/register.post.ts` — `platform`-Feld (windows) + Cross-Counting Desktop-Slots +- `magic/status.get.ts` — **neu** (Token-Status-Poll für Win-Tamper-Service) +- `magic/info.get.ts` — Windows-Installer-URL +- `plan-features.ts` — Pro `maxProtectedDevices 0→1` (Geräte-Matrix Pro 1+1 / Legend 3+2) +- `db/devices.ts` — MAGIC_DEVICE_LIMIT entfernt (jetzt plan-gated) +- `devices/enroll.post.ts` — Cross-Counting Magic+Protected + +**Native (Frontend, kein Backend-Deploy):** +- `devices.tsx` (Mac/Win-Menü raus → MagicSheet direkt), `MagicSheet.tsx` (Mac/Win-Toggle + i18n), `DeviceProgressBar.tsx` (label), `AddMacSheet.tsx`, locales ar/de/en/fr + +**Marketing:** `layouts/default.vue` (Nav-Umbau), locales de/en (Pricing 2/5 Geräte) + +--- + +## 🚀 Committed + deployed heute + +- `80be124` **blocklist `||domain^`** (Subdomain-Fix) → deployed Staging, AdGuard re-pulled (395k Regeln), `www.*` verifiziert NXDOMAIN +- `4b4b9fc` / `771af0f` / `869d8af` **rebreak-magic-win App + CI** → Build grün, Installer-Artefakt da +- **AdGuard-Server (rebreak-mdm):** `blocking_mode: default → nxdomain` (Config-Edit, Backup `AdGuardHome.yaml.bak-1780828505`). Beides LIVE für alle DNS-Plattformen. + +--- + +## 🧪 Artefakte (lokal) + +- `/tmp/rebreak-win-installer/ReBreak Magic_0.1.0_x64-setup.exe` — Windows-Installer (3,8 MB) +- `~/Downloads/rebreak-schutz-signed.mobileconfig` — signiertes Mac-DNS-Profil (für Clean-Boot-Test) +- `~/Downloads/removal-lock-test.mobileconfig` — Dock+RemovalPassword (beweist Removal-Lock, installiert) +- `~/Downloads/Windows11-ARM64-de.iso` — VM-ISO (4,9 GB) + +--- + +## 🧠 Key-Findings (auch in Memory) + +- **[[chromium-dns-bypass]]** — Chrome/Edge/Brave umgehen System-DNS (Mac+Win), Fix = 2 Browser-Policies +- **[[mac-magic-profile-lock]]** — RemovalPassword > Admin bewiesen; macOS-26 evtl. DNS-nur-via-MDM (Clean-Boot-Test pending); ProhibitDisablement gegen Toggle-Bypass +- **[[rebreak-magic-win]]** — Windows-App-Architektur + E2E-Validierung +- **[[Legend-USP = Multi-Device-Protection]]** — Geräte-Matrix Pro 1+1 / Legend 3+2 final + +## ⚠️ Mac-Speicher: kritisch +460-GB-Disk war voll (865 MB frei). Heute ~29 GB Xcode-DevData gelöscht → ~35 GB frei. Windows-VM braucht ~40 GB. Langfristig: externe NVMe-SSD für VMs/Archive. diff --git a/docs/internal/SESSION_2026-06-08_handoff.md b/docs/internal/SESSION_2026-06-08_handoff.md new file mode 100644 index 0000000..db7aa04 --- /dev/null +++ b/docs/internal/SESSION_2026-06-08_handoff.md @@ -0,0 +1,69 @@ +# Session-Handoff 2026-06-07/08 — Magic-Windows E2E + Geräte-UI + Marketing-Prod + +> Marathon-Session. Stand: spät nachts 08.06. User macht Feierabend, schreibt +> die **FAGS-Mail** (Fachverband Glücksspielsucht meldet Interesse auf +> **Vorstandsebene** — strategisch riesig). Nächste Session vorbereitet (unten). + +--- + +## 🏆 Das große Ding: ReBreak-Magic für Windows läuft E2E +Der komplette Flow ist **live + verifiziert**: Download (rebreak.org) → SmartScreen-Warnung → Pair (6-stelliger Code aus iPhone-App) → **register** → AdGuard-DNS-Client provisioniert → systemweiter Glücksspiel-Block am PC → **Push „Neues Gerät verbunden" aufs iPhone**. Gerät zeigt „mit ReBreak-Konto verbunden". + +### Zwei harte Backend-Bugs heute gefunden + gefixt (waren der Blocker) +1. **DNS-Token 64 Zeichen** → AdGuard lehnt Client-ID ab (`hostname label too long: got 64, max 63`). Fix: `randomBytes(24).hex` = 48 Zeichen (`register.post.ts`), `magic/status` Regex `{64}`→`{1,63}`. Commit `db6db54` (gepusht + deployed). +2. **nginx-IP-Allow-Liste** auf `dns.rebreak.org` (`/control/`-API) hatte die **neue Staging-Box nicht** drin → 403 Forbidden (sah aus wie falsches PW, war IP). Fix: `allow 91.99.225.223;` in `/etc/nginx/sites-available/dns.rebreak.org` auf **rebreak-mdm** + nginx-reload. Backup liegt da (`.bak-*`). + +### ⚠️ Wichtige Lektion (kostete ~Stunde): falsche Box +- `ssh rebreak-server` (49.13.55.22) = **ALTE migrierte Box**, läuft nur noch stale weiter. NICHT für Staging debuggen. +- **Echte Staging = `staging.rebreak.org` = 91.99.225.223** (`backend/`-Layout, pm2 `rebreak-staging`). Win-App + Deploy zeigen dahin. Memory `reference_rebreak_server` korrigiert. +- AdGuard-Reproduktion + DB-Checks via Infisical-Pattern: `source /etc/environment; infisical login --method=universal-auth --client-id=$INFISICAL_CLIENT_ID --client-secret=$INFISICAL_CLIENT_SECRET --silent --plain` → `infisical run --projectId=14b11b35-… --env=staging --token=…`. + +--- + +## ✅ Phase A (Backend) — live auf Staging (Commit `a95e665`) +4 Blöcke + Hard-Lock + Reveal: +- Offline-Enroll → 410 (kein Klartext-PW-Download mehr); stationär nur via Magic +- `ProhibitDisablement` im Mac-DNS-Template +- Push „Neues Gerät verbunden" (mobile Tokens) aus `magic/register` +- `user_devices`-Realtime-Migration (Publication) +- Hard-Lock: server-PW (`magic_removal_password`) generiert/injiziert, Reveal NUR bei Account-Löschung (`user/delete`) + Kündigung (`stripe/webhook`) via Resend-Mail. Signing config-gated INAKTIV. + +--- + +## ✅ Marketing — live auf **PROD** (rebreak.org) +- **Windows-Download-Seite** `/download/windows` (PC-Schutz korrekt geframt) + Installer `public/downloads/RebreakMagic-Setup.exe` (3,7 MB, aus CI-Artefakt; im Repo, überlebt `rsync --delete`) +- **Trial-Klarheit:** Hero „14 Tage kostenlos testen" + „danach ab 3,99 €/Monat" (löst free-vs-Preis-Verwirrung; 14-Tage-Trial existiert Stripe-seitig) +- **OS-Detection** (`useOS`): Windows-Besucher → Windows-Download, Mac → Mac +- **Pricing:** Device-Cross-Section + Header/Hamburger-Nav (Floating-Tabbar raus) — war nur auf Staging, jetzt Prod +- Deploy: `MARKETING_REMOTE_DIR=/var/www/marketing-prod ./scripts/deploy-marketing.sh`. **Fix:** `--info=progress2`→`--progress` (macOS-rsync-kompatibel). + +--- + +## ✅ Native UI-Polish (committet LOKAL, 6 Commits ahead von origin = db6db54) +`e0eb171 e2e5a10 227c30c 77ce5e5 c3478f4 ca72437` — deployen erst per **App-Rebuild**: +- Device-PNG-Icons (`assets/devices/*.png` statt Ionicons) +- Geräte-Detail-Sheet (Tap → Status, verbunden-seit, HalfDonut), Row antippbar +- Trash/Menü raus → **chevron-forward** (Entfernen am Gerät selbst/Cooldown) +- Slot-Anzeige: **2 volle Progress-Circles** (Mobil grün / Computer blau) + darunter **animierter Gesamt-Verteilungs-Balken** (eigener, kein native; grün/blau-Segmente + Legende). `DeviceSlotDonut` (segment-API, `half`-Modus vorhanden aber ungenutzt), `DeviceDistributionBar`. +- **Status-Pill** in der Liste: Online (grün) / Cooldown · noch Xh (amber, aus `releaseRequestedAt`) / Ungeschützt (rot). + +--- + +## 🚀 NÄCHSTE SESSION — der eigentliche Gamechanger (User-Priorität) +**„ReBreak für Windows echt magic wie Mac"** = iPhone-Supervision (no-erase Self-Bind) **auf Windows** portieren. +- **Warum Gamechanger:** erreicht die **breite Masse** — alle mit iPhone/iPad **ohne Mac** (nur Windows). MDM-enforced → **erzwingt Legend-Account** → Business/Umsatz. +- **Technisch plausibel:** `supervise-magic` ([[supervise-magic-phase-1]]) basiert auf **go-ios** (cross-platform Go → cross-compile nach Windows). Protokoll (lockdownd, MCInstall.SetCloudConfiguration, MobileBackup2) OS-agnostisch. Windows-usbmuxd via **Apple Mobile Device Support** (iTunes / „Apple Geräte"-App). +- **Ungeprüft (= Spike):** ob go-ios' Windows-usbmuxd den **schweren MobileBackup2-Flow** durchzieht. FMI/SDP-Precondition (ErrorCode 211) = gleiche Wall wie Mac. +- **Spike-Plan:** supervise-magic-Go-CLI für Windows cross-compilen → echtes x64-Windows + „Apple Geräte"-App + Test-iPhone (UTM-ARM64-VM taugt für iPhone-USB-Passthrough wahrscheinlich NICHT). rebreak-binder-Territorium. + +### Weitere offene Threads (Prio absteigend) +- **Native-Rebuild + Push** der 6 lokalen UI-Commits (am iPhone testen: Detail-Sheet/Icons/Realtime/Rings/Status) +- **Phase B** Sleep/Budget (Design: [[magic-hardlock-offboarding]]) — 1-Tag/Gerät-Budget, eskal. Cooldown 4/8/12/24h, Auto-Reaktivieren 10h-default, Sleep = AdGuard filtering off +- **Signing:** Magic-Profile (Cert/Sign-Proxy) + **Windows-Code-Signing** gegen SmartScreen (Empfehlung: **Azure Trusted Signing ~10$/Mon**) +- **`magic/status` lastSeen-Heartbeat** → für echten Online/Offline-Status der Magic-Geräte in der Liste +- Pricing-Inkonsistenz: founding_desc „1 Monat Standard" vs Banner „3 Monate Legend" (+ „Standard" ist alter Plan-Name) + +--- + +## 🧠 FAGS (Fachverband Glücksspielsucht) — strategisch +Vorstandsvorsitzender hat Interesse gemeldet (08.06.). Fachliche Validierung + Partnerschafts-/DiGA-Türen. User schreibt die Antwort-Mail. Bei Bedarf: rebreak-strategist / diga-regulatory für Tonalität + fachliche Positionierung. diff --git a/docs/internal/SESSION_2026-06-08_preview_screenshots_handoff.md b/docs/internal/SESSION_2026-06-08_preview_screenshots_handoff.md new file mode 100644 index 0000000..bda08e2 --- /dev/null +++ b/docs/internal/SESSION_2026-06-08_preview_screenshots_handoff.md @@ -0,0 +1,61 @@ +# Session-Handoff 2026-06-08 — Preview-Page, Screenshots, Bug-Hunt + +> **Fortsetzung in neuer Session mit `claude --dangerously-skip-permissions`.** +> Founder war zwischendurch weg (Familie). Diese Datei = vollständiger Stand zum nahtlosen Weitermachen. + +## ✅ ERLEDIGT in Fortsetzung 2026-06-09 +- **208k → 300k**: native Locales (de/en/fr/ar, inkl. Arabisch-Edge-Cases) **+ Marketing** (de/en). Alle JSON valide. +- **Bug #1 (Protection-Sheet/Push zu früh) GEFIXT**: wahre Ursache = `protectionShouldBeActive` ist Account-DEFAULT (nicht „je aktiv"). Fix = lokales AsyncStorage-Flag `protection:everActiveHere` (gesetzt nach erfolgreichem `activateUrlFilter()`), gated `recoveringFromBypass` in `lib/protection.ts`. **Live verifiziert** am Sim (Blocker-Tab zeigt kein Sheet mehr). Siehe Memory `project_protection_bypass_default_flag_fix`. NEXT_RELEASE.md gepflegt. +- **Screenshots 05 + 09 frisch aufgenommen**: 05-breathing = aktive 4-7-8-Animation („Halten/7", Runde 1/3) via SOS→3 Lyra-Turns→Chip (Koordinaten-Tap, Umlaut bricht Text-Match). 09-geraete = sauberer Devices-Screen (3/5). Beide in `public/preview/`. Neue Flows: `.maestro/screens/capture-05-breathing.yaml`, `capture-05-09-verify.yaml`. +- **Deploys (beide mit GO, beide grün):** (a) Backend `adguard.ts`-Idempotenz-Fix → `547f861` push → GH-Actions Deploy-Staging **success** (Health-Check 401). (b) Marketing **Prod**: `MARKETING_REMOTE_DIR=/var/www/marketing-prod ./scripts/deploy-marketing.sh` → `https://rebreak.org/preview/` **HTTP 200** (frisch, last-modified 00:48). Seiten-PW `rebreak-fags`. Link kann an Ilona. +- **Erkenntnis:** Live-Prod-nginx hat KEINE Basic-Auth (Repo `rebreak.org.conf` ist stale/zeigt :3015-Proxy; live = static aus `/var/www/marketing-prod`). + +## Laufender Zustand der Umgebung (WICHTIG) +- **iOS-Simulator iPhone 17 Pro gebootet**, App `org.rebreak.app` installiert + **manuell via Google eingeloggt** (Account `nisyb@gmx.net`). ⚠️ **NICHT clearState / nicht neu installieren** → sonst Login (OAuth/2FA) weg. +- **Metro läuft** (Port 8081). **Marketing-Dev-Server** läuft (Port 3020) → `http://localhost:3020/preview`, Passwort `rebreak-fags`. +- **Live-Server** = `91.99.225.223` (staging.rebreak.org). SSH-Alias `rebreak-server` zeigt auf ALTEN 49.13.55.22 → für Live `ssh root@91.99.225.223`. + +## ✅ DONE diese Session +- **Mac-Magic-502 gefixt**: verwaister AdGuard-Client gelöscht (live) + `backend/server/utils/adguard.ts` `createAdGuardClient` idempotent gemacht (bei 400 → clients/update). ⚠️ **Code uncommitted + undeployed** (Backend-Deploy braucht GO). +- **Johnson-Agent** angelegt: `.claude/agents/johnson.md` (Rebreak-Magic Mac+Win, FE+BE). +- **Ilona/FAGS-Mail** final: `docs/marketing/ilona-vorstand-mail.md` (human-style, kompakt, Gamban-Tabelle). Versendet (Typo lona→ilona gebounced, dann an `ilona.fuechtenschnieder@gluecksspielsucht.de` korrekt raus). +- **Marketing /preview-Seite** gebaut: `apps/marketing/app/pages/preview.vue` + `components/PreviewPhone.vue` + `PreviewDesktop.vue`. App-Icon-Logo, Mail-Provider-Logos (simple-icons), Schutz-Sektion pro Plattform, Gamban-Vergleich, Cooldown/„kein Gefängnis". Erwartet PNGs in `apps/marketing/public/preview/`. +- **Marketing de-AI'd** (Agent): ~45 Gedankenstriche raus, AI-Floskeln entschärft, de+en, Build grün. (Marketing nutzt `{var}`-Platzhalter, NICHT `%{var}`.) +- **rebreak-native UI-Batch** (Agent): Login-Logo zurück (`app/index.tsx`), Splash +1,5s (`components/BrandSplash.tsx`, Delays 3300/2700), DiGA-Wording raus (`DemographicsAccordion.tsx` + `DigaMissionBanner.tsx`), `clean`→`spielfrei` (de) / `gambling-free` (en), Lyra-Avatar (RiveAvatar) statt medkit-Icon im DigaMissionBanner. +- **BrandSplash-Crash gefixt**: `runOnJS(onDone)()` (Worklet-Crash). Splash-Delays vom Agent erhöht. +- **testIDs**: `header-avatar-btn` (`components/AppHeader.tsx`), `sos-send-btn` (`app/urge.tsx`). +- **Maestro-Screenshot-Pipeline**: `apps/rebreak-native/.maestro/screens/marketing-tour-loggedin.yaml` (single-session, tab-basiert, sheet-resilient) + `capture-marketing-loggedin.sh`. Maestro legt `takeScreenshot` in `$REPO_ROOT/screenshots/` ab → Script kopiert nach `public/preview/`. +- **settings.json allowlist** ergänzt: `dig *`, `eas build:list/view *`, `maestro *`, `xcrun simctl *`, capture-Script. + +## 📸 Screenshot-Status +Verifiziert GUT (frisch, korrekt): **02-blocker, 03-blocked, 04-sos-lyra (= Coach/Lyra ✓), 06-mail, 07-community (Home-Feed, dialogfrei ✓), 07b-dm, 08-streak**. Liegen in `public/preview/`. +⚠️ **STALE/falsch**: `05-breathing.png` + `09-geraete.png` (alte Läufe, mtime 14:29/14:30) — entweder echt aufnehmen oder löschen (dann greift Platzhalter). +- **05-breathing**: SOS/Atemübung lebt unter `/urge` — Einstieg in der UI noch unklar (SOS-Button finden). +- **09-geraete**: via Einstellungen → `router.push('/devices')` (`app/settings.tsx:413`). Settings-Einstieg finden. +- Erkenntnis: **Bottom-Tabs = Home · Chat · Coach · Blocker · Mail** (NativeTabs, `app/(app)/_layout.tsx`). Profil via **Header-Avatar** (`header-avatar-btn`). ⚠️ **Blocker-Tab triggert das „Schutz ist aus"-Sheet, das modal alle Taps blockiert** → im Flow Blocker ZULETZT + „Später" wegtippen. Beim Launch „Nicht erlauben" (Screen-Time-Dialog) wegtippen. +- Capture-Run: `bash apps/rebreak-native/.maestro/screens/capture-marketing-loggedin.sh` (App muss eingeloggt + am Home sein). + +## 🐞 OFFENE BUGS (vom Founder beim Testen gefunden) +1. **⚠️ KRITISCH (3× bestätigt): „Schutz ist aus"-Sheet + „Schutz manipuliert"-Push feuern zu früh/falsch.** + Root: `apps/rebreak-native/lib/protection.ts:584-590` — `phase='recoveringFromBypass'`, wenn `backend.protectionShouldBeActive===true && !mdmManaged && kein Filter aktiv`. Das ist **account-global, nicht pro-Gerät** → auf frischem Gerät/Sim, wo Schutz nie LOKAL aktiviert war, fälschlich „recoveringFromBypass" → Push (`app/(app)/_layout.tsx` `enforceProtection`/`notifyBypassDetected` ~Z.214) + ProtectionOffSheet erscheinen sofort + Sheet blockiert Navigation. + **FIX:** `recoveringFromBypass` nur, wenn ein **lokales „war hier schon mal aktiv"-Signal** existiert (persistierter Flag nach erfolgreichem `activate()`), sonst `inactive`/`setup`. Sensible Kern-Schutz-Logik → **mit Founder abstimmen** (gewünschtes Verhalten), nicht blind hacken. +2. **208k → 300k** (SAFE, einfach anwenden — wurde beim Permission-Stop unterbrochen): + Hartkodiert in `apps/rebreak-native/locales/{de,en,fr,ar}.json`. Keys: `subtitle`, `domain_limit_desc`, `protection_subtitle_legend`, `protection_subtitle_pro`, `setup_step3_subtitle_pending`, `android_step1_subtitle_pending`, `feat_blocklist`. Exakter Befehl: + ``` + cd apps/rebreak-native/locales + for f in de.json en.json fr.json ar.json; do + sed -i '' -e 's/208\.000/300.000/g' -e 's/208,000/300,000/g' -e 's/208 000/300 000/g' -e 's/208k/300k/g' "$f" + done + ``` + (Dynamische Stellen via `state.blocklistCount` sind ok.) Danach JSON validieren. +3. **Extension-Versions-Mismatch** (Build-Warnung): App-Extension `0.4.3` vs App `0.4.4` (CFBundleShortVersionString) → vor nächstem Release angleichen (zied). + +## ⏭️ NÄCHSTE SCHRITTE (Bypass-Session) +1. **208k→300k** anwenden (safe). +2. **Protection-Sheet/Push-Bug** fixen (Bug 1) — mit Founder-Input zum Verhalten. +3. Screenshots **05-breathing** (`/urge`), **09-geraete** (Settings→Geräte) echt aufnehmen; Flow erweitern. Ggf. `07c-calls`, `12-domains` (custom domains), `01a/b/c-onboarding` ergänzen. Stale 05/09 vorher löschen. +4. Restliche Preview-Platzhalter (`06b-mail-connect`, `13-admin-approve` Admin-App) später. +5. **Pending Deploys (brauchen GO):** (a) Mac-Magic `adguard.ts`-Idempotenz-Fix → Backend push; (b) Marketing `/preview` deployen → Link an Ilona. + +## Agenten-Lernpunkt +Background-Agents (ahmed) **können im Hintergrund keine Bash-Permission-Prompts bestätigt bekommen** → für Bash-lastige Tasks (maestro/xcrun) hängen sie. In der `--dangerously-skip-permissions`-Session entfällt das Problem. diff --git a/docs/marketing/ilona-vorstand-mail.md b/docs/marketing/ilona-vorstand-mail.md new file mode 100644 index 0000000..63eed95 --- /dev/null +++ b/docs/marketing/ilona-vorstand-mail.md @@ -0,0 +1,97 @@ +# Ilona / FAGS — Mail an Ilona (Antwort auf ihre 2. PN) + +**Kontext:** Ilona Füchtenschnieder-Petry (Vorsitzende fags e.V.) hat warm geantwortet, +will den Vorschlag **intern mit dem Vorstand besprechen** und bittet um einen **Text als +Mail** an `ilona.fuechtenschnieder@gluecksspielsucht.de`, den sie weiterleiten kann. + +> **Regel:** Claude entwirft, Ram versendet selbst von seiner Adresse. + +## Stil-Hinweis +**Kompakte Human-Style-Fassung (Stand 08.06., final).** Bewusst KURZ (lange Mails +schrecken ab), mit Tabelle (informativer als Fließtext) und „bei Interesse erzähle ich gern +mehr"-Haken. Ohne Gedankenstriche im Satz / KI-Polish. Tipp vorm Senden: einmal laut lesen, +ein paar Sätze in eigenen Worten umtippen, dann ist „KI oder nicht" erledigt. + +## ⚠️ Vor dem Senden ausfüllen / bestätigen +1. **Preise** ✅ geprüft (Pro 3,99 €/Mt, Legend 7,99 €/Mt; Jahres-Optionen 29/59 €, 14-Tage-Trial). +2. **„Warst du das auch?"** ✅ bestätigt: *war nicht ich*. +3. **Sonntagscafé-Ort**: offen gehalten (Anfahrt ok) — konkreten Ort nur einsetzen, wenn sicher. +4. **PDF mit Screenshots**: angeboten; Screenshot-Brief separat, sobald gewünscht. +5. **Gamban-Tabelle**: Fakten geprüft (gamban.com/pricing, gamban.com/blocking, GambleAware, + Stand Juni 2026), bewusst FAIR (inkl. Gamban-Stärken Linux, Preis, Reifegrad). £/€ ca. 1,17. +6. **Tabellen-Rendering**: Markdown-Tabelle rendert in vielen Mail-Clients nicht sauber. + Wenn's verrutscht: Mail als HTML senden oder Tabelle als Bild/PDF beilegen. + +--- + +## Mail-Entwurf (kompakt, mit Tabelle) + +**An:** ilona.fuechtenschnieder@gluecksspielsucht.de +**Betreff:** Rebreak, kurz zum Weiterleiten an den Vorstand + +> Hallo Ilona, +> +> danke dir wirklich, dass du Rebreak intern besprichst und weitergibst. Meine Geschichte +> kennst du ja schon, deshalb fasse ich mich kurz. (Und zu deiner Frage: nein, das frühere +> Angebot ohne Erklärung war nicht von mir.) +> +> Kurz gesagt: Rebreak sperrt Glücksspiel geräteweit, auch die nicht-lizenzierten +> Offshore-Seiten, die OASIS nicht erreicht. Es ist aber mehr als ein Blocker. Es begleitet +> auch in den akuten Druckmomenten und hat eine Community, die sich gegenseitig schützt. Alles +> DSGVO-konform auf Servern in Deutschland, sichtbar nur über einen Spitznamen. +> +> Hier der Vergleich zu Gamban, das in eurem Beitrag ja als möglicher Baustein genannt wurde. +> Nur die Fakten: +> +> | | Rebreak | Gamban | +> |---|---|---| +> | Plattformen | iPhone, Android, Mac, Windows | iOS, Android, Mac, Windows, Linux | +> | Offshore-Seiten blockieren | ✓ (>300.000 Domains) | ✓ (40.000+) | +> | Casino-Werbemails im Postfach | ✓ in Echtzeit | nein | +> | Begleitung im Druckmoment (KI 24/7, Atemübung) | ✓ („Lyra") | nein | +> | Community, gegenseitiger Halt | ✓ | nein | +> | Datenhaltung | Deutschland, DSGVO, nur Spitzname | UK-Anbieter | +> | Sprache, Markt | Deutsch, OASIS-Kontext | Englisch, UK | +> | Preis pro Monat | Pro 3,99 €, Legend 7,99 € | ca. 2,90 € | +> | Reifegrad | Beta, im Praxistest | etabliert (bis 99 % wirksam) | +> +> Ich will mir kein Urteil anmaßen, das überlasse ich gern dir. :) +> +> Zwei Angebote noch: +> - Rebreak ist gerade in der Beta. Schick mir ein paar Mailadressen (Android oder iPhone) der +> Kolleginnen und Kollegen, dann trage ich euch als Testende ein. Für fags gibt es kostenlose +> Legend-Lizenzen. +> - Ich komme gern persönlich zu eurem Sonntagscafé und stelle Rebreak vor. +> +> Wenn das Thema für euch interessant ist, erzähle ich sehr gern mehr (zu Mail-Schutz, +> Community, Datenschutz und dem Weg Richtung DiGA) und schicke auf Wunsch ein kompaktes PDF +> mit Screenshots. +> +> Und zum Schluss noch etwas Persönliches, das mir wirklich am Herzen liegt: Rebreak ist nicht +> aus dem Gedanken entstanden, eine App zu bauen und damit Geld zu verdienen. Es ist in einer +> dunklen Zeit entstanden, in der ich selbst nach Halt gesucht und nichts gefunden habe, das +> mir wirklich helfen konnte. Ich bin nicht nur der Entwickler, sondern auch einer von den +> Menschen, für die diese App gedacht ist. Ich kenne diesen Kreislauf von innen, und ich weiß, +> wie einsam er sich anfühlt. Wenn Rebreak auch nur einem einzigen Menschen hilft, da wieder +> herauszufinden, hat sich für mich jede Mühe gelohnt. Und wenn ich eines Tages als Vater von +> zwei Kindern von Rebreak leben kann, dann möchte ich nichts lieber tun, als genau dafür da +> zu sein und Menschen zu helfen. +> +> Dürfte ich innerhalb von Rebreak auf fags und eure Hilfe verweisen? +> +> Herzliche Grüße +> Ram + +--- + +## Forums-Antwort (1 Zeile, Faden warm halten) + +> Hallo Ilona, das freut mich sehr, danke dir! Ich schicke dir den Text gleich als Mail an deine +> Adresse, dann hast du ihn direkt zum Weiterleiten. Herzliche Grüße, Ram + +--- + +## Lange Fassung (Backup) +Die ausführliche Variante (alle Features einzeln, große Tabelle, langer persönlicher Schluss) +gab es als Vorstufe — bei Bedarf aus der Git-Historie holen. Bewusst durch die kompakte Fassung +ersetzt, weil lange Mails abschrecken und die Tabelle die Detailtiefe trägt. diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index c5d7ee5..43d3fef 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,16 +1,16 @@ # Graph Report - rebreak-monorepo (2026-06-10) ## Corpus Check -- 1373 files · ~2,163,903 words +- 1373 files · ~2,165,389 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 14353 nodes · 19343 edges · 877 communities (828 shown, 49 thin omitted) -- Extraction: 99% EXTRACTED · 1% INFERRED · 0% AMBIGUOUS · INFERRED: 219 edges (avg confidence: 0.8) +- 14351 nodes · 19342 edges · 870 communities (824 shown, 46 thin omitted) +- Extraction: 99% EXTRACTED · 1% INFERRED · 0% AMBIGUOUS · INFERRED: 217 edges (avg confidence: 0.8) - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `6937ff15` +- Built from commit: `df3c4faf` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). @@ -752,15 +752,8 @@ - [[_COMMUNITY_Community 865|Community 865]] - [[_COMMUNITY_Community 866|Community 866]] - [[_COMMUNITY_Community 867|Community 867]] -- [[_COMMUNITY_Community 868|Community 868]] -- [[_COMMUNITY_Community 869|Community 869]] -- [[_COMMUNITY_Community 870|Community 870]] -- [[_COMMUNITY_Community 871|Community 871]] - [[_COMMUNITY_Community 872|Community 872]] -- [[_COMMUNITY_Community 873|Community 873]] - [[_COMMUNITY_Community 874|Community 874]] -- [[_COMMUNITY_Community 875|Community 875]] -- [[_COMMUNITY_Community 876|Community 876]] ## God Nodes (most connected - your core abstractions) 1. `usePrisma()` - 299 edges @@ -803,7 +796,7 @@ - **IEC-62304-Traceability (Anforderung→Risikomaßnahme→Test→Lyra-Eval)** — diga_03_req_lyra, diga_04_risk_lyra_01_verpasste_krise, diga_05b_test_verifikation, diga_05c_crisis_detection_recall [EXTRACTED 0.95] - **FAGS/NLS Förder- & Partnerschafts-Strategie (Träger, Forschung, Geldgeber)** — entity_fags, entity_nls, entity_nbank, entity_uni_bremen, entity_step_lukaswerk, entity_bfarm [EXTRACTED 0.85] -## Communities (877 total, 49 thin omitted) +## Communities (870 total, 46 thin omitted) ### Community 0 - "i18n: Blocker/Activation Strings" Cohesion: 0.01 @@ -823,35 +816,35 @@ Nodes (204): blocker, activate_app_lock_failed_msg, activate_app_lock_failed_tit ### Community 4 - "Debug & Dev Tools" Cohesion: 0.04 -Nodes (52): createChatMessage(), countPostLikes(), createComment(), createCommentLike(), deleteCommentLike(), deletePostLike(), deleteUserPosts(), getCommentLike() (+44 more) +Nodes (53): VALID_COUNTRIES, SupportedCountry, deleteUserPosts(), writeConsentRevoke(), decideCuratedDomain(), getCuratedDomains(), suggestCuratedDomain(), redeemDigaCode() (+45 more) ### Community 5 - "Backend API Routes" -Cohesion: 0.06 -Nodes (29): EMPTY_STATS, GamesScreen(), GameStat, GameStats, LastScore, ScoreProgressBar(), ScoreProgressBarProps, useSnakeSounds() (+21 more) +Cohesion: 0.08 +Nodes (21): ScoreProgressBar(), ScoreProgressBarProps, useSnakeSounds(), checkWinner(), Dir, MEMORY_EMOJIS, OPPOSITES, Pos (+13 more) ### Community 6 - "Backend Tests & Auth Routes" -Cohesion: 0.05 -Nodes (64): getConsentLogsByUser(), setMailConnectionConsent(), writeConsentGrant(), getBlocklistedDomainsSet(), consumeOauthPendingState(), createOauthPendingState(), deleteAllMailConnections(), deleteMailConnection() (+56 more) +Cohesion: 0.04 +Nodes (68): getConsentLogsByUser(), setMailConnectionConsent(), writeConsentGrant(), getBlocklistedDomainsSet(), getCustomMailDisplayNames(), getMailDisplayNamePatterns(), consumeOauthPendingState(), countMailConnections() (+60 more) ### Community 7 - "Consent & Magic API Routes" Cohesion: 0.04 -Nodes (48): DevicesScreen(), formatCountdown(), formatLastSeen(), formatSince(), MobileDeviceRow(), mobileIcon(), SectionCard(), SectionLabel() (+40 more) +Nodes (53): DevicesScreen(), formatCountdown(), formatLastSeen(), formatSince(), MobileDeviceRow(), mobileIcon(), SectionCard(), SectionLabel() (+45 more) ### Community 8 - "i18n: Pricing Strings" Cohesion: 0.03 -Nodes (95): CoachTabRedirect(), CooldownTestModeToggle(), DebugScreen(), DebugStub(), LogLine(), LyraEmotionPreviewCard(), ONBOARDING_STEPS, OnboardingStepValue (+87 more) +Nodes (76): CoachTabRedirect(), CooldownTestModeToggle(), DebugScreen(), DebugStub(), LogLine(), LyraEmotionPreviewCard(), ONBOARDING_STEPS, OnboardingStepValue (+68 more) ### Community 9 - "Android DNS Filter (Kotlin)" -Cohesion: 0.05 -Nodes (39): prismaMock, requireUserMock, isAdminUser(), cancelCooldown(), createCooldown(), getActiveCooldown(), resolveCooldown(), touchDevice() (+31 more) +Cohesion: 0.04 +Nodes (48): prismaMock, requireUserMock, isAdminUser(), cleanupStaleDevices(), findUserDevice(), listUserDevices(), registerDevice(), touchDevice() (+40 more) ### Community 10 - "i18n: Pricing Strings" -Cohesion: 0.07 -Nodes (21): Any, Boolean, ByteArray, Int, String, Boolean, HashList, Int (+13 more) +Cohesion: 0.05 +Nodes (37): Any, Boolean, ByteArray, Int, String, Boolean, HashList, Int (+29 more) ### Community 11 - "i18n: Landing Page Strings" -Cohesion: 0.09 -Nodes (66): runtimeFiles, buildFiles, buildTargetsCommandComponents, cFileExtensions, cleanCommandsComponents, abi, artifactName, output (+58 more) +Cohesion: 0.07 +Nodes (89): runtimeFiles, buildFiles, buildTargetsCommandComponents, cFileExtensions, cleanCommandsComponents, abi, artifactName, output (+81 more) ### Community 12 - "Tauri ACL Manifests (Magic Win)" Cohesion: 0.02 @@ -875,27 +868,27 @@ Nodes (87): landing, blocker_badge, blocker_desc, blocker_feat_cooldown, blocker ### Community 17 - "App Root Layout & Shell" Cohesion: 0.04 -Nodes (53): BlockerScreen(), makeModalStyles(), makeStyles(), RoomDetail, RoomScreen(), RoomSettingsModal(), AuthCallback(), CooldownBanner() (+45 more) +Nodes (64): CallScreen(), fmtDuration(), DmData, DmHistoryResponse, DmScreen(), makeStyles(), MediaLibraryModule, makeModalStyles() (+56 more) ### Community 18 - "Community 18" -Cohesion: 0.06 -Nodes (43): ping(), useLastSeenHeartbeat(), invalidateMe(), listeners, Me, OnboardingStep, apiFetch(), apiUrl (+35 more) +Cohesion: 0.05 +Nodes (49): CreateRoomSheet(), Props, FormSheet(), FormSheetProps, ProtectionOffSheet(), StepState, Props, SheetField (+41 more) ### Community 19 - "Community 19" Cohesion: 0.02 Nodes (82): auth, acceptTerms, acceptTermsSuffix, alreadyRegistered, appleSignin, appleSignup, backToLogin, backToLoginPlain (+74 more) ### Community 20 - "Community 20" -Cohesion: 0.04 -Nodes (62): DmData, DmHistoryResponse, DmScreen(), makeStyles(), MediaLibraryModule, queryClient, RootLayoutInner(), PickerOption (+54 more) +Cohesion: 0.05 +Nodes (48): EASE_OUT, LandingScreen(), { width: SW, height: SH }, queryClient, RootLayoutInner(), ConfirmOtpScreen(), OTP_INPUT_STYLE, OTP_INPUT_STYLE (+40 more) ### Community 21 - "Community 21" Cohesion: 0.04 -Nodes (54): MailScreen(), PLAN_LABEL, PROVIDER_CONFIG, ConnectBody, ConnectResult, PROVIDER_DOMAIN_MAP, useMailConnect(), UseMailConnectReturn (+46 more) +Nodes (50): MailScreen(), PLAN_LABEL, ConnectBody, ConnectResult, PROVIDER_DOMAIN_MAP, useMailConnect(), UseMailConnectReturn, useMailDisconnect() (+42 more) ### Community 22 - "Community 22" -Cohesion: 0.06 -Nodes (37): AddDomainSheet(), Props, DomainGrid(), DomainTile(), Props, STATUS_PRIORITY, timeAgo(), Props (+29 more) +Cohesion: 0.03 +Nodes (60): BlockerScreen(), AuthCallback(), AddDomainSheet(), Props, CooldownBanner(), Props, DomainGrid(), DomainTile() (+52 more) ### Community 23 - "Community 23" Cohesion: 0.03 @@ -914,16 +907,16 @@ Cohesion: 0.03 Nodes (68): dependencies, @config-plugins/react-native-webrtc, expo, expo-apple-authentication, expo-application, expo-av, expo-blur, expo-build-properties (+60 more) ### Community 27 - "Community 27" -Cohesion: 0.05 -Nodes (57): arcPath(), HalfDonut(), HalfDonutSegment, polar(), Props, DiGaMilestoneModal(), MILESTONES, DeviceDetail (+49 more) +Cohesion: 0.06 +Nodes (47): ApprovedDomainsData, BackendCooldownEntry, CooldownHistoryData, DemographicsResponse, formatDuration(), formatStartedAt(), mapCooldownEntry(), ProtectionCoverageData (+39 more) ### Community 28 - "Community 28" Cohesion: 0.04 Nodes (65): appHeader, editProfile, settings, sosLabel, sosSubtitle, sosTagline, applock, prompt (+57 more) ### Community 29 - "Community 29" -Cohesion: 0.09 -Nodes (26): ChatHeaderStatus(), Props, UserDevice, DeviceLimitRow(), formatLastSeen(), platformIcon(), LastSeenMap, useLastSeenBatch() (+18 more) +Cohesion: 0.05 +Nodes (48): UserDevice, DeviceLimitRow(), formatLastSeen(), platformIcon(), SuggestResult, SuggestState, useCuratedSuggest(), LastSeenMap (+40 more) ### Community 30 - "Community 30" Cohesion: 0.06 @@ -934,16 +927,16 @@ Cohesion: 0.05 Nodes (54): Config: AdGuard DoH Vars (ADGUARD_BASE_URL/USER/PASSWORD), Config: ENCRYPTION_KEY (AES-256 for DB fields incl mdmDnsToken), Config: GROQ_API_KEY LLM Provider Var, Config: Infisical Secret Injection (no .env files), Backend Environment Variables Doc, RebreakMagic Device-Binding API Documentation, Component: BreathingDrawer (Atemuebung), CHIP_SETS.start Atemuebung Chip (sosConstants.ts, hardcoded) (+46 more) ### Community 32 - "Community 32" -Cohesion: 0.07 -Nodes (33): autoReleaseInactiveDevices(), bindDeviceToUser(), cancelDeviceRelease(), cleanupStaleDevices(), countActiveMagicBindings(), deleteUserDevice(), DEVICE_SELECT, DeviceRecord (+25 more) +Cohesion: 0.06 +Nodes (37): autoReleaseInactiveDevices(), bindDeviceToUser(), cancelDeviceRelease(), countActiveMagicBindings(), deleteUserDevice(), DEVICE_SELECT, DeviceRecord, ensureMagicRemovalPassword() (+29 more) ### Community 33 - "Community 33" Cohesion: 0.08 Nodes (22): Data, Error, HashList, Int, NEPacketTunnelNetworkSettings, NEProviderStopReason, NSObject, ExtLog (+14 more) ### Community 34 - "Community 34" -Cohesion: 0.13 -Nodes (16): addStreakEvent(), deleteUserStreaks(), getActiveStreak(), getStreakEvents(), resetStreak(), updateStreakSavings(), upsertStreak(), createUrgeLog() (+8 more) +Cohesion: 0.14 +Nodes (18): cancelCooldown(), createCooldown(), getActiveCooldown(), resolveCooldown(), appendProtectionEvent(), computeProtectionCoverage(), getLastProtectionEvent(), ProtectionCoverage (+10 more) ### Community 35 - "Community 35" Cohesion: 0.05 @@ -962,8 +955,8 @@ Cohesion: 0.06 Nodes (46): jsonFile, kind, cache-v2, cmakeFiles-v1, codemodel-v2, cmake, generator, paths (+38 more) ### Community 39 - "Community 39" -Cohesion: 0.50 -Nodes (3): callHandler(), g, mocks +Cohesion: 0.05 +Nodes (42): Lang, LANG_NAME, LANGS, LYRA_TOPICS, LyraTopic, TOPIC_HINTS, postFromCatalog(), postFromLLM() (+34 more) ### Community 40 - "Community 40" Cohesion: 0.07 @@ -994,12 +987,12 @@ Cohesion: 0.07 Nodes (32): Any, Bool, ExpoReactNativeFactoryDelegate, NSUserActivity, RCTBridge, RCTReactNativeFactory, String, UIApplication (+24 more) ### Community 47 - "Community 47" -Cohesion: 0.06 -Nodes (44): AppLayout(), DmConvUnreadSlice, NotificationsScreen(), AppHeader(), Props, HeroShieldCheck(), Props, createNativeTabNavigator (+36 more) +Cohesion: 0.04 +Nodes (65): AppLayout(), DmConvUnreadSlice, NotificationsScreen(), PickerOption, PLAN_ACCENT, Section, SectionRow, SettingsScreen() (+57 more) ### Community 48 - "Community 48" -Cohesion: 0.09 -Nodes (21): Candidate, detectAndSaveFeedback(), speakCartesia(), speakElevenLabs(), speakGoogle(), deleteMemoryById(), enforceMaxMemories(), getMemoriesForUser() (+13 more) +Cohesion: 0.12 +Nodes (12): Candidate, detectAndSaveFeedback(), PROVIDER_CONFIG, deleteMemoryById(), enforceMaxMemories(), getMemoriesForUser(), LyraMemoryRow, markReferenced() (+4 more) ### Community 49 - "Community 49" Cohesion: 0.08 @@ -1007,7 +1000,7 @@ Nodes (40): ProtectionLogCard(), nickname, error_invalid_input, lyra, placeholde ### Community 50 - "Community 50" Cohesion: 0.08 -Nodes (18): ContentView, Bool, String, String, Bool, Int, String, Binding (+10 more) +Nodes (17): ContentView, Bool, String, String, Bool, Int, String, WizardStep (+9 more) ### Community 51 - "Community 51" Cohesion: 0.05 @@ -1018,12 +1011,12 @@ Cohesion: 0.07 Nodes (38): pnpm-workspace.yaml (apps/*, backend), DiGA-Listung (BfArM) Pfad, Landesfachstelle Glücksspielsucht Niedersachsen (LSG-Nds), MHH AG Verhaltenssüchte (Prof. Astrid Müller), NBank LOI förderstrategie, FAGS-Outreach-Paket Rebreak Beta + NBank-LOIs, Fachverband Glücksspielsucht e.V. (FAGS), Bielefeld, MDM-Lock Add-On (3-5€ on top auf Pro/Legend) (+30 more) ### Community 53 - "Community 53" -Cohesion: 0.07 -Nodes (39): CallScreen(), fmtDuration(), ChatScreen(), DmItem(), formatTime(), makeStyles(), FilterChip, HomeScreen() (+31 more) +Cohesion: 0.09 +Nodes (33): ChatScreen(), DmItem(), formatTime(), makeStyles(), FilterChip, HomeScreen(), ComposeCard(), Props (+25 more) ### Community 54 - "Community 54" -Cohesion: 0.11 -Nodes (26): Bool, Double, Int, String, UInt32, Double, String, URL (+18 more) +Cohesion: 0.14 +Nodes (21): Bool, Double, Int, String, UInt32, Double, Bool, Double (+13 more) ### Community 55 - "Community 55" Cohesion: 0.06 @@ -1046,8 +1039,8 @@ Cohesion: 0.19 Nodes (32): runtimeFiles, buildFiles, buildTargetsCommandComponents, cFileExtensions, cleanCommandsComponents, abi, artifactName, output (+24 more) ### Community 60 - "Community 60" -Cohesion: 0.12 -Nodes (27): DiGA/MDR Dossier-Plan & Arbeitsteilung, Kostenlose BfArM-Hersteller-Beratung (Klasse I/IIa-Hebel), Zweckbestimmung / Intended Use v0 (Dok 01), Indikation Glücksspielstörung (ICD-10 F63.0 / ICD-11 6C50), Intended-Use-Claim (Begleitung, kein Therapie-/Diagnose-Ersatz), MDR Rule 11 Klassifizierung (I/IIa, größter Kostenhebel), REQ-MAGIC Selbstbindung (RebreakMagic Lock-Modus, 24h-Cooldown), REQ-MAIL Mail-Schutz (deterministische Trigger-Mail-Entfernung) (+19 more) +Cohesion: 0.09 +Nodes (32): DiGA/MDR Dossier-Plan & Arbeitsteilung, Kostenlose BfArM-Hersteller-Beratung (Klasse I/IIa-Hebel), Zweckbestimmung / Intended Use v0 (Dok 01), Indikation Glücksspielstörung (ICD-10 F63.0 / ICD-11 6C50), Intended-Use-Claim (Begleitung, kein Therapie-/Diagnose-Ersatz), MDR Rule 11 Klassifizierung (I/IIa, größter Kostenhebel), REQ-MAGIC Selbstbindung (RebreakMagic Lock-Modus, 24h-Cooldown), REQ-MAIL Mail-Schutz (deterministische Trigger-Mail-Entfernung) (+24 more) ### Community 61 - "Community 61" Cohesion: 0.19 @@ -1070,8 +1063,8 @@ Cohesion: 0.06 Nodes (30): artifacts, backtrace, backtraceGraph, commands, files, nodes, compileGroups, id (+22 more) ### Community 66 - "Community 66" -Cohesion: 0.08 -Nodes (3): RebreakProtectionModule, Module, RebreakProtectionModule +Cohesion: 0.07 +Nodes (5): RebreakProtectionModule, Module, NETunnelProviderManager, DisableResult, RebreakProtectionModule ### Community 67 - "Community 67" Cohesion: 0.16 @@ -1079,15 +1072,15 @@ Nodes (24): Bool, Date, String, URL, Codable, MagicAPIClient.swift (/api/magic/* ### Community 68 - "Community 68" Cohesion: 0.15 -Nodes (29): refreshAndSaveTokens(), assertEnv(), clearConnectionError(), coalescePending, decrypt(), encrypt(), getCredentialsForConnection(), getKey() (+21 more) +Nodes (31): refreshAndSaveTokens(), assertEnv(), clearConnectionError(), coalescePending, decrypt(), encrypt(), getCredentialsForConnection(), getKey() (+23 more) ### Community 69 - "Community 69" -Cohesion: 0.09 -Nodes (24): landing, settings, headerMenu, debug, logout, home, greeting_day, greeting_evening (+16 more) +Cohesion: 0.07 +Nodes (31): landing, settings, games, back_to_picker, last_score, skeleton_footer, subtitle, headerMenu (+23 more) ### Community 70 - "Community 70" Cohesion: 0.06 -Nodes (31): cta_button, cta_title, resources, blocklist_desc, blocklist_title, chart_label, fact1_text, fact1_title (+23 more) +Nodes (34): nav, download_app, login, cta_button, cta_title, resources, blocklist_desc, blocklist_title (+26 more) ### Community 71 - "Community 71" Cohesion: 0.06 @@ -1102,12 +1095,12 @@ Cohesion: 0.11 Nodes (20): Bool, MagicDevice, String, Timer, Void, Date, MagicDevice, String (+12 more) ### Community 74 - "Community 74" -Cohesion: 0.11 -Nodes (23): Any, Binding, Bool, Configuration, ErrorDetails, String, Field, PrefilterFetchInterval (+15 more) +Cohesion: 0.10 +Nodes (24): Any, Binding, Bool, Configuration, ErrorDetails, String, CaseIterable, Field (+16 more) ### Community 75 - "Community 75" -Cohesion: 0.10 -Nodes (27): delphi GmbH / DigiSucht (Versorgungsforschung, Triage-Verweisziel), FAGS / fags e.V. (Fachverband Glücksspielsucht, Ilona Füchtenschnieder), Gamban (UK-Wettbewerber, Glücksspiel-Blocker), GGL (Gemeinsame Glücksspielbehörde der Länder, OASIS-Aufsicht), MHH AG Verhaltenssüchte (Med. Hochschule Hannover), NBank Niedersachsen (Gründungskredit-Geber), NLS Hannover (Niedersächsische Landesstelle für Suchtfragen), OASIS (staatliches Spielersperrsystem) (+19 more) +Cohesion: 0.09 +Nodes (30): delphi GmbH / DigiSucht (Versorgungsforschung, Triage-Verweisziel), FAGS / fags e.V. (Fachverband Glücksspielsucht, Ilona Füchtenschnieder), Gamban (UK-Wettbewerber, Glücksspiel-Blocker), GGL (Gemeinsame Glücksspielbehörde der Länder, OASIS-Aufsicht), MHH AG Verhaltenssüchte (Med. Hochschule Hannover), NBank Niedersachsen (Gründungskredit-Geber), NLS Hannover (Niedersächsische Landesstelle für Suchtfragen), OASIS (staatliches Spielersperrsystem) (+22 more) ### Community 76 - "Community 76" Cohesion: 0.07 @@ -1122,12 +1115,12 @@ Cohesion: 0.20 Nodes (20): AppHandle, Option, Result, String, activateProtection(), cancelRelease(), getState(), logout() (+12 more) ### Community 79 - "Community 79" -Cohesion: 0.10 -Nodes (23): crisisPrompts, EvalPrompt, EXPECTED_CRISIS_MATCHES, harmlessPrompts, PROMPTS_DIR, REQ-LYRA Lyra KI-Coach & Krisen-Behandlung (höchste Sicherheitsrelevanz), Deterministischer Krisen-Keyword-Pre-Filter (crisis-filter.ts), R-LYRA-01 verpasste Krise/Suizidalität (S4, Top-Risiko) (+15 more) +Cohesion: 0.11 +Nodes (21): crisisPrompts, EvalPrompt, EXPECTED_CRISIS_MATCHES, harmlessPrompts, PROMPTS_DIR, REQ-LYRA Lyra KI-Coach & Krisen-Behandlung (höchste Sicherheitsrelevanz), Deterministischer Krisen-Keyword-Pre-Filter (crisis-filter.ts), R-LYRA-01 verpasste Krise/Suizidalität (S4, Top-Risiko) (+13 more) ### Community 80 - "Community 80" -Cohesion: 0.13 -Nodes (18): protectedDeviceIcon(), ProtectedDeviceRow(), confirmProtectedDeviceInstalled(), countActiveProtectedDevices(), createProtectedDevice(), DEVICE_SELECT, DEVICE_SELECT_WITH_TOKEN, getDeviceBlocklistMode() (+10 more) +Cohesion: 0.11 +Nodes (20): protectedDeviceIcon(), ProtectedDeviceRow(), listMagicDevices(), confirmProtectedDeviceInstalled(), countActiveProtectedDevices(), createProtectedDevice(), DEVICE_SELECT, DEVICE_SELECT_WITH_TOKEN (+12 more) ### Community 81 - "Community 81" Cohesion: 0.14 @@ -1178,8 +1171,8 @@ Cohesion: 0.25 Nodes (26): buildFiles, buildTargetsCommandComponents, cleanCommandsComponents, abi, artifactName, output, runtimeFiles, libraries (+18 more) ### Community 93 - "Community 93" -Cohesion: 0.12 -Nodes (24): R-FALSE-01 falsche Sicherheit bei inaktivem Schutz, useProtectionState(), UseProtectionStateReturn, BackendCooldownStatus, BackendProtectionState, CooldownState, formatCooldownRemaining(), isAllLayersOn() (+16 more) +Cohesion: 0.14 +Nodes (23): REQ-PROT Schutz/Blocker (geräteweite Zugangserschwerung), R-FALSE-01 falsche Sicherheit bei inaktivem Schutz, useProtectionState(), UseProtectionStateReturn, BackendCooldownStatus, BackendProtectionState, CooldownState, formatCooldownRemaining() (+15 more) ### Community 94 - "Community 94" Cohesion: 0.10 @@ -1187,7 +1180,7 @@ Nodes (25): buildType, serviceAccountKeyPath, track, build, development, preview ### Community 95 - "Community 95" Cohesion: 0.11 -Nodes (19): callIdToUuid(), displayIncomingCall(), endCall(), reportConnected(), reportEnded(), setupCallKeep(), startOutgoingCall(), startRingback() (+11 more) +Nodes (21): useCallKeepEvents(), useIncomingCalls(), callIdToUuid(), displayIncomingCall(), endCall(), reportConnected(), reportEnded(), setupCallKeep() (+13 more) ### Community 96 - "Community 96" Cohesion: 0.08 @@ -1242,8 +1235,8 @@ Cohesion: 0.08 Nodes (24): backtraceGraph, commands, files, nodes, installers, paths, build, source (+16 more) ### Community 109 - "Community 109" -Cohesion: 0.12 -Nodes (18): Bool, String, Bool, DeviceState, String, EnrollmentStatus, Equatable, DetectorError (+10 more) +Cohesion: 0.14 +Nodes (14): Bool, DeviceState, String, Equatable, DetectorError, cfgutilMissing, deviceLocked, ideviceinfoMissing (+6 more) ### Community 110 - "Community 110" Cohesion: 0.19 @@ -1303,7 +1296,7 @@ Nodes (21): String, Int, CodingKey, CodingKeys, bitCount, bits, falsePositiveTol ### Community 124 - "Community 124" Cohesion: 0.13 -Nodes (18): AuthSession, Bool, Date, DeviceState, WizardStep, CaseIterable, advance(), DebugSupervisionMode (+10 more) +Nodes (17): AuthSession, Bool, Date, DeviceState, WizardStep, advance(), DebugSupervisionMode, forceSupervised (+9 more) ### Community 125 - "Community 125" Cohesion: 0.09 @@ -1430,8 +1423,8 @@ Cohesion: 0.09 Nodes (22): artifacts, backtrace, backtraceGraph, commands, files, nodes, compileGroups, dependencies (+14 more) ### Community 156 - "Community 156" -Cohesion: 0.07 -Nodes (25): Option, Props, WheelPickerModal(), Plan, useUserPlan(), GERMAN_CITIES_BY_BUNDESLAND, getCitiesForBundesland(), BIRTH_YEAR_OPTIONS (+17 more) +Cohesion: 0.09 +Nodes (19): Option, Props, WheelPickerModal(), GERMAN_CITIES_BY_BUNDESLAND, getCitiesForBundesland(), BIRTH_YEAR_OPTIONS, BUNDESLAND_OPTIONS, DemographicsAccordion() (+11 more) ### Community 157 - "Community 157" Cohesion: 0.11 @@ -1530,8 +1523,8 @@ Cohesion: 0.18 Nodes (10): RebreakAccessibilityService, requestPowerDialog(), AccessibilityEvent, AccessibilityNodeInfo, AccessibilityService, Boolean, Int, Long (+2 more) ### Community 181 - "Community 181" -Cohesion: 0.16 -Nodes (10): DmConversation, ALLOWED_EMOJIS, countUnreadDms(), getChatMessages(), getDmConversations(), getDmHistory(), markDmsAsRead(), sendDirectMessage() (+2 more) +Cohesion: 0.09 +Nodes (18): DmConversation, ALLOWED_EMOJIS, EmptyState(), Props, countUnreadDms(), createChatMessage(), getChatMessages(), getDmConversations() (+10 more) ### Community 182 - "Community 182" Cohesion: 0.32 @@ -1838,12 +1831,12 @@ Cohesion: 0.16 Nodes (14): APPROVAL_SELECT, approveRequest(), createApprovalRequest(), DeviceApprovalRecord, generateCode(), generateEmailToken(), getApprovalByEmailToken(), getApprovalRequest() (+6 more) ### Community 258 - "Community 258" -Cohesion: 0.10 -Nodes (13): CrisisLevel, SseEvents, streamSosLyra(), BenchMarker, BenchOnMetric, BenchSession, MarkerEntry, cleanForTts() (+5 more) +Cohesion: 0.19 +Nodes (6): cleanForTts(), QueueItem, SosTtsFetchOpts, SosTtsMode, SosTtsQueue, SosTtsQueueOpts ### Community 259 - "Community 259" -Cohesion: 0.19 -Nodes (18): FileProvider, FormatBackupDate(), RenderInfoPlist(), RenderManifestPlist(), RenderStatusPlist(), renderTemplate(), TLManifestDB(), TLManifestPlist() (+10 more) +Cohesion: 0.18 +Nodes (19): FileProvider, FormatBackupDate(), RenderInfoPlist(), RenderManifestPlist(), RenderStatusPlist(), renderTemplate(), TLManifestDB(), TLManifestPlist() (+11 more) ### Community 260 - "Community 260" Cohesion: 0.13 @@ -1855,23 +1848,23 @@ Nodes (20): artifacts, backtrace, backtraceGraph, commands, files, nodes, compil ### Community 262 - "Community 262" Cohesion: 0.18 -Nodes (9): Any, Bool, Int, String, URL, SharedLogStore, ModuleDefinition, NEVPNStatus (+1 more) +Nodes (8): Any, Bool, Int, String, URL, SharedLogStore, ModuleDefinition, NEVPNStatus ### Community 263 - "Community 263" Cohesion: 0.19 Nodes (14): blocklist.bin Sync Mechanism, Brand-Token (curated brand core), Brand-Token-Matching (shared system), GET /api/url-filter/brand-tokens Endpoint, brand_tokens DB Table, BrandTokenList class (Swift, pendant to HashList), Klartext Brand-Token Privacy Decision, DnsFilter.classify Integration Point (+6 more) ### Community 264 - "Community 264" -Cohesion: 0.16 -Nodes (16): _cooldown_ok(), extract_client_id(), main(), _mark_fired(), post_handshake(), # NOTE: field name is "CP" in AdGuard Home's querylog JSON serialization, Parse one NDJSON line from querylog.json. Returns the ClientID string if non, Tails a file line-by-line. Detects log rotation by monitoring inode. On rota (+8 more) +Cohesion: 0.17 +Nodes (15): _cooldown_ok(), extract_client_id(), main(), _mark_fired(), post_handshake(), # NOTE: field name is "CP" in AdGuard Home's querylog JSON serialization, Parse one NDJSON line from querylog.json. Returns the ClientID string if non, Tails a file line-by-line. Detects log rotation by monitoring inode. On rota (+7 more) ### Community 265 - "Community 265" Cohesion: 0.16 Nodes (8): deviceConnReadWriter, envBool(), Open(), plistUnmarshal(), Conn, DeviceConnectionInterface, DeviceEntry, Client ### Community 266 - "Community 266" -Cohesion: 0.33 -Nodes (10): Connect(), WaitForReconnect(), Duration, Conn, backupCurrentConfig(), makeLogger(), Supervise(), superviseEscalated() (+2 more) +Cohesion: 0.22 +Nodes (17): Connect(), Conn, cliOpts, backupCurrentConfig(), makeLogger(), superviseEscalated(), superviseFresh(), Unsupervise() (+9 more) ### Community 267 - "Community 267" Cohesion: 0.20 @@ -1882,8 +1875,8 @@ Cohesion: 0.20 Nodes (8): Bool, Int, HashList, Snapshot, String, UInt64, UnsafeRawPointer, URL ### Community 269 - "Community 269" -Cohesion: 0.15 -Nodes (14): Lang, LANG_NAME, LANGS, LYRA_TOPICS, LyraTopic, TOPIC_HINTS, postFromCatalog(), postFromLLM() (+6 more) +Cohesion: 0.18 +Nodes (13): Country-Curated Layer-2 Blocklist (50-cap), Pro=10/Legend=20 Custom-Domain Slots (refillable), Layer1/Layer2 Decoupling (Custom vs Country-Curated), Layer-2 Country-Pivot Plan, Travel-Detection via Cellular-MCC, IMAP IDLE Real-Time Mail-Scan Daemon, rebreak-imap-idle Daemon README, Mail Daemon Deployment Handoff (+5 more) ### Community 270 - "Community 270" Cohesion: 0.11 @@ -1910,8 +1903,8 @@ Cohesion: 0.11 Nodes (17): archive, artifacts, backtrace, backtraceGraph, commands, files, nodes, compileGroups (+9 more) ### Community 276 - "Community 276" -Cohesion: 0.15 -Nodes (16): MagicRemovalCredential, AppPlan, VALID_PLANS, reconcileMailAccounts(), reconcileProtectedDevices(), reconcileUpgrade(), runDowngradeReconciliation(), triggerFinalScanForConnection() (+8 more) +Cohesion: 0.24 +Nodes (10): NanoMDM Server (mdm.rebreak.org), supervise-magic Go-CLI Binary, ReBreak Magic Mac App, AuthService.swift (Supabase + Keychain), ReBreak Magic Mac Phase 2 Summary, rebreak-magic-mac XcodeGen project.yml, ReBreak Magic Mac README, Rebreak Magic Mac (Self-Bind Wizard) (+2 more) ### Community 277 - "Community 277" Cohesion: 0.15 @@ -1922,8 +1915,8 @@ Cohesion: 0.20 Nodes (9): Bool, ConfigurationModel, ErrorDetails, TimeInterval, View, ContentViewModel, ActivationButtonAction, disableFilter (+1 more) ### Community 279 - "Community 279" -Cohesion: 0.20 -Nodes (9): build, beforeBuildCommand, beforeDevCommand, devUrl, frontendDist, identifier, productName, $schema (+1 more) +Cohesion: 0.13 +Nodes (14): build, beforeBuildCommand, beforeDevCommand, devUrl, frontendDist, bundle, active, externalBin (+6 more) ### Community 280 - "Community 280" Cohesion: 0.11 @@ -1950,24 +1943,24 @@ Cohesion: 0.29 Nodes (9): Bool, Date, Int, String, EnrollmentStatus, MDMStatus, MDMStatusError, parseError (+1 more) ### Community 286 - "Community 286" -Cohesion: 0.08 -Nodes (29): CoachScreen(), formatDuration(), LoadingPulse(), MessageWithMeta, styles, ThinkingDots(), formatVoiceDuration(), Props (+21 more) +Cohesion: 0.06 +Nodes (36): CoachScreen(), formatDuration(), formatTimestamp(), LoadingPulse(), MessageRow(), MessageWithMeta, styles, ThinkingDots() (+28 more) ### Community 287 - "Community 287" Cohesion: 0.22 Nodes (8): Bool, Int, Never, String, Task, Void, EnrollView, TransferAnimationView ### Community 288 - "Community 288" -Cohesion: 0.18 -Nodes (13): Date, Double, Error, Void, DispatchWorkItem, HealthProbeDelegate, Outcome, blocked (+5 more) +Cohesion: 0.17 +Nodes (14): Date, Double, Error, Void, DispatchWorkItem, HealthProbeDelegate, Outcome, blocked (+6 more) ### Community 289 - "Community 289" -Cohesion: 0.08 -Nodes (32): Country-Curated Layer-2 Blocklist (50-cap), Pro=10/Legend=20 Custom-Domain Slots (refillable), Layer1/Layer2 Decoupling (Custom vs Country-Curated), Layer-2 Country-Pivot Plan, Travel-Detection via Cellular-MCC, Rive Animator Brief — Lyra Avatar, Lyra Avatar Rive Emotion-State Animation, Timeline-Name Code-Contract (no-rename) (+24 more) +Cohesion: 0.13 +Nodes (17): Microsoft as Sub-Processor (Art. 28), Privacy-Policy DSB Notes, No separate Consent-UI for Lyra LLM transfer, Stufe-2 Lyra PII-Pseudonymization (Q3 2026), 12 Sub-Processor DPA/TIA Status, rebreak-native ~1.3% A11y Coverage Gap, Accessibility Audit & DiGA-Roadmap, WCAG 2.1 AA / BITV Compliance for DiGA (+9 more) ### Community 290 - "Community 290" -Cohesion: 0.17 -Nodes (6): Bool, Configuration, String, ConfigurationError, badConfiguration, ConfigurationModel +Cohesion: 0.20 +Nodes (4): Bool, Configuration, String, ConfigurationModel ### Community 291 - "Community 291" Cohesion: 0.12 @@ -2350,8 +2343,8 @@ Cohesion: 0.19 Nodes (9): prismaMock, banUserFromModerationItem(), deleteModerationItem(), dismissModerationItem(), listModerationQueue(), ListQueueOpts, ModerationItemType, ModerationQueueItem (+1 more) ### Community 386 - "Community 386" -Cohesion: 0.15 -Nodes (16): POST /api/magic/register Endpoint, GET /api/magic/status Endpoint, rebreak-staging Backend (Nitro) Service, ReBreak Magic Mac App, AuthService.swift (Supabase + Keychain), ReBreak Magic Mac Phase 2 Summary, MacProfileInstaller.swift (DNS-Filter Profile), ReBreak Magic Mac README (+8 more) +Cohesion: 0.20 +Nodes (11): POST /api/magic/register Endpoint, GET /api/magic/status Endpoint, MacProfileInstaller.swift (DNS-Filter Profile), ReBreak Magic Windows App (Tauri 2), Eigene DoH-Infra (dns.rebreak.org, AdGuard), ReBreak Magic Windows index.html, ReBreak Magic Windows README, rebreak-protection-service (Windows SYSTEM Tamper-Service) (+3 more) ### Community 387 - "Community 387" Cohesion: 0.14 @@ -2458,16 +2451,16 @@ Cohesion: 0.32 Nodes (13): confirm(), die(), dim(), err(), info(), log(), ok(), run() (+5 more) ### Community 413 - "Community 413" -Cohesion: 0.09 -Nodes (23): coach, crisis_bar_label, error, feedback_saved, input_placeholder, modeBadge, new_chat, online (+15 more) +Cohesion: 0.08 +Nodes (25): welcomeBack, coach, crisis_bar_label, error, feedback_saved, input_placeholder, modeBadge, new_chat (+17 more) ### Community 414 - "Community 414" Cohesion: 0.15 Nodes (12): Configuration, String, CustomDebugStringConvertible, FilterStatus, disabled, invalid, running, starting (+4 more) ### Community 415 - "Community 415" -Cohesion: 0.14 -Nodes (17): Client, EscalateUnsupervised(), Open(), Certificate, DeviceConnectionInterface, DeviceEntry, PlistCodec, cliOpts (+9 more) +Cohesion: 0.24 +Nodes (8): Client, EscalateUnsupervised(), Open(), Certificate, DeviceConnectionInterface, DeviceEntry, PlistCodec, Supervise() ### Community 416 - "Community 416" Cohesion: 0.31 @@ -2478,8 +2471,8 @@ Cohesion: 0.13 Nodes (14): dependencies, @fontsource/nunito, react, react-dom, @tauri-apps/api, name, private, scripts (+6 more) ### Community 418 - "Community 418" -Cohesion: 0.16 -Nodes (11): Apple_SwiftHomomorphicEncryption_Pir_V1_KeywordDatabaseRow, Bool, Data, String, _2, _GeneratedWithProtocGenSwiftVersion, D, Sendable (+3 more) +Cohesion: 0.11 +Nodes (18): Apple_SwiftHomomorphicEncryption_Pir_V1_KeywordDatabaseRow, String, URL, Bool, Data, String, RuntimeError, _2 (+10 more) ### Community 419 - "Community 419" Cohesion: 0.11 @@ -2494,8 +2487,8 @@ Cohesion: 0.14 Nodes (12): String, String, Identifiable, Int, WizardStep, done, enroll, macRegistration (+4 more) ### Community 422 - "Community 422" -Cohesion: 0.15 -Nodes (11): EASE_OUT, LandingScreen(), { width: SW, height: SH }, BrandSplash(), EASE_IN, EASE_OUT, { height: SH }, ParticleConfig (+3 more) +Cohesion: 0.28 +Nodes (9): SAFETY-REQ-LLM-002 Sicherheits-Grenzen (Rollen-Integrität, Refusal), Rive Animator Brief — Lyra Avatar, Lyra Avatar Rive Emotion-State Animation, Timeline-Name Code-Contract (no-rename), Forbidden Vocabulary (no Sucht/addiction/Therapie), Lyra AI-Coach Persona (SOS + Coach modes), Lyra Persona — Single Source of Truth, Verbotenes Pathologisierungs-Vokabular (Sucht/süchtig/Therapie) (+1 more) ### Community 423 - "Community 423" Cohesion: 0.14 @@ -2510,8 +2503,12 @@ Cohesion: 0.19 Nodes (14): Maestro Flow: blocker/vpn-activate-verify, Android 16 VPN FGS specialUse Type Fix, Android Surgical Tamper-Lock (a11y + device admin), Blocker / Protection Screen, iOS Guided 3-Step Protection Setup (FamilyControls + Screen Time + VPN URL-Filter), Protection Bypass Local 'was active here' Flag, RebreakVpnService (Android DNS-Filter FGS), 24h-Cooldown Server-Timed Deactivation (+6 more) ### Community 426 - "Community 426" -Cohesion: 0.12 -Nodes (21): PermissionDeniedVariant, applock, prompt, signOut_body, signOut_title, unlock, family_controls_error, permission_denied (+13 more) +Cohesion: 0.20 +Nodes (14): PermissionDeniedVariant, applock, prompt, signOut_body, signOut_title, unlock, family_controls_error, permission_denied (+6 more) + +### Community 427 - "Community 427" +Cohesion: 0.20 +Nodes (4): Conn, WaitForReconnect(), DeviceEntry, Duration ### Community 428 - "Community 428" Cohesion: 0.14 @@ -2523,16 +2520,16 @@ Nodes (5): fs, MODULE_A11Y_XML, MODULE_DEVICE_ADMIN_XML, path, { } ### Community 429 - "Community 429" -Cohesion: 0.05 -Nodes (44): ResolveResult, resolveTypeAndValue(), TestResolveResult, listUserDevices(), addUserCustomDomain(), countActiveCustomDomains(), getUserCustomDomains(), countMailConnections() (+36 more) +Cohesion: 0.09 +Nodes (30): speakCartesia(), speakElevenLabs(), speakGoogle(), resolveTypeAndValue(), TestResolveResult, consumeVoiceQuota(), estimateAudioSeconds(), getRemainingVoiceQuota() (+22 more) ### Community 430 - "Community 430" -Cohesion: 0.22 -Nodes (13): rebreak Admin App (Nuxt SSR panel), admin_audit_log DSGVO Audit-Log (Hans-Mueller), requireAdmin Middleware (admin_users JWT check), GitHub Actions Artifact-Deploy Pattern, imap-idle Daemon, rebreak-admin-staging Service, Build admin (Nuxt SSR) Job, Deploy admin to Hetzner Job (+5 more) +Cohesion: 0.33 +Nodes (7): rebreak Admin App (Nuxt SSR panel), admin_audit_log DSGVO Audit-Log (Hans-Mueller), requireAdmin Middleware (admin_users JWT check), rebreak-admin-staging Service, Build admin (Nuxt SSR) Job, Deploy admin to Hetzner Job, Deploy Admin Staging Workflow ### Community 431 - "Community 431" -Cohesion: 0.06 -Nodes (25): prismaMock, EmptyState(), Props, adminApproveSubmission(), adminRejectSubmission(), castDomainVote(), CustomDomainType, deleteUserCustomDomain() (+17 more) +Cohesion: 0.08 +Nodes (18): prismaMock, ResolveResult, addUserCustomDomain(), adminApproveSubmission(), adminRejectSubmission(), countActiveCustomDomains(), CustomDomainType, deleteUserCustomDomain() (+10 more) ### Community 432 - "Community 432" Cohesion: 0.22 @@ -2555,8 +2552,8 @@ Cohesion: 0.24 Nodes (10): args, dryRun, fetchFromDb(), fetchFromHagezi(), formatTxtpb(), main(), normalizeDomain(), outputPath (+2 more) ### Community 437 - "Community 437" -Cohesion: 0.11 -Nodes (22): makeStyles(), SOSScreen(), ChipSpec, detectEmotion(), LyraEmotion, parseLyraResponse(), SOS_BOOT, currentProvider() (+14 more) +Cohesion: 0.13 +Nodes (19): makeStyles(), SOSScreen(), ChipSpec, detectEmotion(), LyraEmotion, parseLyraResponse(), BreathPhase, BreathState (+11 more) ### Community 438 - "Community 438" Cohesion: 0.24 @@ -2571,16 +2568,16 @@ Cohesion: 0.18 Nodes (10): _comment, DE, FR, GB, _meta, maxDomainsPerCountry, status, updatedAt (+2 more) ### Community 441 - "Community 441" -Cohesion: 0.32 -Nodes (23): abi, artifactName, output, runtimeFiles, libraries, appmodules::@6890427a1f51a3e7e1df, core::@1b9a7d546b295b7d0867, react_codegen_lottiereactnative::@0fa4dc904d7e359a99fb (+15 more) +Cohesion: 0.40 +Nodes (5): GameRatingStars(), sizeMap, StarRating(), StarRatingProps, StarSize ### Community 442 - "Community 442" Cohesion: 0.18 Nodes (11): error, common, back, cancel, confirm, continue, loading, ok (+3 more) ### Community 443 - "Community 443" -Cohesion: 0.20 -Nodes (9): App, Scene, Scene, View, SimpleURLFilterApp, RebreakMagicApp, app, security (+1 more) +Cohesion: 0.15 +Nodes (12): App, Scene, Scene, View, SimpleURLFilterApp, RebreakMagicApp, app, security (+4 more) ### Community 444 - "Community 444" Cohesion: 0.20 @@ -2603,8 +2600,8 @@ Cohesion: 0.20 Nodes (9): DE, FR, GB, _meta, maxDomainsPerCountry, status, updatedAt, version (+1 more) ### Community 449 - "Community 449" -Cohesion: 0.18 -Nodes (12): ReBreak Magic RE-Hardening Assessment & Plan, Admin-User kann alles aufheben (echter Schutz = Cooldown+Psychologie), Server-seitige Token-Revocation (Kern-Sicherheit im Backend), DNS-Token DPAPI-Verschlüsselung (Windows), Windows protection.json ACL-Härtung (DNS-Token-Schutz), Windows Service-Name-Bypass (sc.exe stop RebreakProtection), Session-Handoff 2026-06-07/08 (Magic-Windows E2E), DNS-Token 64-Zeichen-Bug (AdGuard hostname label too long) (+4 more) +Cohesion: 0.22 +Nodes (10): ReBreak Magic RE-Hardening Assessment & Plan, Admin-User kann alles aufheben (echter Schutz = Cooldown+Psychologie), Server-seitige Token-Revocation (Kern-Sicherheit im Backend), DNS-Token DPAPI-Verschlüsselung (Windows), Windows protection.json ACL-Härtung (DNS-Token-Schutz), Windows Service-Name-Bypass (sc.exe stop RebreakProtection), DNS-Token 64-Zeichen-Bug (AdGuard hostname label too long), ReBreak Magic Windows E2E-Flow (Download→Pair→Register→AdGuard-DNS) (+2 more) ### Community 450 - "Community 450" Cohesion: 0.36 @@ -3071,16 +3068,16 @@ Cohesion: 0.22 Nodes (8): backtraceGraph, commands, files, nodes, installers, paths, build, source ### Community 566 - "Community 566" -Cohesion: 0.12 -Nodes (16): CallRingPushPayload, ChatPushPayload, DeviceAddedPushPayload, devicePlatformLabel(), expo, getDisplayName(), sendCallRingPush(), sendChatPush() (+8 more) +Cohesion: 0.11 +Nodes (18): CallRingPushPayload, ChatPushPayload, DeviceAddedPushPayload, devicePlatformLabel(), ensureExpo(), ExpoInstance, ExpoModule, ExpoPushMessage (+10 more) ### Community 567 - "Community 567" Cohesion: 0.22 Nodes (7): AppAlert(), AppAlertMode, AppAlertProps, BaseProps, ConfirmProps, ErrorProps, SuccessProps ### Community 568 - "Community 568" -Cohesion: 0.14 -Nodes (13): formatTimestamp(), MessageRow(), GameCard(), GameCardProps, Props, st, CardType, GameHeader() (+5 more) +Cohesion: 0.40 +Nodes (3): Props, st, GamePickerGrid() ### Community 569 - "Community 569" Cohesion: 0.42 @@ -3207,8 +3204,8 @@ Cohesion: 0.29 Nodes (8): Maestro Profile Demographics Flow, Maestro Profile View-and-Edit Flow, Maestro View-Profile Flow, Maestro E2E Test Setup Guide, Maestro Selector Strategy (testID > text > coordinates), Maestro TestID TODO Backlog, Maestro SOS Urge Flow (Lyra chat + breathing), Maestro Start-Session Urge Flow ### Community 600 - "Community 600" -Cohesion: 0.21 -Nodes (13): Outlook OAuth DSGVO Review Memo, MS lacks 3rd-party token-revoke endpoint, OAuth preferred over App-Password (DSGVO datamin), Microsoft Basic-Auth Deprecation (Sep 2024), BFF OAuth Token-Exchange Pattern, Outlook OAuth2 Implementation Plan, Microsoft Outlook OAuth2 Mail Integration, ImapFlow XOAUTH2 Auth (+5 more) +Cohesion: 0.36 +Nodes (8): Outlook OAuth DSGVO Review Memo, MS lacks 3rd-party token-revoke endpoint, OAuth preferred over App-Password (DSGVO datamin), Microsoft Basic-Auth Deprecation (Sep 2024), BFF OAuth Token-Exchange Pattern, Outlook OAuth2 Implementation Plan, Microsoft Outlook OAuth2 Mail Integration, ImapFlow XOAUTH2 Auth ### Community 601 - "Community 601" Cohesion: 0.25 @@ -3219,16 +3216,16 @@ Cohesion: 0.43 Nodes (8): family_controls_error, permission_denied, title, fallback_body, fallback_label, retry_cta, retry_loading, settings_cta ### Community 603 - "Community 603" -Cohesion: 0.12 -Nodes (16): compilerOptions, allowSyntheticDefaultImports, baseUrl, forceConsistentCasingInFileNames, lib, module, moduleResolution, noEmit (+8 more) +Cohesion: 0.50 +Nodes (4): Binding, Bool, String, PreflightView ### Community 604 - "Community 604" Cohesion: 0.43 Nodes (8): family_controls_error, permission_denied, title, fallback_body, fallback_label, retry_cta, retry_loading, settings_cta ### Community 605 - "Community 605" -Cohesion: 0.18 -Nodes (12): CallNoteRow(), ChatBubble(), fmtSec(), MessageReaction, Props, useBubbleColors(), VoiceNoteBubble(), AnchorRect (+4 more) +Cohesion: 0.60 +Nodes (5): Maestro Flow: calls/incoming-call-screen, CallScreen (/call, useCallStore), PKPushRegistry Local-Var Dealloc Bug (Build 76), iOS VoIP PushKit + CallKit Incoming-Call Flow, Voice-Calls Debug State (2026-06-05) ### Community 606 - "Community 606" Cohesion: 0.43 @@ -3515,12 +3512,12 @@ Cohesion: 0.50 Nodes (3): info, author, version ### Community 686 - "Community 686" -Cohesion: 0.50 -Nodes (3): nav, download_app, login +Cohesion: 0.20 +Nodes (11): EMPTY_STATS, GamesScreen(), GameStat, GameStats, LastScore, GameCard(), GameCardProps, GAME_META (+3 more) ### Community 687 - "Community 687" -Cohesion: 0.50 -Nodes (3): nav, download_app, login +Cohesion: 0.17 +Nodes (7): CrisisLevel, SseEvents, streamSosLyra(), BenchMarker, BenchOnMetric, BenchSession, MarkerEntry ### Community 688 - "Community 688" Cohesion: 0.83 @@ -3539,8 +3536,8 @@ Cohesion: 0.50 Nodes (3): enabled, packages, prefabPath ### Community 696 - "Community 696" -Cohesion: 1.00 -Nodes (3): WizardStep, Color, StepIndicator +Cohesion: 0.50 +Nodes (5): InlineRatingDrawer(), s, s, SosFeedback, SosFeedbackModal() ### Community 704 - "Community 704" Cohesion: 0.67 @@ -3555,67 +3552,47 @@ Cohesion: 1.00 Nodes (3): Deploy Pipeline (deploy.sh, atomic .output-staging swap, pm2), WEBHOOK_MIGRATION_PLAN.md (standalone→Nitro endpoint), GitHub Webhook as Nitro API Endpoint (Trucko pattern) ### Community 863 - "Community 863" -Cohesion: 0.24 -Nodes (7): VALID_COUNTRIES, SupportedCountry, decideCuratedDomain(), getCuratedDomains(), suggestCuratedDomain(), PUBLIC_EMAIL_DOMAINS, isPublicEmailDomain() +Cohesion: 0.50 +Nodes (3): nav, download_app, login ### Community 864 - "Community 864" -Cohesion: 0.22 -Nodes (9): BreathPhase, BreathState, Chip, CHIP_SETS, ChipSet, BreathingCard(), BreathingDrawer(), Props (+1 more) +Cohesion: 0.50 +Nodes (4): Bool, String, EnrollmentStatus, DevicesState ### Community 865 - "Community 865" -Cohesion: 0.31 -Nodes (8): MailBlockedItem, MailResultsResponse, useMailResults(), ActivityItem(), domainFromEmail(), formatDate(), MailActivityLog(), Props +Cohesion: 0.25 +Nodes (7): currentProvider(), endpointForProvider(), listeners, TTS_PROVIDER_ENDPOINT, TTS_PROVIDER_LABEL, TtsProvider, PROVIDERS ### Community 866 - "Community 866" Cohesion: 0.28 Nodes (7): currentLlmProvider(), listeners, LLM_PROVIDER_LABEL, LlmProvider, useLlmProvider(), LlmProviderToggle(), PROVIDERS ### Community 867 - "Community 867" -Cohesion: 0.25 -Nodes (8): windows, bundle, active, externalBin, icon, targets, installMode, nsis - -### Community 868 - "Community 868" -Cohesion: 0.29 -Nodes (7): Maestro E2E Test-Schicht (Mobile App, ~20 Flows), Software-Verifikation Test-Nachweis v0 (Dok 05b, IEC 62304), Fehlende Traceability-Matrix (Tests↔Anforderungen↔Risiken), Vitest Unit-/Integrationstests (Backend, 21 Dateien), Maestro-Screenshot-Pipeline (marketing-tour-loggedin), Protection-Bypass-Fix everActiveHere-Flag, Session-Handoff 2026-06-08 Preview/Screenshots/Bug-Hunt - -### Community 869 - "Community 869" -Cohesion: 0.40 -Nodes (5): GameRatingStars(), sizeMap, StarRating(), StarRatingProps, StarSize - -### Community 870 - "Community 870" -Cohesion: 0.40 -Nodes (6): NanoMDM Server (mdm.rebreak.org), supervise-magic Go-CLI Binary, rebreak-magic-mac XcodeGen project.yml, Rebreak Magic Mac (Self-Bind Wizard), supervise-magic (Supervise without Reset), Mac+iPhone Self-Binding 6-Step Wizard - -### Community 871 - "Community 871" -Cohesion: 0.60 -Nodes (5): Maestro Flow: calls/incoming-call-screen, CallScreen (/call, useCallStore), PKPushRegistry Local-Var Dealloc Bug (Build 76), iOS VoIP PushKit + CallKit Incoming-Call Flow, Voice-Calls Debug State (2026-06-05) +Cohesion: 0.67 +Nodes (4): App-Preview Screenshots (/preview), capture-marketing.sh Maestro Pipeline, preview.vue Marketing Page, Maestro Flow: screens/01-onboarding (screenshot) ### Community 872 - "Community 872" Cohesion: 1.00 Nodes (3): getBestScore(), key(), saveBestScore() -### Community 873 - "Community 873" -Cohesion: 0.67 -Nodes (4): App-Preview Screenshots (/preview), capture-marketing.sh Maestro Pipeline, preview.vue Marketing Page, Maestro Flow: screens/01-onboarding (screenshot) - ## Knowledge Gaps -- **8557 isolated node(s):** `graphify (Knowledge-Graph)`, `bundleIdentifier`, `name`, `private`, `version` (+8552 more) +- **8560 isolated node(s):** `RECONNECT_DELAYS_MS`, `pool`, `MS_OAUTH_SCOPES`, `sessions`, `scanInFlight` (+8555 more) These have ≤1 connection - possible missing edges or undocumented components. -- **49 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. +- **46 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `useColors()` connect `i18n: Pricing Strings` to `Backend API Routes`, `Consent & Magic API Routes`, `App Root Layout & Shell`, `Community 18`, `Community 20`, `Community 21`, `Community 22`, `Community 27`, `Community 156`, `Community 29`, `Community 286`, `Community 426`, `Community 47`, `Community 431`, `Community 49`, `Community 53`, `Community 437`, `Community 568`, `Community 80`, `Community 605`, `Community 864`, `Community 865`?** - _High betweenness centrality (0.046) - this node is a cross-community bridge._ -- **Why does `usePrisma()` connect `Debug & Dev Tools` to `Community 32`, `Community 384`, `Community 257`, `Community 385`, `Community 34`, `Community 68`, `Backend Tests & Auth Routes`, `Android DNS Filter (Kotlin)`, `Community 269`, `Community 429`, `Community 431`, `Community 80`, `Community 48`, `Community 276`, `Community 181`, `Community 566`, `Community 62`, `Community 863`?** - _High betweenness centrality (0.029) - this node is a cross-community bridge._ -- **Why does `blocker` connect `i18n: Blocker/Activation Strings` to `Community 389`, `Community 69`, `i18n: Pricing Strings`, `Community 426`, `Community 47`, `App Root Layout & Shell`, `Community 49`, `Community 22`?** - _High betweenness centrality (0.029) - this node is a cross-community bridge._ +- **Why does `useColors()` connect `i18n: Pricing Strings` to `Backend API Routes`, `Consent & Magic API Routes`, `App Root Layout & Shell`, `Community 18`, `Community 20`, `Community 21`, `Community 22`, `Community 27`, `Community 156`, `Community 29`, `Community 286`, `Community 426`, `Community 686`, `Community 47`, `Community 49`, `Community 53`, `Community 437`, `Community 181`, `Community 696`, `Community 80`?** + _High betweenness centrality (0.042) - this node is a cross-community bridge._ +- **Why does `blocker` connect `i18n: Blocker/Activation Strings` to `Community 389`, `Community 69`, `i18n: Pricing Strings`, `Community 426`, `Community 47`, `Community 49`, `Community 22`?** + _High betweenness centrality (0.028) - this node is a cross-community bridge._ +- **Why does `usePrisma()` connect `Debug & Dev Tools` to `Community 32`, `Community 384`, `Community 34`, `Community 257`, `Community 385`, `Community 68`, `Backend Tests & Auth Routes`, `Community 39`, `Android DNS Filter (Kotlin)`, `Community 429`, `Community 431`, `Community 80`, `Community 48`, `Community 181`, `Community 566`, `Community 62`?** + _High betweenness centrality (0.023) - this node is a cross-community bridge._ - **Are the 2 inferred relationships involving `usePrisma()` (e.g. with `runRevoke()` and `requireUser()`) actually correct?** _`usePrisma()` has 2 INFERRED edges - model-reasoned connections that need verification._ -- **What connects `graphify (Knowledge-Graph)`, `bundleIdentifier`, `name` to the rest of the system?** - _8601 weakly-connected nodes found - possible documentation gaps or missing edges._ +- **What connects `RECONNECT_DELAYS_MS`, `pool`, `MS_OAUTH_SCOPES` to the rest of the system?** + _8604 weakly-connected nodes found - possible documentation gaps or missing edges._ - **Should `i18n: Blocker/Activation Strings` be split into smaller, more focused modules?** _Cohesion score 0.006825938566552901 - nodes in this community are weakly interconnected._ - **Should `i18n: Blocker/Activation Strings` be split into smaller, more focused modules?** diff --git a/graphify-out/graph.json b/graphify-out/graph.json index 6e3de45..918172c 100644 --- a/graphify-out/graph.json +++ b/graphify-out/graph.json @@ -137,32 +137,583 @@ ] }, "nodes": [ + { + "label": "index.mjs", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L1", + "id": "backend_imap_idle_index_mjs", + "community": 68, + "norm_label": "index.mjs" + }, + { + "label": "RECONNECT_DELAYS_MS", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L89", + "id": "imap_idle_index_reconnect_delays_ms", + "community": 68, + "norm_label": "reconnect_delays_ms" + }, + { + "label": "pool", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L94", + "id": "imap_idle_index_pool", + "community": 68, + "norm_label": "pool" + }, + { + "label": "updateConnectionError()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L96", + "id": "imap_idle_index_updateconnectionerror", + "community": 68, + "norm_label": "updateconnectionerror()" + }, + { + "label": "clearConnectionError()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L105", + "id": "imap_idle_index_clearconnectionerror", + "community": 68, + "norm_label": "clearconnectionerror()" + }, + { + "label": "updateIdleHeartbeat()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L114", + "id": "imap_idle_index_updateidleheartbeat", + "community": 68, + "norm_label": "updateidleheartbeat()" + }, + { + "label": "loadActiveConnections()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L128", + "id": "imap_idle_index_loadactiveconnections", + "community": 68, + "norm_label": "loadactiveconnections()" + }, + { + "label": "getKey()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L154", + "id": "imap_idle_index_getkey", + "community": 68, + "norm_label": "getkey()" + }, + { + "label": "decrypt()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L166", + "id": "imap_idle_index_decrypt", + "community": 68, + "norm_label": "decrypt()" + }, + { + "label": "encrypt()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L179", + "id": "imap_idle_index_encrypt", + "community": 68, + "norm_label": "encrypt()" + }, + { + "label": "MS_OAUTH_SCOPES", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L201", + "id": "imap_idle_index_ms_oauth_scopes", + "community": 68, + "norm_label": "ms_oauth_scopes" + }, + { + "label": "refreshAndSaveTokensDaemon()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L224", + "id": "imap_idle_index_refreshandsavetokensdaemon", + "community": 68, + "norm_label": "refreshandsavetokensdaemon()" + }, + { + "label": "refreshGoogleTokensDaemon()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L314", + "id": "imap_idle_index_refreshgoogletokensdaemon", + "community": 68, + "norm_label": "refreshgoogletokensdaemon()" + }, + { + "label": "markConnectionAuthBroken()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L395", + "id": "imap_idle_index_markconnectionauthbroken", + "community": 68, + "norm_label": "markconnectionauthbroken()" + }, + { + "label": "getCredentialsForConnection()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L423", + "id": "imap_idle_index_getcredentialsforconnection", + "community": 68, + "norm_label": "getcredentialsforconnection()" + }, + { + "label": "log()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L462", + "id": "imap_idle_index_log", + "community": 68, + "norm_label": "log()" + }, + { + "label": "logError()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L467", + "id": "imap_idle_index_logerror", + "community": 68, + "norm_label": "logerror()" + }, + { + "label": "isAuthError()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L476", + "id": "imap_idle_index_isautherror", + "community": 68, + "norm_label": "isautherror()" + }, + { + "label": "sessions", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L491", + "id": "imap_idle_index_sessions", + "community": 68, + "norm_label": "sessions" + }, + { + "label": "scanInFlight", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L510", + "id": "imap_idle_index_scaninflight", + "community": 68, + "norm_label": "scaninflight" + }, + { + "label": "coalescePending", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L511", + "id": "imap_idle_index_coalescepending", + "community": 68, + "norm_label": "coalescepending" + }, + { + "label": "triggerScan()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L526", + "id": "imap_idle_index_triggerscan", + "community": 68, + "norm_label": "triggerscan()" + }, + { + "label": "runSession()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L601", + "id": "imap_idle_index_runsession", + "community": 68, + "norm_label": "runsession()" + }, + { + "label": "startSession()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L887", + "id": "imap_idle_index_startsession", + "community": 68, + "norm_label": "startsession()" + }, + { + "label": "stopSession()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L898", + "id": "imap_idle_index_stopsession", + "community": 68, + "norm_label": "stopsession()" + }, + { + "label": "refreshConnections()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L911", + "id": "imap_idle_index_refreshconnections", + "community": 68, + "norm_label": "refreshconnections()" + }, + { + "label": "shutdown()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L959", + "id": "imap_idle_index_shutdown", + "community": 68, + "norm_label": "shutdown()" + }, + { + "label": "IMAP_SOCKET_ERROR_CODES", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L984", + "id": "imap_idle_index_imap_socket_error_codes", + "community": 68, + "norm_label": "imap_socket_error_codes" + }, + { + "label": "sleep()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L1036", + "id": "imap_idle_index_sleep", + "community": 68, + "norm_label": "sleep()" + }, + { + "label": "assertEnv()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L1040", + "id": "imap_idle_index_assertenv", + "community": 68, + "norm_label": "assertenv()" + }, + { + "label": "main()", + "file_type": "code", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L1054", + "id": "imap_idle_index_main", + "community": 68, + "norm_label": "main()" + }, + { + "label": "deploy-from-artifact.sh", + "file_type": "code", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L1", + "metadata": { + "language": "bash", + "kind": "file" + }, + "community": 662, + "norm_label": "deploy-from-artifact.sh", + "id": "scripts_deploy_from_artifact_sh" + }, + { + "label": "deploy-from-artifact.sh script", + "file_type": "code", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L1", + "metadata": { + "language": "bash", + "kind": "bash_entrypoint" + }, + "community": 662, + "norm_label": "deploy-from-artifact.sh script", + "id": "users_chahinebrini_mono_rebreak_monorepo_scripts_deploy_from_artifact_sh__entry" + }, + { + "label": "log()", + "file_type": "code", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L28", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "community": 662, + "norm_label": "log()", + "id": "scripts_deploy_from_artifact_log" + }, + { + "label": "log_err()", + "file_type": "code", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L29", + "metadata": { + "language": "bash", + "kind": "bash_function" + }, + "community": 662, + "norm_label": "log_err()", + "id": "scripts_deploy_from_artifact_log_err" + }, + { + "label": "PATH", + "file_type": "code", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L33", + "metadata": { + "language": "bash", + "kind": "code" + }, + "community": 662, + "norm_label": "path", + "id": "scripts_deploy_from_artifact_path" + }, + { + "label": "LockScreen.tsx", + "file_type": "code", + "source_file": "apps/rebreak-native/components/LockScreen.tsx", + "source_location": "L1", + "community": 20, + "norm_label": "lockscreen.tsx", + "id": "apps_rebreak_native_components_lockscreen_tsx" + }, + { + "label": "LockScreen()", + "file_type": "code", + "source_file": "apps/rebreak-native/components/LockScreen.tsx", + "source_location": "L36", + "community": 20, + "norm_label": "lockscreen()", + "id": "components_lockscreen_lockscreen" + }, + { + "label": "appLock.ts", + "file_type": "code", + "source_file": "apps/rebreak-native/stores/appLock.ts", + "source_location": "L1", + "community": 20, + "norm_label": "applock.ts", + "id": "apps_rebreak_native_stores_applock_ts" + }, + { + "label": "LocalAuthModule", + "file_type": "code", + "source_file": "apps/rebreak-native/stores/appLock.ts", + "source_location": "L11", + "community": 20, + "norm_label": "localauthmodule", + "id": "stores_applock_localauthmodule" + }, + { + "label": "AppLockState", + "file_type": "code", + "source_file": "apps/rebreak-native/stores/appLock.ts", + "source_location": "L40", + "community": 20, + "norm_label": "applockstate", + "id": "stores_applock_applockstate" + }, + { + "label": "useAppLockStore", + "file_type": "code", + "source_file": "apps/rebreak-native/stores/appLock.ts", + "source_location": "L58", + "community": 20, + "norm_label": "useapplockstore", + "id": "stores_applock_useapplockstore" + }, + { + "label": "nitro.config.ts", + "file_type": "code", + "source_file": "backend/nitro.config.ts", + "source_location": "L1", + "community": 768, + "norm_label": "nitro.config.ts", + "id": "backend_nitro_config_ts" + }, + { + "label": "scan-internal.post.ts", + "file_type": "code", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L1", + "community": 6, + "norm_label": "scan-internal.post.ts", + "id": "backend_server_api_mail_scan_internal_post_ts" + }, + { + "label": "scan.post.ts", + "file_type": "code", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L1", + "community": 6, + "norm_label": "scan.post.ts", + "id": "backend_server_api_mail_scan_post_ts" + }, + { + "label": "push.ts", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L1", + "community": 566, + "norm_label": "push.ts", + "id": "backend_server_services_push_ts" + }, + { + "label": "ExpoModule", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L25", + "community": 566, + "norm_label": "expomodule", + "id": "services_push_expomodule" + }, + { + "label": "ExpoInstance", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L26", + "community": 566, + "norm_label": "expoinstance", + "id": "services_push_expoinstance" + }, + { + "label": "ExpoPushMessage", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L27", + "community": 566, + "norm_label": "expopushmessage", + "id": "services_push_expopushmessage" + }, + { + "label": "ensureExpo()", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L32", + "community": 566, + "norm_label": "ensureexpo()", + "id": "services_push_ensureexpo" + }, + { + "label": "ChatPushPayload", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L42", + "community": 566, + "norm_label": "chatpushpayload", + "id": "services_push_chatpushpayload" + }, + { + "label": "sendChatPush()", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L58", + "community": 566, + "norm_label": "sendchatpush()", + "id": "services_push_sendchatpush" + }, + { + "label": "getDisplayName()", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L136", + "community": 566, + "norm_label": "getdisplayname()", + "id": "services_push_getdisplayname" + }, + { + "label": "truncatePreview()", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L148", + "community": 566, + "norm_label": "truncatepreview()", + "id": "services_push_truncatepreview" + }, + { + "label": "DeviceAddedPushPayload", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L153", + "community": 566, + "norm_label": "deviceaddedpushpayload", + "id": "services_push_deviceaddedpushpayload" + }, + { + "label": "devicePlatformLabel()", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L162", + "community": 566, + "norm_label": "deviceplatformlabel()", + "id": "services_push_deviceplatformlabel" + }, + { + "label": "sendDeviceAddedPush()", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L181", + "community": 566, + "norm_label": "senddeviceaddedpush()", + "id": "services_push_senddeviceaddedpush" + }, + { + "label": "CallRingPushPayload", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L246", + "community": 566, + "norm_label": "callringpushpayload", + "id": "services_push_callringpushpayload" + }, + { + "label": "sendCallRingPush()", + "file_type": "code", + "source_file": "backend/server/services/push.ts", + "source_location": "L273", + "community": 4, + "norm_label": "sendcallringpush()", + "id": "services_push_sendcallringpush" + }, { "label": "CLAUDE.md", "file_type": "document", "source_file": "CLAUDE.md", "source_location": "L1", - "id": "claude_md", "community": 874, - "norm_label": "claude.md" + "norm_label": "claude.md", + "id": "claude_md" }, { "label": "CLAUDE.md \u2014 rebreak-monorepo", "file_type": "document", "source_file": "CLAUDE.md", "source_location": "L1", - "id": "rebreak_monorepo_claude_claude_md_rebreak_monorepo", "community": 874, - "norm_label": "claude.md \u2014 rebreak-monorepo" + "norm_label": "claude.md \u2014 rebreak-monorepo", + "id": "rebreak_monorepo_claude_claude_md_rebreak_monorepo" }, { "label": "graphify (Knowledge-Graph)", "file_type": "document", "source_file": "CLAUDE.md", "source_location": "L5", - "id": "rebreak_monorepo_claude_graphify_knowledge_graph", "community": 874, - "norm_label": "graphify (knowledge-graph)" + "norm_label": "graphify (knowledge-graph)", + "id": "rebreak_monorepo_claude_graphify_knowledge_graph" }, { "label": "app.json", @@ -443,15 +994,6 @@ "norm_label": "ecosystem.config.js", "id": "ecosystem_config_js" }, - { - "label": "nitro.config.ts", - "file_type": "code", - "source_file": "backend/nitro.config.ts", - "source_location": "L1", - "community": 768, - "norm_label": "nitro.config.ts", - "id": "backend_nitro_config_ts" - }, { "label": "prisma.config.ts", "file_type": "code", @@ -877,7 +1419,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L1", - "community": 603, + "community": 10, "norm_label": "tsconfig.json", "id": "backend_tsconfig_json" }, @@ -886,7 +1428,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L2", - "community": 603, + "community": 10, "norm_label": "extends", "id": "backend_tsconfig_extends" }, @@ -895,7 +1437,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L3", - "community": 603, + "community": 10, "norm_label": "compileroptions", "id": "backend_tsconfig_compileroptions" }, @@ -904,7 +1446,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L4", - "community": 603, + "community": 10, "norm_label": "target", "id": "backend_tsconfig_compileroptions_target" }, @@ -913,7 +1455,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L5", - "community": 603, + "community": 10, "norm_label": "module", "id": "backend_tsconfig_compileroptions_module" }, @@ -922,7 +1464,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L6", - "community": 603, + "community": 10, "norm_label": "moduleresolution", "id": "backend_tsconfig_compileroptions_moduleresolution" }, @@ -931,7 +1473,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L7", - "community": 603, + "community": 10, "norm_label": "strict", "id": "backend_tsconfig_compileroptions_strict" }, @@ -940,7 +1482,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L8", - "community": 603, + "community": 10, "norm_label": "noemit", "id": "backend_tsconfig_compileroptions_noemit" }, @@ -949,7 +1491,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L9", - "community": 603, + "community": 10, "norm_label": "skiplibcheck", "id": "backend_tsconfig_compileroptions_skiplibcheck" }, @@ -958,7 +1500,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L10", - "community": 603, + "community": 10, "norm_label": "resolvejsonmodule", "id": "backend_tsconfig_compileroptions_resolvejsonmodule" }, @@ -967,7 +1509,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L11", - "community": 603, + "community": 10, "norm_label": "allowsyntheticdefaultimports", "id": "backend_tsconfig_compileroptions_allowsyntheticdefaultimports" }, @@ -976,7 +1518,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L12", - "community": 603, + "community": 10, "norm_label": "forceconsistentcasinginfilenames", "id": "backend_tsconfig_compileroptions_forceconsistentcasinginfilenames" }, @@ -985,7 +1527,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L13", - "community": 603, + "community": 10, "norm_label": "noimplicitreturns", "id": "backend_tsconfig_compileroptions_noimplicitreturns" }, @@ -994,7 +1536,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L14", - "community": 603, + "community": 10, "norm_label": "nofallthroughcasesinswitch", "id": "backend_tsconfig_compileroptions_nofallthroughcasesinswitch" }, @@ -1003,7 +1545,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L15", - "community": 603, + "community": 10, "norm_label": "useunknownincatchvariables", "id": "backend_tsconfig_compileroptions_useunknownincatchvariables" }, @@ -1012,7 +1554,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L16", - "community": 603, + "community": 10, "norm_label": "lib", "id": "backend_tsconfig_compileroptions_lib" }, @@ -1021,7 +1563,7 @@ "file_type": "code", "source_file": "backend/tsconfig.json", "source_location": "L17", - "community": 603, + "community": 10, "norm_label": "baseurl", "id": "backend_tsconfig_compileroptions_baseurl" }, @@ -1336,7 +1878,7 @@ "file_type": "code", "source_file": "backend/tests/profile/demographics.patch.test.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "demographics.patch.test.ts", "id": "backend_tests_profile_demographics_patch_test_ts" }, @@ -1345,7 +1887,7 @@ "file_type": "code", "source_file": "backend/tests/profile/demographics.patch.test.ts", "source_location": "L17", - "community": 429, + "community": 9, "norm_label": "mocks", "id": "profile_demographics_patch_test_mocks" }, @@ -1354,7 +1896,7 @@ "file_type": "code", "source_file": "backend/tests/profile/demographics.patch.test.ts", "source_location": "L40", - "community": 429, + "community": 9, "norm_label": "full_demographics", "id": "profile_demographics_patch_test_full_demographics" }, @@ -1363,7 +1905,7 @@ "file_type": "code", "source_file": "backend/tests/profile/install-and-banner.test.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "install-and-banner.test.ts", "id": "backend_tests_profile_install_and_banner_test_ts" }, @@ -1372,7 +1914,7 @@ "file_type": "code", "source_file": "backend/tests/profile/install-and-banner.test.ts", "source_location": "L8", - "community": 429, + "community": 9, "norm_label": "mocks", "id": "profile_install_and_banner_test_mocks" }, @@ -1525,7 +2067,7 @@ "file_type": "code", "source_file": "backend/tests/voice/quota.test.ts", "source_location": "L1", - "community": 48, + "community": 429, "norm_label": "quota.test.ts", "id": "backend_tests_voice_quota_test_ts" }, @@ -1534,7 +2076,7 @@ "file_type": "code", "source_file": "backend/tests/voice/quota.test.ts", "source_location": "L15", - "community": 48, + "community": 429, "norm_label": "mocks", "id": "voice_quota_test_mocks" }, @@ -1975,7 +2517,7 @@ "file_type": "code", "source_file": "backend/server/utils/useSupabase.ts", "source_location": "L1", - "community": 276, + "community": 32, "norm_label": "usesupabase.ts", "id": "backend_server_utils_usesupabase_ts" }, @@ -1984,7 +2526,7 @@ "file_type": "code", "source_file": "backend/server/utils/useSupabase.ts", "source_location": "L14", - "community": 276, + "community": 32, "norm_label": "getsupabaseurl()", "id": "utils_usesupabase_getsupabaseurl" }, @@ -1993,7 +2535,7 @@ "file_type": "code", "source_file": "backend/server/utils/useSupabase.ts", "source_location": "L23", - "community": 276, + "community": 32, "norm_label": "getanonkey()", "id": "utils_usesupabase_getanonkey" }, @@ -2002,7 +2544,7 @@ "file_type": "code", "source_file": "backend/server/utils/useSupabase.ts", "source_location": "L33", - "community": 276, + "community": 32, "norm_label": "getservicerolekey()", "id": "utils_usesupabase_getservicerolekey" }, @@ -2011,7 +2553,7 @@ "file_type": "code", "source_file": "backend/server/utils/useSupabase.ts", "source_location": "L42", - "community": 276, + "community": 32, "norm_label": "serversupabaseclient()", "id": "utils_usesupabase_serversupabaseclient" }, @@ -2020,7 +2562,7 @@ "file_type": "code", "source_file": "backend/server/utils/useSupabase.ts", "source_location": "L65", - "community": 276, + "community": 32, "norm_label": "serversupabaseservicerole()", "id": "utils_usesupabase_serversupabaseservicerole" }, @@ -2128,7 +2670,7 @@ "file_type": "code", "source_file": "backend/server/utils/plan-features.ts", "source_location": "L1", - "community": 276, + "community": 429, "norm_label": "plan", "id": "utils_plan_features_plan" }, @@ -2146,7 +2688,7 @@ "file_type": "code", "source_file": "backend/server/utils/plan-features.ts", "source_location": "L5", - "community": 48, + "community": 429, "norm_label": "voiceconfig", "id": "utils_plan_features_voiceconfig" }, @@ -2200,7 +2742,7 @@ "file_type": "code", "source_file": "backend/server/utils/cooldownToken.ts", "source_location": "L1", - "community": 9, + "community": 34, "norm_label": "cooldowntoken.ts", "id": "backend_server_utils_cooldowntoken_ts" }, @@ -2209,7 +2751,7 @@ "file_type": "code", "source_file": "backend/server/utils/cooldownToken.ts", "source_location": "L7", - "community": 9, + "community": 34, "norm_label": "getsecret()", "id": "utils_cooldowntoken_getsecret" }, @@ -2218,7 +2760,7 @@ "file_type": "code", "source_file": "backend/server/utils/cooldownToken.ts", "source_location": "L17", - "community": 9, + "community": 34, "norm_label": "cooldowntokenpayload", "id": "utils_cooldowntoken_cooldowntokenpayload" }, @@ -2227,7 +2769,7 @@ "file_type": "code", "source_file": "backend/server/utils/cooldownToken.ts", "source_location": "L30", - "community": 9, + "community": 34, "norm_label": "signcooldowntoken()", "id": "utils_cooldowntoken_signcooldowntoken" }, @@ -2236,7 +2778,7 @@ "file_type": "code", "source_file": "backend/server/utils/cooldownToken.ts", "source_location": "L53", - "community": 9, + "community": 34, "norm_label": "verifycooldowntoken()", "id": "utils_cooldowntoken_verifycooldowntoken" }, @@ -2245,7 +2787,7 @@ "file_type": "code", "source_file": "backend/server/utils/cooldownToken.ts", "source_location": "L81", - "community": 9, + "community": 34, "norm_label": "generatejti()", "id": "utils_cooldowntoken_generatejti" }, @@ -2254,7 +2796,7 @@ "file_type": "code", "source_file": "backend/server/utils/downgrade-reconciliation.ts", "source_location": "L1", - "community": 276, + "community": 429, "norm_label": "downgrade-reconciliation.ts", "id": "backend_server_utils_downgrade_reconciliation_ts" }, @@ -2263,7 +2805,7 @@ "file_type": "code", "source_file": "backend/server/utils/downgrade-reconciliation.ts", "source_location": "L21", - "community": 276, + "community": 429, "norm_label": "rundowngradereconciliation()", "id": "utils_downgrade_reconciliation_rundowngradereconciliation" }, @@ -2272,7 +2814,7 @@ "file_type": "code", "source_file": "backend/server/utils/downgrade-reconciliation.ts", "source_location": "L74", - "community": 276, + "community": 429, "norm_label": "reconcilemailaccounts()", "id": "utils_downgrade_reconciliation_reconcilemailaccounts" }, @@ -2281,7 +2823,7 @@ "file_type": "code", "source_file": "backend/server/utils/downgrade-reconciliation.ts", "source_location": "L116", - "community": 276, + "community": 429, "norm_label": "reconcileprotecteddevices()", "id": "utils_downgrade_reconciliation_reconcileprotecteddevices" }, @@ -2290,7 +2832,7 @@ "file_type": "code", "source_file": "backend/server/utils/downgrade-reconciliation.ts", "source_location": "L133", - "community": 276, + "community": 429, "norm_label": "reconcileupgrade()", "id": "utils_downgrade_reconciliation_reconcileupgrade" }, @@ -2299,7 +2841,7 @@ "file_type": "code", "source_file": "backend/server/utils/downgrade-reconciliation.ts", "source_location": "L170", - "community": 276, + "community": 429, "norm_label": "triggerfinalscanforconnection()", "id": "utils_downgrade_reconciliation_triggerfinalscanforconnection" }, @@ -2335,7 +2877,7 @@ "file_type": "code", "source_file": "backend/server/utils/detect-lang.ts", "source_location": "L11", - "community": 48, + "community": 429, "norm_label": "detectlang()", "id": "utils_detect_lang_detectlang" }, @@ -2614,7 +3156,7 @@ "file_type": "code", "source_file": "backend/server/utils/scoring.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "scoring.ts", "id": "backend_server_utils_scoring_ts" }, @@ -2749,7 +3291,7 @@ "file_type": "code", "source_file": "backend/server/utils/imap-providers.ts", "source_location": "L96", - "community": 429, + "community": 6, "norm_label": "detectimapprovider()", "id": "utils_imap_providers_detectimapprovider" }, @@ -2767,7 +3309,7 @@ "file_type": "code", "source_file": "backend/server/utils/imap-providers.ts", "source_location": "L136", - "community": 429, + "community": 6, "norm_label": "detectsmtpprovider()", "id": "utils_imap_providers_detectsmtpprovider" }, @@ -2830,7 +3372,7 @@ "file_type": "code", "source_file": "backend/server/utils/public-email-domains.ts", "source_location": "L51", - "community": 863, + "community": 4, "norm_label": "ispublicemaildomain()", "id": "utils_public_email_domains_ispublicemaildomain" }, @@ -2929,7 +3471,7 @@ "file_type": "code", "source_file": "backend/server/lib/lyraPostCatalog.ts", "source_location": "L1", - "community": 269, + "community": 39, "norm_label": "lyrapostcatalog.ts", "id": "backend_server_lib_lyrapostcatalog_ts" }, @@ -2938,7 +3480,7 @@ "file_type": "code", "source_file": "backend/server/lib/lyraPostCatalog.ts", "source_location": "L16", - "community": 269, + "community": 39, "norm_label": "lyraposttopic", "id": "lib_lyrapostcatalog_lyraposttopic" }, @@ -2947,7 +3489,7 @@ "file_type": "code", "source_file": "backend/server/lib/lyraPostCatalog.ts", "source_location": "L18", - "community": 269, + "community": 39, "norm_label": "lyraposttemplate", "id": "lib_lyrapostcatalog_lyraposttemplate" }, @@ -2956,7 +3498,7 @@ "file_type": "code", "source_file": "backend/server/lib/lyraPostCatalog.ts", "source_location": "L23", - "community": 269, + "community": 39, "norm_label": "lyra_post_catalog", "id": "lib_lyrapostcatalog_lyra_post_catalog" }, @@ -2965,7 +3507,7 @@ "file_type": "code", "source_file": "backend/server/lib/lyraPostCatalog.ts", "source_location": "L56", - "community": 269, + "community": 39, "norm_label": "pickrandomtemplate()", "id": "lib_lyrapostcatalog_pickrandomtemplate" }, @@ -3145,7 +3687,7 @@ "file_type": "code", "source_file": "backend/server/db/devices.ts", "source_location": "L201", - "community": 429, + "community": 9, "norm_label": "listuserdevices()", "id": "db_devices_listuserdevices" }, @@ -3154,7 +3696,7 @@ "file_type": "code", "source_file": "backend/server/db/devices.ts", "source_location": "L211", - "community": 32, + "community": 9, "norm_label": "finduserdevice()", "id": "db_devices_finduserdevice" }, @@ -3172,7 +3714,7 @@ "file_type": "code", "source_file": "backend/server/db/devices.ts", "source_location": "L261", - "community": 32, + "community": 9, "norm_label": "registerdevice()", "id": "db_devices_registerdevice" }, @@ -3442,7 +3984,7 @@ "file_type": "code", "source_file": "backend/server/db/scores.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "scores.ts", "id": "backend_server_db_scores_ts" }, @@ -3451,7 +3993,7 @@ "file_type": "code", "source_file": "backend/server/db/scores.ts", "source_location": "L3", - "community": 4, + "community": 39, "norm_label": "scoreeventtype", "id": "db_scores_scoreeventtype" }, @@ -3460,7 +4002,7 @@ "file_type": "code", "source_file": "backend/server/db/scores.ts", "source_location": "L12", - "community": 4, + "community": 39, "norm_label": "points", "id": "db_scores_points" }, @@ -3469,7 +4011,7 @@ "file_type": "code", "source_file": "backend/server/db/scores.ts", "source_location": "L22", - "community": 4, + "community": 39, "norm_label": "awardpoints()", "id": "db_scores_awardpoints" }, @@ -3478,7 +4020,7 @@ "file_type": "code", "source_file": "backend/server/db/scores.ts", "source_location": "L36", - "community": 4, + "community": 39, "norm_label": "getuserscore()", "id": "db_scores_getuserscore" }, @@ -3487,7 +4029,7 @@ "file_type": "code", "source_file": "backend/server/db/scores.ts", "source_location": "L44", - "community": 4, + "community": 39, "norm_label": "getrecentscoreevents()", "id": "db_scores_getrecentscoreevents" }, @@ -3496,7 +4038,7 @@ "file_type": "code", "source_file": "backend/server/db/scores.ts", "source_location": "L54", - "community": 4, + "community": 39, "norm_label": "getleaderboard()", "id": "db_scores_getleaderboard" }, @@ -3505,7 +4047,7 @@ "file_type": "code", "source_file": "backend/server/db/streak.ts", "source_location": "L1", - "community": 34, + "community": 4, "norm_label": "streak.ts", "id": "backend_server_db_streak_ts" }, @@ -3514,7 +4056,7 @@ "file_type": "code", "source_file": "backend/server/db/streak.ts", "source_location": "L3", - "community": 34, + "community": 4, "norm_label": "getactivestreak()", "id": "db_streak_getactivestreak" }, @@ -3523,7 +4065,7 @@ "file_type": "code", "source_file": "backend/server/db/streak.ts", "source_location": "L10", - "community": 34, + "community": 4, "norm_label": "upsertstreak()", "id": "db_streak_upsertstreak" }, @@ -3532,7 +4074,7 @@ "file_type": "code", "source_file": "backend/server/db/streak.ts", "source_location": "L54", - "community": 34, + "community": 4, "norm_label": "resetstreak()", "id": "db_streak_resetstreak" }, @@ -3541,7 +4083,7 @@ "file_type": "code", "source_file": "backend/server/db/streak.ts", "source_location": "L71", - "community": 34, + "community": 4, "norm_label": "updatestreaksavings()", "id": "db_streak_updatestreaksavings" }, @@ -3550,7 +4092,7 @@ "file_type": "code", "source_file": "backend/server/db/streak.ts", "source_location": "L79", - "community": 34, + "community": 4, "norm_label": "deleteuserstreaks()", "id": "db_streak_deleteuserstreaks" }, @@ -3559,7 +4101,7 @@ "file_type": "code", "source_file": "backend/server/db/streak.ts", "source_location": "L86", - "community": 34, + "community": 4, "norm_label": "addstreakevent()", "id": "db_streak_addstreakevent" }, @@ -3568,7 +4110,7 @@ "file_type": "code", "source_file": "backend/server/db/streak.ts", "source_location": "L97", - "community": 34, + "community": 4, "norm_label": "getstreakevents()", "id": "db_streak_getstreakevents" }, @@ -3622,7 +4164,7 @@ "file_type": "code", "source_file": "backend/server/db/notifications.ts", "source_location": "L15", - "community": 431, + "community": 181, "norm_label": "getnotifications()", "id": "db_notifications_getnotifications" }, @@ -3631,7 +4173,7 @@ "file_type": "code", "source_file": "backend/server/db/notifications.ts", "source_location": "L31", - "community": 431, + "community": 181, "norm_label": "markallread()", "id": "db_notifications_markallread" }, @@ -3640,7 +4182,7 @@ "file_type": "code", "source_file": "backend/server/db/notifications.ts", "source_location": "L39", - "community": 431, + "community": 181, "norm_label": "deletenotification()", "id": "db_notifications_deletenotification" }, @@ -3649,7 +4191,7 @@ "file_type": "code", "source_file": "backend/server/db/notifications.ts", "source_location": "L46", - "community": 431, + "community": 181, "norm_label": "deleteoldnotifications()", "id": "db_notifications_deleteoldnotifications" }, @@ -3685,7 +4227,7 @@ "file_type": "code", "source_file": "backend/server/db/protectedDevices.ts", "source_location": "L35", - "community": 32, + "community": 80, "norm_label": "listprotecteddevices()", "id": "db_protecteddevices_listprotecteddevices" }, @@ -3757,7 +4299,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "community.ts", "id": "backend_server_db_community_ts" }, @@ -3766,7 +4308,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L5", - "community": 4, + "community": 39, "norm_label": "getposts()", "id": "db_community_getposts" }, @@ -3775,7 +4317,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L236", - "community": 4, + "community": 39, "norm_label": "getpostbyid()", "id": "db_community_getpostbyid" }, @@ -3784,7 +4326,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L254", - "community": 269, + "community": 39, "norm_label": "createpost()", "id": "db_community_createpost" }, @@ -3802,7 +4344,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L295", - "community": 4, + "community": 39, "norm_label": "getpostlike()", "id": "db_community_getpostlike" }, @@ -3811,7 +4353,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L303", - "community": 4, + "community": 39, "norm_label": "setpostlike()", "id": "db_community_setpostlike" }, @@ -3820,7 +4362,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L316", - "community": 4, + "community": 39, "norm_label": "deletepostlike()", "id": "db_community_deletepostlike" }, @@ -3829,7 +4371,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L323", - "community": 4, + "community": 39, "norm_label": "countpostlikes()", "id": "db_community_countpostlikes" }, @@ -3838,7 +4380,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L335", - "community": 4, + "community": 39, "norm_label": "syncpostlikecounts()", "id": "db_community_syncpostlikecounts" }, @@ -3847,7 +4389,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L349", - "community": 4, + "community": 39, "norm_label": "getcommentsbypost()", "id": "db_community_getcommentsbypost" }, @@ -3856,7 +4398,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L380", - "community": 4, + "community": 39, "norm_label": "createcomment()", "id": "db_community_createcomment" }, @@ -3865,7 +4407,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L408", - "community": 4, + "community": 39, "norm_label": "getcommentlike()", "id": "db_community_getcommentlike" }, @@ -3874,7 +4416,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L415", - "community": 4, + "community": 39, "norm_label": "createcommentlike()", "id": "db_community_createcommentlike" }, @@ -3883,7 +4425,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L420", - "community": 4, + "community": 39, "norm_label": "deletecommentlike()", "id": "db_community_deletecommentlike" }, @@ -3892,7 +4434,7 @@ "file_type": "code", "source_file": "backend/server/db/community.ts", "source_location": "L432", - "community": 4, + "community": 39, "norm_label": "synccommentlikecount()", "id": "db_community_synccommentlikecount" }, @@ -3919,7 +4461,7 @@ "file_type": "code", "source_file": "backend/server/db/curatedDomains.ts", "source_location": "L1", - "community": 863, + "community": 4, "norm_label": "curateddomains.ts", "id": "backend_server_db_curateddomains_ts" }, @@ -3928,7 +4470,7 @@ "file_type": "code", "source_file": "backend/server/db/curatedDomains.ts", "source_location": "L9", - "community": 863, + "community": 4, "norm_label": "suggestcurateddomain()", "id": "db_curateddomains_suggestcurateddomain" }, @@ -3937,7 +4479,7 @@ "file_type": "code", "source_file": "backend/server/db/curatedDomains.ts", "source_location": "L48", - "community": 863, + "community": 4, "norm_label": "getcurateddomains()", "id": "db_curateddomains_getcurateddomains" }, @@ -3946,7 +4488,7 @@ "file_type": "code", "source_file": "backend/server/db/curatedDomains.ts", "source_location": "L74", - "community": 863, + "community": 4, "norm_label": "decidecurateddomain()", "id": "db_curateddomains_decidecurateddomain" }, @@ -3973,7 +4515,7 @@ "file_type": "code", "source_file": "backend/server/db/chat.ts", "source_location": "L15", - "community": 4, + "community": 181, "norm_label": "createchatmessage()", "id": "db_chat_createchatmessage" }, @@ -4045,7 +4587,7 @@ "file_type": "code", "source_file": "backend/server/db/cooldown.ts", "source_location": "L1", - "community": 9, + "community": 34, "norm_label": "cooldown.ts", "id": "backend_server_db_cooldown_ts" }, @@ -4054,7 +4596,7 @@ "file_type": "code", "source_file": "backend/server/db/cooldown.ts", "source_location": "L8", - "community": 9, + "community": 34, "norm_label": "getactivecooldown()", "id": "db_cooldown_getactivecooldown" }, @@ -4063,7 +4605,7 @@ "file_type": "code", "source_file": "backend/server/db/cooldown.ts", "source_location": "L20", - "community": 9, + "community": 34, "norm_label": "createcooldown()", "id": "db_cooldown_createcooldown" }, @@ -4072,7 +4614,7 @@ "file_type": "code", "source_file": "backend/server/db/cooldown.ts", "source_location": "L37", - "community": 9, + "community": 34, "norm_label": "resolvecooldown()", "id": "db_cooldown_resolvecooldown" }, @@ -4081,7 +4623,7 @@ "file_type": "code", "source_file": "backend/server/db/cooldown.ts", "source_location": "L45", - "community": 9, + "community": 34, "norm_label": "cancelcooldown()", "id": "db_cooldown_cancelcooldown" }, @@ -4108,7 +4650,7 @@ "file_type": "code", "source_file": "backend/server/db/domains.ts", "source_location": "L24", - "community": 429, + "community": 431, "norm_label": "getusercustomdomains()", "id": "db_domains_getusercustomdomains" }, @@ -4117,7 +4659,7 @@ "file_type": "code", "source_file": "backend/server/db/domains.ts", "source_location": "L52", - "community": 429, + "community": 431, "norm_label": "countactivecustomdomains()", "id": "db_domains_countactivecustomdomains" }, @@ -4126,7 +4668,7 @@ "file_type": "code", "source_file": "backend/server/db/domains.ts", "source_location": "L85", - "community": 429, + "community": 431, "norm_label": "addusercustomdomain()", "id": "db_domains_addusercustomdomain" }, @@ -4135,7 +4677,7 @@ "file_type": "code", "source_file": "backend/server/db/domains.ts", "source_location": "L107", - "community": 431, + "community": 6, "norm_label": "getcustommaildisplaynames()", "id": "db_domains_getcustommaildisplaynames" }, @@ -4144,7 +4686,7 @@ "file_type": "code", "source_file": "backend/server/db/domains.ts", "source_location": "L131", - "community": 431, + "community": 6, "norm_label": "getmaildisplaynamepatterns()", "id": "db_domains_getmaildisplaynamepatterns" }, @@ -4180,7 +4722,7 @@ "file_type": "code", "source_file": "backend/server/db/domains.ts", "source_location": "L206", - "community": 431, + "community": 4, "norm_label": "submitdomainforreview()", "id": "db_domains_submitdomainforreview" }, @@ -4189,7 +4731,7 @@ "file_type": "code", "source_file": "backend/server/db/domains.ts", "source_location": "L241", - "community": 431, + "community": 4, "norm_label": "castdomainvote()", "id": "db_domains_castdomainvote" }, @@ -4288,7 +4830,7 @@ "file_type": "code", "source_file": "backend/server/db/urge.ts", "source_location": "L1", - "community": 34, + "community": 4, "norm_label": "urge.ts", "id": "backend_server_db_urge_ts" }, @@ -4297,7 +4839,7 @@ "file_type": "code", "source_file": "backend/server/db/urge.ts", "source_location": "L3", - "community": 34, + "community": 4, "norm_label": "emotion", "id": "db_urge_emotion" }, @@ -4306,7 +4848,7 @@ "file_type": "code", "source_file": "backend/server/db/urge.ts", "source_location": "L5", - "community": 34, + "community": 4, "norm_label": "getrecenturgelogs()", "id": "db_urge_getrecenturgelogs" }, @@ -4315,7 +4857,7 @@ "file_type": "code", "source_file": "backend/server/db/urge.ts", "source_location": "L21", - "community": 34, + "community": 4, "norm_label": "createurgelog()", "id": "db_urge_createurgelog" }, @@ -4324,7 +4866,7 @@ "file_type": "code", "source_file": "backend/server/db/urge.ts", "source_location": "L40", - "community": 34, + "community": 4, "norm_label": "deleteuserurgelogs()", "id": "db_urge_deleteuserurgelogs" }, @@ -4405,7 +4947,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "profile.ts", "id": "backend_server_db_profile_ts" }, @@ -4414,7 +4956,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L3", - "community": 429, + "community": 9, "norm_label": "getprofile()", "id": "db_profile_getprofile" }, @@ -4423,7 +4965,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L8", - "community": 429, + "community": 9, "norm_label": "updateprofile()", "id": "db_profile_updateprofile" }, @@ -4441,7 +4983,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L47", - "community": 429, + "community": 9, "norm_label": "onboardingstep", "id": "db_profile_onboardingstep" }, @@ -4450,7 +4992,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L64", - "community": 429, + "community": 9, "norm_label": "demographicsfields", "id": "db_profile_demographicsfields" }, @@ -4459,7 +5001,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L78", - "community": 429, + "community": 9, "norm_label": "demographicspatch", "id": "db_profile_demographicspatch" }, @@ -4468,7 +5010,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L84", - "community": 429, + "community": 9, "norm_label": "updatedemographics()", "id": "db_profile_updatedemographics" }, @@ -4477,7 +5019,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L120", - "community": 429, + "community": 9, "norm_label": "withdrawdemographics()", "id": "db_profile_withdrawdemographics" }, @@ -4495,7 +5037,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L186", - "community": 429, + "community": 9, "norm_label": "tryawardprotrial()", "id": "db_profile_tryawardprotrial" }, @@ -4504,7 +5046,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L246", - "community": 429, + "community": 9, "norm_label": "allowed_lyra_voice_ids", "id": "db_profile_allowed_lyra_voice_ids" }, @@ -4513,7 +5055,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L252", - "community": 429, + "community": 9, "norm_label": "lyravoiceid", "id": "db_profile_lyravoiceid" }, @@ -4522,7 +5064,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L254", - "community": 429, + "community": 9, "norm_label": "isallowedlyravoiceid()", "id": "db_profile_isallowedlyravoiceid" }, @@ -4531,7 +5073,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L269", - "community": 429, + "community": 9, "norm_label": "dismissdigabanner()", "id": "db_profile_dismissdigabanner" }, @@ -4540,7 +5082,7 @@ "file_type": "code", "source_file": "backend/server/db/profile.ts", "source_location": "L277", - "community": 429, + "community": 9, "norm_label": "recordinstallevent()", "id": "db_profile_recordinstallevent" }, @@ -4621,7 +5163,7 @@ "file_type": "code", "source_file": "backend/server/db/voiceQuota.ts", "source_location": "L1", - "community": 48, + "community": 429, "norm_label": "voicequota.ts", "id": "backend_server_db_voicequota_ts" }, @@ -4630,7 +5172,7 @@ "file_type": "code", "source_file": "backend/server/db/voiceQuota.ts", "source_location": "L15", - "community": 48, + "community": 429, "norm_label": "todayutcmidnight()", "id": "db_voicequota_todayutcmidnight" }, @@ -4639,7 +5181,7 @@ "file_type": "code", "source_file": "backend/server/db/voiceQuota.ts", "source_location": "L26", - "community": 48, + "community": 429, "norm_label": "getremainingvoicequota()", "id": "db_voicequota_getremainingvoicequota" }, @@ -4648,7 +5190,7 @@ "file_type": "code", "source_file": "backend/server/db/voiceQuota.ts", "source_location": "L76", - "community": 48, + "community": 429, "norm_label": "consumevoicequota()", "id": "db_voicequota_consumevoicequota" }, @@ -4657,7 +5199,7 @@ "file_type": "code", "source_file": "backend/server/db/voiceQuota.ts", "source_location": "L102", - "community": 48, + "community": 429, "norm_label": "estimateaudioseconds()", "id": "db_voicequota_estimateaudioseconds" }, @@ -4666,7 +5208,7 @@ "file_type": "code", "source_file": "backend/server/db/social.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "social.ts", "id": "backend_server_db_social_ts" }, @@ -4675,7 +5217,7 @@ "file_type": "code", "source_file": "backend/server/db/social.ts", "source_location": "L3", - "community": 4, + "community": 39, "norm_label": "getfollowrelation()", "id": "db_social_getfollowrelation" }, @@ -4684,7 +5226,7 @@ "file_type": "code", "source_file": "backend/server/db/social.ts", "source_location": "L13", - "community": 4, + "community": 39, "norm_label": "createfollow()", "id": "db_social_createfollow" }, @@ -4693,7 +5235,7 @@ "file_type": "code", "source_file": "backend/server/db/social.ts", "source_location": "L26", - "community": 4, + "community": 39, "norm_label": "deletefollow()", "id": "db_social_deletefollow" }, @@ -4702,7 +5244,7 @@ "file_type": "code", "source_file": "backend/server/db/social.ts", "source_location": "L49", - "community": 4, + "community": 39, "norm_label": "getfollowingset()", "id": "db_social_getfollowingset" }, @@ -4711,7 +5253,7 @@ "file_type": "code", "source_file": "backend/server/db/social.ts", "source_location": "L62", - "community": 4, + "community": 39, "norm_label": "getprofilewithfollowers()", "id": "db_social_getprofilewithfollowers" }, @@ -4846,7 +5388,7 @@ "file_type": "code", "source_file": "backend/server/db/mail.ts", "source_location": "L55", - "community": 429, + "community": 6, "norm_label": "countmailconnections()", "id": "db_mail_countmailconnections" }, @@ -4855,7 +5397,7 @@ "file_type": "code", "source_file": "backend/server/db/mail.ts", "source_location": "L61", - "community": 429, + "community": 6, "norm_label": "upsertmailconnection()", "id": "db_mail_upsertmailconnection" }, @@ -4864,7 +5406,7 @@ "file_type": "code", "source_file": "backend/server/db/mail.ts", "source_location": "L97", - "community": 6, + "community": 4, "norm_label": "deletemailconnection()", "id": "db_mail_deletemailconnection" }, @@ -4873,7 +5415,7 @@ "file_type": "code", "source_file": "backend/server/db/mail.ts", "source_location": "L107", - "community": 6, + "community": 4, "norm_label": "deleteallmailconnections()", "id": "db_mail_deleteallmailconnections" }, @@ -5071,7 +5613,7 @@ "file_type": "code", "source_file": "backend/server/api/curated-domains/suggest.post.ts", "source_location": "L1", - "community": 863, + "community": 4, "norm_label": "suggest.post.ts", "id": "backend_server_api_curated_domains_suggest_post_ts" }, @@ -5080,7 +5622,7 @@ "file_type": "code", "source_file": "backend/server/api/curated-domains/suggest.post.ts", "source_location": "L7", - "community": 863, + "community": 4, "norm_label": "valid_countries", "id": "curated_domains_suggest_post_valid_countries" }, @@ -5089,7 +5631,7 @@ "file_type": "code", "source_file": "backend/server/api/url-filter/blocklist.bin.get.ts", "source_location": "L1", - "community": 429, + "community": 431, "norm_label": "blocklist.bin.get.ts", "id": "backend_server_api_url_filter_blocklist_bin_get_ts" }, @@ -5098,7 +5640,7 @@ "file_type": "code", "source_file": "backend/server/api/url-filter/blocklist.bin.get.ts", "source_location": "L86", - "community": 429, + "community": 431, "norm_label": "mergesortedhashbuffers()", "id": "url_filter_blocklist_bin_get_mergesortedhashbuffers" }, @@ -5125,7 +5667,7 @@ "file_type": "code", "source_file": "backend/server/api/chat/message.post.ts", "source_location": "L1", - "community": 4, + "community": 181, "norm_label": "message.post.ts", "id": "backend_server_api_chat_message_post_ts" }, @@ -5278,7 +5820,7 @@ "file_type": "code", "source_file": "backend/server/api/cooldown/request.post.ts", "source_location": "L1", - "community": 9, + "community": 34, "norm_label": "request.post.ts", "id": "backend_server_api_cooldown_request_post_ts" }, @@ -5287,7 +5829,7 @@ "file_type": "code", "source_file": "backend/server/api/cooldown/status.get.ts", "source_location": "L1", - "community": 9, + "community": 34, "norm_label": "status.get.ts", "id": "backend_server_api_cooldown_status_get_ts" }, @@ -5296,7 +5838,7 @@ "file_type": "code", "source_file": "backend/server/api/cooldown/cancel.post.ts", "source_location": "L1", - "community": 9, + "community": 34, "norm_label": "cancel.post.ts", "id": "backend_server_api_cooldown_cancel_post_ts" }, @@ -5323,7 +5865,7 @@ "file_type": "code", "source_file": "backend/server/api/auth/me.patch.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "me.patch.ts", "id": "backend_server_api_auth_me_patch_ts" }, @@ -5332,7 +5874,7 @@ "file_type": "code", "source_file": "backend/server/api/streak/index.get.ts", "source_location": "L1", - "community": 34, + "community": 4, "norm_label": "index.get.ts", "id": "backend_server_api_streak_index_get_ts" }, @@ -5341,7 +5883,7 @@ "file_type": "code", "source_file": "backend/server/api/streak/index.post.ts", "source_location": "L1", - "community": 34, + "community": 4, "norm_label": "index.post.ts", "id": "backend_server_api_streak_index_post_ts" }, @@ -5350,7 +5892,7 @@ "file_type": "code", "source_file": "backend/server/api/streak/events.get.ts", "source_location": "L1", - "community": 34, + "community": 4, "norm_label": "events.get.ts", "id": "backend_server_api_streak_events_get_ts" }, @@ -5359,7 +5901,7 @@ "file_type": "code", "source_file": "backend/server/api/streak/index.patch.ts", "source_location": "L1", - "community": 34, + "community": 4, "norm_label": "index.patch.ts", "id": "backend_server_api_streak_index_patch_ts" }, @@ -5377,7 +5919,7 @@ "file_type": "code", "source_file": "backend/server/api/custom-domains/index.get.ts", "source_location": "L1", - "community": 429, + "community": 431, "norm_label": "index.get.ts", "id": "backend_server_api_custom_domains_index_get_ts" }, @@ -5386,7 +5928,7 @@ "file_type": "code", "source_file": "backend/server/api/custom-domains/index.post.ts", "source_location": "L1", - "community": 429, + "community": 431, "norm_label": "index.post.ts", "id": "backend_server_api_custom_domains_index_post_ts" }, @@ -5395,7 +5937,7 @@ "file_type": "code", "source_file": "backend/server/api/custom-domains/index.post.ts", "source_location": "L39", - "community": 429, + "community": 431, "norm_label": "resolveresult", "id": "custom_domains_index_post_resolveresult" }, @@ -5413,7 +5955,7 @@ "file_type": "code", "source_file": "backend/server/api/custom-domains/suggest.post.ts", "source_location": "L1", - "community": 863, + "community": 4, "norm_label": "suggest.post.ts", "id": "backend_server_api_custom_domains_suggest_post_ts" }, @@ -5422,7 +5964,7 @@ "file_type": "code", "source_file": "backend/server/api/custom-domains/suggest.post.ts", "source_location": "L7", - "community": 863, + "community": 4, "norm_label": "supportedcountry", "id": "custom_domains_suggest_post_supportedcountry" }, @@ -5431,25 +5973,16 @@ "file_type": "code", "source_file": "backend/server/api/custom-domains/[id]/submit.post.ts", "source_location": "L1", - "community": 429, + "community": 4, "norm_label": "submit.post.ts", "id": "backend_server_api_custom_domains_id_submit_post_ts" }, - { - "label": "scan-internal.post.ts", - "file_type": "code", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L1", - "community": 6, - "norm_label": "scan-internal.post.ts", - "id": "backend_server_api_mail_scan_internal_post_ts" - }, { "label": "proxy-config.get.ts", "file_type": "code", "source_file": "backend/server/api/mail/proxy-config.get.ts", "source_location": "L1", - "community": 429, + "community": 6, "norm_label": "proxy-config.get.ts", "id": "backend_server_api_mail_proxy_config_get_ts" }, @@ -5458,7 +5991,7 @@ "file_type": "code", "source_file": "backend/server/api/mail/proxy-config.get.ts", "source_location": "L8", - "community": 429, + "community": 6, "norm_label": "escapexml()", "id": "mail_proxy_config_get_escapexml" }, @@ -5467,7 +6000,7 @@ "file_type": "code", "source_file": "backend/server/api/mail/proxy-account.post.ts", "source_location": "L1", - "community": 429, + "community": 6, "norm_label": "proxy-account.post.ts", "id": "backend_server_api_mail_proxy_account_post_ts" }, @@ -5485,7 +6018,7 @@ "file_type": "code", "source_file": "backend/server/api/mail/disconnect.delete.ts", "source_location": "L1", - "community": 6, + "community": 4, "norm_label": "disconnect.delete.ts", "id": "backend_server_api_mail_disconnect_delete_ts" }, @@ -5494,19 +6027,10 @@ "file_type": "code", "source_file": "backend/server/api/mail/connect.post.ts", "source_location": "L1", - "community": 429, + "community": 6, "norm_label": "connect.post.ts", "id": "backend_server_api_mail_connect_post_ts" }, - { - "label": "scan.post.ts", - "file_type": "code", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L1", - "community": 6, - "norm_label": "scan.post.ts", - "id": "backend_server_api_mail_scan_post_ts" - }, { "label": "results.get.ts", "file_type": "code", @@ -5530,7 +6054,7 @@ "file_type": "code", "source_file": "backend/server/api/mail/interval.patch.ts", "source_location": "L1", - "community": 429, + "community": 6, "norm_label": "interval.patch.ts", "id": "backend_server_api_mail_interval_patch_ts" }, @@ -5683,7 +6207,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/set-lyra-avatar.post.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "set-lyra-avatar.post.ts", "id": "backend_server_api_admin_set_lyra_avatar_post_ts" }, @@ -5692,7 +6216,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-post.post.ts", "source_location": "L3", - "community": 269, + "community": 39, "norm_label": "lyra_topics", "id": "admin_lyra_post_post_lyra_topics" }, @@ -5701,7 +6225,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-post.post.ts", "source_location": "L12", - "community": 269, + "community": 39, "norm_label": "lyratopic", "id": "admin_lyra_post_post_lyratopic" }, @@ -5710,7 +6234,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-post.post.ts", "source_location": "L14", - "community": 269, + "community": 39, "norm_label": "topic_hints", "id": "admin_lyra_post_post_topic_hints" }, @@ -5719,7 +6243,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-post.post.ts", "source_location": "L27", - "community": 269, + "community": 39, "norm_label": "lang", "id": "admin_lyra_post_post_lang" }, @@ -5728,7 +6252,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-post.post.ts", "source_location": "L28", - "community": 269, + "community": 39, "norm_label": "langs", "id": "admin_lyra_post_post_langs" }, @@ -5737,7 +6261,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-post.post.ts", "source_location": "L29", - "community": 269, + "community": 39, "norm_label": "lang_name", "id": "admin_lyra_post_post_lang_name" }, @@ -5746,7 +6270,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-post.post.ts", "source_location": "L36", - "community": 269, + "community": 39, "norm_label": "lyrasystemprompt()", "id": "admin_lyra_post_post_lyrasystemprompt" }, @@ -5755,7 +6279,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-post.post.ts", "source_location": "L50", - "community": 269, + "community": 39, "norm_label": "rebreaksystemprompt()", "id": "admin_lyra_post_post_rebreaksystemprompt" }, @@ -5764,7 +6288,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-generate.post.ts", "source_location": "L1", - "community": 269, + "community": 39, "norm_label": "lyra-generate.post.ts", "id": "backend_server_api_admin_lyra_generate_post_ts" }, @@ -5773,7 +6297,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/lyra-profile.get.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "lyra-profile.get.ts", "id": "backend_server_api_admin_lyra_profile_get_ts" }, @@ -5800,7 +6324,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/curated-domains/index.get.ts", "source_location": "L1", - "community": 863, + "community": 4, "norm_label": "index.get.ts", "id": "backend_server_api_admin_curated_domains_index_get_ts" }, @@ -5809,7 +6333,7 @@ "file_type": "code", "source_file": "backend/server/api/admin/curated-domains/[id].patch.ts", "source_location": "L1", - "community": 863, + "community": 4, "norm_label": "[id].patch.ts", "id": "backend_server_api_admin_curated_domains_id_patch_ts" }, @@ -5917,7 +6441,7 @@ "file_type": "code", "source_file": "backend/server/api/scores/leaderboard.get.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "leaderboard.get.ts", "id": "backend_server_api_scores_leaderboard_get_ts" }, @@ -5926,7 +6450,7 @@ "file_type": "code", "source_file": "backend/server/api/scores/me.get.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "me.get.ts", "id": "backend_server_api_scores_me_get_ts" }, @@ -6034,7 +6558,7 @@ "file_type": "code", "source_file": "backend/server/api/coach/message.post.ts", "source_location": "L355", - "community": 21, + "community": 48, "norm_label": "provider_config", "id": "coach_message_post_provider_config" }, @@ -6070,7 +6594,7 @@ "file_type": "code", "source_file": "backend/server/api/coach/speak.post.ts", "source_location": "L1", - "community": 48, + "community": 429, "norm_label": "speak.post.ts", "id": "backend_server_api_coach_speak_post_ts" }, @@ -6079,7 +6603,7 @@ "file_type": "code", "source_file": "backend/server/api/coach/speak.post.ts", "source_location": "L100", - "community": 48, + "community": 429, "norm_label": "speakgoogle()", "id": "coach_speak_post_speakgoogle" }, @@ -6088,7 +6612,7 @@ "file_type": "code", "source_file": "backend/server/api/coach/speak.post.ts", "source_location": "L171", - "community": 48, + "community": 429, "norm_label": "speakcartesia()", "id": "coach_speak_post_speakcartesia" }, @@ -6097,7 +6621,7 @@ "file_type": "code", "source_file": "backend/server/api/coach/speak.post.ts", "source_location": "L229", - "community": 48, + "community": 429, "norm_label": "speakelevenlabs()", "id": "coach_speak_post_speakelevenlabs" }, @@ -6214,7 +6738,7 @@ "file_type": "code", "source_file": "backend/server/api/coach/speak-cartesia.post.ts", "source_location": "L1", - "community": 48, + "community": 429, "norm_label": "speak-cartesia.post.ts", "id": "backend_server_api_coach_speak_cartesia_post_ts" }, @@ -6250,7 +6774,7 @@ "file_type": "code", "source_file": "backend/server/api/social/follow.post.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "follow.post.ts", "id": "backend_server_api_social_follow_post_ts" }, @@ -6259,7 +6783,7 @@ "file_type": "code", "source_file": "backend/server/api/social/profile/[userId].get.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "[userid].get.ts", "id": "backend_server_api_social_profile_userid_get_ts" }, @@ -6322,7 +6846,7 @@ "file_type": "code", "source_file": "backend/server/api/protection/state.get.ts", "source_location": "L1", - "community": 9, + "community": 34, "norm_label": "state.get.ts", "id": "backend_server_api_protection_state_get_ts" }, @@ -6358,7 +6882,7 @@ "file_type": "code", "source_file": "backend/server/api/profile/me/lyra-voice.patch.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "lyra-voice.patch.ts", "id": "backend_server_api_profile_me_lyra_voice_patch_ts" }, @@ -6385,7 +6909,7 @@ "file_type": "code", "source_file": "backend/server/api/profile/me/onboarding-step.patch.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "onboarding-step.patch.ts", "id": "backend_server_api_profile_me_onboarding_step_patch_ts" }, @@ -6412,7 +6936,7 @@ "file_type": "code", "source_file": "backend/server/api/profile/me/demographics.patch.ts", "source_location": "L29", - "community": 429, + "community": 9, "norm_label": "gender_values", "id": "me_demographics_patch_gender_values" }, @@ -6421,7 +6945,7 @@ "file_type": "code", "source_file": "backend/server/api/profile/me/demographics.patch.ts", "source_location": "L30", - "community": 429, + "community": 9, "norm_label": "marital_values", "id": "me_demographics_patch_marital_values" }, @@ -6430,7 +6954,7 @@ "file_type": "code", "source_file": "backend/server/api/profile/me/demographics.patch.ts", "source_location": "L40", - "community": 429, + "community": 9, "norm_label": "employment_status_values", "id": "me_demographics_patch_employment_status_values" }, @@ -6439,7 +6963,7 @@ "file_type": "code", "source_file": "backend/server/api/profile/me/demographics.patch.ts", "source_location": "L49", - "community": 429, + "community": 9, "norm_label": "job_tenure_values", "id": "me_demographics_patch_job_tenure_values" }, @@ -6448,7 +6972,7 @@ "file_type": "code", "source_file": "backend/server/api/profile/me/demographics.patch.ts", "source_location": "L57", - "community": 429, + "community": 9, "norm_label": "schema", "id": "me_demographics_patch_schema" }, @@ -6538,7 +7062,7 @@ "file_type": "code", "source_file": "backend/server/api/avatar/upload.post.ts", "source_location": "L1", - "community": 276, + "community": 32, "norm_label": "upload.post.ts", "id": "backend_server_api_avatar_upload_post_ts" }, @@ -6565,7 +7089,7 @@ "file_type": "code", "source_file": "backend/server/api/mail-connections/[id].post.ts", "source_location": "L1", - "community": 429, + "community": 6, "norm_label": "[id].post.ts", "id": "backend_server_api_mail_connections_id_post_ts" }, @@ -6592,7 +7116,7 @@ "file_type": "code", "source_file": "backend/server/api/dev/set-plan.post.ts", "source_location": "L1", - "community": 276, + "community": 429, "norm_label": "set-plan.post.ts", "id": "backend_server_api_dev_set_plan_post_ts" }, @@ -6601,7 +7125,7 @@ "file_type": "code", "source_file": "backend/server/api/dev/set-plan.post.ts", "source_location": "L5", - "community": 276, + "community": 429, "norm_label": "valid_plans", "id": "dev_set_plan_post_valid_plans" }, @@ -6610,7 +7134,7 @@ "file_type": "code", "source_file": "backend/server/api/dev/set-plan.post.ts", "source_location": "L6", - "community": 276, + "community": 429, "norm_label": "appplan", "id": "dev_set_plan_post_appplan" }, @@ -6619,7 +7143,7 @@ "file_type": "code", "source_file": "backend/server/api/community/like.post.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "like.post.ts", "id": "backend_server_api_community_like_post_ts" }, @@ -6637,7 +7161,7 @@ "file_type": "code", "source_file": "backend/server/api/community/upload-image.post.ts", "source_location": "L1", - "community": 276, + "community": 32, "norm_label": "upload-image.post.ts", "id": "backend_server_api_community_upload_image_post_ts" }, @@ -6646,7 +7170,7 @@ "file_type": "code", "source_file": "backend/server/api/community/comment.post.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "comment.post.ts", "id": "backend_server_api_community_comment_post_ts" }, @@ -6655,7 +7179,7 @@ "file_type": "code", "source_file": "backend/server/api/community/posts.get.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "posts.get.ts", "id": "backend_server_api_community_posts_get_ts" }, @@ -6664,7 +7188,7 @@ "file_type": "code", "source_file": "backend/server/api/community/repost.post.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "repost.post.ts", "id": "backend_server_api_community_repost_post_ts" }, @@ -6673,7 +7197,7 @@ "file_type": "code", "source_file": "backend/server/api/community/comment-like.post.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "comment-like.post.ts", "id": "backend_server_api_community_comment_like_post_ts" }, @@ -6682,7 +7206,7 @@ "file_type": "code", "source_file": "backend/server/api/community/post.post.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "post.post.ts", "id": "backend_server_api_community_post_post_ts" }, @@ -6691,7 +7215,7 @@ "file_type": "code", "source_file": "backend/server/api/community/[postId]/comments.get.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "comments.get.ts", "id": "backend_server_api_community_postid_comments_get_ts" }, @@ -6700,7 +7224,7 @@ "file_type": "code", "source_file": "backend/server/api/community/[postId]/index.get.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "index.get.ts", "id": "backend_server_api_community_postid_index_get_ts" }, @@ -6709,7 +7233,7 @@ "file_type": "code", "source_file": "backend/server/api/urge/index.get.ts", "source_location": "L1", - "community": 34, + "community": 4, "norm_label": "index.get.ts", "id": "backend_server_api_urge_index_get_ts" }, @@ -6718,7 +7242,7 @@ "file_type": "code", "source_file": "backend/server/api/urge/index.post.ts", "source_location": "L1", - "community": 34, + "community": 4, "norm_label": "index.post.ts", "id": "backend_server_api_urge_index_post_ts" }, @@ -6727,7 +7251,7 @@ "file_type": "code", "source_file": "backend/server/api/urge/index.post.ts", "source_location": "L4", - "community": 34, + "community": 4, "norm_label": "emotion", "id": "urge_index_post_emotion" }, @@ -6736,7 +7260,7 @@ "file_type": "code", "source_file": "backend/server/api/urge/index.post.ts", "source_location": "L5", - "community": 34, + "community": 4, "norm_label": "valid_emotions", "id": "urge_index_post_valid_emotions" }, @@ -6745,7 +7269,7 @@ "file_type": "code", "source_file": "backend/server/api/dns/profile.get.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "profile.get.ts", "id": "backend_server_api_dns_profile_get_ts" }, @@ -6763,7 +7287,7 @@ "file_type": "code", "source_file": "backend/server/api/domain-submissions/[id]/vote.post.ts", "source_location": "L1", - "community": 431, + "community": 4, "norm_label": "vote.post.ts", "id": "backend_server_api_domain_submissions_id_vote_post_ts" }, @@ -6772,7 +7296,7 @@ "file_type": "code", "source_file": "backend/server/api/games/challenge.post.ts", "source_location": "L1", - "community": 429, + "community": 4, "norm_label": "challenge.post.ts", "id": "backend_server_api_games_challenge_post_ts" }, @@ -6781,7 +7305,7 @@ "file_type": "code", "source_file": "backend/server/api/games/challenge-memory.post.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "challenge-memory.post.ts", "id": "backend_server_api_games_challenge_memory_post_ts" }, @@ -6790,7 +7314,7 @@ "file_type": "code", "source_file": "backend/server/api/games/challenge-memory.post.ts", "source_location": "L4", - "community": 429, + "community": 9, "norm_label": "memory_emojis", "id": "games_challenge_memory_post_memory_emojis" }, @@ -6799,7 +7323,7 @@ "file_type": "code", "source_file": "backend/server/api/games/challenge-memory.post.ts", "source_location": "L6", - "community": 429, + "community": 9, "norm_label": "shuffle()", "id": "games_challenge_memory_post_shuffle" }, @@ -6943,7 +7467,7 @@ "file_type": "code", "source_file": "backend/server/api/games/challenge/[id]/accept.post.ts", "source_location": "L1", - "community": 429, + "community": 4, "norm_label": "accept.post.ts", "id": "backend_server_api_games_challenge_id_accept_post_ts" }, @@ -6961,7 +7485,7 @@ "file_type": "code", "source_file": "backend/server/api/games/challenge/[id]/rematch.post.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "rematch.post.ts", "id": "backend_server_api_games_challenge_id_rematch_post_ts" }, @@ -6970,7 +7494,7 @@ "file_type": "code", "source_file": "backend/server/api/games/challenge/[id]/rematch.post.ts", "source_location": "L4", - "community": 429, + "community": 9, "norm_label": "memory_emojis", "id": "id_rematch_post_memory_emojis" }, @@ -6979,7 +7503,7 @@ "file_type": "code", "source_file": "backend/server/api/games/challenge/[id]/rematch.post.ts", "source_location": "L5", - "community": 429, + "community": 9, "norm_label": "shuffle()", "id": "id_rematch_post_shuffle" }, @@ -7015,7 +7539,7 @@ "file_type": "code", "source_file": "backend/server/api/notifications/[id].delete.ts", "source_location": "L1", - "community": 431, + "community": 181, "norm_label": "[id].delete.ts", "id": "backend_server_api_notifications_id_delete_ts" }, @@ -7024,7 +7548,7 @@ "file_type": "code", "source_file": "backend/server/api/notifications/index.get.ts", "source_location": "L1", - "community": 431, + "community": 181, "norm_label": "index.get.ts", "id": "backend_server_api_notifications_index_get_ts" }, @@ -7033,7 +7557,7 @@ "file_type": "code", "source_file": "backend/server/api/notifications/read.post.ts", "source_location": "L1", - "community": 431, + "community": 181, "norm_label": "read.post.ts", "id": "backend_server_api_notifications_read_post_ts" }, @@ -7042,7 +7566,7 @@ "file_type": "code", "source_file": "backend/server/api/lyra/welcome-back.get.ts", "source_location": "L27", - "community": 876, + "community": 413, "norm_label": "fallback_messages", "id": "lyra_welcome_back_get_fallback_messages" }, @@ -7051,7 +7575,7 @@ "file_type": "code", "source_file": "backend/server/api/lyra/welcome-back.get.ts", "source_location": "L96", - "community": 876, + "community": 413, "norm_label": "pickrandom()", "id": "lyra_welcome_back_get_pickrandom" }, @@ -7096,7 +7620,7 @@ "file_type": "code", "source_file": "backend/server/api/cron/notifications-cleanup.ts", "source_location": "L1", - "community": 431, + "community": 181, "norm_label": "notifications-cleanup.ts", "id": "backend_server_api_cron_notifications_cleanup_ts" }, @@ -7105,7 +7629,7 @@ "file_type": "code", "source_file": "backend/server/api/cron/lyra-post.ts", "source_location": "L1", - "community": 269, + "community": 39, "norm_label": "lyra-post.ts", "id": "backend_server_api_cron_lyra_post_ts" }, @@ -7114,7 +7638,7 @@ "file_type": "code", "source_file": "backend/server/api/cron/lyra-post.ts", "source_location": "L32", - "community": 269, + "community": 39, "norm_label": "topics", "id": "cron_lyra_post_topics" }, @@ -7123,7 +7647,7 @@ "file_type": "code", "source_file": "backend/server/api/cron/lyra-post.ts", "source_location": "L106", - "community": 269, + "community": 39, "norm_label": "postfromcatalog()", "id": "cron_lyra_post_postfromcatalog" }, @@ -7132,7 +7656,7 @@ "file_type": "code", "source_file": "backend/server/api/cron/lyra-post.ts", "source_location": "L134", - "community": 269, + "community": 39, "norm_label": "postfromllm()", "id": "cron_lyra_post_postfromllm" }, @@ -7150,7 +7674,7 @@ "file_type": "code", "source_file": "backend/server/api/devices/index.get.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "index.get.ts", "id": "backend_server_api_devices_index_get_ts" }, @@ -7159,7 +7683,7 @@ "file_type": "code", "source_file": "backend/server/api/devices/protected.get.ts", "source_location": "L1", - "community": 429, + "community": 80, "norm_label": "protected.get.ts", "id": "backend_server_api_devices_protected_get_ts" }, @@ -7168,7 +7692,7 @@ "file_type": "code", "source_file": "backend/server/api/devices/register.post.ts", "source_location": "L1", - "community": 429, + "community": 9, "norm_label": "register.post.ts", "id": "backend_server_api_devices_register_post_ts" }, @@ -7177,7 +7701,7 @@ "file_type": "code", "source_file": "backend/server/api/devices/enroll.post.ts", "source_location": "L1", - "community": 429, + "community": 80, "norm_label": "enroll.post.ts", "id": "backend_server_api_devices_enroll_post_ts" }, @@ -7276,7 +7800,7 @@ "file_type": "code", "source_file": "backend/server/api/stripe/webhook.post.ts", "source_location": "L1", - "community": 276, + "community": 32, "norm_label": "webhook.post.ts", "id": "backend_server_api_stripe_webhook_post_ts" }, @@ -7370,60 +7894,6 @@ "norm_label": "tn", "id": "data_gambling_domains_tn" }, - { - "label": "push.ts", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L1", - "community": 566, - "norm_label": "push.ts", - "id": "backend_server_services_push_ts" - }, - { - "label": "expo", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L18", - "community": 566, - "norm_label": "expo", - "id": "services_push_expo" - }, - { - "label": "ChatPushPayload", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L20", - "community": 566, - "norm_label": "chatpushpayload", - "id": "services_push_chatpushpayload" - }, - { - "label": "sendChatPush()", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L36", - "community": 566, - "norm_label": "sendchatpush()", - "id": "services_push_sendchatpush" - }, - { - "label": "getDisplayName()", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L113", - "community": 566, - "norm_label": "getdisplayname()", - "id": "services_push_getdisplayname" - }, - { - "label": "truncatePreview()", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L125", - "community": 566, - "norm_label": "truncatepreview()", - "id": "services_push_truncatepreview" - }, { "label": "start-idle-staging.sh", "file_type": "code", @@ -7563,249 +8033,6 @@ "norm_label": "node", "id": "imap_idle_package_engines_node" }, - { - "label": "index.mjs", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L1", - "community": 68, - "norm_label": "index.mjs", - "id": "backend_imap_idle_index_mjs" - }, - { - "label": "RECONNECT_DELAYS_MS", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L74", - "community": 68, - "norm_label": "reconnect_delays_ms", - "id": "imap_idle_index_reconnect_delays_ms" - }, - { - "label": "pool", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L79", - "community": 68, - "norm_label": "pool", - "id": "imap_idle_index_pool" - }, - { - "label": "updateConnectionError()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L81", - "community": 68, - "norm_label": "updateconnectionerror()", - "id": "imap_idle_index_updateconnectionerror" - }, - { - "label": "clearConnectionError()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L90", - "community": 68, - "norm_label": "clearconnectionerror()", - "id": "imap_idle_index_clearconnectionerror" - }, - { - "label": "updateIdleHeartbeat()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L99", - "community": 68, - "norm_label": "updateidleheartbeat()", - "id": "imap_idle_index_updateidleheartbeat" - }, - { - "label": "loadActiveConnections()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L113", - "community": 68, - "norm_label": "loadactiveconnections()", - "id": "imap_idle_index_loadactiveconnections" - }, - { - "label": "getKey()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L139", - "community": 68, - "norm_label": "getkey()", - "id": "imap_idle_index_getkey" - }, - { - "label": "decrypt()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L151", - "community": 68, - "norm_label": "decrypt()", - "id": "imap_idle_index_decrypt" - }, - { - "label": "encrypt()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L164", - "community": 68, - "norm_label": "encrypt()", - "id": "imap_idle_index_encrypt" - }, - { - "label": "MS_OAUTH_SCOPES", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L186", - "community": 68, - "norm_label": "ms_oauth_scopes", - "id": "imap_idle_index_ms_oauth_scopes" - }, - { - "label": "refreshGoogleTokensDaemon()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L299", - "community": 68, - "norm_label": "refreshgoogletokensdaemon()", - "id": "imap_idle_index_refreshgoogletokensdaemon" - }, - { - "label": "markConnectionAuthBroken()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L380", - "community": 68, - "norm_label": "markconnectionauthbroken()", - "id": "imap_idle_index_markconnectionauthbroken" - }, - { - "label": "getCredentialsForConnection()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L408", - "community": 68, - "norm_label": "getcredentialsforconnection()", - "id": "imap_idle_index_getcredentialsforconnection" - }, - { - "label": "log()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L447", - "community": 68, - "norm_label": "log()", - "id": "imap_idle_index_log" - }, - { - "label": "logError()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L452", - "community": 68, - "norm_label": "logerror()", - "id": "imap_idle_index_logerror" - }, - { - "label": "isAuthError()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L461", - "community": 68, - "norm_label": "isautherror()", - "id": "imap_idle_index_isautherror" - }, - { - "label": "sessions", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L476", - "community": 68, - "norm_label": "sessions", - "id": "imap_idle_index_sessions" - }, - { - "label": "triggerScan()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L482", - "community": 68, - "norm_label": "triggerscan()", - "id": "imap_idle_index_triggerscan" - }, - { - "label": "runSession()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L523", - "community": 68, - "norm_label": "runsession()", - "id": "imap_idle_index_runsession" - }, - { - "label": "startSession()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L748", - "community": 68, - "norm_label": "startsession()", - "id": "imap_idle_index_startsession" - }, - { - "label": "stopSession()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L759", - "community": 68, - "norm_label": "stopsession()", - "id": "imap_idle_index_stopsession" - }, - { - "label": "refreshConnections()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L772", - "community": 68, - "norm_label": "refreshconnections()", - "id": "imap_idle_index_refreshconnections" - }, - { - "label": "shutdown()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L820", - "community": 68, - "norm_label": "shutdown()", - "id": "imap_idle_index_shutdown" - }, - { - "label": "sleep()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L840", - "community": 68, - "norm_label": "sleep()", - "id": "imap_idle_index_sleep" - }, - { - "label": "assertEnv()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L844", - "community": 68, - "norm_label": "assertenv()", - "id": "imap_idle_index_assertenv" - }, - { - "label": "main()", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L858", - "community": 68, - "norm_label": "main()", - "id": "imap_idle_index_main" - }, { "label": "generate-pir-input.ts", "file_type": "code", @@ -8464,71 +8691,6 @@ "norm_label": "path", "id": "scripts_deploy_path" }, - { - "label": "deploy-from-artifact.sh", - "file_type": "code", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L1", - "metadata": { - "language": "bash", - "kind": "file" - }, - "community": 662, - "norm_label": "deploy-from-artifact.sh", - "id": "scripts_deploy_from_artifact_sh" - }, - { - "label": "deploy-from-artifact.sh script", - "file_type": "code", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L1", - "metadata": { - "language": "bash", - "kind": "bash_entrypoint" - }, - "community": 662, - "norm_label": "deploy-from-artifact.sh script", - "id": "users_chahinebrini_mono_rebreak_monorepo_scripts_deploy_from_artifact_sh__entry" - }, - { - "label": "log()", - "file_type": "code", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L23", - "metadata": { - "language": "bash", - "kind": "bash_function" - }, - "community": 662, - "norm_label": "log()", - "id": "scripts_deploy_from_artifact_log" - }, - { - "label": "log_err()", - "file_type": "code", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L24", - "metadata": { - "language": "bash", - "kind": "bash_function" - }, - "community": 662, - "norm_label": "log_err()", - "id": "scripts_deploy_from_artifact_log_err" - }, - { - "label": "PATH", - "file_type": "code", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L28", - "metadata": { - "language": "bash", - "kind": "code" - }, - "community": 662, - "norm_label": "path", - "id": "scripts_deploy_from_artifact_path" - }, { "label": "server.mjs", "file_type": "code", @@ -9107,7 +9269,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L1", - "community": 415, + "community": 266, "norm_label": "main.go", "id": "ops_mdm_supervise_magic_cmd_supervise_main_go" }, @@ -9116,7 +9278,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L24", - "community": 415, + "community": 266, "norm_label": "init()", "id": "supervise_main_init" }, @@ -9125,7 +9287,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L42", - "community": 415, + "community": 266, "norm_label": "dlmsgdebugset()", "id": "supervise_main_dlmsgdebugset" }, @@ -9134,7 +9296,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L73", - "community": 415, + "community": 266, "norm_label": "cliopts", "id": "supervise_cliopts" }, @@ -9143,7 +9305,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L82", - "community": 415, + "community": 266, "norm_label": "main()", "id": "supervise_main_main" }, @@ -9152,7 +9314,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L129", - "community": 415, + "community": 266, "norm_label": "runcheck()", "id": "supervise_main_runcheck" }, @@ -9161,7 +9323,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L162", - "community": 415, + "community": 266, "norm_label": "runcertinfo()", "id": "supervise_main_runcertinfo" }, @@ -9170,7 +9332,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L176", - "community": 415, + "community": 266, "norm_label": "runcloudconfig()", "id": "supervise_main_runcloudconfig" }, @@ -9179,7 +9341,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L265", - "community": 415, + "community": 266, "norm_label": "defaultbackuppath()", "id": "supervise_main_defaultbackuppath" }, @@ -9188,7 +9350,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L303", - "community": 415, + "community": 266, "norm_label": "confirm()", "id": "supervise_main_confirm" }, @@ -9197,7 +9359,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/cmd/supervise/main.go", "source_location": "L311", - "community": 415, + "community": 266, "norm_label": "exitonerr()", "id": "supervise_main_exitonerr" }, @@ -9361,7 +9523,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/internal/mobilebackup2/embed.go", "source_location": "L93", - "community": 264, + "community": 259, "norm_label": "time", "id": "time" }, @@ -9937,7 +10099,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/internal/device/lockdown.go", "source_location": "L1", - "community": 266, + "community": 427, "norm_label": "lockdown.go", "id": "ops_mdm_supervise_magic_internal_device_lockdown_go" }, @@ -10045,7 +10207,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/internal/device/lockdown.go", "source_location": "L137", - "community": 266, + "community": 427, "norm_label": "waitforreconnect()", "id": "device_lockdown_waitforreconnect" }, @@ -10054,7 +10216,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/internal/device/lockdown.go", "source_location": "L137", - "community": 266, + "community": 427, "norm_label": "duration", "id": "ops_mdm_supervise_magic_internal_device_lockdown_go_duration" }, @@ -10441,7 +10603,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/internal/supervise/flow.go", "source_location": "L40", - "community": 266, + "community": 415, "norm_label": "supervise()", "id": "supervise_flow_supervise" }, @@ -10468,7 +10630,7 @@ "file_type": "code", "source_file": "ops/mdm/supervise-magic/internal/supervise/flow.go", "source_location": "L189", - "community": 415, + "community": 266, "norm_label": "unsupervise()", "id": "supervise_flow_unsupervise" }, @@ -12867,7 +13029,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/locales/de.json", "source_location": "L15", - "community": 876, + "community": 413, "norm_label": "welcomeback", "id": "locales_de_auth_welcomeback" }, @@ -13515,7 +13677,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/locales/de.json", "source_location": "L104", - "community": 426, + "community": 69, "norm_label": "splash", "id": "locales_de_splash" }, @@ -13524,7 +13686,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/locales/de.json", "source_location": "L107", - "community": 426, + "community": 69, "norm_label": "madeingermany", "id": "locales_de_splash_madeingermany" }, @@ -13686,7 +13848,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/locales/de.json", "source_location": "L141", - "community": 426, + "community": 69, "norm_label": "games", "id": "locales_de_games" }, @@ -13704,7 +13866,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/locales/de.json", "source_location": "L143", - "community": 426, + "community": 69, "norm_label": "subtitle", "id": "locales_de_games_subtitle" }, @@ -13713,7 +13875,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/locales/de.json", "source_location": "L144", - "community": 426, + "community": 69, "norm_label": "back_to_picker", "id": "locales_de_games_back_to_picker" }, @@ -13722,7 +13884,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/locales/de.json", "source_location": "L145", - "community": 426, + "community": 69, "norm_label": "last_score", "id": "locales_de_games_last_score" }, @@ -13731,7 +13893,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/locales/de.json", "source_location": "L146", - "community": 426, + "community": 69, "norm_label": "skeleton_footer", "id": "locales_de_games_skeleton_footer" }, @@ -28257,7 +28419,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/settings.tsx", "source_location": "L1", - "community": 20, + "community": 47, "norm_label": "settings.tsx", "id": "apps_rebreak_native_app_settings_tsx" }, @@ -28266,7 +28428,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/settings.tsx", "source_location": "L34", - "community": 20, + "community": 47, "norm_label": "subscriptionsheetprops", "id": "app_settings_subscriptionsheetprops" }, @@ -28275,7 +28437,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/settings.tsx", "source_location": "L40", - "community": 20, + "community": 47, "norm_label": "plan_accent", "id": "app_settings_plan_accent" }, @@ -28284,7 +28446,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/settings.tsx", "source_location": "L46", - "community": 20, + "community": 47, "norm_label": "subscriptionsheet()", "id": "app_settings_subscriptionsheet" }, @@ -28293,7 +28455,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/settings.tsx", "source_location": "L126", - "community": 20, + "community": 47, "norm_label": "pickeroption", "id": "app_settings_pickeroption" }, @@ -28302,7 +28464,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/settings.tsx", "source_location": "L128", - "community": 20, + "community": 47, "norm_label": "sectionrow", "id": "app_settings_sectionrow" }, @@ -28311,7 +28473,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/settings.tsx", "source_location": "L151", - "community": 20, + "community": 47, "norm_label": "section", "id": "app_settings_section" }, @@ -28320,7 +28482,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/settings.tsx", "source_location": "L157", - "community": 20, + "community": 47, "norm_label": "settingsscreen()", "id": "app_settings_settingsscreen" }, @@ -28329,7 +28491,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/settings.tsx", "source_location": "L769", - "community": 20, + "community": 47, "norm_label": "streaktimepickersheet()", "id": "app_settings_streaktimepickersheet" }, @@ -28338,7 +28500,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/index.tsx", "source_location": "L1", - "community": 422, + "community": 20, "norm_label": "index.tsx", "id": "apps_rebreak_native_app_index_tsx" }, @@ -28347,7 +28509,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/index.tsx", "source_location": "L9", - "community": 422, + "community": 20, "norm_label": "{ width: sw, height: sh }", "id": "app_index_width_sw_height_sh" }, @@ -28356,7 +28518,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/index.tsx", "source_location": "L11", - "community": 422, + "community": 20, "norm_label": "landingscreen()", "id": "app_index_landingscreen" }, @@ -28365,7 +28527,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/dm.tsx", "source_location": "L1", - "community": 20, + "community": 17, "norm_label": "dm.tsx", "id": "apps_rebreak_native_app_dm_tsx" }, @@ -28374,7 +28536,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/dm.tsx", "source_location": "L36", - "community": 20, + "community": 17, "norm_label": "dmhistoryresponse", "id": "app_dm_dmhistoryresponse" }, @@ -28383,7 +28545,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/dm.tsx", "source_location": "L62", - "community": 20, + "community": 17, "norm_label": "dmscreen()", "id": "app_dm_dmscreen" }, @@ -28392,7 +28554,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/dm.tsx", "source_location": "L617", - "community": 20, + "community": 17, "norm_label": "makestyles()", "id": "app_dm_makestyles" }, @@ -28581,7 +28743,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/games.tsx", "source_location": "L1", - "community": 5, + "community": 686, "norm_label": "games.tsx", "id": "apps_rebreak_native_app_games_tsx" }, @@ -28590,7 +28752,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/games.tsx", "source_location": "L19", - "community": 5, + "community": 686, "norm_label": "gamestat", "id": "app_games_gamestat" }, @@ -28599,7 +28761,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/games.tsx", "source_location": "L20", - "community": 5, + "community": 686, "norm_label": "gamestats", "id": "app_games_gamestats" }, @@ -28608,7 +28770,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/games.tsx", "source_location": "L22", - "community": 5, + "community": 686, "norm_label": "empty_stats", "id": "app_games_empty_stats" }, @@ -28617,7 +28779,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/games.tsx", "source_location": "L29", - "community": 5, + "community": 686, "norm_label": "lastscore", "id": "app_games_lastscore" }, @@ -28626,7 +28788,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/games.tsx", "source_location": "L31", - "community": 5, + "community": 686, "norm_label": "gamesscreen()", "id": "app_games_gamesscreen" }, @@ -28887,7 +29049,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/lyra.tsx", "source_location": "L44", - "community": 568, + "community": 286, "norm_label": "formattimestamp()", "id": "app_lyra_formattimestamp" }, @@ -28932,7 +29094,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/lyra.tsx", "source_location": "L129", - "community": 568, + "community": 286, "norm_label": "messagerow()", "id": "app_lyra_messagerow" }, @@ -29040,7 +29202,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(app)/notifications.tsx", "source_location": "L147", - "community": 431, + "community": 181, "norm_label": "iconfortype()", "id": "app_notifications_iconfortype" }, @@ -29049,7 +29211,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(app)/blocker.tsx", "source_location": "L1", - "community": 17, + "community": 22, "norm_label": "blocker.tsx", "id": "apps_rebreak_native_app_app_blocker_tsx" }, @@ -29058,7 +29220,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(app)/blocker.tsx", "source_location": "L24", - "community": 17, + "community": 22, "norm_label": "blockerscreen()", "id": "app_blocker_blockerscreen" }, @@ -29175,7 +29337,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/auth/callback.tsx", "source_location": "L1", - "community": 17, + "community": 22, "norm_label": "callback.tsx", "id": "apps_rebreak_native_app_auth_callback_tsx" }, @@ -29184,7 +29346,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/auth/callback.tsx", "source_location": "L20", - "community": 17, + "community": 22, "norm_label": "authcallback()", "id": "auth_callback_authcallback" }, @@ -29373,7 +29535,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(auth)/signup.tsx", "source_location": "L1", - "community": 20, + "community": 47, "norm_label": "signup.tsx", "id": "apps_rebreak_native_app_auth_signup_tsx" }, @@ -29382,7 +29544,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(auth)/signup.tsx", "source_location": "L20", - "community": 20, + "community": 47, "norm_label": "googleicon()", "id": "auth_signup_googleicon" }, @@ -29391,7 +29553,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(auth)/signup.tsx", "source_location": "L31", - "community": 20, + "community": 47, "norm_label": "appleicon()", "id": "auth_signup_appleicon" }, @@ -29400,7 +29562,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(auth)/signup.tsx", "source_location": "L39", - "community": 20, + "community": 47, "norm_label": "oauthprovider", "id": "auth_signup_oauthprovider" }, @@ -29409,7 +29571,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(auth)/signup.tsx", "source_location": "L41", - "community": 20, + "community": 47, "norm_label": "input_style", "id": "auth_signup_input_style" }, @@ -29418,7 +29580,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(auth)/signup.tsx", "source_location": "L50", - "community": 20, + "community": 47, "norm_label": "signupscreen()", "id": "auth_signup_signupscreen" }, @@ -29445,7 +29607,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(auth)/confirm.tsx", "source_location": "L1", - "community": 17, + "community": 22, "norm_label": "confirm.tsx", "id": "apps_rebreak_native_app_auth_confirm_tsx" }, @@ -29454,7 +29616,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/(auth)/confirm.tsx", "source_location": "L17", - "community": 17, + "community": 22, "norm_label": "confirmscreen()", "id": "auth_confirm_confirmscreen" }, @@ -30111,7 +30273,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/notificationPrefs.ts", "source_location": "L1", - "community": 18, + "community": 47, "norm_label": "notificationprefs.ts", "id": "apps_rebreak_native_stores_notificationprefs_ts" }, @@ -30120,7 +30282,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/notificationPrefs.ts", "source_location": "L7", - "community": 18, + "community": 47, "norm_label": "notificationprefsstate", "id": "stores_notificationprefs_notificationprefsstate" }, @@ -30129,7 +30291,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/notificationPrefs.ts", "source_location": "L19", - "community": 18, + "community": 47, "norm_label": "persist()", "id": "stores_notificationprefs_persist" }, @@ -30138,7 +30300,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/notificationPrefs.ts", "source_location": "L25", - "community": 18, + "community": 47, "norm_label": "usenotificationprefsstore", "id": "stores_notificationprefs_usenotificationprefsstore" }, @@ -30165,7 +30327,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/devices.ts", "source_location": "L18", - "community": 109, + "community": 864, "norm_label": "devicesstate", "id": "stores_devices_devicesstate" }, @@ -30183,7 +30345,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/notifications.ts", "source_location": "L1", - "community": 17, + "community": 22, "norm_label": "notifications.ts", "id": "apps_rebreak_native_stores_notifications_ts" }, @@ -30412,42 +30574,6 @@ "norm_label": "usedevicelimitstore", "id": "stores_devicelimit_usedevicelimitstore" }, - { - "label": "appLock.ts", - "file_type": "code", - "source_file": "apps/rebreak-native/stores/appLock.ts", - "source_location": "L1", - "community": 20, - "norm_label": "applock.ts", - "id": "apps_rebreak_native_stores_applock_ts" - }, - { - "label": "LocalAuthModule", - "file_type": "code", - "source_file": "apps/rebreak-native/stores/appLock.ts", - "source_location": "L11", - "community": 20, - "norm_label": "localauthmodule", - "id": "stores_applock_localauthmodule" - }, - { - "label": "AppLockState", - "file_type": "code", - "source_file": "apps/rebreak-native/stores/appLock.ts", - "source_location": "L40", - "community": 20, - "norm_label": "applockstate", - "id": "stores_applock_applockstate" - }, - { - "label": "useAppLockStore", - "file_type": "code", - "source_file": "apps/rebreak-native/stores/appLock.ts", - "source_location": "L58", - "community": 20, - "norm_label": "useapplockstore", - "id": "stores_applock_useapplockstore" - }, { "label": "lyraVoice.ts", "file_type": "code", @@ -30480,7 +30606,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/theme.ts", "source_location": "L1", - "community": 20, + "community": 17, "norm_label": "theme.ts", "id": "apps_rebreak_native_stores_theme_ts" }, @@ -30489,7 +30615,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/theme.ts", "source_location": "L5", - "community": 20, + "community": 17, "norm_label": "thememode", "id": "stores_theme_thememode" }, @@ -30498,7 +30624,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/theme.ts", "source_location": "L9", - "community": 20, + "community": 17, "norm_label": "resolvecolorscheme()", "id": "stores_theme_resolvecolorscheme" }, @@ -30507,7 +30633,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/theme.ts", "source_location": "L16", - "community": 20, + "community": 17, "norm_label": "themestate", "id": "stores_theme_themestate" }, @@ -30516,7 +30642,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/theme.ts", "source_location": "L23", - "community": 20, + "community": 17, "norm_label": "usethemestore", "id": "stores_theme_usethemestore" }, @@ -30606,7 +30732,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/realtimeDebug.ts", "source_location": "L1", - "community": 8, + "community": 22, "norm_label": "realtimedebug.ts", "id": "apps_rebreak_native_stores_realtimedebug_ts" }, @@ -30615,7 +30741,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/realtimeDebug.ts", "source_location": "L4", - "community": 8, + "community": 22, "norm_label": "logentry", "id": "stores_realtimedebug_logentry" }, @@ -30624,7 +30750,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/realtimeDebug.ts", "source_location": "L10", - "community": 8, + "community": 22, "norm_label": "realtimedebugstate", "id": "stores_realtimedebug_realtimedebugstate" }, @@ -30633,7 +30759,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/realtimeDebug.ts", "source_location": "L26", - "community": 8, + "community": 20, "norm_label": "userealtimedebugstore", "id": "stores_realtimedebug_userealtimedebugstore" }, @@ -32244,7 +32370,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L1", - "community": 422, + "community": 20, "norm_label": "brandsplash.tsx", "id": "apps_rebreak_native_components_brandsplash_tsx" }, @@ -32253,7 +32379,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L16", - "community": 422, + "community": 20, "norm_label": "{ width: sw, height: sh }", "id": "components_brandsplash_width_sw_height_sh" }, @@ -32262,7 +32388,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L18", - "community": 422, + "community": 20, "norm_label": "particleconfig", "id": "components_brandsplash_particleconfig" }, @@ -32271,7 +32397,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L28", - "community": 422, + "community": 20, "norm_label": "particles", "id": "components_brandsplash_particles" }, @@ -32280,7 +32406,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L36", - "community": 422, + "community": 20, "norm_label": "particle()", "id": "components_brandsplash_particle" }, @@ -32289,7 +32415,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L106", - "community": 422, + "community": 20, "norm_label": "brandsplash()", "id": "components_brandsplash_brandsplash" }, @@ -32298,7 +32424,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/SheetFieldStack.tsx", "source_location": "L13", - "community": 8, + "community": 18, "norm_label": "sheetfield", "id": "components_sheetfieldstack_sheetfield" }, @@ -32307,7 +32433,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/SheetFieldStack.tsx", "source_location": "L28", - "community": 8, + "community": 18, "norm_label": "props", "id": "components_sheetfieldstack_props" }, @@ -32428,30 +32554,12 @@ "norm_label": "appalert()", "id": "components_appalert_appalert" }, - { - "label": "LockScreen.tsx", - "file_type": "code", - "source_file": "apps/rebreak-native/components/LockScreen.tsx", - "source_location": "L1", - "community": 20, - "norm_label": "lockscreen.tsx", - "id": "apps_rebreak_native_components_lockscreen_tsx" - }, - { - "label": "LockScreen()", - "file_type": "code", - "source_file": "apps/rebreak-native/components/LockScreen.tsx", - "source_location": "L23", - "community": 20, - "norm_label": "lockscreen()", - "id": "components_lockscreen_lockscreen" - }, { "label": "ProtectionOffSheet()", "file_type": "code", "source_file": "apps/rebreak-native/components/ProtectionOffSheet.tsx", "source_location": "L22", - "community": 8, + "community": 18, "norm_label": "protectionoffsheet()", "id": "components_protectionoffsheet_protectionoffsheet" }, @@ -32460,7 +32568,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/FormSheet.tsx", "source_location": "L47", - "community": 8, + "community": 18, "norm_label": "formsheetprops", "id": "components_formsheet_formsheetprops" }, @@ -32469,7 +32577,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/FormSheet.tsx", "source_location": "L78", - "community": 8, + "community": 18, "norm_label": "formsheet()", "id": "components_formsheet_formsheet" }, @@ -33018,7 +33126,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/EmptyState.tsx", "source_location": "L5", - "community": 431, + "community": 181, "norm_label": "props", "id": "components_emptystate_props" }, @@ -33027,7 +33135,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/EmptyState.tsx", "source_location": "L12", - "community": 431, + "community": 181, "norm_label": "emptystate()", "id": "components_emptystate_emptystate" }, @@ -33036,7 +33144,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/UserAvatar.tsx", "source_location": "L1", - "community": 53, + "community": 17, "norm_label": "useravatar.tsx", "id": "apps_rebreak_native_components_useravatar_tsx" }, @@ -33045,7 +33153,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/UserAvatar.tsx", "source_location": "L8", - "community": 53, + "community": 17, "norm_label": "size", "id": "components_useravatar_size" }, @@ -33054,7 +33162,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/UserAvatar.tsx", "source_location": "L10", - "community": 53, + "community": 17, "norm_label": "props", "id": "components_useravatar_props" }, @@ -33063,7 +33171,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/UserAvatar.tsx", "source_location": "L19", - "community": 53, + "community": 17, "norm_label": "size_map", "id": "components_useravatar_size_map" }, @@ -33072,7 +33180,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/UserAvatar.tsx", "source_location": "L32", - "community": 53, + "community": 17, "norm_label": "onlinedot()", "id": "components_useravatar_onlinedot" }, @@ -33081,7 +33189,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/UserAvatar.tsx", "source_location": "L56", - "community": 53, + "community": 17, "norm_label": "useravatar()", "id": "components_useravatar_useravatar" }, @@ -33090,7 +33198,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/ProtectionOnboardingSheet.tsx", "source_location": "L1", - "community": 8, + "community": 18, "norm_label": "protectiononboardingsheet.tsx", "id": "apps_rebreak_native_components_protectiononboardingsheet_tsx" }, @@ -33099,7 +33207,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/ProtectionOnboardingSheet.tsx", "source_location": "L9", - "community": 8, + "community": 18, "norm_label": "stepstate", "id": "components_protectiononboardingsheet_stepstate" }, @@ -33108,7 +33216,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/ProtectionOnboardingSheet.tsx", "source_location": "L168", - "community": 8, + "community": 18, "norm_label": "stepcard()", "id": "components_protectiononboardingsheet_stepcard" }, @@ -33117,7 +33225,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/MessageActionMenu.tsx", "source_location": "L29", - "community": 605, + "community": 17, "norm_label": "reaction_emojis", "id": "chat_messageactionmenu_reaction_emojis" }, @@ -33126,7 +33234,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/MessageActionMenu.tsx", "source_location": "L31", - "community": 605, + "community": 17, "norm_label": "anchorrect", "id": "chat_messageactionmenu_anchorrect" }, @@ -33135,7 +33243,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/MessageActionMenu.tsx", "source_location": "L33", - "community": 605, + "community": 17, "norm_label": "props", "id": "chat_messageactionmenu_props" }, @@ -33144,7 +33252,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/MessageActionMenu.tsx", "source_location": "L49", - "community": 605, + "community": 17, "norm_label": "messageactionmenu()", "id": "chat_messageactionmenu_messageactionmenu" }, @@ -33153,7 +33261,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/MessageActionMenu.tsx", "source_location": "L191", - "community": 605, + "community": 17, "norm_label": "styles", "id": "chat_messageactionmenu_styles" }, @@ -33162,7 +33270,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/DmChatBackground.tsx", "source_location": "L9", - "community": 20, + "community": 17, "norm_label": "symbol", "id": "chat_dmchatbackground_symbol" }, @@ -33171,7 +33279,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/DmChatBackground.tsx", "source_location": "L11", - "community": 20, + "community": 17, "norm_label": "sequence", "id": "chat_dmchatbackground_sequence" }, @@ -33180,7 +33288,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/DmChatBackground.tsx", "source_location": "L16", - "community": 20, + "community": 17, "norm_label": "symbolshape()", "id": "chat_dmchatbackground_symbolshape" }, @@ -33189,7 +33297,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/DmChatBackground.tsx", "source_location": "L78", - "community": 20, + "community": 17, "norm_label": "dmchatbackground()", "id": "chat_dmchatbackground_dmchatbackground" }, @@ -33198,7 +33306,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatHeaderStatus.tsx", "source_location": "L6", - "community": 29, + "community": 17, "norm_label": "props", "id": "chat_chatheaderstatus_props" }, @@ -33207,7 +33315,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatHeaderStatus.tsx", "source_location": "L10", - "community": 29, + "community": 17, "norm_label": "formatlastseen()", "id": "chat_chatheaderstatus_formatlastseen" }, @@ -33216,7 +33324,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatHeaderStatus.tsx", "source_location": "L18", - "community": 29, + "community": 17, "norm_label": "chatheaderstatus()", "id": "chat_chatheaderstatus_chatheaderstatus" }, @@ -33225,7 +33333,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/CreateRoomSheet.tsx", "source_location": "L15", - "community": 8, + "community": 18, "norm_label": "props", "id": "chat_createroomsheet_props" }, @@ -33234,7 +33342,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/CreateRoomSheet.tsx", "source_location": "L21", - "community": 8, + "community": 18, "norm_label": "createroomsheet()", "id": "chat_createroomsheet_createroomsheet" }, @@ -33243,7 +33351,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/CreateRoomSheet.tsx", "source_location": "L162", - "community": 8, + "community": 18, "norm_label": "makestyles()", "id": "chat_createroomsheet_makestyles" }, @@ -33297,7 +33405,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatBubble.tsx", "source_location": "L17", - "community": 605, + "community": 17, "norm_label": "messagereaction", "id": "chat_chatbubble_messagereaction" }, @@ -33315,7 +33423,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatBubble.tsx", "source_location": "L48", - "community": 605, + "community": 17, "norm_label": "props", "id": "chat_chatbubble_props" }, @@ -33324,7 +33432,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatBubble.tsx", "source_location": "L65", - "community": 605, + "community": 17, "norm_label": "formattime()", "id": "chat_chatbubble_formattime" }, @@ -33333,7 +33441,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatBubble.tsx", "source_location": "L69", - "community": 605, + "community": 17, "norm_label": "usebubblecolors()", "id": "chat_chatbubble_usebubblecolors" }, @@ -33342,7 +33450,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatBubble.tsx", "source_location": "L82", - "community": 605, + "community": 17, "norm_label": "chatbubble()", "id": "chat_chatbubble_chatbubble" }, @@ -33351,7 +33459,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatBubble.tsx", "source_location": "L422", - "community": 605, + "community": 17, "norm_label": "makestyles()", "id": "chat_chatbubble_makestyles" }, @@ -33423,7 +33531,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailActivityLog.tsx", "source_location": "L20", - "community": 865, + "community": 21, "norm_label": "props", "id": "mail_mailactivitylog_props" }, @@ -33432,7 +33540,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailActivityLog.tsx", "source_location": "L26", - "community": 865, + "community": 21, "norm_label": "formatdate()", "id": "mail_mailactivitylog_formatdate" }, @@ -33441,7 +33549,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailActivityLog.tsx", "source_location": "L38", - "community": 865, + "community": 21, "norm_label": "domainfromemail()", "id": "mail_mailactivitylog_domainfromemail" }, @@ -33450,7 +33558,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailActivityLog.tsx", "source_location": "L42", - "community": 865, + "community": 21, "norm_label": "providerdisplayname()", "id": "mail_mailactivitylog_providerdisplayname" }, @@ -33459,7 +33567,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailActivityLog.tsx", "source_location": "L54", - "community": 865, + "community": 21, "norm_label": "mailactivitylog()", "id": "mail_mailactivitylog_mailactivitylog" }, @@ -33468,7 +33576,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailActivityLog.tsx", "source_location": "L239", - "community": 865, + "community": 21, "norm_label": "activityitem()", "id": "mail_mailactivitylog_activityitem" }, @@ -33477,7 +33585,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailDistributionChart.tsx", "source_location": "L8", - "community": 21, + "community": 8, "norm_label": "props", "id": "mail_maildistributionchart_props" }, @@ -33486,7 +33594,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailDistributionChart.tsx", "source_location": "L16", - "community": 21, + "community": 8, "norm_label": "slice_colors", "id": "mail_maildistributionchart_slice_colors" }, @@ -33495,7 +33603,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailDistributionChart.tsx", "source_location": "L23", - "community": 21, + "community": 8, "norm_label": "formatcompact()", "id": "mail_maildistributionchart_formatcompact" }, @@ -33504,7 +33612,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailDistributionChart.tsx", "source_location": "L30", - "community": 21, + "community": 8, "norm_label": "domainfromemail()", "id": "mail_maildistributionchart_domainfromemail" }, @@ -33513,7 +33621,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailDistributionChart.tsx", "source_location": "L34", - "community": 21, + "community": 8, "norm_label": "displaylabel()", "id": "mail_maildistributionchart_displaylabel" }, @@ -33522,7 +33630,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailDistributionChart.tsx", "source_location": "L38", - "community": 21, + "community": 8, "norm_label": "maildistributionchart()", "id": "mail_maildistributionchart_maildistributionchart" }, @@ -33531,7 +33639,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailDistributionChart.tsx", "source_location": "L155", - "community": 21, + "community": 8, "norm_label": "legendrow()", "id": "mail_maildistributionchart_legendrow" }, @@ -33540,7 +33648,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailAccountSettingsSheet.tsx", "source_location": "L18", - "community": 8, + "community": 29, "norm_label": "editmode", "id": "mail_mailaccountsettingssheet_editmode" }, @@ -33549,7 +33657,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailAccountSettingsSheet.tsx", "source_location": "L20", - "community": 8, + "community": 29, "norm_label": "props", "id": "mail_mailaccountsettingssheet_props" }, @@ -33558,7 +33666,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailAccountSettingsSheet.tsx", "source_location": "L34", - "community": 8, + "community": 29, "norm_label": "interval_options_by_plan", "id": "mail_mailaccountsettingssheet_interval_options_by_plan" }, @@ -33567,7 +33675,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailAccountSettingsSheet.tsx", "source_location": "L40", - "community": 8, + "community": 29, "norm_label": "domainfromemail()", "id": "mail_mailaccountsettingssheet_domainfromemail" }, @@ -33576,7 +33684,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailAccountSettingsSheet.tsx", "source_location": "L44", - "community": 8, + "community": 29, "norm_label": "settingsrow()", "id": "mail_mailaccountsettingssheet_settingsrow" }, @@ -33585,7 +33693,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailAccountSettingsSheet.tsx", "source_location": "L97", - "community": 8, + "community": 29, "norm_label": "editview()", "id": "mail_mailaccountsettingssheet_editview" }, @@ -33594,7 +33702,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailAccountSettingsSheet.tsx", "source_location": "L209", - "community": 8, + "community": 29, "norm_label": "mailaccountsettingssheet()", "id": "mail_mailaccountsettingssheet_mailaccountsettingssheet" }, @@ -33603,7 +33711,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailWeeklyChart.tsx", "source_location": "L8", - "community": 21, + "community": 29, "norm_label": "props", "id": "mail_mailweeklychart_props" }, @@ -33612,7 +33720,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailWeeklyChart.tsx", "source_location": "L18", - "community": 21, + "community": 29, "norm_label": "mailweeklychart()", "id": "mail_mailweeklychart_mailweeklychart" }, @@ -33621,7 +33729,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailConsentReminderSheet.tsx", "source_location": "L12", - "community": 47, + "community": 29, "norm_label": "pendingconnection", "id": "mail_mailconsentremindersheet_pendingconnection" }, @@ -33630,7 +33738,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailConsentReminderSheet.tsx", "source_location": "L17", - "community": 47, + "community": 29, "norm_label": "props", "id": "mail_mailconsentremindersheet_props" }, @@ -33639,7 +33747,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/MailConsentReminderSheet.tsx", "source_location": "L23", - "community": 47, + "community": 29, "norm_label": "mailconsentremindersheet()", "id": "mail_mailconsentremindersheet_mailconsentremindersheet" }, @@ -33891,7 +33999,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/EditMailTitleSheet.tsx", "source_location": "L8", - "community": 8, + "community": 29, "norm_label": "props", "id": "mail_editmailtitlesheet_props" }, @@ -33900,7 +34008,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/mail/EditMailTitleSheet.tsx", "source_location": "L16", - "community": 8, + "community": 29, "norm_label": "editmailtitlesheet()", "id": "mail_editmailtitlesheet_editmailtitlesheet" }, @@ -34017,7 +34125,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/LayerSwitchCard.tsx", "source_location": "L5", - "community": 17, + "community": 22, "norm_label": "props", "id": "blocker_layerswitchcard_props" }, @@ -34026,7 +34134,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/LayerSwitchCard.tsx", "source_location": "L23", - "community": 17, + "community": 22, "norm_label": "layerswitchcard()", "id": "blocker_layerswitchcard_layerswitchcard" }, @@ -34287,7 +34395,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/CooldownBanner.tsx", "source_location": "L1", - "community": 17, + "community": 22, "norm_label": "cooldownbanner.tsx", "id": "apps_rebreak_native_components_blocker_cooldownbanner_tsx" }, @@ -34296,7 +34404,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/CooldownBanner.tsx", "source_location": "L7", - "community": 17, + "community": 22, "norm_label": "props", "id": "blocker_cooldownbanner_props" }, @@ -34305,7 +34413,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/CooldownBanner.tsx", "source_location": "L12", - "community": 17, + "community": 22, "norm_label": "cooldownbanner()", "id": "blocker_cooldownbanner_cooldownbanner" }, @@ -34449,7 +34557,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/common/HalfDonut.tsx", "source_location": "L1", - "community": 27, + "community": 8, "norm_label": "halfdonut.tsx", "id": "apps_rebreak_native_components_common_halfdonut_tsx" }, @@ -34458,7 +34566,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/common/HalfDonut.tsx", "source_location": "L6", - "community": 27, + "community": 8, "norm_label": "halfdonutsegment", "id": "common_halfdonut_halfdonutsegment" }, @@ -34467,7 +34575,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/common/HalfDonut.tsx", "source_location": "L8", - "community": 27, + "community": 8, "norm_label": "props", "id": "common_halfdonut_props" }, @@ -34476,7 +34584,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/common/HalfDonut.tsx", "source_location": "L20", - "community": 27, + "community": 8, "norm_label": "polar()", "id": "common_halfdonut_polar" }, @@ -34485,7 +34593,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/common/HalfDonut.tsx", "source_location": "L25", - "community": 27, + "community": 8, "norm_label": "arcpath()", "id": "common_halfdonut_arcpath" }, @@ -34494,7 +34602,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/common/HalfDonut.tsx", "source_location": "L32", - "community": 27, + "community": 8, "norm_label": "halfdonut()", "id": "common_halfdonut_halfdonut" }, @@ -34755,7 +34863,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/profile/ProfileHeader.tsx", "source_location": "L10", - "community": 156, + "community": 47, "norm_label": "googleicon()", "id": "profile_profileheader_googleicon" }, @@ -34764,7 +34872,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/profile/ProfileHeader.tsx", "source_location": "L21", - "community": 156, + "community": 47, "norm_label": "appleicon()", "id": "profile_profileheader_appleicon" }, @@ -34773,7 +34881,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/profile/ProfileHeader.tsx", "source_location": "L31", - "community": 156, + "community": 47, "norm_label": "props", "id": "profile_profileheader_props" }, @@ -34782,7 +34890,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/profile/ProfileHeader.tsx", "source_location": "L45", - "community": 156, + "community": 47, "norm_label": "planlabel", "id": "profile_profileheader_planlabel" }, @@ -34791,7 +34899,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/profile/ProfileHeader.tsx", "source_location": "L51", - "community": 156, + "community": 47, "norm_label": "plancolors", "id": "profile_profileheader_plancolors" }, @@ -34800,7 +34908,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/profile/ProfileHeader.tsx", "source_location": "L58", - "community": 156, + "community": 47, "norm_label": "profileheader()", "id": "profile_profileheader_profileheader" }, @@ -35016,7 +35124,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/icons/LanguageIcon.tsx", "source_location": "L9", - "community": 20, + "community": 47, "norm_label": "props", "id": "icons_languageicon_props" }, @@ -35025,7 +35133,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/icons/LanguageIcon.tsx", "source_location": "L14", - "community": 20, + "community": 47, "norm_label": "languageicon()", "id": "icons_languageicon_languageicon" }, @@ -35061,7 +35169,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/UrgeGames.tsx", "source_location": "L25", - "community": 568, + "community": 686, "norm_label": "gametype", "id": "urge_urgegames_gametype" }, @@ -35070,7 +35178,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/UrgeGames.tsx", "source_location": "L27", - "community": 5, + "community": 686, "norm_label": "game_meta", "id": "urge_urgegames_game_meta" }, @@ -35160,7 +35268,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/UrgeGames.tsx", "source_location": "L486", - "community": 5, + "community": 686, "norm_label": "memorygame()", "id": "urge_urgegames_memorygame" }, @@ -35223,7 +35331,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/UrgeGames.tsx", "source_location": "L690", - "community": 5, + "community": 686, "norm_label": "tictactoegame()", "id": "urge_urgegames_tictactoegame" }, @@ -35313,7 +35421,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/InlineRatingDrawer.tsx", "source_location": "L22", - "community": 437, + "community": 696, "norm_label": "inlineratingdrawer()", "id": "urge_inlineratingdrawer_inlineratingdrawer" }, @@ -35322,7 +35430,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/InlineRatingDrawer.tsx", "source_location": "L154", - "community": 437, + "community": 696, "norm_label": "s", "id": "urge_inlineratingdrawer_s" }, @@ -35412,7 +35520,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/SosFeedbackModal.tsx", "source_location": "L6", - "community": 437, + "community": 696, "norm_label": "sosfeedback", "id": "urge_sosfeedbackmodal_sosfeedback" }, @@ -35421,7 +35529,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/SosFeedbackModal.tsx", "source_location": "L12", - "community": 437, + "community": 696, "norm_label": "sosfeedbackmodal()", "id": "urge_sosfeedbackmodal_sosfeedbackmodal" }, @@ -35430,7 +35538,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/SosFeedbackModal.tsx", "source_location": "L115", - "community": 437, + "community": 696, "norm_label": "s", "id": "urge_sosfeedbackmodal_s" }, @@ -35511,7 +35619,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/MessageRow.tsx", "source_location": "L8", - "community": 568, + "community": 286, "norm_label": "cardtype", "id": "urge_messagerow_cardtype" }, @@ -35520,7 +35628,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/MessageRow.tsx", "source_location": "L9", - "community": 568, + "community": 286, "norm_label": "sosmsg", "id": "urge_messagerow_sosmsg" }, @@ -35529,7 +35637,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/MessageRow.tsx", "source_location": "L22", - "community": 568, + "community": 286, "norm_label": "overcomecard()", "id": "urge_messagerow_overcomecard" }, @@ -35538,7 +35646,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/MessageRow.tsx", "source_location": "L33", - "community": 568, + "community": 286, "norm_label": "messagerowprops", "id": "urge_messagerow_messagerowprops" }, @@ -35547,7 +35655,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/MessageRow.tsx", "source_location": "L40", - "community": 568, + "community": 286, "norm_label": "messagerow()", "id": "urge_messagerow_messagerow" }, @@ -35556,7 +35664,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/MessageRow.tsx", "source_location": "L56", - "community": 568, + "community": 286, "norm_label": "gameheader()", "id": "urge_messagerow_gameheader" }, @@ -35565,7 +35673,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/MessageRow.tsx", "source_location": "L70", - "community": 568, + "community": 286, "norm_label": "st", "id": "urge_messagerow_st" }, @@ -35574,7 +35682,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/TtsProviderToggle.tsx", "source_location": "L4", - "community": 437, + "community": 865, "norm_label": "providers", "id": "urge_ttsprovidertoggle_providers" }, @@ -35619,7 +35727,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/Breathing.tsx", "source_location": "L1", - "community": 864, + "community": 437, "norm_label": "breathing.tsx", "id": "apps_rebreak_native_components_urge_breathing_tsx" }, @@ -35628,7 +35736,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/Breathing.tsx", "source_location": "L7", - "community": 864, + "community": 437, "norm_label": "props", "id": "urge_breathing_props" }, @@ -35637,7 +35745,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/Breathing.tsx", "source_location": "L9", - "community": 864, + "community": 437, "norm_label": "breathingcard()", "id": "urge_breathing_breathingcard" }, @@ -35646,7 +35754,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/Breathing.tsx", "source_location": "L117", - "community": 864, + "community": 437, "norm_label": "breathingdrawer()", "id": "urge_breathing_breathingdrawer" }, @@ -35655,7 +35763,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/urge/Breathing.tsx", "source_location": "L134", - "community": 864, + "community": 437, "norm_label": "st", "id": "urge_breathing_st" }, @@ -35709,7 +35817,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/games/GameCard.tsx", "source_location": "L9", - "community": 568, + "community": 686, "norm_label": "gamecardprops", "id": "games_gamecard_gamecardprops" }, @@ -35718,7 +35826,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/games/GameCard.tsx", "source_location": "L19", - "community": 568, + "community": 686, "norm_label": "gamecard()", "id": "games_gamecard_gamecard" }, @@ -35727,7 +35835,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/games/StarRating.tsx", "source_location": "L1", - "community": 869, + "community": 441, "norm_label": "starrating.tsx", "id": "apps_rebreak_native_components_games_starrating_tsx" }, @@ -35736,7 +35844,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/games/StarRating.tsx", "source_location": "L7", - "community": 869, + "community": 441, "norm_label": "starsize", "id": "games_starrating_starsize" }, @@ -35745,7 +35853,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/games/StarRating.tsx", "source_location": "L9", - "community": 869, + "community": 441, "norm_label": "sizemap", "id": "games_starrating_sizemap" }, @@ -35754,7 +35862,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/games/StarRating.tsx", "source_location": "L17", - "community": 869, + "community": 441, "norm_label": "starratingprops", "id": "games_starrating_starratingprops" }, @@ -35763,7 +35871,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/games/StarRating.tsx", "source_location": "L27", - "community": 869, + "community": 441, "norm_label": "starrating()", "id": "games_starrating_starrating" }, @@ -35772,7 +35880,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/games/GameRatingStars.tsx", "source_location": "L10", - "community": 869, + "community": 441, "norm_label": "gameratingstars()", "id": "games_gameratingstars_gameratingstars" }, @@ -35826,7 +35934,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/onboarding/SlideProgress.tsx", "source_location": "L9", - "community": 8, + "community": 18, "norm_label": "slideprogress()", "id": "onboarding_slideprogress_slideprogress" }, @@ -35835,7 +35943,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/onboarding/SlideProgress.tsx", "source_location": "L56", - "community": 8, + "community": 18, "norm_label": "clamp01()", "id": "onboarding_slideprogress_clamp01" }, @@ -35844,7 +35952,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/onboarding/ScreenshotPointer.tsx", "source_location": "L28", - "community": 8, + "community": 18, "norm_label": "screenshotpointer()", "id": "onboarding_screenshotpointer_screenshotpointer" }, @@ -35988,7 +36096,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/onboarding/slides/WelcomeSlide.tsx", "source_location": "L10", - "community": 18, + "community": 20, "norm_label": "langs", "id": "slides_welcomeslide_langs" }, @@ -35997,7 +36105,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/onboarding/slides/WelcomeSlide.tsx", "source_location": "L61", - "community": 18, + "community": 20, "norm_label": "welcomeslide()", "id": "slides_welcomeslide_welcomeslide" }, @@ -36006,7 +36114,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/onboarding/slides/WelcomeSlide.tsx", "source_location": "L106", - "community": 18, + "community": 20, "norm_label": "bulletrow()", "id": "slides_welcomeslide_bulletrow" }, @@ -36060,7 +36168,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/onboarding/slides/ProtectionSlide.tsx", "source_location": "L364", - "community": 8, + "community": 18, "norm_label": "a11ypendingview()", "id": "slides_protectionslide_a11ypendingview" }, @@ -36375,7 +36483,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailTitleEdit.ts", "source_location": "L4", - "community": 8, + "community": 29, "norm_label": "usemailtitleedit()", "id": "hooks_usemailtitleedit_usemailtitleedit" }, @@ -36393,7 +36501,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailStatus.ts", "source_location": "L25", - "community": 21, + "community": 29, "norm_label": "dailystat", "id": "hooks_usemailstatus_dailystat" }, @@ -36402,7 +36510,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailStatus.ts", "source_location": "L31", - "community": 21, + "community": 29, "norm_label": "mailstatusresponse", "id": "hooks_usemailstatus_mailstatusresponse" }, @@ -36411,7 +36519,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailStatus.ts", "source_location": "L39", - "community": 21, + "community": 29, "norm_label": "plan", "id": "hooks_usemailstatus_plan" }, @@ -36420,7 +36528,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailStatus.ts", "source_location": "L56", - "community": 21, + "community": 29, "norm_label": "derivemaxaccounts()", "id": "hooks_usemailstatus_derivemaxaccounts" }, @@ -36429,7 +36537,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailStatus.ts", "source_location": "L70", - "community": 21, + "community": 29, "norm_label": "usemailstatus()", "id": "hooks_usemailstatus_usemailstatus" }, @@ -36456,7 +36564,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useUserPlan.ts", "source_location": "L15", - "community": 156, + "community": 47, "norm_label": "useuserplan()", "id": "hooks_useuserplan_useuserplan" }, @@ -36465,7 +36573,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useDomainSubmissionRealtime.ts", "source_location": "L1", - "community": 17, + "community": 22, "norm_label": "usedomainsubmissionrealtime.ts", "id": "apps_rebreak_native_hooks_usedomainsubmissionrealtime_ts" }, @@ -36672,7 +36780,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailResults.ts", "source_location": "L4", - "community": 865, + "community": 21, "norm_label": "mailblockeditem", "id": "hooks_usemailresults_mailblockeditem" }, @@ -36681,7 +36789,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailResults.ts", "source_location": "L23", - "community": 865, + "community": 21, "norm_label": "mailresultsresponse", "id": "hooks_usemailresults_mailresultsresponse" }, @@ -36690,7 +36798,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailResults.ts", "source_location": "L35", - "community": 865, + "community": 21, "norm_label": "usemailresults()", "id": "hooks_usemailresults_usemailresults" }, @@ -36699,7 +36807,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useBlocklistSync.ts", "source_location": "L7", - "community": 17, + "community": 22, "norm_label": "syncresult", "id": "hooks_useblocklistsync_syncresult" }, @@ -36708,7 +36816,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useBlocklistSync.ts", "source_location": "L26", - "community": 17, + "community": 22, "norm_label": "useblocklistsync()", "id": "hooks_useblocklistsync_useblocklistsync" }, @@ -36879,7 +36987,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useCustomDomains.ts", "source_location": "L119", - "community": 863, + "community": 4, "norm_label": "public_email_domains", "id": "hooks_usecustomdomains_public_email_domains" }, @@ -36960,7 +37068,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMe.ts", "source_location": "L1", - "community": 18, + "community": 47, "norm_label": "useme.ts", "id": "apps_rebreak_native_hooks_useme_ts" }, @@ -36969,7 +37077,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMe.ts", "source_location": "L4", - "community": 156, + "community": 47, "norm_label": "plan", "id": "hooks_useme_plan" }, @@ -36978,7 +37086,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMe.ts", "source_location": "L20", - "community": 18, + "community": 47, "norm_label": "onboardingstep", "id": "hooks_useme_onboardingstep" }, @@ -36987,7 +37095,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMe.ts", "source_location": "L30", - "community": 18, + "community": 47, "norm_label": "me", "id": "hooks_useme_me" }, @@ -36996,7 +37104,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMe.ts", "source_location": "L45", - "community": 18, + "community": 47, "norm_label": "listeners", "id": "hooks_useme_listeners" }, @@ -37077,7 +37185,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useChatRealtime.ts", "source_location": "L1", - "community": 17, + "community": 22, "norm_label": "usechatrealtime.ts", "id": "apps_rebreak_native_hooks_usechatrealtime_ts" }, @@ -37086,7 +37194,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useChatRealtime.ts", "source_location": "L11", - "community": 20, + "community": 17, "norm_label": "usedmrealtime()", "id": "hooks_usechatrealtime_usedmrealtime" }, @@ -37104,7 +37212,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useLastSeenHeartbeat.ts", "source_location": "L5", - "community": 18, + "community": 29, "norm_label": "ping()", "id": "hooks_uselastseenheartbeat_ping" }, @@ -37113,7 +37221,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useLastSeenHeartbeat.ts", "source_location": "L10", - "community": 18, + "community": 29, "norm_label": "uselastseenheartbeat()", "id": "hooks_uselastseenheartbeat_uselastseenheartbeat" }, @@ -37266,7 +37374,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useMailInterval.ts", "source_location": "L8", - "community": 8, + "community": 29, "norm_label": "usemailinterval()", "id": "hooks_usemailinterval_usemailinterval" }, @@ -37275,7 +37383,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useCuratedSuggest.ts", "source_location": "L4", - "community": 22, + "community": 29, "norm_label": "suggestresult", "id": "hooks_usecuratedsuggest_suggestresult" }, @@ -37284,7 +37392,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useCuratedSuggest.ts", "source_location": "L9", - "community": 22, + "community": 29, "norm_label": "suggeststate", "id": "hooks_usecuratedsuggest_suggeststate" }, @@ -37293,7 +37401,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useCuratedSuggest.ts", "source_location": "L11", - "community": 22, + "community": 29, "norm_label": "usecuratedsuggest()", "id": "hooks_usecuratedsuggest_usecuratedsuggest" }, @@ -37419,7 +37527,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L36", - "community": 441, + "community": 11, "norm_label": "libraries", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries" }, @@ -37428,7 +37536,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L37", - "community": 441, + "community": 11, "norm_label": "react_codegen_rncslider::@4898bc4726ecf1751b6a", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rncslider_4898bc4726ecf1751b6a" }, @@ -37437,7 +37545,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L47", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnctabview::@54948b52a0aeebf4e5a8", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnctabview_54948b52a0aeebf4e5a8" }, @@ -37446,7 +37554,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L52", - "community": 441, + "community": 11, "norm_label": "react_codegen_safeareacontext::@7984cd80db47aa7b952a", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_safeareacontext_7984cd80db47aa7b952a" }, @@ -37455,7 +37563,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L62", - "community": 441, + "community": 11, "norm_label": "react_codegen_rngesturehandler_codegen::@39f233abcd2c728bc6ec", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rngesturehandler_codegen_39f233abcd2c728bc6ec" }, @@ -37464,7 +37572,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L67", - "community": 441, + "community": 11, "norm_label": "appmodules::@6890427a1f51a3e7e1df", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_appmodules_6890427a1f51a3e7e1df" }, @@ -37473,7 +37581,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L85", - "community": 441, + "community": 11, "norm_label": "react_codegen_truesheetspec::@a0669760263672514cc3", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_truesheetspec_a0669760263672514cc3" }, @@ -37482,7 +37590,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L95", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnsvg::@4f40eb209d0c0b4a3b65", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnsvg_4f40eb209d0c0b4a3b65" }, @@ -37491,7 +37599,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L105", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnworklets::@68f58d84d4754f193387", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnworklets_68f58d84d4754f193387" }, @@ -37500,7 +37608,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L110", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnasyncstorage::@1596841e19ec5b9eeffe", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnasyncstorage_1596841e19ec5b9eeffe" }, @@ -37509,7 +37617,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L115", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnreanimated::@8afabad14bfffa3f8b9a", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnreanimated_8afabad14bfffa3f8b9a" }, @@ -37518,7 +37626,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L120", - "community": 441, + "community": 11, "norm_label": "core::@1b9a7d546b295b7d0867", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_core_1b9a7d546b295b7d0867" }, @@ -37527,7 +37635,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L121", - "community": 441, + "community": 11, "norm_label": "artifactname", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_core_1b9a7d546b295b7d0867_artifactname" }, @@ -37536,7 +37644,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L122", - "community": 441, + "community": 11, "norm_label": "abi", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_core_1b9a7d546b295b7d0867_abi" }, @@ -37545,7 +37653,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L123", - "community": 441, + "community": 11, "norm_label": "output", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_core_1b9a7d546b295b7d0867_output" }, @@ -37554,7 +37662,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L124", - "community": 441, + "community": 11, "norm_label": "runtimefiles", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_core_1b9a7d546b295b7d0867_runtimefiles" }, @@ -37563,7 +37671,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L126", - "community": 441, + "community": 11, "norm_label": "react-native-mmkv::@4ae6a1e65d3e68ba0197", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_native_mmkv_4ae6a1e65d3e68ba0197" }, @@ -37572,7 +37680,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L136", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnmenuviewspec::@8c49e93dd4e1930e04c8", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnmenuviewspec_8c49e93dd4e1930e04c8" }, @@ -37581,7 +37689,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L141", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnscreens::@25bcbd507e98d3a854ad", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnscreens_25bcbd507e98d3a854ad" }, @@ -37590,7 +37698,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L151", - "community": 441, + "community": 11, "norm_label": "react_codegen_lottiereactnative::@0fa4dc904d7e359a99fb", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_lottiereactnative_0fa4dc904d7e359a99fb" }, @@ -37599,7 +37707,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L156", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnkc::@01e3c54a97c6e9d385b6", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnkc_01e3c54a97c6e9d385b6" }, @@ -37608,7 +37716,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L166", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnmmkvspec::@7541eabbae598da31a69", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnmmkvspec_7541eabbae598da31a69" }, @@ -37617,7 +37725,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json", "source_location": "L171", - "community": 441, + "community": 11, "norm_label": "react_codegen_rnpicker::@e8bb2e9e833f47d0d516", "id": "apps_rebreak_native_android_app_cxx_relwithdebinfo_5m151t3n_armeabi_v7a_android_gradle_build_mini_json_armeabi_v7a_android_gradle_build_mini_libraries_react_codegen_rnpicker_e8bb2e9e833f47d0d516" }, @@ -71460,7 +71568,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/protection.ts", "source_location": "L95", - "community": 93, + "community": 8, "norm_label": "setcooldowntestmode()", "id": "lib_protection_setcooldowntestmode" }, @@ -71712,7 +71820,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosTtsBenchmark.ts", "source_location": "L1", - "community": 258, + "community": 687, "norm_label": "sosttsbenchmark.ts", "id": "apps_rebreak_native_lib_sosttsbenchmark_ts" }, @@ -71721,7 +71829,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosTtsBenchmark.ts", "source_location": "L23", - "community": 258, + "community": 687, "norm_label": "benchmarker", "id": "lib_sosttsbenchmark_benchmarker" }, @@ -71730,7 +71838,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosTtsBenchmark.ts", "source_location": "L35", - "community": 258, + "community": 687, "norm_label": "benchonmetric", "id": "lib_sosttsbenchmark_benchonmetric" }, @@ -71739,7 +71847,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosTtsBenchmark.ts", "source_location": "L37", - "community": 258, + "community": 687, "norm_label": "markerentry", "id": "lib_sosttsbenchmark_markerentry" }, @@ -71748,7 +71856,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosTtsBenchmark.ts", "source_location": "L44", - "community": 258, + "community": 687, "norm_label": "benchsession", "id": "lib_sosttsbenchmark_benchsession" }, @@ -71757,7 +71865,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosTtsBenchmark.ts", "source_location": "L52", - "community": 258, + "community": 687, "norm_label": ".constructor()", "id": "lib_sosttsbenchmark_benchsession_constructor" }, @@ -71766,7 +71874,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosTtsBenchmark.ts", "source_location": "L66", - "community": 258, + "community": 687, "norm_label": ".print()", "id": "lib_sosttsbenchmark_benchsession_print" }, @@ -71775,7 +71883,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosTtsBenchmark.ts", "source_location": "L105", - "community": 258, + "community": 687, "norm_label": ".snapshot()", "id": "lib_sosttsbenchmark_benchsession_snapshot" }, @@ -71901,7 +72009,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/i18n.ts", "source_location": "L1", - "community": 18, + "community": 20, "norm_label": "i18n.ts", "id": "apps_rebreak_native_lib_i18n_ts" }, @@ -72117,7 +72225,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/api.ts", "source_location": "L36", - "community": 18, + "community": 29, "norm_label": "apifetch()", "id": "lib_api_apifetch" }, @@ -72171,7 +72279,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosConstants.ts", "source_location": "L1", - "community": 864, + "community": 437, "norm_label": "sosconstants.ts", "id": "apps_rebreak_native_lib_sosconstants_ts" }, @@ -72180,7 +72288,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosConstants.ts", "source_location": "L3", - "community": 864, + "community": 437, "norm_label": "chipset", "id": "lib_sosconstants_chipset" }, @@ -72189,7 +72297,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosConstants.ts", "source_location": "L4", - "community": 864, + "community": 437, "norm_label": "chip", "id": "lib_sosconstants_chip" }, @@ -72198,7 +72306,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosConstants.ts", "source_location": "L6", - "community": 864, + "community": 437, "norm_label": "chip_sets", "id": "lib_sosconstants_chip_sets" }, @@ -72207,7 +72315,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosConstants.ts", "source_location": "L44", - "community": 864, + "community": 437, "norm_label": "breathphase", "id": "lib_sosconstants_breathphase" }, @@ -72216,7 +72324,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosConstants.ts", "source_location": "L45", - "community": 864, + "community": 437, "norm_label": "breathstate", "id": "lib_sosconstants_breathstate" }, @@ -72306,7 +72414,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/ttsProvider.ts", "source_location": "L7", - "community": 437, + "community": 865, "norm_label": "ttsprovider", "id": "lib_ttsprovider_ttsprovider" }, @@ -72315,7 +72423,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/ttsProvider.ts", "source_location": "L12", - "community": 437, + "community": 865, "norm_label": "tts_provider_label", "id": "lib_ttsprovider_tts_provider_label" }, @@ -72324,7 +72432,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/ttsProvider.ts", "source_location": "L20", - "community": 437, + "community": 865, "norm_label": "tts_provider_endpoint", "id": "lib_ttsprovider_tts_provider_endpoint" }, @@ -72333,7 +72441,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/ttsProvider.ts", "source_location": "L28", - "community": 437, + "community": 865, "norm_label": "listeners", "id": "lib_ttsprovider_listeners" }, @@ -72342,7 +72450,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/ttsProvider.ts", "source_location": "L31", - "community": 437, + "community": 865, "norm_label": "loadttsprovider()", "id": "lib_ttsprovider_loadttsprovider" }, @@ -72360,7 +72468,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/ttsProvider.ts", "source_location": "L47", - "community": 437, + "community": 865, "norm_label": "endpointforprovider()", "id": "lib_ttsprovider_endpointforprovider" }, @@ -72369,7 +72477,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/ttsProvider.ts", "source_location": "L54", - "community": 437, + "community": 865, "norm_label": "currentprovider()", "id": "lib_ttsprovider_currentprovider" }, @@ -72378,7 +72486,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosStream.ts", "source_location": "L1", - "community": 258, + "community": 687, "norm_label": "sosstream.ts", "id": "apps_rebreak_native_lib_sosstream_ts" }, @@ -72387,7 +72495,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosStream.ts", "source_location": "L17", - "community": 258, + "community": 687, "norm_label": "sseevents", "id": "lib_sosstream_sseevents" }, @@ -72396,7 +72504,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosStream.ts", "source_location": "L53", - "community": 258, + "community": 687, "norm_label": "consumecompletedsentences()", "id": "lib_sosstream_consumecompletedsentences" }, @@ -72405,7 +72513,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosStream.ts", "source_location": "L68", - "community": 258, + "community": 687, "norm_label": "streamsoslyra()", "id": "lib_sosstream_streamsoslyra" }, @@ -72504,7 +72612,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/theme.ts", "source_location": "L1", - "community": 8, + "community": 18, "norm_label": "theme.ts", "id": "apps_rebreak_native_lib_theme_ts" }, @@ -72513,7 +72621,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/theme.ts", "source_location": "L3", - "community": 8, + "community": 18, "norm_label": "theme", "id": "lib_theme_theme" }, @@ -72522,7 +72630,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/theme.ts", "source_location": "L15", - "community": 8, + "community": 18, "norm_label": "colorscheme", "id": "lib_theme_colorscheme" }, @@ -72531,7 +72639,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/theme.ts", "source_location": "L33", - "community": 8, + "community": 18, "norm_label": "light", "id": "lib_theme_light" }, @@ -72540,7 +72648,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/theme.ts", "source_location": "L49", - "community": 8, + "community": 18, "norm_label": "dark", "id": "lib_theme_dark" }, @@ -72558,7 +72666,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/supabase.ts", "source_location": "L1", - "community": 17, + "community": 22, "norm_label": "supabase.ts", "id": "apps_rebreak_native_lib_supabase_ts" }, @@ -72567,7 +72675,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/supabase.ts", "source_location": "L6", - "community": 17, + "community": 22, "norm_label": "supabaseurl", "id": "lib_supabase_supabaseurl" }, @@ -72576,7 +72684,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/supabase.ts", "source_location": "L7", - "community": 17, + "community": 22, "norm_label": "supabaseanonkey", "id": "lib_supabase_supabaseanonkey" }, @@ -72585,7 +72693,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/supabase.ts", "source_location": "L16", - "community": 17, + "community": 22, "norm_label": "supabase", "id": "lib_supabase_supabase" }, @@ -72783,7 +72891,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/ios/RebreakProtectionModule.swift", "source_location": "L85", - "community": 262, + "community": 288, "norm_label": "wkwebview", "id": "wkwebview" }, @@ -72855,7 +72963,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/ios/RebreakProtectionModule.swift", "source_location": "L1342", - "community": 875, + "community": 66, "norm_label": ".findrebreaktunnel()", "id": "ios_rebreakprotectionmodule_rebreakprotectionmodule_findrebreaktunnel" }, @@ -72864,7 +72972,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/ios/RebreakProtectionModule.swift", "source_location": "L1342", - "community": 875, + "community": 66, "norm_label": "netunnelprovidermanager", "id": "netunnelprovidermanager" }, @@ -72873,7 +72981,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/ios/RebreakProtectionModule.swift", "source_location": "L1358", - "community": 875, + "community": 66, "norm_label": ".loadorcreatetunnelmanager()", "id": "ios_rebreakprotectionmodule_rebreakprotectionmodule_loadorcreatetunnelmanager" }, @@ -73071,7 +73179,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/ios/RebreakProtectionModule.swift", "source_location": "L1583", - "community": 288, + "community": 262, "norm_label": ".durationms()", "id": "ios_rebreakprotectionmodule_healthprobedelegate_durationms" }, @@ -73206,7 +73314,7 @@ "file_type": "code", "source_file": "", "source_location": "", - "community": 54, + "community": 418, "norm_label": "error", "id": "error" }, @@ -73386,7 +73494,7 @@ "file_type": "code", "source_file": "", "source_location": "", - "community": 54, + "community": 418, "norm_label": "customstringconvertible", "id": "customstringconvertible" }, @@ -75141,7 +75249,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/android/src/main/java/expo/modules/rebreakprotection/vpn/RebreakVpnService.kt", "source_location": "L247", - "community": 431, + "community": 181, "norm_label": "notification", "id": "notification" }, @@ -75645,7 +75753,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/src/RebreakProtection.types.ts", "source_location": "L74", - "community": 93, + "community": 66, "norm_label": "disableresult", "id": "src_rebreakprotection_types_disableresult" }, @@ -75735,7 +75843,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/src/RebreakProtectionModule.web.ts", "source_location": "L17", - "community": 93, + "community": 66, "norm_label": ".activate()", "id": "src_rebreakprotectionmodule_web_rebreakprotectionmoduleweb_activate" }, @@ -75744,7 +75852,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/src/RebreakProtectionModule.web.ts", "source_location": "L21", - "community": 93, + "community": 66, "norm_label": ".disable()", "id": "src_rebreakprotectionmodule_web_rebreakprotectionmoduleweb_disable" }, @@ -75753,7 +75861,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/modules/rebreak-protection/src/RebreakProtectionModule.web.ts", "source_location": "L25", - "community": 93, + "community": 66, "norm_label": ".getdevicestate()", "id": "src_rebreakprotectionmodule_web_rebreakprotectionmoduleweb_getdevicestate" }, @@ -76639,7 +76747,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/BloomFilterTool/BloomFilterTool/BloomFilterTool.swift", "source_location": "L34", - "community": 54, + "community": 418, "norm_label": "url", "id": "apps_rebreak_native_tmp_filteringtrafficbyurl_bloomfiltertool_bloomfiltertool_bloomfiltertool_swift_url" }, @@ -76648,7 +76756,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/BloomFilterTool/BloomFilterTool/BloomFilterTool.swift", "source_location": "L53", - "community": 54, + "community": 418, "norm_label": ".run()", "id": "bloomfiltertool_bloomfiltertool_bloomfiltertool_run" }, @@ -76657,7 +76765,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/BloomFilterTool/BloomFilterTool/BloomFilterTool.swift", "source_location": "L101", - "community": 54, + "community": 418, "norm_label": ".readto()", "id": "bloomfiltertool_bloomfiltertool_bloomfiltertool_readto" }, @@ -76666,7 +76774,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/BloomFilterTool/BloomFilterTool/BloomFilterTool.swift", "source_location": "L101", - "community": 54, + "community": 418, "norm_label": "string", "id": "apps_rebreak_native_tmp_filteringtrafficbyurl_bloomfiltertool_bloomfiltertool_bloomfiltertool_swift_string" }, @@ -76684,7 +76792,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/BloomFilterTool/BloomFilterTool/BloomFilterTool.swift", "source_location": "L135", - "community": 54, + "community": 418, "norm_label": ".createbloomfilterfile()", "id": "bloomfiltertool_bloomfiltertool_bloomfiltertool_createbloomfilterfile" }, @@ -76693,7 +76801,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/BloomFilterTool/BloomFilterTool/BloomFilterTool.swift", "source_location": "L156", - "community": 54, + "community": 418, "norm_label": ".createpirdatafile()", "id": "bloomfiltertool_bloomfiltertool_bloomfiltertool_createpirdatafile" }, @@ -76702,7 +76810,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/BloomFilterTool/BloomFilterTool/BloomFilterTool.swift", "source_location": "L169", - "community": 54, + "community": 418, "norm_label": "runtimeerror", "id": "bloomfiltertool_bloomfiltertool_runtimeerror" }, @@ -76711,7 +76819,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/BloomFilterTool/BloomFilterTool/BloomFilterTool.swift", "source_location": "L172", - "community": 54, + "community": 418, "norm_label": ".init()", "id": "bloomfiltertool_bloomfiltertool_runtimeerror_init" }, @@ -77485,7 +77593,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/SimpleURLFilter/SimpleURLFilter/Model/ConfigurationModel.swift", "source_location": "L162", - "community": 290, + "community": 418, "norm_label": "configurationerror", "id": "model_configurationmodel_configurationerror" }, @@ -77494,7 +77602,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/tmp/FilteringTrafficByURL/SimpleURLFilter/SimpleURLFilter/Model/ConfigurationModel.swift", "source_location": "L163", - "community": 290, + "community": 418, "norm_label": "badconfiguration", "id": "model_configurationmodel_configurationerror_badconfiguration" }, @@ -78007,7 +78115,7 @@ "file_type": "code", "source_file": "", "source_location": "", - "community": 124, + "community": 74, "norm_label": "caseiterable", "id": "caseiterable" }, @@ -79101,7 +79209,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Models/DeviceState.swift", "source_location": "L4", - "community": 109, + "community": 864, "norm_label": "string", "id": "apps_rebreak_magic_mac_sources_models_devicestate_swift_string" }, @@ -79110,7 +79218,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Models/DeviceState.swift", "source_location": "L9", - "community": 109, + "community": 864, "norm_label": "bool", "id": "apps_rebreak_magic_mac_sources_models_devicestate_swift_bool" }, @@ -79119,7 +79227,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Models/DeviceState.swift", "source_location": "L14", - "community": 109, + "community": 864, "norm_label": "enrollmentstatus", "id": "enrollmentstatus" }, @@ -79533,7 +79641,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Views/PreflightView.swift", "source_location": "L3", - "community": 50, + "community": 603, "norm_label": "preflightview", "id": "views_preflightview_preflightview" }, @@ -79542,7 +79650,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Views/PreflightView.swift", "source_location": "L64", - "community": 50, + "community": 603, "norm_label": ".checklistitem()", "id": "views_preflightview_preflightview_checklistitem" }, @@ -79551,7 +79659,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Views/PreflightView.swift", "source_location": "L64", - "community": 50, + "community": 603, "norm_label": "binding", "id": "apps_rebreak_magic_mac_sources_views_preflightview_swift_binding" }, @@ -79560,7 +79668,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Views/PreflightView.swift", "source_location": "L64", - "community": 50, + "community": 603, "norm_label": "bool", "id": "apps_rebreak_magic_mac_sources_views_preflightview_swift_bool" }, @@ -79569,7 +79677,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Views/PreflightView.swift", "source_location": "L64", - "community": 50, + "community": 603, "norm_label": "string", "id": "apps_rebreak_magic_mac_sources_views_preflightview_swift_string" }, @@ -79848,7 +79956,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Views/StepIndicator.swift", "source_location": "L3", - "community": 696, + "community": 50, "norm_label": "stepindicator", "id": "views_stepindicator_stepindicator" }, @@ -79857,7 +79965,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Views/StepIndicator.swift", "source_location": "L4", - "community": 696, + "community": 50, "norm_label": "wizardstep", "id": "apps_rebreak_magic_mac_sources_views_stepindicator_swift_wizardstep" }, @@ -79866,7 +79974,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-mac/Sources/Views/StepIndicator.swift", "source_location": "L25", - "community": 696, + "community": 50, "norm_label": "color", "id": "color" }, @@ -80973,7 +81081,7 @@ "file_type": "code", "source_file": "apps/marketing/app/locales/de.json", "source_location": "L1", - "community": 686, + "community": 863, "norm_label": "de.json", "id": "apps_marketing_app_locales_de_json" }, @@ -80982,7 +81090,7 @@ "file_type": "code", "source_file": "apps/marketing/app/locales/de.json", "source_location": "L2", - "community": 686, + "community": 863, "norm_label": "nav", "id": "locales_de_nav" }, @@ -80991,7 +81099,7 @@ "file_type": "code", "source_file": "apps/marketing/app/locales/de.json", "source_location": "L5", - "community": 686, + "community": 863, "norm_label": "login", "id": "locales_de_nav_login" }, @@ -81000,7 +81108,7 @@ "file_type": "code", "source_file": "apps/marketing/app/locales/de.json", "source_location": "L6", - "community": 686, + "community": 863, "norm_label": "download_app", "id": "locales_de_nav_download_app" }, @@ -82899,7 +83007,7 @@ "file_type": "code", "source_file": "apps/marketing/app/locales/en.json", "source_location": "L1", - "community": 687, + "community": 70, "norm_label": "en.json", "id": "apps_marketing_app_locales_en_json" }, @@ -82908,7 +83016,7 @@ "file_type": "code", "source_file": "apps/marketing/app/locales/en.json", "source_location": "L2", - "community": 687, + "community": 70, "norm_label": "nav", "id": "locales_en_nav" }, @@ -82917,7 +83025,7 @@ "file_type": "code", "source_file": "apps/marketing/app/locales/en.json", "source_location": "L5", - "community": 687, + "community": 70, "norm_label": "login", "id": "locales_en_nav_login" }, @@ -82926,7 +83034,7 @@ "file_type": "code", "source_file": "apps/marketing/app/locales/en.json", "source_location": "L6", - "community": 687, + "community": 70, "norm_label": "download_app", "id": "locales_en_nav_download_app" }, @@ -85204,32 +85312,6 @@ "norm_label": "deploy admin staging workflow", "id": "workflows_deploy_admin_staging_workflow" }, - { - "label": "Deploy Staging Workflow (backend Nitro)", - "file_type": "document", - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "source_url": null, - "captured_at": null, - "author": null, - "contributor": null, - "community": 430, - "norm_label": "deploy staging workflow (backend nitro)", - "id": "workflows_deploy_staging_workflow" - }, - { - "label": "GitHub-Actions Deploy Pipeline (build-on-runner, scp-to-Hetzner)", - "file_type": "rationale", - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "source_url": null, - "captured_at": null, - "author": null, - "contributor": null, - "community": 430, - "norm_label": "github-actions deploy pipeline (build-on-runner, scp-to-hetzner)", - "id": "workflows_deploy_staging_gh_actions_pipeline" - }, { "label": "Maestro Cloud E2E CI Workflow (template)", "file_type": "document", @@ -85291,7 +85373,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 870, + "community": 276, "norm_label": "rebreak magic mac (self-bind wizard)", "id": "rebreak_magic_mac_readme_magic_mac" }, @@ -85304,7 +85386,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 870, + "community": 276, "norm_label": "supervise-magic (supervise without reset)", "id": "rebreak_magic_mac_readme_supervise_magic" }, @@ -85317,7 +85399,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 870, + "community": 276, "norm_label": "rebreak-magic-mac xcodegen project.yml", "id": "rebreak_magic_mac_project_xcodegen_spec" }, @@ -86162,7 +86244,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 600, + "community": 269, "norm_label": "rebreak-imap-idle daemon readme", "id": "imap-idle_readme_doc" }, @@ -86175,7 +86257,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 600, + "community": 269, "norm_label": "imap idle real-time mail-scan daemon", "id": "imap-idle_readme_daemon" }, @@ -86266,7 +86348,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 422, "norm_label": "rive animator brief \u2014 lyra avatar", "id": "docs_RIVE_ANIMATOR_BRIEF_doc" }, @@ -86279,7 +86361,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 422, "norm_label": "lyra avatar rive emotion-state animation", "id": "docs_RIVE_ANIMATOR_BRIEF_lyra_avatar" }, @@ -86292,7 +86374,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 422, "norm_label": "timeline-name code-contract (no-rename)", "id": "docs_RIVE_ANIMATOR_BRIEF_naming_contract" }, @@ -86305,7 +86387,7 @@ "captured_at": "2026-05-25", "author": null, "contributor": null, - "community": 289, + "community": 269, "norm_label": "layer-2 country-pivot plan", "id": "concepts_layer2-country-pivot_doc" }, @@ -86318,7 +86400,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 269, "norm_label": "layer1/layer2 decoupling (custom vs country-curated)", "id": "concepts_layer2-country-pivot_decoupling" }, @@ -86331,7 +86413,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 269, "norm_label": "country-curated layer-2 blocklist (50-cap)", "id": "concepts_layer2-country-pivot_country_curated" }, @@ -86344,7 +86426,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 269, "norm_label": "travel-detection via cellular-mcc", "id": "concepts_layer2-country-pivot_travel_mcc" }, @@ -86357,7 +86439,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 269, "norm_label": "pro=10/legend=20 custom-domain slots (refillable)", "id": "concepts_layer2-country-pivot_custom_slots" }, @@ -86370,7 +86452,7 @@ "captured_at": "2026-05-09", "author": "Mo", "contributor": null, - "community": 600, + "community": 269, "norm_label": "mail daemon deployment handoff", "id": "internal_MAIL_DAEMON_DEPLOYMENT_doc" }, @@ -86383,7 +86465,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 600, + "community": 269, "norm_label": "pm2 + infisical daemon deploy", "id": "internal_MAIL_DAEMON_DEPLOYMENT_pm2_infisical" }, @@ -86539,7 +86621,7 @@ "captured_at": "2026-05-29", "author": "Chahine Brini", "contributor": null, - "community": 289, + "community": 269, "norm_label": "businessplan nbank grundungskredit 75k", "id": "ops_BUSINESS_PLAN_NBANK_doc" }, @@ -86552,7 +86634,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 269, "norm_label": "oasis offshore-schwarzmarkt versorgungslucke", "id": "ops_BUSINESS_PLAN_NBANK_oasis_gap" }, @@ -86565,7 +86647,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 269, "norm_label": "stripe-web-checkout, no in-app-purchase", "id": "ops_BUSINESS_PLAN_NBANK_pricing_no_iap" }, @@ -86578,7 +86660,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 600, + "community": 269, "norm_label": "usp: only de provider with imap-idle mail-protection", "id": "ops_BUSINESS_PLAN_NBANK_usp_imap_mail" }, @@ -86773,7 +86855,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 422, "norm_label": "lyra ai-coach persona (sos + coach modes)", "id": "ops_LYRA_PERSONA_lyra_coach" }, @@ -86786,7 +86868,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 289, + "community": 422, "norm_label": "forbidden vocabulary (no sucht/addiction/therapie)", "id": "ops_LYRA_PERSONA_forbidden_vocab" }, @@ -88755,7 +88837,7 @@ "file_type": "code", "source_file": "backend/server/utils/magic-removal-email.ts", "source_location": "L1", - "community": 276, + "community": 32, "norm_label": "magic-removal-email.ts", "id": "backend_server_utils_magic_removal_email_ts" }, @@ -88764,7 +88846,7 @@ "file_type": "code", "source_file": "backend/server/utils/magic-removal-email.ts", "source_location": "L17", - "community": 276, + "community": 32, "norm_label": "magicremovalemailopts", "id": "utils_magic_removal_email_magicremovalemailopts" }, @@ -88773,7 +88855,7 @@ "file_type": "code", "source_file": "backend/server/utils/magic-removal-email.ts", "source_location": "L26", - "community": 276, + "community": 32, "norm_label": "sendmagicremovalemail()", "id": "utils_magic_removal_email_sendmagicremovalemail" }, @@ -88980,7 +89062,7 @@ "file_type": "code", "source_file": "backend/server/db/devices.ts", "source_location": "L224", - "community": 32, + "community": 9, "norm_label": "cleanupstaledevices()", "id": "db_devices_cleanupstaledevices" }, @@ -88998,7 +89080,7 @@ "file_type": "code", "source_file": "backend/server/db/devices.ts", "source_location": "L432", - "community": 32, + "community": 80, "norm_label": "listmagicdevices()", "id": "db_devices_listmagicdevices" }, @@ -89034,7 +89116,7 @@ "file_type": "code", "source_file": "backend/server/db/devices.ts", "source_location": "L530", - "community": 276, + "community": 32, "norm_label": "magicremovalcredential", "id": "db_devices_magicremovalcredential" }, @@ -89043,7 +89125,7 @@ "file_type": "code", "source_file": "backend/server/db/devices.ts", "source_location": "L541", - "community": 4, + "community": 32, "norm_label": "listmagicremovalcredentials()", "id": "db_devices_listmagicremovalcredentials" }, @@ -89178,7 +89260,7 @@ "file_type": "code", "source_file": "backend/server/db/protectionStateLog.ts", "source_location": "L5", - "community": 9, + "community": 34, "norm_label": "protectionsource", "id": "db_protectionstatelog_protectionsource" }, @@ -89187,7 +89269,7 @@ "file_type": "code", "source_file": "backend/server/db/protectionStateLog.ts", "source_location": "L18", - "community": 9, + "community": 34, "norm_label": "getlastprotectionevent()", "id": "db_protectionstatelog_getlastprotectionevent" }, @@ -89196,7 +89278,7 @@ "file_type": "code", "source_file": "backend/server/db/protectionStateLog.ts", "source_location": "L30", - "community": 9, + "community": 34, "norm_label": "appendprotectionevent()", "id": "db_protectionstatelog_appendprotectionevent" }, @@ -89205,7 +89287,7 @@ "file_type": "code", "source_file": "backend/server/db/protectionStateLog.ts", "source_location": "L67", - "community": 9, + "community": 34, "norm_label": "protectioncoverage", "id": "db_protectionstatelog_protectioncoverage" }, @@ -89214,7 +89296,7 @@ "file_type": "code", "source_file": "backend/server/db/protectionStateLog.ts", "source_location": "L90", - "community": 9, + "community": 34, "norm_label": "computeprotectioncoverage()", "id": "db_protectionstatelog_computeprotectioncoverage" }, @@ -89223,7 +89305,7 @@ "file_type": "code", "source_file": "backend/server/db/protectionStateLog.ts", "source_location": "L213", - "community": 9, + "community": 34, "norm_label": "utcdaystart()", "id": "db_protectionstatelog_utcdaystart" }, @@ -89241,7 +89323,7 @@ "file_type": "code", "source_file": "backend/server/db/social.ts", "source_location": "L81", - "community": 4, + "community": 39, "norm_label": "cancall()", "id": "db_social_cancall" }, @@ -89268,7 +89350,7 @@ "file_type": "code", "source_file": "backend/server/api/calls/ring.post.ts", "source_location": "L1", - "community": 9, + "community": 4, "norm_label": "ring.post.ts", "id": "backend_server_api_calls_ring_post_ts" }, @@ -89286,7 +89368,7 @@ "file_type": "code", "source_file": "backend/server/api/chat/can-call/[userId].get.ts", "source_location": "L1", - "community": 4, + "community": 39, "norm_label": "[userid].get.ts", "id": "backend_server_api_chat_can_call_userid_get_ts" }, @@ -89331,7 +89413,7 @@ "file_type": "code", "source_file": "backend/server/api/magic/devices.get.ts", "source_location": "L1", - "community": 32, + "community": 80, "norm_label": "devices.get.ts", "id": "backend_server_api_magic_devices_get_ts" }, @@ -89340,7 +89422,7 @@ "file_type": "code", "source_file": "backend/server/api/magic/devices.get.ts", "source_location": "L132", - "community": 32, + "community": 80, "norm_label": "prettyplatform()", "id": "magic_devices_get_prettyplatform" }, @@ -89412,7 +89494,7 @@ "file_type": "code", "source_file": "backend/server/api/protection/event.post.ts", "source_location": "L1", - "community": 9, + "community": 34, "norm_label": "event.post.ts", "id": "backend_server_api_protection_event_post_ts" }, @@ -89421,7 +89503,7 @@ "file_type": "code", "source_file": "backend/server/api/protection/event.post.ts", "source_location": "L7", - "community": 9, + "community": 34, "norm_label": "valid_sources", "id": "protection_event_post_valid_sources" }, @@ -89430,7 +89512,7 @@ "file_type": "code", "source_file": "backend/server/api/protection/coverage.get.ts", "source_location": "L1", - "community": 9, + "community": 34, "norm_label": "coverage.get.ts", "id": "backend_server_api_protection_coverage_get_ts" }, @@ -89439,7 +89521,7 @@ "file_type": "code", "source_file": "backend/server/api/protection/screentime-passcode.get.ts", "source_location": "L1", - "community": 9, + "community": 34, "norm_label": "screentime-passcode.get.ts", "id": "backend_server_api_protection_screentime_passcode_get_ts" }, @@ -89502,7 +89584,7 @@ "file_type": "code", "source_file": "backend/server/api/devices/approvals/[id]/approve.post.ts", "source_location": "L1", - "community": 32, + "community": 257, "norm_label": "approve.post.ts", "id": "backend_server_api_devices_approvals_id_approve_post_ts" }, @@ -89524,51 +89606,6 @@ "norm_label": "reject.post.ts", "id": "backend_server_api_devices_approvals_id_reject_post_ts" }, - { - "label": "DeviceAddedPushPayload", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L131", - "community": 566, - "norm_label": "deviceaddedpushpayload", - "id": "services_push_deviceaddedpushpayload" - }, - { - "label": "devicePlatformLabel()", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L140", - "community": 566, - "norm_label": "deviceplatformlabel()", - "id": "services_push_deviceplatformlabel" - }, - { - "label": "sendDeviceAddedPush()", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L159", - "community": 566, - "norm_label": "senddeviceaddedpush()", - "id": "services_push_senddeviceaddedpush" - }, - { - "label": "CallRingPushPayload", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L223", - "community": 566, - "norm_label": "callringpushpayload", - "id": "services_push_callringpushpayload" - }, - { - "label": "sendCallRingPush()", - "file_type": "code", - "source_file": "backend/server/services/push.ts", - "source_location": "L250", - "community": 566, - "norm_label": "sendcallringpush()", - "id": "services_push_sendcallringpush" - }, { "label": "voip-push.ts", "file_type": "code", @@ -89650,24 +89687,6 @@ "norm_label": "shutdownvoipprovider()", "id": "services_voip_push_shutdownvoipprovider" }, - { - "label": "scanInFlight", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L498", - "community": 68, - "norm_label": "scaninflight", - "id": "imap_idle_index_scaninflight" - }, - { - "label": "coalescePending", - "file_type": "code", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L499", - "community": 68, - "norm_label": "coalescepending", - "id": "imap_idle_index_coalescepending" - }, { "label": "deploy-marketing.sh", "file_type": "code", @@ -90943,7 +90962,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/index.tsx", "source_location": "L16", - "community": 422, + "community": 20, "norm_label": "ease_out", "id": "app_index_ease_out" }, @@ -90952,7 +90971,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/dm.tsx", "source_location": "L31", - "community": 20, + "community": 17, "norm_label": "medialibrarymodule", "id": "app_dm_medialibrarymodule" }, @@ -90961,7 +90980,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/dm.tsx", "source_location": "L76", - "community": 20, + "community": 17, "norm_label": "dmdata", "id": "app_dm_dmdata" }, @@ -90970,7 +90989,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/dm.tsx", "source_location": "L84", - "community": 20, + "community": 17, "norm_label": "mergemessages()", "id": "app_dm_mergemessages" }, @@ -90979,7 +90998,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/dm.tsx", "source_location": "L1038", - "community": 20, + "community": 17, "norm_label": "dminfosheet()", "id": "app_dm_dminfosheet" }, @@ -91006,7 +91025,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/call.tsx", "source_location": "L1", - "community": 53, + "community": 17, "norm_label": "call.tsx", "id": "apps_rebreak_native_app_call_tsx" }, @@ -91015,7 +91034,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/call.tsx", "source_location": "L11", - "community": 53, + "community": 17, "norm_label": "fmtduration()", "id": "app_call_fmtduration" }, @@ -91024,7 +91043,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/call.tsx", "source_location": "L17", - "community": 53, + "community": 17, "norm_label": "callscreen()", "id": "app_call_callscreen" }, @@ -91033,7 +91052,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/app/call.tsx", "source_location": "L182", - "community": 53, + "community": 17, "norm_label": "circlebtn()", "id": "app_call_circlebtn" }, @@ -91285,7 +91304,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/call.ts", "source_location": "L175", - "community": 20, + "community": 17, "norm_label": "usecallstore", "id": "stores_call_usecallstore" }, @@ -91330,7 +91349,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/blockerStats.ts", "source_location": "L4", - "community": 17, + "community": 22, "norm_label": "blockerstats", "id": "stores_blockerstats_blockerstats" }, @@ -91339,7 +91358,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/blockerStats.ts", "source_location": "L23", - "community": 17, + "community": 22, "norm_label": "rawstatsresponse", "id": "stores_blockerstats_rawstatsresponse" }, @@ -91348,7 +91367,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/blockerStats.ts", "source_location": "L47", - "community": 17, + "community": 22, "norm_label": "blockerstatsstate", "id": "stores_blockerstats_blockerstatsstate" }, @@ -91357,7 +91376,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/blockerStats.ts", "source_location": "L63", - "community": 17, + "community": 22, "norm_label": "asnumber()", "id": "stores_blockerstats_asnumber" }, @@ -91366,7 +91385,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/blockerStats.ts", "source_location": "L67", - "community": 17, + "community": 22, "norm_label": "normalizestats()", "id": "stores_blockerstats_normalizestats" }, @@ -91375,7 +91394,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/stores/blockerStats.ts", "source_location": "L108", - "community": 17, + "community": 22, "norm_label": "useblockerstatsstore", "id": "stores_blockerstats_useblockerstatsstore" }, @@ -91521,7 +91540,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L16", - "community": 422, + "community": 20, "norm_label": "{ height: sh }", "id": "components_brandsplash_height_sh" }, @@ -91530,7 +91549,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L18", - "community": 422, + "community": 20, "norm_label": "ease_out", "id": "components_brandsplash_ease_out" }, @@ -91539,7 +91558,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L19", - "community": 422, + "community": 20, "norm_label": "ease_in", "id": "components_brandsplash_ease_in" }, @@ -91548,7 +91567,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/BrandSplash.tsx", "source_location": "L21", - "community": 422, + "community": 20, "norm_label": "props", "id": "components_brandsplash_props" }, @@ -91629,7 +91648,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/DiGaMilestoneModal.tsx", "source_location": "L14", - "community": 27, + "community": 47, "norm_label": "milestones", "id": "components_digamilestonemodal_milestones" }, @@ -91638,7 +91657,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/DiGaMilestoneModal.tsx", "source_location": "L16", - "community": 27, + "community": 47, "norm_label": "storagekey()", "id": "components_digamilestonemodal_storagekey" }, @@ -91647,7 +91666,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/DiGaMilestoneModal.tsx", "source_location": "L22", - "community": 27, + "community": 47, "norm_label": "digamilestonemodal()", "id": "components_digamilestonemodal_digamilestonemodal" }, @@ -91710,7 +91729,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/TypingBubble.tsx", "source_location": "L1", - "community": 20, + "community": 17, "norm_label": "typingbubble.tsx", "id": "apps_rebreak_native_components_chat_typingbubble_tsx" }, @@ -91719,7 +91738,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/TypingBubble.tsx", "source_location": "L15", - "community": 20, + "community": 17, "norm_label": "wavedots()", "id": "chat_typingbubble_wavedots" }, @@ -91728,7 +91747,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/TypingBubble.tsx", "source_location": "L52", - "community": 20, + "community": 17, "norm_label": "typingbubble()", "id": "chat_typingbubble_typingbubble" }, @@ -91737,7 +91756,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/TypingBubble.tsx", "source_location": "L83", - "community": 20, + "community": 17, "norm_label": "styles", "id": "chat_typingbubble_styles" }, @@ -91746,7 +91765,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatBubble.tsx", "source_location": "L19", - "community": 605, + "community": 17, "norm_label": "fmtsec()", "id": "chat_chatbubble_fmtsec" }, @@ -91755,7 +91774,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatBubble.tsx", "source_location": "L27", - "community": 605, + "community": 17, "norm_label": "voicenotebubble()", "id": "chat_chatbubble_voicenotebubble" }, @@ -91764,7 +91783,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/ChatBubble.tsx", "source_location": "L233", - "community": 605, + "community": 17, "norm_label": "callnoterow()", "id": "chat_chatbubble_callnoterow" }, @@ -91773,7 +91792,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/chat/MediaLightbox.tsx", "source_location": "L28", - "community": 20, + "community": 17, "norm_label": "medialightbox()", "id": "chat_medialightbox_medialightbox" }, @@ -91782,7 +91801,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L1", - "community": 17, + "community": 22, "norm_label": "setupflows.tsx", "id": "apps_rebreak_native_components_blocker_setupflows_tsx" }, @@ -91791,7 +91810,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L11", - "community": 17, + "community": 22, "norm_label": "setupflowprops", "id": "blocker_setupflows_setupflowprops" }, @@ -91800,7 +91819,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L25", - "community": 17, + "community": 22, "norm_label": "iosunsupervisedsetupflow()", "id": "blocker_setupflows_iosunsupervisedsetupflow" }, @@ -91809,7 +91828,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L71", - "community": 17, + "community": 22, "norm_label": "setupstep1()", "id": "blocker_setupflows_setupstep1" }, @@ -91818,7 +91837,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L115", - "community": 17, + "community": 22, "norm_label": "setupstep2()", "id": "blocker_setupflows_setupstep2" }, @@ -91827,7 +91846,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L207", - "community": 17, + "community": 22, "norm_label": "setupstep3()", "id": "blocker_setupflows_setupstep3" }, @@ -91836,7 +91855,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L283", - "community": 17, + "community": 22, "norm_label": "androidsetupflow()", "id": "blocker_setupflows_androidsetupflow" }, @@ -91845,7 +91864,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L344", - "community": 17, + "community": 22, "norm_label": "androidstep1()", "id": "blocker_setupflows_androidstep1" }, @@ -91854,7 +91873,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L466", - "community": 17, + "community": 22, "norm_label": "androidstepbattery()", "id": "blocker_setupflows_androidstepbattery" }, @@ -91863,7 +91882,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/blocker/SetupFlows.tsx", "source_location": "L582", - "community": 17, + "community": 22, "norm_label": "setupstepcard()", "id": "blocker_setupflows_setupstepcard" }, @@ -91872,7 +91891,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/onboarding/PermissionConfirmSheet.tsx", "source_location": "L17", - "community": 8, + "community": 18, "norm_label": "permissionconfirmsheet()", "id": "onboarding_permissionconfirmsheet_permissionconfirmsheet" }, @@ -92007,7 +92026,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceSlotDonut.tsx", "source_location": "L14", - "community": 8, + "community": 7, "norm_label": "slotsegment", "id": "devices_deviceslotdonut_slotsegment" }, @@ -92016,7 +92035,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceSlotDonut.tsx", "source_location": "L16", - "community": 8, + "community": 7, "norm_label": "polar()", "id": "devices_deviceslotdonut_polar" }, @@ -92025,7 +92044,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceSlotDonut.tsx", "source_location": "L21", - "community": 8, + "community": 7, "norm_label": "arcpath()", "id": "devices_deviceslotdonut_arcpath" }, @@ -92034,7 +92053,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceSlotDonut.tsx", "source_location": "L34", - "community": 8, + "community": 7, "norm_label": "deviceslotdonut()", "id": "devices_deviceslotdonut_deviceslotdonut" }, @@ -92061,7 +92080,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceDistributionBar.tsx", "source_location": "L12", - "community": 8, + "community": 7, "norm_label": "devicedistributionbar()", "id": "devices_devicedistributionbar_devicedistributionbar" }, @@ -92070,7 +92089,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceDistributionBar.tsx", "source_location": "L89", - "community": 8, + "community": 7, "norm_label": "legend()", "id": "devices_devicedistributionbar_legend" }, @@ -92079,7 +92098,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceDetailSheet.tsx", "source_location": "L15", - "community": 27, + "community": 8, "norm_label": "devicedetail", "id": "devices_devicedetailsheet_devicedetail" }, @@ -92088,7 +92107,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceDetailSheet.tsx", "source_location": "L26", - "community": 27, + "community": 8, "norm_label": "fmtdate()", "id": "devices_devicedetailsheet_fmtdate" }, @@ -92097,7 +92116,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceDetailSheet.tsx", "source_location": "L34", - "community": 27, + "community": 8, "norm_label": "fmtlastseen()", "id": "devices_devicedetailsheet_fmtlastseen" }, @@ -92106,7 +92125,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/components/devices/DeviceDetailSheet.tsx", "source_location": "L224", - "community": 27, + "community": 8, "norm_label": "inforow()", "id": "devices_devicedetailsheet_inforow" }, @@ -92115,7 +92134,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useIncomingCalls.ts", "source_location": "L13", - "community": 20, + "community": 95, "norm_label": "useincomingcalls()", "id": "hooks_useincomingcalls_useincomingcalls" }, @@ -92169,7 +92188,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useDmTyping.ts", "source_location": "L26", - "community": 17, + "community": 22, "norm_label": "usedmtyping()", "id": "hooks_usedmtyping_usedmtyping" }, @@ -92196,7 +92215,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/hooks/useCallKeepEvents.ts", "source_location": "L30", - "community": 20, + "community": 95, "norm_label": "usecallkeepevents()", "id": "hooks_usecallkeepevents_usecallkeepevents" }, @@ -123777,7 +123796,7 @@ "file_type": "code", "source_file": "apps/rebreak-native/lib/sosStream.ts", "source_location": "L19", - "community": 258, + "community": 687, "norm_label": "crisislevel", "id": "lib_sosstream_crisislevel" }, @@ -124713,7 +124732,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-win/src-tauri/tauri.conf.json", "source_location": "L13", - "community": 867, + "community": 443, "norm_label": "windows", "id": "src_tauri_tauri_conf_app_windows" }, @@ -124740,7 +124759,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-win/src-tauri/tauri.conf.json", "source_location": "L28", - "community": 867, + "community": 279, "norm_label": "bundle", "id": "src_tauri_tauri_conf_bundle" }, @@ -124749,7 +124768,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-win/src-tauri/tauri.conf.json", "source_location": "L29", - "community": 867, + "community": 279, "norm_label": "active", "id": "src_tauri_tauri_conf_bundle_active" }, @@ -124758,7 +124777,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-win/src-tauri/tauri.conf.json", "source_location": "L30", - "community": 867, + "community": 279, "norm_label": "targets", "id": "src_tauri_tauri_conf_bundle_targets" }, @@ -124767,7 +124786,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-win/src-tauri/tauri.conf.json", "source_location": "L31", - "community": 867, + "community": 279, "norm_label": "icon", "id": "src_tauri_tauri_conf_bundle_icon" }, @@ -124776,7 +124795,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-win/src-tauri/tauri.conf.json", "source_location": "L38", - "community": 867, + "community": 279, "norm_label": "externalbin", "id": "src_tauri_tauri_conf_bundle_externalbin" }, @@ -124785,7 +124804,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-win/src-tauri/tauri.conf.json", "source_location": "L40", - "community": 867, + "community": 443, "norm_label": "nsis", "id": "src_tauri_tauri_conf_windows_nsis" }, @@ -124794,7 +124813,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-win/src-tauri/tauri.conf.json", "source_location": "L41", - "community": 867, + "community": 443, "norm_label": "installmode", "id": "src_tauri_tauri_conf_nsis_installmode" }, @@ -126396,7 +126415,7 @@ "file_type": "code", "source_file": "apps/rebreak-magic-win/src-tauri/protection-core/src/lib.rs", "source_location": "L28", - "community": 9, + "community": 34, "norm_label": "protectionstate", "id": "src_lib_protectionstate" }, @@ -129079,71 +129098,6 @@ "norm_label": "rebreak-admin-staging service", "id": "concept_rebreak_admin_staging_service" }, - { - "label": "Build backend (Nitro) Job", - "file_type": "code", - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "source_url": null, - "captured_at": null, - "author": null, - "contributor": null, - "community": 430, - "norm_label": "build backend (nitro) job", - "id": "workflows_deploy_staging_build_job" - }, - { - "label": "Deploy backend to Hetzner Job", - "file_type": "code", - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "source_url": null, - "captured_at": null, - "author": null, - "contributor": null, - "community": 430, - "norm_label": "deploy backend to hetzner job", - "id": "workflows_deploy_staging_deploy_job" - }, - { - "label": "rebreak-staging Backend (Nitro) Service", - "file_type": "concept", - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "source_url": null, - "captured_at": null, - "author": null, - "contributor": null, - "community": 386, - "norm_label": "rebreak-staging backend (nitro) service", - "id": "concept_rebreak_staging_backend_service" - }, - { - "label": "imap-idle Daemon", - "file_type": "concept", - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "source_url": null, - "captured_at": null, - "author": null, - "contributor": null, - "community": 430, - "norm_label": "imap-idle daemon", - "id": "concept_imap_idle_daemon" - }, - { - "label": "GitHub Actions Artifact-Deploy Pattern", - "file_type": "rationale", - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "source_url": null, - "captured_at": null, - "author": null, - "contributor": null, - "community": 430, - "norm_label": "github actions artifact-deploy pattern", - "id": "concept_gh_actions_artifact_deploy_pattern" - }, { "label": "Maestro Cloud E2E (mobile.dev)", "file_type": "concept", @@ -129179,7 +129133,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 873, + "community": 867, "norm_label": "app-preview screenshots (/preview)", "id": "preview_readme_app_preview_screenshots" }, @@ -129192,7 +129146,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 873, + "community": 867, "norm_label": "capture-marketing.sh maestro pipeline", "id": "preview_readme_capture_marketing_pipeline" }, @@ -129205,7 +129159,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 873, + "community": 867, "norm_label": "preview.vue marketing page", "id": "preview_readme_preview_vue_page" }, @@ -129218,7 +129172,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 386, + "community": 276, "norm_label": "rebreak magic mac phase 2 summary", "id": "rebreak_magic_mac_phase2_summary" }, @@ -129231,7 +129185,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 386, + "community": 276, "norm_label": "rebreak magic mac readme", "id": "rebreak_magic_mac_readme" }, @@ -129244,7 +129198,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 386, + "community": 276, "norm_label": "rebreak magic mac app", "id": "rebreak_magic_mac_app" }, @@ -129257,7 +129211,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 870, + "community": 276, "norm_label": "mac+iphone self-binding 6-step wizard", "id": "rebreak_magic_mac_self_bind_wizard" }, @@ -129270,7 +129224,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 386, + "community": 276, "norm_label": "authservice.swift (supabase + keychain)", "id": "rebreak_magic_mac_auth_service" }, @@ -129361,7 +129315,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 870, + "community": 276, "norm_label": "nanomdm server (mdm.rebreak.org)", "id": "concept_nanomdm_server" }, @@ -129374,7 +129328,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 870, + "community": 276, "norm_label": "supervise-magic go-cli binary", "id": "concept_supervise_magic_binary" }, @@ -129465,7 +129419,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 871, + "community": 605, "norm_label": "voice-calls debug state (2026-06-05)", "id": "rebreak_native_calls_debug_state" }, @@ -129478,7 +129432,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 871, + "community": 605, "norm_label": "ios voip pushkit + callkit incoming-call flow", "id": "concept_voip_pushkit_callkit_flow" }, @@ -129491,7 +129445,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 871, + "community": 605, "norm_label": "pkpushregistry local-var dealloc bug (build 76)", "id": "concept_pushkit_registry_dealloc_bug" }, @@ -129634,7 +129588,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 871, + "community": 605, "norm_label": "maestro flow: calls/incoming-call-screen", "id": "calls_incoming_call_screen_flow" }, @@ -129686,7 +129640,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 873, + "community": 867, "norm_label": "maestro flow: screens/01-onboarding (screenshot)", "id": "screens_01_onboarding_flow" }, @@ -129751,7 +129705,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 871, + "community": 605, "norm_label": "callscreen (/call, usecallstore)", "id": "concept_call_screen" }, @@ -130531,7 +130485,7 @@ "captured_at": "2026-06-08", "author": null, "contributor": null, - "community": 449, + "community": 75, "norm_label": "session-handoff 2026-06-07/08 (magic-windows e2e)", "id": "session_2026_06_08_handoff" }, @@ -130596,7 +130550,7 @@ "captured_at": "2026-06-08", "author": null, "contributor": null, - "community": 449, + "community": 75, "norm_label": "windows-iphone-supervision gamechanger (go-ios cross-compile)", "id": "session_2026_06_08_handoff_windows_supervision_gamechanger" }, @@ -130609,7 +130563,7 @@ "captured_at": "2026-06-08", "author": null, "contributor": null, - "community": 868, + "community": 75, "norm_label": "session-handoff 2026-06-08 preview/screenshots/bug-hunt", "id": "session_2026_06_08_preview_screenshots_handoff" }, @@ -130622,7 +130576,7 @@ "captured_at": "2026-06-09", "author": null, "contributor": null, - "community": 868, + "community": 75, "norm_label": "protection-bypass-fix everactivehere-flag", "id": "session_2026_06_08_preview_protection_everactivehere_flag" }, @@ -130648,7 +130602,7 @@ "captured_at": "2026-06-09", "author": null, "contributor": null, - "community": 868, + "community": 60, "norm_label": "maestro-screenshot-pipeline (marketing-tour-loggedin)", "id": "session_2026_06_08_preview_maestro_screenshot_pipeline" }, @@ -130804,7 +130758,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 75, + "community": 60, "norm_label": "vorvida (alkohol-diga als vorbild)", "id": "marketing_onepager_fachstellen_vorvida_vorbild" }, @@ -130934,7 +130888,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 34, + "community": 4, "norm_label": "spec protection coverage & streak (diga-kernmetrik)", "id": "protection_coverage_streak" }, @@ -130947,7 +130901,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 34, + "community": 4, "norm_label": "protection_state_log (append-only schutz-transitions-log)", "id": "protection_coverage_streak_log_model" }, @@ -130960,7 +130914,7 @@ "captured_at": null, "author": null, "contributor": null, - "community": 34, + "community": 4, "norm_label": "optimistisches streak-modell (wert fallt nie auf 0)", "id": "protection_coverage_streak_optimistic_principle" }, @@ -131064,7 +131018,7 @@ "captured_at": null, "author": "Dr. Marlene Brandt (diga-regulatory)", "contributor": null, - "community": 60, + "community": 93, "norm_label": "req-prot schutz/blocker (gerateweite zugangserschwerung)", "id": "diga_03_req_prot" }, @@ -131129,7 +131083,7 @@ "captured_at": null, "author": "Dr. Marlene Brandt (diga-regulatory)", "contributor": null, - "community": 9, + "community": 34, "norm_label": "server-time-authoritativer cooldown (uhr-manipulation-schutz)", "id": "diga_03_req_cooldown_server_authoritative" }, @@ -131246,7 +131200,7 @@ "captured_at": null, "author": "Ahmed (Test-Agent)", "contributor": null, - "community": 868, + "community": 60, "norm_label": "software-verifikation test-nachweis v0 (dok 05b, iec 62304)", "id": "diga_05b_test_verifikation" }, @@ -131259,7 +131213,7 @@ "captured_at": null, "author": "Ahmed (Test-Agent)", "contributor": null, - "community": 868, + "community": 60, "norm_label": "maestro e2e test-schicht (mobile app, ~20 flows)", "id": "diga_05b_maestro_e2e" }, @@ -131272,7 +131226,7 @@ "captured_at": null, "author": "Ahmed (Test-Agent)", "contributor": null, - "community": 868, + "community": 60, "norm_label": "vitest unit-/integrationstests (backend, 21 dateien)", "id": "diga_05b_vitest_backend" }, @@ -131285,7 +131239,7 @@ "captured_at": null, "author": "Ahmed (Test-Agent)", "contributor": null, - "community": 868, + "community": 60, "norm_label": "fehlende traceability-matrix (tests\u2194anforderungen\u2194risiken)", "id": "diga_05b_traceability_matrix_gap" }, @@ -131324,7 +131278,7 @@ "captured_at": null, "author": "Ahmed (Test-Agent)", "contributor": null, - "community": 79, + "community": 422, "norm_label": "safety-req-llm-002 sicherheits-grenzen (rollen-integritat, refusal)", "id": "diga_05c_safety_req_llm_002" }, @@ -131519,7 +131473,7 @@ "captured_at": "2026-06-02", "author": "lyra-persona agent", "contributor": null, - "community": 289, + "community": 422, "norm_label": "lyra persona \u2014 single source of truth", "id": "ops_lyra_persona" }, @@ -131532,7 +131486,7 @@ "captured_at": "2026-06-02", "author": "lyra-persona agent", "contributor": null, - "community": 289, + "community": 422, "norm_label": "lyra modi (sos-crisis-mode / coach-casual-mode)", "id": "ops_lyra_persona_sos_coach_modes" }, @@ -131545,7 +131499,7 @@ "captured_at": "2026-06-02", "author": "lyra-persona agent", "contributor": null, - "community": 79, + "community": 422, "norm_label": "verbotenes pathologisierungs-vokabular (sucht/suchtig/therapie)", "id": "ops_lyra_persona_no_pathologizing_vocab" }, @@ -131772,15 +131726,1866 @@ } ], "links": [ + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L212", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "db_mail_refreshandsavetokens" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L885", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_assertenv" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L93", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_clearconnectionerror" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L499", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_coalescepending" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L154", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_decrypt" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L167", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_encrypt" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L411", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_getcredentialsforconnection" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L142", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_getkey" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L899", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_imap_socket_error_codes" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L464", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_isautherror" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L116", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_loadactiveconnections" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L450", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_log" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L455", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_logerror" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L899", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_main" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L383", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_markconnectionauthbroken" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L189", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_ms_oauth_scopes" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L82", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_pool" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L77", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_reconnect_delays_ms" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L212", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_refreshandsavetokensdaemon" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L813", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_refreshconnections" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L302", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_refreshgoogletokensdaemon" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L564", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_runsession" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L498", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_scaninflight" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L479", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_sessions" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L861", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_shutdown" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L881", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_sleep" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L789", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_startsession" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L800", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_stopsession" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L501", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_triggerscan" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L84", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_updateconnectionerror" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L102", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_imap_idle_index_mjs", + "target": "imap_idle_index_updateidleheartbeat" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L580", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_updateconnectionerror" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L623", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_clearconnectionerror" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L622", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_updateidleheartbeat" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L816", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_refreshconnections", + "target": "imap_idle_index_loadactiveconnections" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L160", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_decrypt", + "target": "imap_idle_index_getkey" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L168", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_encrypt", + "target": "imap_idle_index_getkey" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L229", + "weight": 1.0, + "confidence_score": 1.0, + "source": "db_mail_refreshandsavetokens", + "target": "imap_idle_index_decrypt" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L436", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_getcredentialsforconnection", + "target": "imap_idle_index_decrypt" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L229", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_refreshandsavetokensdaemon", + "target": "imap_idle_index_decrypt" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L319", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_refreshgoogletokensdaemon", + "target": "imap_idle_index_decrypt" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L259", + "weight": 1.0, + "confidence_score": 1.0, + "source": "db_mail_refreshandsavetokens", + "target": "imap_idle_index_encrypt" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L259", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_refreshandsavetokensdaemon", + "target": "imap_idle_index_encrypt" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L347", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_refreshgoogletokensdaemon", + "target": "imap_idle_index_encrypt" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L756", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_encrypt" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L427", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_getcredentialsforconnection", + "target": "imap_idle_index_refreshandsavetokensdaemon" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L765", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_refreshandsavetokensdaemon" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L425", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_getcredentialsforconnection", + "target": "imap_idle_index_refreshgoogletokensdaemon" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L750", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_refreshgoogletokensdaemon" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L578", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_markconnectionauthbroken" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L427", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_getcredentialsforconnection", + "target": "db_mail_refreshandsavetokens" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L421", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_getcredentialsforconnection", + "target": "imap_idle_index_log" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L572", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_getcredentialsforconnection" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L902", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_main", + "target": "imap_idle_index_log" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L846", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_refreshconnections", + "target": "imap_idle_index_log" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L610", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_log" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L862", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_shutdown", + "target": "imap_idle_index_log" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L791", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_startsession", + "target": "imap_idle_index_log" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L803", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_stopsession", + "target": "imap_idle_index_log" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L507", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_triggerscan", + "target": "imap_idle_index_log" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L574", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_logerror" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L534", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_triggerscan", + "target": "imap_idle_index_logerror" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L729", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_isautherror" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L632", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_triggerscan" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L752", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "db_mail_refreshandsavetokens" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L712", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_runsession", + "target": "imap_idle_index_sleep" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L794", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_startsession", + "target": "imap_idle_index_runsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L827", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_refreshconnections", + "target": "imap_idle_index_startsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L834", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_refreshconnections", + "target": "imap_idle_index_stopsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L867", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_shutdown", + "target": "imap_idle_index_stopsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L906", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_main", + "target": "imap_idle_index_refreshconnections" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/imap-idle/index.mjs", + "source_location": "L900", + "weight": 1.0, + "confidence_score": 1.0, + "source": "imap_idle_index_main", + "target": "imap_idle_index_assertenv" + }, + { + "relation": "defines", + "confidence": "EXTRACTED", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L28", + "weight": 1.0, + "confidence_score": 1.0, + "source": "scripts_deploy_from_artifact_sh", + "target": "scripts_deploy_from_artifact_log" + }, + { + "relation": "defines", + "confidence": "EXTRACTED", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L29", + "weight": 1.0, + "confidence_score": 1.0, + "source": "scripts_deploy_from_artifact_sh", + "target": "scripts_deploy_from_artifact_log_err" + }, + { + "relation": "defines", + "confidence": "EXTRACTED", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L33", + "weight": 1.0, + "confidence_score": 1.0, + "source": "scripts_deploy_from_artifact_sh", + "target": "scripts_deploy_from_artifact_path" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "scripts_deploy_from_artifact_sh", + "target": "users_chahinebrini_mono_rebreak_monorepo_scripts_deploy_from_artifact_sh__entry" + }, + { + "relation": "calls", + "confidence": "EXTRACTED", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L31", + "weight": 1.0, + "context": "call", + "confidence_score": 1.0, + "source": "users_chahinebrini_mono_rebreak_monorepo_scripts_deploy_from_artifact_sh__entry", + "target": "scripts_deploy_from_artifact_log" + }, + { + "relation": "calls", + "confidence": "EXTRACTED", + "source_file": "scripts/deploy-from-artifact.sh", + "source_location": "L43", + "weight": 1.0, + "context": "call", + "confidence_score": 1.0, + "source": "users_chahinebrini_mono_rebreak_monorepo_scripts_deploy_from_artifact_sh__entry", + "target": "scripts_deploy_from_artifact_log_err" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/components/AppLockGate.tsx", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_components_applockgate_tsx", + "target": "apps_rebreak_native_components_lockscreen_tsx" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/components/LockScreen.tsx", + "source_location": "L7", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_components_lockscreen_tsx", + "target": "apps_rebreak_native_stores_applock_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/components/LockScreen.tsx", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_components_lockscreen_tsx", + "target": "apps_rebreak_native_stores_auth_ts" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/components/LockScreen.tsx", + "source_location": "L23", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_components_lockscreen_tsx", + "target": "components_lockscreen_lockscreen" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/components/LockScreen.tsx", + "source_location": "L7", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_components_lockscreen_tsx", + "target": "stores_applock_useapplockstore" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/components/LockScreen.tsx", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_components_lockscreen_tsx", + "target": "stores_auth_useauthstore" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/components/AppLockGate.tsx", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_components_applockgate_tsx", + "target": "components_lockscreen_lockscreen" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "apps/rebreak-native/components/LockScreen.tsx", + "source_location": "L26", + "weight": 1.0, + "source": "components_lockscreen_lockscreen", + "target": "stores_applock_useapplockstore" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "apps/rebreak-native/components/LockScreen.tsx", + "source_location": "L27", + "weight": 1.0, + "source": "components_lockscreen_lockscreen", + "target": "stores_auth_useauthstore" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/app/_layout.tsx", + "source_location": "L28", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_app_layout_tsx", + "target": "apps_rebreak_native_stores_applock_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/app/settings.tsx", + "source_location": "L23", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_app_settings_tsx", + "target": "apps_rebreak_native_stores_applock_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/components/AppLockGate.tsx", + "source_location": "L3", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_components_applockgate_tsx", + "target": "apps_rebreak_native_stores_applock_ts" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/stores/appLock.ts", + "source_location": "L40", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_stores_applock_ts", + "target": "stores_applock_applockstate" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/stores/appLock.ts", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_stores_applock_ts", + "target": "stores_applock_localauthmodule" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/stores/appLock.ts", + "source_location": "L58", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_stores_applock_ts", + "target": "stores_applock_useapplockstore" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/app/_layout.tsx", + "source_location": "L69", + "weight": 1.0, + "confidence_score": 1.0, + "source": "app_layout_rootlayoutinner", + "target": "stores_applock_useapplockstore" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "apps/rebreak-native/app/settings.tsx", + "source_location": "L163", + "weight": 1.0, + "source": "app_settings_settingsscreen", + "target": "stores_applock_useapplockstore" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/app/_layout.tsx", + "source_location": "L28", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_app_layout_tsx", + "target": "stores_applock_useapplockstore" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/app/settings.tsx", + "source_location": "L23", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_app_settings_tsx", + "target": "stores_applock_useapplockstore" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "apps/rebreak-native/components/AppLockGate.tsx", + "source_location": "L3", + "weight": 1.0, + "confidence_score": 1.0, + "source": "apps_rebreak_native_components_applockgate_tsx", + "target": "stores_applock_useapplockstore" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "apps/rebreak-native/components/AppLockGate.tsx", + "source_location": "L18", + "weight": 1.0, + "source": "components_applockgate_applockgate", + "target": "stores_applock_useapplockstore" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "backend_server_db_domains_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "backend_server_db_mail_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L14", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "backend_server_db_profile_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "backend_server_utils_imap_providers_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L17", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "backend_server_utils_mail_auth_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L18", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "backend_server_utils_mail_classifier_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L15", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "backend_server_utils_plan_features_ts" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_domains_getblocklisteddomainsset" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_domains_getmaildisplaynamepatterns" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_mail_deleteoldmailblocked" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_mail_getalreadyblockeduidset" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_mail_getmailconnections" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_mail_insertmailblocked" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_mail_insertmailclassificationsample" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_mail_markfullsweepdone" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_mail_patchfolderscanstate" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_mail_updatemailconnectiontitle" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_mail_upsertmailblockedstat" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L14", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "db_profile_getprofile" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "utils_imap_providers_resolveprovidermeta" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L17", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "utils_mail_auth_resolveimapauth" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L18", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "utils_mail_classifier_classifymail" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan-internal.post.ts", + "source_location": "L15", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_internal_post_ts", + "target": "utils_plan_features_getplanlimits" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "backend_server_db_domains_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "backend_server_db_mail_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L12", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "backend_server_db_profile_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L14", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "backend_server_utils_imap_providers_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L15", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "backend_server_utils_mail_auth_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "backend_server_utils_mail_classifier_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "backend_server_utils_plan_features_ts" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_domains_getblocklisteddomainsset" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_domains_getcustommaildisplaynames" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_mail_deleteoldmailblocked" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_mail_getalreadyblockeduidset" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_mail_getmailconnections" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_mail_insertmailblocked" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_mail_insertmailclassificationsample" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_mail_updatemailconnectiontitle" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_mail_upsertmailblockedstat" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L12", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "db_profile_getprofile" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L14", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "utils_imap_providers_resolveprovidermeta" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L15", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "utils_mail_auth_resolveimapauth" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "utils_mail_classifier_classifymail" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/mail/scan.post.ts", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_mail_scan_post_ts", + "target": "utils_plan_features_getplanlimits" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/calls/ring.post.ts", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_calls_ring_post_ts", + "target": "backend_server_services_push_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/magic/register.post.ts", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_magic_register_post_ts", + "target": "backend_server_services_push_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L17", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "backend_server_services_voip_push_ts" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "backend_server_utils_prisma_ts" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L223", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_callringpushpayload" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_chatpushpayload" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L131", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_deviceaddedpushpayload" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L140", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_deviceplatformlabel" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L32", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_ensureexpo" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L26", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_expoinstance" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L25", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_expomodule" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L27", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_expopushmessage" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L114", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_getdisplayname" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L250", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_sendcallringpush" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L37", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_sendchatpush" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L159", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_senddeviceaddedpush" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L126", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_push_truncatepreview" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L17", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "services_voip_push_sendvoippush" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_services_push_ts", + "target": "utils_prisma_useprisma" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L276", + "weight": 1.0, + "confidence_score": 1.0, + "source": "services_push_sendcallringpush", + "target": "services_push_ensureexpo" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L61", + "weight": 1.0, + "confidence_score": 1.0, + "source": "services_push_sendchatpush", + "target": "services_push_ensureexpo" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L186", + "weight": 1.0, + "confidence_score": 1.0, + "source": "services_push_senddeviceaddedpush", + "target": "services_push_ensureexpo" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/server/services/push.ts", + "source_location": "L39", + "weight": 1.0, + "source": "services_push_sendchatpush", + "target": "utils_prisma_useprisma" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/server/services/push.ts", + "source_location": "L115", + "weight": 1.0, + "source": "services_push_getdisplayname", + "target": "utils_prisma_useprisma" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "backend/server/services/push.ts", + "source_location": "L177", + "weight": 1.0, + "confidence_score": 1.0, + "source": "services_push_senddeviceaddedpush", + "target": "services_push_deviceplatformlabel" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/magic/register.post.ts", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_magic_register_post_ts", + "target": "services_push_senddeviceaddedpush" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/server/services/push.ts", + "source_location": "L163", + "weight": 1.0, + "source": "services_push_senddeviceaddedpush", + "target": "utils_prisma_useprisma" + }, + { + "relation": "imports", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "backend/server/api/calls/ring.post.ts", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "backend_server_api_calls_ring_post_ts", + "target": "services_push_sendcallringpush" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/server/services/push.ts", + "source_location": "L279", + "weight": 1.0, + "source": "services_push_sendcallringpush", + "target": "services_voip_push_sendvoippush" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "confidence_score": 1.0, + "source_file": "backend/server/services/push.ts", + "source_location": "L252", + "weight": 1.0, + "source": "services_push_sendcallringpush", + "target": "utils_prisma_useprisma" + }, { "relation": "contains", "confidence": "EXTRACTED", "source_file": "CLAUDE.md", "source_location": "L1", "weight": 1.0, + "confidence_score": 1.0, "source": "claude_md", - "target": "rebreak_monorepo_claude_claude_md_rebreak_monorepo", - "confidence_score": 1.0 + "target": "rebreak_monorepo_claude_claude_md_rebreak_monorepo" }, { "relation": "contains", @@ -131788,9 +133593,9 @@ "source_file": "CLAUDE.md", "source_location": "L5", "weight": 1.0, + "confidence_score": 1.0, "source": "rebreak_monorepo_claude_claude_md_rebreak_monorepo", - "target": "rebreak_monorepo_claude_graphify_knowledge_graph", - "confidence_score": 1.0 + "target": "rebreak_monorepo_claude_graphify_knowledge_graph" }, { "relation": "contains", @@ -134829,17 +136634,6 @@ "source": "backend_server_db_voicequota_ts", "target": "backend_server_utils_prisma_ts" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L16", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "backend_server_utils_prisma_ts" - }, { "relation": "imports_from", "context": "import", @@ -135730,17 +137524,6 @@ "source": "backend_server_db_voicequota_ts", "target": "utils_prisma_useprisma" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L16", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "utils_prisma_useprisma" - }, { "relation": "imports", "context": "import", @@ -137996,50 +139779,6 @@ "source": "plugins_mail_retention_cron_runrowcap", "target": "utils_prisma_useprisma" }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/server/services/push.ts", - "source_location": "L115", - "weight": 1.0, - "source": "services_push_getdisplayname", - "target": "utils_prisma_useprisma" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/server/services/push.ts", - "source_location": "L252", - "weight": 1.0, - "source": "services_push_sendcallringpush", - "target": "utils_prisma_useprisma" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/server/services/push.ts", - "source_location": "L39", - "weight": 1.0, - "source": "services_push_sendchatpush", - "target": "utils_prisma_useprisma" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/server/services/push.ts", - "source_location": "L163", - "weight": 1.0, - "source": "services_push_senddeviceaddedpush", - "target": "utils_prisma_useprisma" - }, { "relation": "imports", "context": "import", @@ -138464,28 +140203,6 @@ "source": "db_mail_insertmailclassificationsample", "target": "utils_mail_training_utils_sanitizesubjectfortraining" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L17", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "backend_server_utils_mail_auth_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L15", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "backend_server_utils_mail_auth_ts" - }, { "relation": "imports_from", "context": "import", @@ -138570,28 +140287,6 @@ "source": "backend_server_utils_mail_auth_ts", "target": "utils_mail_auth_resolveimapauth" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L17", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "utils_mail_auth_resolveimapauth" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L15", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "utils_mail_auth_resolveimapauth" - }, { "relation": "calls", "context": "call", @@ -139315,28 +141010,6 @@ "source": "backend_server_api_mail_proxy_config_get_ts", "target": "backend_server_utils_plan_features_ts" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L15", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "backend_server_utils_plan_features_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L13", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "backend_server_utils_plan_features_ts" - }, { "relation": "imports_from", "context": "import", @@ -139726,28 +141399,6 @@ "source": "backend_server_api_mail_proxy_config_get_ts", "target": "utils_plan_features_getplanlimits" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L15", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "utils_plan_features_getplanlimits" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L13", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "utils_plan_features_getplanlimits" - }, { "relation": "imports", "context": "import", @@ -140384,28 +142035,6 @@ "source": "backend_server_api_devices_id_profile_mobileconfig_get_ts", "target": "utils_mobileconfig_generatemacosdnsprofile" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L18", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "backend_server_utils_mail_classifier_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L16", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "backend_server_utils_mail_classifier_ts" - }, { "relation": "contains", "confidence": "EXTRACTED", @@ -140627,28 +142256,6 @@ "source": "utils_mail_classifier_classifymail", "target": "utils_mail_classifier_computescore" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L18", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "utils_mail_classifier_classifymail" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L16", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "utils_mail_classifier_classifymail" - }, { "relation": "imports_from", "context": "import", @@ -141304,28 +142911,6 @@ "source": "backend_server_api_mail_results_get_ts", "target": "backend_server_utils_imap_providers_ts" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L16", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "backend_server_utils_imap_providers_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L14", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "backend_server_utils_imap_providers_ts" - }, { "relation": "imports_from", "context": "import", @@ -141483,28 +143068,6 @@ "source": "backend_server_api_mail_results_get_ts", "target": "utils_imap_providers_resolveprovidermeta" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L16", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "utils_imap_providers_resolveprovidermeta" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L14", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "utils_imap_providers_resolveprovidermeta" - }, { "relation": "imports", "context": "import", @@ -146428,28 +147991,6 @@ "source": "backend_server_api_domain_submissions_id_vote_post_ts", "target": "backend_server_db_domains_ts" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L13", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "backend_server_db_domains_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L11", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "backend_server_db_domains_ts" - }, { "relation": "imports_from", "context": "import", @@ -146802,28 +148343,6 @@ "source": "backend_server_api_custom_domains_index_post_ts", "target": "db_domains_addusercustomdomain" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L11", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_domains_getcustommaildisplaynames" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L13", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_domains_getmaildisplaynamepatterns" - }, { "relation": "imports", "context": "import", @@ -146978,28 +148497,6 @@ "source": "backend_server_api_url_filter_blocklist_txt_get_ts", "target": "db_domains_getactiveblocklistdomains" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L13", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_domains_getblocklisteddomainsset" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L11", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_domains_getblocklisteddomainsset" - }, { "relation": "imports", "context": "import", @@ -147681,28 +149178,6 @@ "source": "backend_server_api_mail_proxy_config_get_ts", "target": "backend_server_db_profile_ts" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L14", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "backend_server_db_profile_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L12", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "backend_server_db_profile_ts" - }, { "relation": "imports_from", "context": "import", @@ -148464,28 +149939,6 @@ "source": "backend_server_api_mail_proxy_config_get_ts", "target": "db_profile_getprofile" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L14", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_profile_getprofile" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L12", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_profile_getprofile" - }, { "relation": "imports", "context": "import", @@ -149612,28 +151065,6 @@ "source": "backend_server_api_mail_results_get_ts", "target": "backend_server_db_mail_ts" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "backend_server_db_mail_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "backend_server_db_mail_ts" - }, { "relation": "imports_from", "context": "import", @@ -150012,28 +151443,6 @@ "source": "backend_server_api_mail_proxy_config_get_ts", "target": "db_mail_getmailconnections" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_mail_getmailconnections" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_mail_getmailconnections" - }, { "relation": "imports", "context": "import", @@ -150166,50 +151575,6 @@ "source": "backend_server_api_mail_status_get_ts", "target": "db_mail_getmailblockedstats" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_mail_getalreadyblockeduidset" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_mail_getalreadyblockeduidset" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_mail_insertmailblocked" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_mail_insertmailblocked" - }, { "relation": "imports", "context": "import", @@ -150221,28 +151586,6 @@ "source": "backend_server_api_user_delete_delete_ts", "target": "db_mail_deleteusermailclassificationsamples" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_mail_insertmailclassificationsample" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_mail_insertmailclassificationsample" - }, { "relation": "imports", "context": "import", @@ -150298,50 +151641,6 @@ "source": "backend_server_api_mail_results_get_ts", "target": "db_mail_deleteoldmailblocked" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_mail_deleteoldmailblocked" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_mail_deleteoldmailblocked" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_mail_upsertmailblockedstat" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_mail_upsertmailblockedstat" - }, { "relation": "imports", "context": "import", @@ -150375,28 +151674,6 @@ "source": "backend_server_api_mail_interval_patch_ts", "target": "db_mail_updatemailconnectiontitle" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_mail_updatemailconnectiontitle" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_post_ts", - "target": "db_mail_updatemailconnectiontitle" - }, { "relation": "imports", "context": "import", @@ -150485,60 +151762,6 @@ "source": "backend_server_api_mail_oauth_google_callback_post_ts", "target": "db_mail_upsertoauthgoogleconnection" }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L212", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "db_mail_refreshandsavetokens" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L229", - "weight": 1.0, - "confidence_score": 1.0, - "source": "db_mail_refreshandsavetokens", - "target": "imap_idle_index_decrypt" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L259", - "weight": 1.0, - "confidence_score": 1.0, - "source": "db_mail_refreshandsavetokens", - "target": "imap_idle_index_encrypt" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L427", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_getcredentialsforconnection", - "target": "db_mail_refreshandsavetokens" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L752", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "db_mail_refreshandsavetokens" - }, { "relation": "imports", "context": "import", @@ -150686,28 +151909,6 @@ "source": "backend_server_api_custom_domains_suggest_post_ts", "target": "hooks_usecustomdomains_public_email_domains" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_mail_markfullsweepdone" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/mail/scan-internal.post.ts", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_mail_scan_internal_post_ts", - "target": "db_mail_patchfolderscanstate" - }, { "relation": "contains", "confidence": "EXTRACTED", @@ -151825,150 +153026,6 @@ "source": "data_gambling_domains_meta", "target": "data_gambling_domains_meta_version" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/calls/ring.post.ts", - "source_location": "L16", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_calls_ring_post_ts", - "target": "backend_server_services_push_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/magic/register.post.ts", - "source_location": "L8", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_magic_register_post_ts", - "target": "backend_server_services_push_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L17", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "backend_server_services_voip_push_ts" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L223", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_callringpushpayload" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L21", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_chatpushpayload" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L131", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_deviceaddedpushpayload" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L140", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_deviceplatformlabel" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L19", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_expo" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L114", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_getdisplayname" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L250", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_sendcallringpush" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L37", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_sendchatpush" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L159", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_senddeviceaddedpush" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L126", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_push_truncatepreview" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L17", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_services_push_ts", - "target": "services_voip_push_sendvoippush" - }, { "relation": "contains", "confidence": "EXTRACTED", @@ -152099,649 +153156,6 @@ "source": "imap_idle_package_engines", "target": "imap_idle_package_engines_node" }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L885", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_assertenv" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L93", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_clearconnectionerror" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L499", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_coalescepending" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L154", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_decrypt" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L167", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_encrypt" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L411", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_getcredentialsforconnection" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L142", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_getkey" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L464", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_isautherror" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L116", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_loadactiveconnections" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L450", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_log" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L455", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_logerror" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L899", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_main" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L383", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_markconnectionauthbroken" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L189", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_ms_oauth_scopes" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L82", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_pool" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L77", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_reconnect_delays_ms" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L813", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_refreshconnections" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L302", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_refreshgoogletokensdaemon" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L564", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_runsession" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L498", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_scaninflight" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L479", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_sessions" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L861", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_shutdown" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L881", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_sleep" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L789", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_startsession" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L800", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_stopsession" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L501", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_triggerscan" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L84", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_updateconnectionerror" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L102", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_imap_idle_index_mjs", - "target": "imap_idle_index_updateidleheartbeat" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L580", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_updateconnectionerror" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L623", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_clearconnectionerror" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L622", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_updateidleheartbeat" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L816", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_refreshconnections", - "target": "imap_idle_index_loadactiveconnections" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L160", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_decrypt", - "target": "imap_idle_index_getkey" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L168", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_encrypt", - "target": "imap_idle_index_getkey" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L436", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_getcredentialsforconnection", - "target": "imap_idle_index_decrypt" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L319", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_refreshgoogletokensdaemon", - "target": "imap_idle_index_decrypt" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L347", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_refreshgoogletokensdaemon", - "target": "imap_idle_index_encrypt" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L756", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_encrypt" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L425", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_getcredentialsforconnection", - "target": "imap_idle_index_refreshgoogletokensdaemon" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L750", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_refreshgoogletokensdaemon" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L578", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_markconnectionauthbroken" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L421", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_getcredentialsforconnection", - "target": "imap_idle_index_log" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L572", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_getcredentialsforconnection" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L902", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_main", - "target": "imap_idle_index_log" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L846", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_refreshconnections", - "target": "imap_idle_index_log" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L610", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_log" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L862", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_shutdown", - "target": "imap_idle_index_log" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L791", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_startsession", - "target": "imap_idle_index_log" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L803", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_stopsession", - "target": "imap_idle_index_log" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L507", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_triggerscan", - "target": "imap_idle_index_log" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L574", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_logerror" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L534", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_triggerscan", - "target": "imap_idle_index_logerror" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L729", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_isautherror" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L632", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_triggerscan" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L712", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_runsession", - "target": "imap_idle_index_sleep" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L794", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_startsession", - "target": "imap_idle_index_runsession" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L827", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_refreshconnections", - "target": "imap_idle_index_startsession" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L834", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_refreshconnections", - "target": "imap_idle_index_stopsession" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L867", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_shutdown", - "target": "imap_idle_index_stopsession" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L906", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_main", - "target": "imap_idle_index_refreshconnections" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/imap-idle/index.mjs", - "source_location": "L900", - "weight": 1.0, - "confidence_score": 1.0, - "source": "imap_idle_index_main", - "target": "imap_idle_index_assertenv" - }, { "relation": "contains", "confidence": "EXTRACTED", @@ -153468,68 +153882,6 @@ "source": "users_chahinebrini_mono_rebreak_monorepo_scripts_deploy_sh__entry", "target": "scripts_deploy_log_err" }, - { - "relation": "defines", - "confidence": "EXTRACTED", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L28", - "weight": 1.0, - "confidence_score": 1.0, - "source": "scripts_deploy_from_artifact_sh", - "target": "scripts_deploy_from_artifact_log" - }, - { - "relation": "defines", - "confidence": "EXTRACTED", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L29", - "weight": 1.0, - "confidence_score": 1.0, - "source": "scripts_deploy_from_artifact_sh", - "target": "scripts_deploy_from_artifact_log_err" - }, - { - "relation": "defines", - "confidence": "EXTRACTED", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L33", - "weight": 1.0, - "confidence_score": 1.0, - "source": "scripts_deploy_from_artifact_sh", - "target": "scripts_deploy_from_artifact_path" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L1", - "weight": 1.0, - "confidence_score": 1.0, - "source": "scripts_deploy_from_artifact_sh", - "target": "users_chahinebrini_mono_rebreak_monorepo_scripts_deploy_from_artifact_sh__entry" - }, - { - "relation": "calls", - "confidence": "EXTRACTED", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L31", - "weight": 1.0, - "context": "call", - "confidence_score": 1.0, - "source": "users_chahinebrini_mono_rebreak_monorepo_scripts_deploy_from_artifact_sh__entry", - "target": "scripts_deploy_from_artifact_log" - }, - { - "relation": "calls", - "confidence": "EXTRACTED", - "source_file": "scripts/deploy-from-artifact.sh", - "source_location": "L43", - "weight": 1.0, - "context": "call", - "confidence_score": 1.0, - "source": "users_chahinebrini_mono_rebreak_monorepo_scripts_deploy_from_artifact_sh__entry", - "target": "scripts_deploy_from_artifact_log_err" - }, { "relation": "contains", "confidence": "EXTRACTED", @@ -182802,17 +183154,6 @@ "source": "apps_rebreak_native_app_settings_tsx", "target": "apps_rebreak_native_lib_theme_ts" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/app/settings.tsx", - "source_location": "L23", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_app_settings_tsx", - "target": "apps_rebreak_native_stores_applock_ts" - }, { "relation": "imports_from", "context": "import", @@ -182956,17 +183297,6 @@ "source": "apps_rebreak_native_app_settings_tsx", "target": "lib_theme_usecolors" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/app/settings.tsx", - "source_location": "L23", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_app_settings_tsx", - "target": "stores_applock_useapplockstore" - }, { "relation": "imports", "context": "import", @@ -183066,17 +183396,6 @@ "source": "app_settings_settingsscreen", "target": "lib_theme_usecolors" }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "apps/rebreak-native/app/settings.tsx", - "source_location": "L163", - "weight": 1.0, - "source": "app_settings_settingsscreen", - "target": "stores_applock_useapplockstore" - }, { "relation": "calls", "context": "call", @@ -185562,17 +185881,6 @@ "source": "apps_rebreak_native_app_layout_tsx", "target": "apps_rebreak_native_lib_theme_ts" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/app/_layout.tsx", - "source_location": "L28", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_app_layout_tsx", - "target": "apps_rebreak_native_stores_applock_ts" - }, { "relation": "imports_from", "context": "import", @@ -185716,17 +186024,6 @@ "source": "apps_rebreak_native_app_layout_tsx", "target": "lib_theme_usecolors" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/app/_layout.tsx", - "source_location": "L28", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_app_layout_tsx", - "target": "stores_applock_useapplockstore" - }, { "relation": "imports", "context": "import", @@ -185859,17 +186156,6 @@ "source": "app_layout_rootlayoutinner", "target": "lib_theme_usecolors" }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/app/_layout.tsx", - "source_location": "L69", - "weight": 1.0, - "confidence_score": 1.0, - "source": "app_layout_rootlayoutinner", - "target": "stores_applock_useapplockstore" - }, { "relation": "calls", "context": "call", @@ -192255,102 +192541,6 @@ "source": "apps_rebreak_native_stores_auth_ts", "target": "stores_devicelimit_usedevicelimitstore" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/components/AppLockGate.tsx", - "source_location": "L3", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_components_applockgate_tsx", - "target": "apps_rebreak_native_stores_applock_ts" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/components/LockScreen.tsx", - "source_location": "L7", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_components_lockscreen_tsx", - "target": "apps_rebreak_native_stores_applock_ts" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/stores/appLock.ts", - "source_location": "L40", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_stores_applock_ts", - "target": "stores_applock_applockstate" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/stores/appLock.ts", - "source_location": "L11", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_stores_applock_ts", - "target": "stores_applock_localauthmodule" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/stores/appLock.ts", - "source_location": "L58", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_stores_applock_ts", - "target": "stores_applock_useapplockstore" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/components/AppLockGate.tsx", - "source_location": "L3", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_components_applockgate_tsx", - "target": "stores_applock_useapplockstore" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/components/LockScreen.tsx", - "source_location": "L7", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_components_lockscreen_tsx", - "target": "stores_applock_useapplockstore" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "apps/rebreak-native/components/AppLockGate.tsx", - "source_location": "L18", - "weight": 1.0, - "source": "components_applockgate_applockgate", - "target": "stores_applock_useapplockstore" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "apps/rebreak-native/components/LockScreen.tsx", - "source_location": "L26", - "weight": 1.0, - "source": "components_lockscreen_lockscreen", - "target": "stores_applock_useapplockstore" - }, { "relation": "imports_from", "context": "import", @@ -192797,17 +192987,6 @@ "source": "apps_rebreak_native_components_applockgate_tsx", "target": "apps_rebreak_native_stores_auth_ts" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/components/LockScreen.tsx", - "source_location": "L8", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_components_lockscreen_tsx", - "target": "apps_rebreak_native_stores_auth_ts" - }, { "relation": "imports_from", "context": "import", @@ -192988,17 +193167,6 @@ "source": "apps_rebreak_native_components_applockgate_tsx", "target": "stores_auth_useauthstore" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/components/LockScreen.tsx", - "source_location": "L8", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_components_lockscreen_tsx", - "target": "stores_auth_useauthstore" - }, { "relation": "calls", "context": "call", @@ -193021,17 +193189,6 @@ "source": "components_applockgate_applockgate", "target": "stores_auth_useauthstore" }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "apps/rebreak-native/components/LockScreen.tsx", - "source_location": "L27", - "weight": 1.0, - "source": "components_lockscreen_lockscreen", - "target": "stores_auth_useauthstore" - }, { "relation": "imports", "context": "import", @@ -196554,38 +196711,6 @@ "source": "components_appalert_appalert", "target": "components_appalert_appalertprops" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/components/AppLockGate.tsx", - "source_location": "L5", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_components_applockgate_tsx", - "target": "apps_rebreak_native_components_lockscreen_tsx" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/components/LockScreen.tsx", - "source_location": "L23", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_components_lockscreen_tsx", - "target": "components_lockscreen_lockscreen" - }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "apps/rebreak-native/components/AppLockGate.tsx", - "source_location": "L5", - "weight": 1.0, - "confidence_score": 1.0, - "source": "apps_rebreak_native_components_applockgate_tsx", - "target": "components_lockscreen_lockscreen" - }, { "relation": "imports_from", "context": "import", @@ -274462,16 +274587,6 @@ "source": "admin_readme_admin_app", "target": "workflows_deploy_admin_staging_workflow" }, - { - "relation": "implements", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-admin-staging.yml", - "source_location": null, - "weight": 1.0, - "source": "workflows_deploy_admin_staging_workflow", - "target": "concept_gh_actions_artifact_deploy_pattern" - }, { "relation": "implements", "confidence": "EXTRACTED", @@ -274492,76 +274607,6 @@ "source": "workflows_deploy_admin_staging_workflow", "target": "workflows_deploy_admin_staging_deploy_job" }, - { - "relation": "conceptually_related_to", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-admin-staging.yml", - "source_location": "L5-9", - "weight": 1.0, - "source": "workflows_deploy_admin_staging_workflow", - "target": "workflows_deploy_staging_gh_actions_pipeline" - }, - { - "relation": "references", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-admin-staging.yml", - "source_location": null, - "weight": 1.0, - "source": "workflows_deploy_admin_staging_workflow", - "target": "workflows_deploy_staging_workflow" - }, - { - "relation": "references", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "apps/admin/README.md", - "source_location": "GitHub-Actions-Pipeline", - "weight": 1.0, - "source": "admin_readme_admin_app", - "target": "workflows_deploy_staging_workflow" - }, - { - "relation": "implements", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "weight": 1.0, - "source": "workflows_deploy_staging_workflow", - "target": "concept_gh_actions_artifact_deploy_pattern" - }, - { - "relation": "implements", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "weight": 1.0, - "source": "workflows_deploy_staging_workflow", - "target": "workflows_deploy_staging_build_job" - }, - { - "relation": "implements", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "weight": 1.0, - "source": "workflows_deploy_staging_workflow", - "target": "workflows_deploy_staging_deploy_job" - }, - { - "relation": "references", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": "L3-21", - "weight": 1.0, - "source": "workflows_deploy_staging_workflow", - "target": "workflows_deploy_staging_gh_actions_pipeline" - }, { "relation": "references", "confidence": "EXTRACTED", @@ -278795,17 +278840,6 @@ "source": "backend_server_api_chat_can_call_userid_get_ts", "target": "db_social_cancall" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/calls/ring.post.ts", - "source_location": "L16", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_calls_ring_post_ts", - "target": "services_push_sendcallringpush" - }, { "relation": "implements", "confidence": "INFERRED", @@ -278818,17 +278852,6 @@ "source": "backend_server_api_magic_register_post_ts", "target": "diga_03_req_magic" }, - { - "relation": "imports", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "backend/server/api/magic/register.post.ts", - "source_location": "L8", - "weight": 1.0, - "confidence_score": 1.0, - "source": "backend_server_api_magic_register_post_ts", - "target": "services_push_senddeviceaddedpush" - }, { "relation": "contains", "confidence": "EXTRACTED", @@ -278913,28 +278936,6 @@ "source": "backend_server_api_protection_coverage_get_ts", "target": "src_lib_protectionstate" }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "backend/server/services/push.ts", - "source_location": "L177", - "weight": 1.0, - "confidence_score": 1.0, - "source": "services_push_senddeviceaddedpush", - "target": "services_push_deviceplatformlabel" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": "backend/server/services/push.ts", - "source_location": "L279", - "weight": 1.0, - "source": "services_push_sendcallringpush", - "target": "services_voip_push_sendvoippush" - }, { "relation": "contains", "confidence": "EXTRACTED", @@ -327097,56 +327098,6 @@ "source": "workflows_deploy_admin_staging_deploy_job", "target": "concept_rebreak_admin_staging_service" }, - { - "relation": "references", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "weight": 1.0, - "source": "workflows_deploy_staging_deploy_job", - "target": "workflows_deploy_staging_build_job" - }, - { - "relation": "references", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "weight": 1.0, - "source": "workflows_deploy_staging_deploy_job", - "target": "concept_imap_idle_daemon" - }, - { - "relation": "references", - "confidence": "EXTRACTED", - "confidence_score": 1.0, - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "weight": 1.0, - "source": "workflows_deploy_staging_deploy_job", - "target": "concept_rebreak_staging_backend_service" - }, - { - "relation": "references", - "confidence": "INFERRED", - "confidence_score": 0.75, - "source_file": ".github/workflows/deploy-staging.yml", - "source_location": null, - "weight": 1.0, - "source": "concept_rebreak_staging_backend_service", - "target": "concept_magic_register_endpoint" - }, - { - "relation": "references", - "confidence": "INFERRED", - "confidence_score": 0.75, - "source_file": "apps/rebreak-magic-mac/PHASE2_SUMMARY.md", - "source_location": null, - "weight": 1.0, - "source": "rebreak_magic_mac_auth_service", - "target": "concept_rebreak_staging_backend_service" - }, { "relation": "conceptually_related_to", "confidence": "EXTRACTED", @@ -330091,5 +330042,5 @@ "source_file": "docs/marketing/funding-partnership-plan.md" } ], - "built_at_commit": "6937ff155fa5a0e0ee89c74f4bb34a8267f0d0ca" + "built_at_commit": "df3c4fafa3f27cb26b44bcecc42cc923f9acb24c" } \ No newline at end of file diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json index d35d88c..677f285 100644 --- a/graphify-out/manifest.json +++ b/graphify-out/manifest.json @@ -25,9 +25,9 @@ "semantic_hash": "e5f6eb13c875f326cfd5915d3364614f" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/nitro.config.ts": { - "mtime": 1780651100.3393717, - "ast_hash": "5337f6dc128a2e0f99758c66097a22e3", - "semantic_hash": "5337f6dc128a2e0f99758c66097a22e3" + "mtime": 1781098496.7526796, + "ast_hash": "00fe0ab55b634aca00786cbfba7697ea", + "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/prisma.config.ts": { "mtime": 1778033276.136318, @@ -1120,9 +1120,9 @@ "semantic_hash": "dc170d505aedde45d648baa6aacd7e8d" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/server/api/mail/scan-internal.post.ts": { - "mtime": 1780772000.0296645, - "ast_hash": "4196a86701ac61dee101e35944af5fae", - "semantic_hash": "4196a86701ac61dee101e35944af5fae" + "mtime": 1781092509.8649359, + "ast_hash": "fde632a8537b8a013f39fb91f69e1ac4", + "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/server/api/mail/proxy-config.get.ts": { "mtime": 1778032995.0984364, @@ -1150,9 +1150,9 @@ "semantic_hash": "5a819c76f2b7cf9747798bdcd07992d5" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/server/api/mail/scan.post.ts": { - "mtime": 1779973242.1609433, - "ast_hash": "5cad50581294fcf372fad8752269ebe6", - "semantic_hash": "5cad50581294fcf372fad8752269ebe6" + "mtime": 1781092587.402889, + "ast_hash": "a5fda386477f7e66e25526698ef9d199", + "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/server/api/mail/results.get.ts": { "mtime": 1778683260.5017214, @@ -1920,9 +1920,9 @@ "semantic_hash": "55af2637a5b3c77f7fb7c8163cc201f7" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/server/services/push.ts": { - "mtime": 1780861075.5283923, - "ast_hash": "35d56dcaab3e786304ab73b79abb3cea", - "semantic_hash": "35d56dcaab3e786304ab73b79abb3cea" + "mtime": 1781092766.6544745, + "ast_hash": "e25f9ea7353380d1c73de789a0e127a2", + "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/server/services/voip-push.ts": { "mtime": 1780595681.9513056, @@ -1940,9 +1940,9 @@ "semantic_hash": "c18933134fc157906a3e491e8d342e87" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/imap-idle/index.mjs": { - "mtime": 1780772017.8478682, - "ast_hash": "4f41e3575c5c8416e95bcf33cd0b1d0b", - "semantic_hash": "4f41e3575c5c8416e95bcf33cd0b1d0b" + "mtime": 1781119795.4583845, + "ast_hash": "d80d2455a44a3d3ac9277ad8da3aa0ba", + "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/backend/scripts/generate-pir-input.ts": { "mtime": 1779277186.8516371, @@ -2005,9 +2005,9 @@ "semantic_hash": "8c0913472d610e7a6f2b2e7a3caec6dc" }, "/Users/chahinebrini/mono/rebreak-monorepo/scripts/deploy-from-artifact.sh": { - "mtime": 1780298966.7916753, - "ast_hash": "8dd3099346bf2c491fecd62c5afa6681", - "semantic_hash": "8dd3099346bf2c491fecd62c5afa6681" + "mtime": 1781099229.5164309, + "ast_hash": "96939f3d96a62246da00795981d2d03e", + "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/scripts/deploy-webhook/server.mjs": { "mtime": 1778106454.0610669, @@ -2195,8 +2195,8 @@ "semantic_hash": "da631aa4384ac11d6511e73f1ff0c5bf" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/app.config.ts": { - "mtime": 1781073703.6655655, - "ast_hash": "5cb4572c544fd385522d9d019d32b752", + "mtime": 1781099346.8820252, + "ast_hash": "4c41684adceca23a5c30e8293e07c44c", "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/babel.config.js": { @@ -2205,8 +2205,8 @@ "semantic_hash": "754dc6a047f1004deb396cadb03c5d7c" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/package.json": { - "mtime": 1781073703.6689231, - "ast_hash": "e3570fd91354c8017ce07eaa2a26f35b", + "mtime": 1781099346.8844354, + "ast_hash": "1ac439b18d99e589e0ab5036a2f42f64", "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/tsconfig.json": { @@ -2275,8 +2275,8 @@ "semantic_hash": "cfad92e1cfdee1be4486bc56df15e7b0" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/app/dm.tsx": { - "mtime": 1781090770.358354, - "ast_hash": "afaa8864153c549fa26716b7998d4d9b", + "mtime": 1781091425.5896177, + "ast_hash": "2ee40dab096fb63cd4d010a4636256cf", "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/app/debug.tsx": { @@ -2590,62 +2590,62 @@ "semantic_hash": "79892b512c5b108eecf7ce2573a819a5" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/Podfile.properties.json": { - "mtime": 1780886883.2589357, + "mtime": 1781099356.0946026, "ast_hash": "0847919237e15fbd3abf30da0e4cb8c4", "semantic_hash": "0847919237e15fbd3abf30da0e4cb8c4" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/RebreakPacketTunnelExtension/HashList.swift": { - "mtime": 1780886883.182512, + "mtime": 1781099356.0209033, "ast_hash": "a8d42be577e98ea2bde0eb3beb5bbfe6", "semantic_hash": "a8d42be577e98ea2bde0eb3beb5bbfe6" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/RebreakPacketTunnelExtension/DomainHasher.swift": { - "mtime": 1780886883.1822066, + "mtime": 1781099356.0206153, "ast_hash": "093b1e647a0d3803c75060c0355c095e", "semantic_hash": "093b1e647a0d3803c75060c0355c095e" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/RebreakPacketTunnelExtension/PacketTunnelProvider.swift": { - "mtime": 1780886883.1835492, + "mtime": 1781099356.0227797, "ast_hash": "b8c819e0f611ec3c6b685429a34bb1c8", "semantic_hash": "b8c819e0f611ec3c6b685429a34bb1c8" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/RebreakPacketTunnelExtension/DnsFilter.swift": { - "mtime": 1780886883.1819117, + "mtime": 1781099356.020003, "ast_hash": "be7ad5d15bf0edf4a90dc6ef8ac88ce9", "semantic_hash": "be7ad5d15bf0edf4a90dc6ef8ac88ce9" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/ReBreak-Bridging-Header.h": { - "mtime": 1780886883.187419, + "mtime": 1781099356.0249267, "ast_hash": "7bda22d76cc88bc22215241b452bd3d3", "semantic_hash": "7bda22d76cc88bc22215241b452bd3d3" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/AppDelegate.swift": { - "mtime": 1780886883.2745233, + "mtime": 1781099356.111295, "ast_hash": "00cf50df46613f328fe200ab677f3b1a", "semantic_hash": "00cf50df46613f328fe200ab677f3b1a" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/Images.xcassets/Contents.json": { - "mtime": 1780886882.844067, + "mtime": 1781099355.7058473, "ast_hash": "96cbaeb138eab0aceebfdf0022c7d835", "semantic_hash": "96cbaeb138eab0aceebfdf0022c7d835" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/Images.xcassets/AppIcon.appiconset/Contents.json": { - "mtime": 1780886883.173795, + "mtime": 1781099356.014499, "ast_hash": "e753dae9a3ae1e8aeb8f44742ea0614b", "semantic_hash": "e753dae9a3ae1e8aeb8f44742ea0614b" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/Images.xcassets/SplashScreenBackground.colorset/Contents.json": { - "mtime": 1780886883.1759312, + "mtime": 1781099356.0158637, "ast_hash": "7a1fd2646e70f93ae4034dadbe219b43", "semantic_hash": "7a1fd2646e70f93ae4034dadbe219b43" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/Images.xcassets/SplashScreenLegacy.imageset/Contents.json": { - "mtime": 1780886883.177204, + "mtime": 1781099356.0170434, "ast_hash": "a84d44e2229df0082c16210906e94575", "semantic_hash": "a84d44e2229df0082c16210906e94575" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/RebreakContentFilter/FilterDataProvider.swift": { - "mtime": 1780886883.1850178, + "mtime": 1781099356.0233262, "ast_hash": "75d30ad1138439cb747519fe75dd5462", "semantic_hash": "75d30ad1138439cb747519fe75dd5462" }, @@ -3365,8 +3365,8 @@ "semantic_hash": "c243c6784e80ca91e22c1e37f71bcf20" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/hooks/useChatRealtime.ts": { - "mtime": 1781090763.2619104, - "ast_hash": "243caa8c159822d41375b6ff422f5914", + "mtime": 1781091420.6683738, + "ast_hash": "86afc4068b0d4e1ca045d6a6f3fed587", "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/hooks/useLastSeenHeartbeat.ts": { @@ -3440,8 +3440,8 @@ "semantic_hash": "d46991903a163c0331feb7c15e8211f4" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/build.gradle": { - "mtime": 1781073703.6626234, - "ast_hash": "75fdd78656d6a210c2b7874b0ee0faae", + "mtime": 1781099346.8792436, + "ast_hash": "3572e426b00fc0f801751b93e38f9ee6", "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/google-services.json": { @@ -3490,12 +3490,12 @@ "semantic_hash": "53876b03fe0a931f3accc4e6ef99503b" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/compile_commands.json": { - "mtime": 1781073836.0998764, + "mtime": 1781100084.6737607, "ast_hash": "a47cc6a699bb29c35b353e290d0e9d3b", "semantic_hash": "a47cc6a699bb29c35b353e290d0e9d3b" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build_mini.json": { - "mtime": 1781073836.174424, + "mtime": 1781100084.766397, "ast_hash": "9301f24629f8d09ea1e6ec9ac1861fd9", "semantic_hash": "9301f24629f8d09ea1e6ec9ac1861fd9" }, @@ -3505,17 +3505,17 @@ "semantic_hash": "d314c30797af8190a9eeaecda8c0ee99" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/android_gradle_build.json": { - "mtime": 1781073836.1413016, + "mtime": 1781100084.7344887, "ast_hash": "3e5d069e204dc4f0515b59f44287f1a3", "semantic_hash": "3e5d069e204dc4f0515b59f44287f1a3" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/CMakeFiles/_CMakeLTOTest-CXX/src/foo.cpp": { - "mtime": 1781073835.804489, + "mtime": 1781100084.267121, "ast_hash": "bbf8a05ecab16853fd9ad99b367175f8", "semantic_hash": "bbf8a05ecab16853fd9ad99b367175f8" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/CMakeFiles/_CMakeLTOTest-CXX/src/main.cpp": { - "mtime": 1781073835.8048143, + "mtime": 1781100084.267873, "ast_hash": "6155bf9e179fd0f9c2529e16119d24d8", "semantic_hash": "6155bf9e179fd0f9c2529e16119d24d8" }, @@ -3725,12 +3725,12 @@ "semantic_hash": "bc5564cd1a233b5995493d0a94bbdd76" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/compile_commands.json": { - "mtime": 1781073866.9398248, + "mtime": 1781100117.9617994, "ast_hash": "66984f9a8a2ef85bf6765e0fa4fe4b83", "semantic_hash": "66984f9a8a2ef85bf6765e0fa4fe4b83" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/android_gradle_build_mini.json": { - "mtime": 1781073867.0011928, + "mtime": 1781100118.0257287, "ast_hash": "30d567c74332cde560affcd138d9604d", "semantic_hash": "30d567c74332cde560affcd138d9604d" }, @@ -3740,17 +3740,17 @@ "semantic_hash": "d314c30797af8190a9eeaecda8c0ee99" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/android_gradle_build.json": { - "mtime": 1781073866.9804351, + "mtime": 1781100118.0082788, "ast_hash": "5fc1b715aeadb95d76c0ea04ef900cce", "semantic_hash": "5fc1b715aeadb95d76c0ea04ef900cce" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/CMakeFiles/_CMakeLTOTest-CXX/src/foo.cpp": { - "mtime": 1781073866.5783515, + "mtime": 1781100117.6987588, "ast_hash": "bbf8a05ecab16853fd9ad99b367175f8", "semantic_hash": "bbf8a05ecab16853fd9ad99b367175f8" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/CMakeFiles/_CMakeLTOTest-CXX/src/main.cpp": { - "mtime": 1781073866.578687, + "mtime": 1781100117.699018, "ast_hash": "6155bf9e179fd0f9c2529e16119d24d8", "semantic_hash": "6155bf9e179fd0f9c2529e16119d24d8" }, @@ -3960,12 +3960,12 @@ "semantic_hash": "78a35038e0622e60963edc9e2bb98350" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/compile_commands.json": { - "mtime": 1781073800.525331, + "mtime": 1781100051.5533953, "ast_hash": "0f33a6cf3d9c81a85595d18f755caaa6", "semantic_hash": "0f33a6cf3d9c81a85595d18f755caaa6" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/android_gradle_build_mini.json": { - "mtime": 1781073801.183012, + "mtime": 1781100051.7113771, "ast_hash": "c5285287748988fb63ef367ac81c7048", "semantic_hash": "c5285287748988fb63ef367ac81c7048" }, @@ -3975,17 +3975,17 @@ "semantic_hash": "d314c30797af8190a9eeaecda8c0ee99" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/android_gradle_build.json": { - "mtime": 1781073801.064058, + "mtime": 1781100051.6193027, "ast_hash": "9450cfc36a13b7f24fa57dcd84d6965b", "semantic_hash": "9450cfc36a13b7f24fa57dcd84d6965b" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/CMakeFiles/_CMakeLTOTest-CXX/src/foo.cpp": { - "mtime": 1781073799.8494682, + "mtime": 1781100050.7198606, "ast_hash": "bbf8a05ecab16853fd9ad99b367175f8", "semantic_hash": "bbf8a05ecab16853fd9ad99b367175f8" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/CMakeFiles/_CMakeLTOTest-CXX/src/main.cpp": { - "mtime": 1781073799.849759, + "mtime": 1781100050.7201498, "ast_hash": "6155bf9e179fd0f9c2529e16119d24d8", "semantic_hash": "6155bf9e179fd0f9c2529e16119d24d8" }, @@ -4195,12 +4195,12 @@ "semantic_hash": "76d80416ea4b83e2170137be0f6c62d7" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/compile_commands.json": { - "mtime": 1781073898.8306706, + "mtime": 1781100148.1231582, "ast_hash": "cce4bf831bc4b7f5a9b284f56696cb22", "semantic_hash": "cce4bf831bc4b7f5a9b284f56696cb22" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/android_gradle_build_mini.json": { - "mtime": 1781073898.89234, + "mtime": 1781100148.1796436, "ast_hash": "09a097b4d4dade95e0cf0055c5c76c71", "semantic_hash": "09a097b4d4dade95e0cf0055c5c76c71" }, @@ -4210,17 +4210,17 @@ "semantic_hash": "d314c30797af8190a9eeaecda8c0ee99" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/android_gradle_build.json": { - "mtime": 1781073898.8724933, + "mtime": 1781100148.1618986, "ast_hash": "d34917cd0acf613830fa24ce4d823dc5", "semantic_hash": "d34917cd0acf613830fa24ce4d823dc5" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/CMakeFiles/_CMakeLTOTest-CXX/src/foo.cpp": { - "mtime": 1781073898.5592494, + "mtime": 1781100147.8950455, "ast_hash": "bbf8a05ecab16853fd9ad99b367175f8", "semantic_hash": "bbf8a05ecab16853fd9ad99b367175f8" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/CMakeFiles/_CMakeLTOTest-CXX/src/main.cpp": { - "mtime": 1781073898.559822, + "mtime": 1781100147.895296, "ast_hash": "6155bf9e179fd0f9c2529e16119d24d8", "semantic_hash": "6155bf9e179fd0f9c2529e16119d24d8" }, @@ -6505,9 +6505,9 @@ "semantic_hash": "2fd4e4c916da6ace47a63119f42c44ec" }, "/Users/chahinebrini/mono/rebreak-monorepo/.github/workflows/deploy-staging.yml": { - "mtime": 1780298849.8483675, - "ast_hash": "405612dc7a24d9cda0388ef873ef8db1", - "semantic_hash": "405612dc7a24d9cda0388ef873ef8db1" + "mtime": 1781096788.1786268, + "ast_hash": "f6b41140b98cd8446489173b3b8d8175", + "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/.github/workflows/build-magic-win.yml": { "mtime": 1780832567.5303535, @@ -6935,7 +6935,7 @@ "semantic_hash": "f4afab5570d6101011b7b84eb7d11d17" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/additional_project_files.txt": { - "mtime": 1781073836.139619, + "mtime": 1781100084.730819, "ast_hash": "ce4de092e3d56226e9c4f869a10540b0", "semantic_hash": "ce4de092e3d56226e9c4f869a10540b0" }, @@ -6950,22 +6950,22 @@ "semantic_hash": "bc83b589a97bb0c895990549d7ba73fc" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/CMakeFiles/TargetDirectories.txt": { - "mtime": 1781073836.0989523, + "mtime": 1781100084.672128, "ast_hash": "19be9476b5a519b647b0d9fb774ed89b", "semantic_hash": "19be9476b5a519b647b0d9fb774ed89b" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeCache.txt": { - "mtime": 1781073835.814379, + "mtime": 1781100084.2792053, "ast_hash": "0b8d2cea0f921952e562191dd9a6f46f", "semantic_hash": "0b8d2cea0f921952e562191dd9a6f46f" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/TargetDirectories.txt": { - "mtime": 1781073835.8188832, + "mtime": 1781100084.2853115, "ast_hash": "5bcb11cdfd08eb18fd4b4ec3262d4468", "semantic_hash": "5bcb11cdfd08eb18fd4b4ec3262d4468" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/CMakeFiles/_CMakeLTOTest-CXX/src/CMakeLists.txt": { - "mtime": 1781073835.804099, + "mtime": 1781100084.2665324, "ast_hash": "3b72b5cc3e6a0f6bfa3e24ca244eea7d", "semantic_hash": "3b72b5cc3e6a0f6bfa3e24ca244eea7d" }, @@ -6980,7 +6980,7 @@ "semantic_hash": "f4afab5570d6101011b7b84eb7d11d17" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/additional_project_files.txt": { - "mtime": 1781073866.979074, + "mtime": 1781100118.0064566, "ast_hash": "6bcdbb448e790539b93a892d19846be7", "semantic_hash": "6bcdbb448e790539b93a892d19846be7" }, @@ -6995,22 +6995,22 @@ "semantic_hash": "e93e240404f6cdee362151f18088f806" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/CMakeFiles/TargetDirectories.txt": { - "mtime": 1781073866.9387717, + "mtime": 1781100117.9604154, "ast_hash": "f7975dc628a4a1c4cfcf11083b5079c2", "semantic_hash": "f7975dc628a4a1c4cfcf11083b5079c2" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeCache.txt": { - "mtime": 1781073866.608122, + "mtime": 1781100117.707986, "ast_hash": "6424c691ed74073b9d9ed2728e164272", "semantic_hash": "6424c691ed74073b9d9ed2728e164272" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/TargetDirectories.txt": { - "mtime": 1781073866.6233263, + "mtime": 1781100117.7121255, "ast_hash": "e1ba60372eb0f0eed1533515a3d62d2e", "semantic_hash": "e1ba60372eb0f0eed1533515a3d62d2e" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/CMakeFiles/_CMakeLTOTest-CXX/src/CMakeLists.txt": { - "mtime": 1781073866.577554, + "mtime": 1781100117.6984527, "ast_hash": "3b72b5cc3e6a0f6bfa3e24ca244eea7d", "semantic_hash": "3b72b5cc3e6a0f6bfa3e24ca244eea7d" }, @@ -7025,7 +7025,7 @@ "semantic_hash": "f4afab5570d6101011b7b84eb7d11d17" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/additional_project_files.txt": { - "mtime": 1781073801.061488, + "mtime": 1781100051.6168122, "ast_hash": "1b4fb0cc14a842924757df80ecca9ed3", "semantic_hash": "1b4fb0cc14a842924757df80ecca9ed3" }, @@ -7040,22 +7040,22 @@ "semantic_hash": "6712c8fd2785a4067cd65bf280bad965" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/CMakeFiles/TargetDirectories.txt": { - "mtime": 1781073800.5246754, + "mtime": 1781100051.5523384, "ast_hash": "835bfd3ee9e8fe2c784e3f6d5f68e41d", "semantic_hash": "835bfd3ee9e8fe2c784e3f6d5f68e41d" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeCache.txt": { - "mtime": 1781073799.867049, + "mtime": 1781100050.7305112, "ast_hash": "e9ff3221d0ee689fccb1bfce436f17b3", "semantic_hash": "e9ff3221d0ee689fccb1bfce436f17b3" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/TargetDirectories.txt": { - "mtime": 1781073799.8718777, + "mtime": 1781100050.7356062, "ast_hash": "83ad581a716027adc4b57bd8b271bf19", "semantic_hash": "83ad581a716027adc4b57bd8b271bf19" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/CMakeFiles/_CMakeLTOTest-CXX/src/CMakeLists.txt": { - "mtime": 1781073799.8490732, + "mtime": 1781100050.7192829, "ast_hash": "3b72b5cc3e6a0f6bfa3e24ca244eea7d", "semantic_hash": "3b72b5cc3e6a0f6bfa3e24ca244eea7d" }, @@ -7070,7 +7070,7 @@ "semantic_hash": "f4afab5570d6101011b7b84eb7d11d17" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/additional_project_files.txt": { - "mtime": 1781073898.8708692, + "mtime": 1781100148.1593788, "ast_hash": "396fe611b9074b42bde5f6e761139e59", "semantic_hash": "396fe611b9074b42bde5f6e761139e59" }, @@ -7085,22 +7085,22 @@ "semantic_hash": "24ac769e34192d05c47ba73d2c60e85c" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/CMakeFiles/TargetDirectories.txt": { - "mtime": 1781073898.8301, + "mtime": 1781100148.1224687, "ast_hash": "0541e12c132a86d4d73f571a94893e7f", "semantic_hash": "0541e12c132a86d4d73f571a94893e7f" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeCache.txt": { - "mtime": 1781073898.5701597, + "mtime": 1781100147.9036858, "ast_hash": "baf1d4c4ff8b8bcbac1962f4f77bc760", "semantic_hash": "baf1d4c4ff8b8bcbac1962f4f77bc760" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/CMakeFiles/_CMakeLTOTest-CXX/bin/CMakeFiles/TargetDirectories.txt": { - "mtime": 1781073898.5747914, + "mtime": 1781100147.907912, "ast_hash": "d104b31c9f5a42c9df45b3ecc805cce3", "semantic_hash": "d104b31c9f5a42c9df45b3ecc805cce3" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/CMakeFiles/_CMakeLTOTest-CXX/src/CMakeLists.txt": { - "mtime": 1781073898.5588317, + "mtime": 1781100147.8946912, "ast_hash": "3b72b5cc3e6a0f6bfa3e24ca244eea7d", "semantic_hash": "3b72b5cc3e6a0f6bfa3e24ca244eea7d" }, @@ -7384,26 +7384,6 @@ "ast_hash": "6ccbb870b630233e41a6a4273b4672b0", "semantic_hash": "6ccbb870b630233e41a6a4273b4672b0" }, - "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/.cmake/api/v1/reply/index-2026-06-10T06-43-56-0126.json": { - "mtime": 1781073836.1269782, - "ast_hash": "92e5e4513854a8ee33b8649d8a5a733a", - "semantic_hash": "" - }, - "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/.cmake/api/v1/reply/index-2026-06-10T06-44-26-0968.json": { - "mtime": 1781073866.9680228, - "ast_hash": "9e3cc2c421898601a78766628e7f425d", - "semantic_hash": "" - }, - "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/.cmake/api/v1/reply/index-2026-06-10T06-43-20-0573.json": { - "mtime": 1781073800.5735383, - "ast_hash": "aadb4abeff66a8c956aa2a198fa11ae0", - "semantic_hash": "" - }, - "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/.cmake/api/v1/reply/index-2026-06-10T06-44-58-0859.json": { - "mtime": 1781073898.8597715, - "ast_hash": "a6ab1ed40e911ae57fed01928b2a8be7", - "semantic_hash": "" - }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/Debug/51sk2e6z/armeabi-v7a/.cmake/api/v1/reply/cmakeFiles-v1-3bc501df0f7b3202d590.json": { "mtime": 1781071634.0955763, "ast_hash": "508cc45db0022c80dbe37ad64f58d7e4", @@ -7685,22 +7665,22 @@ "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png": { - "mtime": 1780886883.165441, + "mtime": 1781099356.0136845, "ast_hash": "f13c8cff3aa27d1021eac9e6124a73b4", "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/Images.xcassets/SplashScreenLegacy.imageset/image@3x.png": { - "mtime": 1780886883.1792867, + "mtime": 1781099356.0190911, "ast_hash": "06a3074fc25dc205cc2265a269958dd0", "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/Images.xcassets/SplashScreenLegacy.imageset/image@2x.png": { - "mtime": 1780886883.1792939, + "mtime": 1781099356.0190566, "ast_hash": "06a3074fc25dc205cc2265a269958dd0", "semantic_hash": "" }, "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/ios/ReBreak/Images.xcassets/SplashScreenLegacy.imageset/image.png": { - "mtime": 1780886883.1792905, + "mtime": 1781099356.0190496, "ast_hash": "06a3074fc25dc205cc2265a269958dd0", "semantic_hash": "" }, @@ -8413,5 +8393,25 @@ "mtime": 1780556379.4233892, "ast_hash": "64cbd4c2d284cbd433fd32523c90debc", "semantic_hash": "" + }, + "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/armeabi-v7a/.cmake/api/v1/reply/index-2026-06-10T14-01-24-0714.json": { + "mtime": 1781100084.7143128, + "ast_hash": "92e5e4513854a8ee33b8649d8a5a733a", + "semantic_hash": "" + }, + "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86/.cmake/api/v1/reply/index-2026-06-10T14-01-57-0989.json": { + "mtime": 1781100117.9897835, + "ast_hash": "9e3cc2c421898601a78766628e7f425d", + "semantic_hash": "" + }, + "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/arm64-v8a/.cmake/api/v1/reply/index-2026-06-10T14-00-51-0586.json": { + "mtime": 1781100051.586443, + "ast_hash": "aadb4abeff66a8c956aa2a198fa11ae0", + "semantic_hash": "" + }, + "/Users/chahinebrini/mono/rebreak-monorepo/apps/rebreak-native/android/app/.cxx/RelWithDebInfo/5m151t3n/x86_64/.cmake/api/v1/reply/index-2026-06-10T14-02-28-0148.json": { + "mtime": 1781100148.1485403, + "ast_hash": "a6ab1ed40e911ae57fed01928b2a8be7", + "semantic_hash": "" } } \ No newline at end of file diff --git a/ops/BUSINESS_PLAN_NBANK.md b/ops/BUSINESS_PLAN_NBANK.md index 90da5cc..859000e 100644 --- a/ops/BUSINESS_PLAN_NBANK.md +++ b/ops/BUSINESS_PLAN_NBANK.md @@ -300,7 +300,7 @@ Rebreak ist bewusst **plattformübergreifend nativ**, nicht hybrid. Grund: der S | Anbieter | Herkunft | Plattformen | DNS-/URL-Block | Mail-Schutz | KI-Coach | DE-Fokus | Lock-Modus | Preis (Monat) | |---|---|---|---|---|---|---|---|---| | **Rebreak** | DE | iOS, Android, **macOS** | ✅ (~330k Domains) | ✅ **IMAP-IDLE Echtzeit** | ✅ Lyra (DE) | ✅ | ✅ Rebreak Magic | 3,99 / 7,99 € | -| Gamban | UK | iOS, Android, Win, Mac | ✅ | ❌ | ❌ | teilweise EN | nur passwortgeschützt | ~3,75 € (£ 2,99 ähnl.) | +| Gamban | UK | iOS, Android, Win, Mac | ✅ | ❌ | ❌ | teilweise EN | nur passwortgeschützt | 5,99 € (35,99 €/Jahr, Stand 2026) | | BetBlocker | UK (Charity) | iOS, Android, Win, Mac | ✅ | ❌ | ❌ | nein | timer-basiert | kostenlos | | GamBlock | AU | Win, Mac, Android | ✅ | ❌ | ❌ | nein | stark | ~5–9 € | | Truple / Net Nanny | US | iOS, Android, Win | nur teils, Fokus Porn | ❌ | ❌ | nein | ja | ~10 € | diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 590bba1..80c04b9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,7 +45,7 @@ importers: version: 14.3.0(vue@3.5.34(typescript@5.9.3)) '@vueuse/nuxt': specifier: ^14.2.1 - version: 14.3.0(magicast@0.5.3)(nuxt@4.1.3(@electric-sql/pglite@0.4.1)(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@electric-sql/pglite@0.4.1)(mysql2@3.15.3))(eslint@10.3.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.3)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.60.3)(terser@5.46.2)(typescript@5.9.3)(vite@7.3.3(@types/node@22.19.17)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.4))(yaml@2.8.4))(vue@3.5.34(typescript@5.9.3)) + version: 14.3.0(magicast@0.5.3)(nuxt@4.1.3(@electric-sql/pglite@0.4.1)(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@electric-sql/pglite@0.4.1)(mysql2@3.15.3))(eslint@10.3.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.3)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.60.3)(terser@5.46.2)(typescript@5.9.3)(yaml@2.8.4))(vue@3.5.34(typescript@5.9.3)) nuxt: specifier: 4.1.3 version: 4.1.3(@electric-sql/pglite@0.4.1)(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@electric-sql/pglite@0.4.1)(mysql2@3.15.3))(eslint@10.3.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.3)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.60.3)(terser@5.46.2)(typescript@5.9.3)(vite@7.3.3(@types/node@22.19.17)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.4))(yaml@2.8.4) @@ -94,7 +94,7 @@ importers: version: 3.0.3(magicast@0.5.3)(vue@3.5.34(typescript@5.9.3)) '@vueuse/nuxt': specifier: ^14.2.1 - version: 14.3.0(magicast@0.5.3)(nuxt@4.1.3(@electric-sql/pglite@0.4.1)(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@electric-sql/pglite@0.4.1)(mysql2@3.15.3))(eslint@10.3.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.3)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.60.3)(terser@5.46.2)(typescript@5.9.3)(vite@7.3.3(@types/node@22.19.17)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.4))(yaml@2.8.4))(vue@3.5.34(typescript@5.9.3)) + version: 14.3.0(magicast@0.5.3)(nuxt@4.1.3(@electric-sql/pglite@0.4.1)(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@electric-sql/pglite@0.4.1)(mysql2@3.15.3))(eslint@10.3.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.3)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.60.3)(terser@5.46.2)(typescript@5.9.3)(yaml@2.8.4))(vue@3.5.34(typescript@5.9.3)) chart.js: specifier: ^4.5.1 version: 4.5.1 @@ -114,6 +114,9 @@ importers: specifier: ^4.5.1 version: 4.6.4(vue@3.5.34(typescript@5.9.3)) devDependencies: + '@iconify-json/simple-icons': + specifier: ^1.2.86 + version: 1.2.86 '@nuxt/devtools': specifier: latest version: 4.0.0-alpha.7(db0@0.3.4(@electric-sql/pglite@0.4.1)(mysql2@3.15.3))(ioredis@5.10.1)(typescript@5.9.3)(vite@7.3.3(@types/node@22.19.17)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.4))(vue@3.5.34(typescript@5.9.3)) @@ -1879,6 +1882,9 @@ packages: '@iconify-json/heroicons@1.2.3': resolution: {integrity: sha512-n+vmCEgTesRsOpp5AB5ILB6srsgsYK+bieoQBNlafvoEhjVXLq8nIGN4B0v/s4DUfa0dOrjwE/cKJgIKdJXOEg==} + '@iconify-json/simple-icons@1.2.86': + resolution: {integrity: sha512-t3jck5qPQuK1qy+bRn9eCoDQhIB7XSazKz1Fjp8hcan3XOAsTI5Mq/s3F0ekOKSvMQqkVORYK6ns6o6T9f5EMA==} + '@iconify/collections@1.0.680': resolution: {integrity: sha512-zALf9JfXAKxExpb8bYA5Ds0cHgZceRMR1pkUiwLPa0Ctl8sfXw6Honrc/APpcLbTSyBaH1ZMnS4Y/2SdSPa4Pg==} @@ -11434,6 +11440,10 @@ snapshots: dependencies: '@iconify/types': 2.0.0 + '@iconify-json/simple-icons@1.2.86': + dependencies: + '@iconify/types': 2.0.0 + '@iconify/collections@1.0.680': dependencies: '@iconify/types': 2.0.0 @@ -14610,7 +14620,7 @@ snapshots: transitivePeerDependencies: - magicast - '@vueuse/nuxt@14.3.0(magicast@0.5.3)(nuxt@4.1.3(@electric-sql/pglite@0.4.1)(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@electric-sql/pglite@0.4.1)(mysql2@3.15.3))(eslint@10.3.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.3)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.60.3)(terser@5.46.2)(typescript@5.9.3)(vite@7.3.3(@types/node@22.19.17)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.2)(yaml@2.8.4))(yaml@2.8.4))(vue@3.5.34(typescript@5.9.3))': + '@vueuse/nuxt@14.3.0(magicast@0.5.3)(nuxt@4.1.3(@electric-sql/pglite@0.4.1)(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)(@parcel/watcher@2.5.6)(@types/node@22.19.17)(@vue/compiler-sfc@3.5.35)(cac@6.7.14)(db0@0.3.4(@electric-sql/pglite@0.4.1)(mysql2@3.15.3))(eslint@10.3.0(jiti@2.7.0))(ioredis@5.10.1)(lightningcss@1.32.0)(magicast@0.5.3)(mysql2@3.15.3)(optionator@0.9.4)(rollup@4.60.3)(terser@5.46.2)(typescript@5.9.3)(yaml@2.8.4))(vue@3.5.34(typescript@5.9.3))': dependencies: '@nuxt/kit': 4.4.4(magicast@0.5.3) '@vueuse/core': 14.3.0(vue@3.5.34(typescript@5.9.3))