# anildhiman88/kinpulse architecture

> Architecture diagram of the GitHub repository anildhiman88/kinpulse, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-23). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/anildhiman88/kinpulse
- Repository: https://github.com/anildhiman88/kinpulse

## Overview

1. **Project shape**
   - KinPulse Phase 1 is primarily an **Android Kotlin app** with a small **TypeScript Firebase Functions** backend for optional server-side alerts.
   - The Android app uses **Jetpack Compose**, **WorkManager**, **Firebase/FCM**, and a **single app-level ViewModel**. The repo also contains a **demo/local persistence path** so the app can run without Firebase config.

2. **Top-level runtime boundary**
   - `KinPulseApplication` and `AppContainer` set up the app-wide dependencies.
   - `MainActivity` hosts the Compose UI, while `ui/navigation/KinPulseApp.kt` drives screen flow.
   - Dependency wiring is intentionally manual rather than Hilt-based, so architecture is straightforward and centralized.

3. **Domain/data model boundary**
   - `data/model/Models.kt` holds the Firestore-compatible records used across the app.
   - The readme indicates the key entities are things like users, companion profiles, invite codes, family connections, heartbeats, heartbeat signals, and notification logs.
   - These models are the shared contract between UI, repository, background work, and Firebase.

4. **Repository layer as the main data boundary**
   - `data/repository/KinPulseRepository.kt` is the abstraction used by the rest of the app.
   - `FirebaseKinPulseRepository` is the cloud-backed implementation; `DemoKinPulseRepository` is the founder-demo/local fallback.
   - `LocalSignalStore` supports local persistence for signal capture and continuity.
   - This repository boundary is the main switch that determines whether the app is running against Firebase or in demo mode.

5. **State management and UI flow**
   - `viewmodel/MainViewModel.kt` is the app-level state holder.
   - It exposes `StateFlow`-based UI state and user actions to the Compose screens.
   - The UI layer is split into `ui/screens` for feature screens, `ui/components` for shared widgets, and `ui/theme` for styling.
   - The architecture is “screen driven”: the UI reads state from the ViewModel and sends events back to it, rather than talking directly to Firebase.

6. **Heartbeat engine: core business logic**
   - The `heartbeat` package is the product’s main business subsystem.
   - `HeartbeatEngine`, `HeartbeatScoringService`, `HeartbeatTrustStateEngine`, `HeartbeatNotificationPolicy`, `HeartbeatAccessPolicy`, `SignalCapturePolicy`, and `HeartbeatExplanationService` together implement the daily heartbeat rules.
   - This layer converts privacy-safe signals into calm states such as received, waiting, delayed, manual check-in, and sharing paused.
   - It also enforces confidence scoring, duplicate caps, time-window logic, and user-facing explanations.

7. **Signal ingestion and local event sources**
   - The app captures only safe operational signals, not private content.
   - `services/BootCompletedReceiver.kt`, `ChargingEventReceiver.kt`, and `DevicePresenceReceiver.kt` are Android broadcast/service entry points that feed the heartbeat logic.
   - `workers/HeartbeatWorker.kt` provides periodic background refresh and delayed checks when the app is backgrounded.
   - These inputs are best-effort because Android power policies may delay them; the app is designed around that constraint.

8. **Notification subsystem**
   - `notifications/KinPulseNotificationChannels.kt` defines notification channels.
   - `notifications/KinPulseMessagingService.kt` handles FCM messages when cloud push is available.
   - `notifications/NotificationRepository.kt` stores notification-related state/logging.
   - Notifications are emitted from both local Android logic and optional cloud events, with the product favoring local calm-state rendering and best-effort delivery in Spark mode.

9. **Firebase and cloud backend**
   - The Android app uses Firestore and Firebase Auth for sign-in and shared family data.
   - `firestore.rules` and `firestore.indexes.json` define the backend access boundary and query support.
   - The `functions/src/index.ts` TypeScript backend is optional but supports later-stage server notifications and scheduled delayed-heartbeat checks.
   - The README makes clear that cloud functions are not required for the MVP to run, but they improve notification reliability and delayed alert handling.

10. **Data flow from signal to family view**
   - A signal arrives from the app, boot, charging, or periodic worker.
   - The signal is stored locally and/or written through the repository.
   - Heartbeat logic recalculates the daily state and confidence, then persists the heartbeat document.
   - The family-facing UI reads the updated repository state and shows the calm status, daily timestamps, and seven-day summary.

11. **Sharing and access control**
   - Sharing on/off is enforced at multiple levels: UI, repository writes, notifications, and Firestore rules.
   - Family access is mediated by invite codes and connected-family records.
   - Revocation is non-destructive but immediately removes future access for the revoked family member.
   - This is a key architectural boundary: the app is privacy-first and treats access as a controlled relationship, not an open feed.

12. **Time and presentation rules**
   - `utils/TimeUtils.kt` plus the heartbeat services handle local-day and timezone-sensitive behavior.
   - The app uses the Companion’s timezone for daily heartbeat boundaries and late-day “appears settled around …” presentation.
   - This matters because the architecture is not just storing timestamps; it is interpreting them relative to each companion’s local day and wake/sensitivity windows.

13. **Testing and verification**
   - The repo includes focused unit tests for the heartbeat services, time utilities, and user profile capability logic.
   - The `docs/TESTING_CHECKLIST.md` and README manual QA steps reflect the main architectural risks: access control, duplicate alerts, delayed alerts, and state transitions.
   - This suggests the critical correctness surface is in the domain logic, not in UI rendering.

14. **Architecture summary for a diagram**
   - The cleanest diagram would show: **Android UI/Compose → MainViewModel → Repository → Firebase/Demo storage**, with **heartbeat engine** as the central domain processor.
   - Side inputs come from **receivers/workers** into the heartbeat engine, and side outputs go to **local notifications / FCM / cloud functions**.
   - The main boundaries are **UI state**, **repository abstraction**, **heartbeat rules**, and **Firebase/cloud integration**.

Main entry points: [`app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatEngine.kt`](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatEngine.kt) (Heartbeat engine), [`app/src/main/java/com/kinpulse/app/AppContainer.kt`](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/AppContainer.kt) (App container), [`app/src/main/java/com/kinpulse/app/viewmodel/MainViewModel.kt`](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/viewmodel/MainViewModel.kt) (Main view model), [`app/src/main/java/com/kinpulse/app/data/repository/KinPulseRepository.kt`](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/repository/KinPulseRepository.kt) (Repo API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_android["Android app"]
  node_app["KinPulse app<br/>android runtime"]
  node_container["App container<br/>manual DI<br/>[AppContainer.kt]"]
  node_activity["Main activity<br/>Compose host<br/>[MainActivity.kt]"]
  node_nav["App nav<br/>Compose navigation<br/>[KinPulseApp.kt]"]
  node_vm["Main view model<br/>UI state holder<br/>[MainViewModel.kt]"]
  node_screens["Screens"]
  node_components["Shared UI<br/>Compose widgets"]
end

subgraph group_domain["Domain"]
  node_models["Models<br/>data contract<br/>[Models.kt]"]
  node_repo["Repo API<br/>repository abstraction"]
  node_demo_repo["Demo repo<br/>local fallback"]
  node_heartbeat{{"Heartbeat engine<br/>business rules<br/>[HeartbeatEngine.kt]"}}
  node_scoring["Scoring"]
  node_trust["Trust state<br/>state machine"]
  node_policy["Policies<br/>rules bundle"]
end

subgraph group_infra["Infrastructure"]
  node_local_store[("Local signals<br/>local persistence")]
  node_signals["Signal sources<br/>android receivers"]
  node_worker["Heartbeat worker<br/>background worker<br/>[HeartbeatWorker.kt]"]
  node_notifications["Notifications<br/>notification layer"]
end

subgraph group_cloud["Cloud"]
  node_firebase_repo["Firebase repo<br/>cloud repository"]
  node_cloud_fn["Cloud functions<br/>TypeScript backend<br/>[index.ts]"]
  node_firestore["Firestore rules<br/>backend boundary<br/>[firestore.rules]"]
end

node_app -->|"creates"| node_container
node_container -->|"provides"| node_repo
node_container -->|"provides"| node_heartbeat
node_container -->|"provides"| node_notifications
node_activity -->|"hosts"| node_nav
node_nav -->|"reads state"| node_vm
node_vm -->|"uses"| node_repo
node_vm -->|"dispatches"| node_heartbeat
node_vm -->|"drives"| node_screens
node_screens -->|"composes"| node_components
node_heartbeat -->|"calls"| node_scoring
node_heartbeat -->|"calls"| node_trust
node_heartbeat -->|"applies"| node_policy
node_heartbeat -->|"reads/writes"| node_models
node_signals -->|"triggers"| node_worker
node_signals -->|"feeds"| node_heartbeat
node_worker -->|"refreshes"| node_heartbeat
node_heartbeat -->|"stores"| node_local_store
node_repo -->|"implements"| node_firebase_repo
node_repo -->|"implements"| node_demo_repo
node_demo_repo -->|"uses"| node_local_store
node_firebase_repo -->|"uses"| node_models
node_firebase_repo -->|"constrained by"| node_firestore
node_notifications -->|"reflects"| node_heartbeat
node_notifications -->|"receives"| node_cloud_fn
node_cloud_fn -->|"accesses"| node_firestore

click node_app "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/KinPulseApplication.kt"
click node_container "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/AppContainer.kt"
click node_activity "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/MainActivity.kt"
click node_nav "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/ui/navigation/KinPulseApp.kt"
click node_vm "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/viewmodel/MainViewModel.kt"
click node_screens "https://github.com/anildhiman88/kinpulse/tree/main/app/src/main/java/com/kinpulse/app/ui/screens"
click node_components "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/ui/components/CommonComponents.kt"
click node_models "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/model/Models.kt"
click node_repo "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/repository/KinPulseRepository.kt"
click node_firebase_repo "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/repository/FirebaseKinPulseRepository.kt"
click node_demo_repo "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/repository/DemoKinPulseRepository.kt"
click node_local_store "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/repository/LocalSignalStore.kt"
click node_heartbeat "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatEngine.kt"
click node_scoring "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatScoringService.kt"
click node_trust "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatTrustStateEngine.kt"
click node_policy "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatAccessPolicy.kt"
click node_signals "https://github.com/anildhiman88/kinpulse/tree/main/app/src/main/java/com/kinpulse/app/services"
click node_worker "https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/workers/HeartbeatWorker.kt"
click node_notifications "https://github.com/anildhiman88/kinpulse/tree/main/app/src/main/java/com/kinpulse/app/notifications"
click node_cloud_fn "https://github.com/anildhiman88/kinpulse/blob/main/functions/src/index.ts"
click node_firestore "https://github.com/anildhiman88/kinpulse/blob/main/firestore.rules"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_container,node_activity,node_nav,node_vm,node_screens,node_components toneBlue
class node_models,node_repo,node_demo_repo,node_heartbeat,node_scoring,node_trust,node_policy toneAmber
class node_local_store,node_signals,node_worker,node_notifications toneMint
class node_firebase_repo,node_cloud_fn,node_firestore toneRose
```

## Components

### Android app

Primary Kotlin app runtime and UI layers.

- [KinPulse app](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/KinPulseApplication.kt): android runtime · Android application entry and dependency root. · `app/src/main/java/com/kinpulse/app/KinPulseApplication.kt`
- [App container](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/AppContainer.kt): manual DI · Central dependency wiring and runtime selection. · `app/src/main/java/com/kinpulse/app/AppContainer.kt`
- [Main activity](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/MainActivity.kt): Compose host · Hosts the Compose UI tree. · `app/src/main/java/com/kinpulse/app/MainActivity.kt`
- [App nav](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/ui/navigation/KinPulseApp.kt): Compose navigation · Drives screen flow through the app. · `app/src/main/java/com/kinpulse/app/ui/navigation/KinPulseApp.kt`
- [Main view model](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/viewmodel/MainViewModel.kt): UI state holder · Single app-level state and action surface for screens. · `app/src/main/java/com/kinpulse/app/viewmodel/MainViewModel.kt`
- [Screens](https://github.com/anildhiman88/kinpulse/tree/main/app/src/main/java/com/kinpulse/app/ui/screens): Compose screens · Dashboard, onboarding, setup, settings, and preview flows. · `app/src/main/java/com/kinpulse/app/ui/screens`
- [Shared UI](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/ui/components/CommonComponents.kt): Compose widgets · Reusable UI components and theme styling. · `app/src/main/java/com/kinpulse/app/ui/components/CommonComponents.kt`

### Domain

Heartbeat rules and shared data contracts.

- [Models](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/model/Models.kt): data contract · Firestore-compatible entities shared across the app. · `app/src/main/java/com/kinpulse/app/data/model/Models.kt`
- [Repo API](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/repository/KinPulseRepository.kt): repository abstraction · Primary data boundary used by UI and heartbeat logic. · `app/src/main/java/com/kinpulse/app/data/repository/KinPulseRepository.kt`
- [Demo repo](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/repository/DemoKinPulseRepository.kt): local fallback · Founder-demo and offline-friendly repository implementation. · `app/src/main/java/com/kinpulse/app/data/repository/DemoKinPulseRepository.kt`
- [Heartbeat engine](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatEngine.kt): business rules · Coordinates state calculation, confidence, and calm statuses. · `app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatEngine.kt`
- [Scoring](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatScoringService.kt): signal scoring · Computes confidence from safe operational signals. · `app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatScoringService.kt`
- [Trust state](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatTrustStateEngine.kt): state machine · Derives waiting, delayed, received, and paused states. · `app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatTrustStateEngine.kt`
- [Policies](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatAccessPolicy.kt): rules bundle · Access, notification, capture, and explanation rules. · `app/src/main/java/com/kinpulse/app/heartbeat/HeartbeatAccessPolicy.kt`

### Infrastructure

Firebase, persistence, background entry points, and notifications.

- [Local signals](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/repository/LocalSignalStore.kt): local persistence · Stores signal capture data for continuity. · `app/src/main/java/com/kinpulse/app/data/repository/LocalSignalStore.kt`
- [Signal sources](https://github.com/anildhiman88/kinpulse/tree/main/app/src/main/java/com/kinpulse/app/services): android receivers · Boot, charging, and device-presence entry points. · `app/src/main/java/com/kinpulse/app/services`
- [Heartbeat worker](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/workers/HeartbeatWorker.kt): background worker · Periodic refresh and delayed checks when backgrounded. · `app/src/main/java/com/kinpulse/app/workers/HeartbeatWorker.kt`
- [Notifications](https://github.com/anildhiman88/kinpulse/tree/main/app/src/main/java/com/kinpulse/app/notifications): notification layer · Channels, local logging, and FCM message handling. · `app/src/main/java/com/kinpulse/app/notifications`

### Cloud

Optional TypeScript backend and Firebase access boundaries.

- [Firebase repo](https://github.com/anildhiman88/kinpulse/blob/main/app/src/main/java/com/kinpulse/app/data/repository/FirebaseKinPulseRepository.kt): cloud repository · Firestore/Auth-backed implementation. · `app/src/main/java/com/kinpulse/app/data/repository/FirebaseKinPulseRepository.kt`
- [Cloud functions](https://github.com/anildhiman88/kinpulse/blob/main/functions/src/index.ts): TypeScript backend · Optional scheduled checks and server-side alert support. · `functions/src/index.ts`
- [Firestore rules](https://github.com/anildhiman88/kinpulse/blob/main/firestore.rules): backend boundary · Access control and query support for shared family data. · `firestore.rules`

## Connections

- KinPulse app → App container: creates · Application initializes shared dependencies.
- App container → Repo API: provides · Selects cloud or demo data path.
- App container → Heartbeat engine: provides · Wires domain services into the app.
- App container → Notifications: provides · Supplies notification infrastructure.
- Main activity → App nav: hosts · Activity sets up the Compose tree.
- App nav → Main view model: reads state · Navigation reacts to app state.
- Main view model → Repo API: uses · ViewModel loads and mutates shared records.
- Main view model → Heartbeat engine: dispatches · User actions flow into heartbeat updates.
- Main view model → Screens: drives · Screens render from ViewModel state.
- Screens → Shared UI: composes · Screens reuse common widgets and theme.
- Heartbeat engine → Scoring: calls · Calculates confidence from captured signals.
- Heartbeat engine → Trust state: calls · Derives calm-state transitions.
- Heartbeat engine → Policies: applies · Enforces access, capture, and notification rules.
- Heartbeat engine → Models: reads/writes · Uses shared entities for state persistence.
- Signal sources → Heartbeat worker: triggers · Android entry points and periodic work feed the engine.
- Signal sources → Heartbeat engine: feeds · Operational signals enter the rules engine.
- Heartbeat worker → Heartbeat engine: refreshes · Runs delayed and periodic recalculation.
- Heartbeat engine → Local signals: stores · Persists safe local continuity data.
- Repo API → Firebase repo: implements · Cloud-backed repository variant.
- Repo API → Demo repo: implements · Offline/demo repository variant.
- Demo repo → Local signals: uses · Keeps demo and local signal data available.
- Firebase repo → Models: uses · Maps shared models to Firestore.
- Firebase repo → Firestore rules: constrained by · Reads and writes under backend rules.
- Notifications → Heartbeat engine: reflects · Local notifications present heartbeat state.
- Notifications → Cloud functions: receives · FCM and server-side alert support.
- Cloud functions → Firestore rules: accesses · Backend operations remain within Firestore policy.
