Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 

Repository files navigation

EndoMatrix Core

A cycle-aware symptom pattern interpreter that transforms daily logs into longitudinal insight — helping users understand when their body gets worse, how it shows up, and what to expect next.

Pattern recognition and interpretation. Not diagnosis.


What this is

Most cycle trackers answer one question: when is my next period? EndoMatrix answers a different one: why does my body feel the way it does, and when will it happen again?

Users log three signals per day. The system learns their personal baseline, maps symptoms to cycle phases, and after 30 days produces an insight page that shows patterns the user could not see on their own. The goal is a single moment of recognition: I'm not imagining this. I can prove it. I can plan around it.


Screens

1. Onboarding

First open only. Under 2 minutes. Three steps.

Step What the user sees
Intent "What brings you here?" — one of four options: chronic menstrual pain, irregular cycles, severe PMS, just trying to understand my body
Tracker choice Use EndoMatrix's built-in calendar, link an existing tracker (Flo, Clue, or Apple Health via HealthKit), or skip for now
Cycle baseline Last period start date (date picker) + average cycle length bucket, or "irregular / not sure"

The expectation is set once: "We won't diagnose you. We help you notice patterns you couldn't see before."

The system infers cycle phase silently from this point forward. The user never selects a phase manually.


2. Cycle Calendar

Period tracking and cycle overview.

Element Description
Month grid Monday-start. Tap any day to mark or unmark it as a period day.
Period days Shown as filled white circles against the gradient header.
Predicted days Next period window shown with a dashed ring, derived from last period start and average cycle length.
High-pain window Days 18–22 shown with a subtle dot from day one, based on typical luteal phase averages. Replaced by personal pattern data once enough logs exist.
Flow logger Appears when today is marked as a period day: Spotting / Light / Medium / Heavy.
Cycle stats strip Cycle length, period length, predicted next period date.
Phase strip Four phases shown as a compact row — current phase highlighted in purple.

3. Daily Log

One screen. No scrolling.

Input Type Detail
Pain today Slider 0–10 Rose gradient. Value shown in serif at top right.
Energy level Slider 0–10 Purple gradient. Same treatment.
Flow today Segmented: Spotting / Light / Medium / Heavy Shown only on days marked as period days in the calendar.
Dominant symptom Chip grid (single-select) Pelvic pain, lower back pain, leg pain, bloating, nausea, headache, acne flare, mood crash, brain fog, insomnia, other.
Log button Full-width CTA "Log today" — disabled until a symptom is selected.

After logging: "Saved. See you tomorrow." Nothing else.

Cycle day and phase are attached to the log silently by the system.


4. Home

The screen you open every day.

Element Description
Gradient header Current cycle day and phase shown at top. Streak and logs-until-insights counters.
Log prompt If today has no log: a tappable card — "Log today's symptoms →"
Logged state If today is already logged: a quiet rose-tinted confirmation with pain and energy values.
Early feedback card Appears from day 7 onward, one sentence only: e.g. "You tend to log higher pain around this point in your cycle." Generated by the API.
Phase context card A short, plain-language description of the current phase and what to expect.

No charts. No summaries. Nothing that competes with the habit of logging.


5. Insights

Locked until 30 days of logs exist.

Before unlock — teaser state:

An empty state showing days remaining and a plain description of what the insight page will contain once unlocked. No fabricated data, no blurred previews.

After unlock — full insight page:

Section Content
When symptoms begin Which cycle days symptoms typically start, shown as a range.
How severity changes Bar chart showing pain intensity across the luteal phase. Trend label: escalating, improving, stable, variable.
What travels together Top symptom cluster — which symptoms appear together on high-pain days.
What to try next cycle Soft guidance list: schedule rest, lighter workloads, preparation notes.
Export "Export for clinician →" — triggers print dialog (PDF). User controls if and when this is shared.

All language uses qualifiers: "so far", "based on your data", "may change as we learn more."


6. Settings

Not yet implemented.

Option Description
Daily reminder Toggle on/off, set preferred time
Cycle info Edit last period date and average cycle length
Tracker connection Connect or disconnect Flo, Clue, or Apple Health
Account Email, sign out, delete account
Privacy View what data is stored, request full export, delete all data
About Version, non-diagnostic disclaimer, link to endomatrixlabs.tech

MVP additions

Shipped after v0 validation. The core screens stay the same — these extend them.

Daily log gains two optional inputs:

  • Mood level (0–10 slider) — fourth slider, same neutral treatment as pain and energy
  • Free text note — one sentence maximum, optional, appears below the log button

Insights page gains one new section:

  • Cycle comparison: this cycle versus the previous cycle, side by side, same phase windows

History calendar gains:

  • Pain intensity dot per day (light to deep color based on pain level)
  • Tap a day to see the full log entry for that day

Wearable data (optional, user-initiated):

  • Resting heart rate, HRV, skin temperature, sleep duration ingested as supplementary signals
  • Shown in Insights as supporting context alongside logged data
  • Never the primary signal — the daily log always anchors the pattern

Roadmap

Not in scope until MVP is validated.

  • SMS/USSD interface for low-connectivity access
  • Clinician export with structured symptom timeline
  • Perimenopause and menopause logging cohort
  • Population analytics layer — EndoMatrix Sentinel

Architecture

Hexagonal architecture (ports and adapters). The domain layer has zero framework dependencies and is fully testable in isolation.

endomatrix/
├── apps/
│   ├── api/                          ← FastAPI (Python 3.11)
│   │   ├── domain/                   ← Pure Python. No FastAPI. No SQLAlchemy.
│   │   │   ├── models/               ← DailyLog, CycleBaseline, Symptom, PatternResult, events
│   │   │   ├── engine/               ← PatternEngine, PhaseCalculator (pure functions)
│   │   │   └── ports/                ← ILogRepository, ICycleRepository, IPatternRepository (ABCs)
│   │   ├── application/              ← Use cases
│   │   │   └── use_cases/            ← LogDailyEntry, SetCycleBaseline, GeneratePattern,
│   │   │                                GetHomeState, GenerateEarlyFeedback
│   │   ├── infrastructure/           ← Framework-facing
│   │   │   ├── orm/tables.py         ← SQLAlchemy table definitions
│   │   │   ├── repositories/         ← PostgresLogRepository, PostgresCycleRepository,
│   │   │   │                            PostgresPatternRepository
│   │   │   └── events/publisher.py   ← DatabaseEventPublisher
│   │   ├── presentation/             ← FastAPI layer
│   │   │   ├── app.py                ← App factory, exception handlers
│   │   │   ├── dependencies.py       ← DI wiring
│   │   │   ├── schemas/              ← Pydantic request/response schemas
│   │   │   └── routers/              ← /baseline, /logs, /home, /insights
│   │   ├── alembic/                  ← Migrations
│   │   │   └── versions/0001_initial_schema.py
│   │   └── tests/
│   │       ├── fakes.py              ← In-memory repository fakes
│   │       ├── domain/               ← Domain model tests
│   │       ├── engine/               ← PatternEngine + PhaseCalculator tests
│   │       ├── ports/                ← Port contract tests
│   │       ├── application/          ← Use case tests
│   │       ├── integration/          ← Postgres repository tests (requires TEST_DATABASE_URL)
│   │       └── presentation/         ← Router tests (63/63 passing)
│   │
│   └── web/                          ← Next.js 15 PWA (TypeScript)
│       ├── public/manifest.json      ← PWA manifest
│       └── src/
│           ├── middleware.ts          ← Clerk auth guard
│           ├── lib/
│           │   ├── theme.ts           ← Design tokens, palette, phase constants
│           │   ├── types.ts           ← Shared TypeScript types (aligned with API schemas)
│           │   └── api.ts             ← Fetch wrapper for all API calls
│           ├── components/
│           │   ├── ui/               ← Card, SectionLabel, GradientHeader, StatCard,
│           │   │                        FlowButton, SymptomChip, NavBar
│           │   └── calendar/         ← MonthCalendar, PhaseStrip
│           └── app/
│               ├── layout.tsx         ← Root layout with ClerkProvider
│               ├── globals.css        ← Reset, slider styles, shared utility classes
│               ├── (auth)/
│               │   └── sign-in/      ← Clerk magic-link sign-in page
│               └── (app)/            ← Authenticated route group
│                   ├── layout.tsx    ← App shell with NavBar
│                   ├── onboarding/   ← 3-step onboarding flow
│                   ├── calendar/     ← Period tracking calendar
│                   ├── log/          ← Daily symptom log
│                   ├── home/         ← Home screen (server + client split)
│                   └── insights/     ← Pattern summary (server + client split)
│
├── packages/
│   └── shared-types/                 ← TypeScript types generated from FastAPI OpenAPI schema
│
├── docker-compose.yml                ← db (5432) + db_test (5433, tmpfs)
├── cloudbuild.yaml                   ← GCP Cloud Build: build → push → migrate → deploy
├── Makefile                          ← Dev commands: up, migrate, test, lint, fmt
└── .env.example

Tech stack

Layer Technology
Frontend Next.js 15 + TypeScript (App Router, PWA)
Styling CSS classes + inline design tokens (no Tailwind)
Backend FastAPI (Python 3.11)
Database PostgreSQL
ORM / Migrations SQLAlchemy + Alembic
Auth Clerk (magic link email)
Deployment GCP Cloud Run (API, africa-south1) + Vercel (web)
CI/CD GCP Cloud Build
Secrets GCP Secret Manager
Observability Prometheus + Grafana + Loki
Shared types openapi-typescript (generated from FastAPI schema)

Running locally

# Start Postgres (main + test)
make up

# Run API migrations
make migrate

# Start the API
make run

# Start the web app
cd apps/web
cp .env.example .env.local   # fill in Clerk keys + NEXT_PUBLIC_API_URL
npm install
npm run dev

Environment variables required:

apps/api/.env:

DATABASE_URL=postgresql://postgres:postgres@localhost:5432/endomatrix
TEST_DATABASE_URL=postgresql://postgres:postgres@localhost:5433/endomatrix_test

apps/web/.env.local:

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/home
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/onboarding
NEXT_PUBLIC_API_URL=http://localhost:8000

Testing

make test          # presentation + domain + engine (no DB required)
make integration   # repository tests (requires make up + make migrate-test)
make test-all      # everything

Current: 63/63 presentation tests passing. Integration tests ready — require a running Postgres instance.


Data and privacy

  • Audit log: every mutation to health data writes an immutable append-only event to audit_events — ships from day one, not a later addition
  • Data minimisation: the daily log captures only what pattern detection requires
  • No third-party data sharing: user-level data never leaves the platform
  • Supersession: re-logging a day soft-deletes the previous entry (is_active = false) rather than overwriting it — the record is preserved in the audit trail
  • User data export and deletion: available from Settings

Status

Milestone Status
Architecture and domain design Complete
Domain models + PatternEngine + PhaseCalculator Complete
Application use cases Complete
Infrastructure (PostgreSQL repos, Alembic, Docker) Complete
Presentation layer (FastAPI routers + Pydantic schemas) Complete
Presentation tests (63/63) Complete
Integration tests Complete (requires live Postgres to run)
GCP Cloud Build + Cloud Run config Complete
Web: design tokens + shared types + API client Complete
Web: Clerk auth + middleware Complete
Web: Onboarding (3-step flow) Complete
Web: Cycle calendar Complete
Web: Daily log Complete
Web: Home screen Complete
Web: Insights (teaser + summary) Complete
Web: Settings screen Not started
Web: History calendar (pain dots + day tap) Not started
Web: Export (PDF / share) Not started
MVP: mood slider + notes Not started
MVP: wearable ingestion Not started
Beta (50 users) Targeted Q1 2026

Related

About

The MVP. A web dashboard for users to view daily routines, insights, and trends, with logging and feedback interface

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages