# akshat3144/synapse architecture

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

- Interactive diagram: https://gitdiagram.com/akshat3144/synapse
- Repository: https://github.com/akshat3144/synapse

## Overview

1. **System shape**
   Synapse is a two-tier application: a Python **FastAPI backend** that continuously ingests pharma signals and generates intelligence, and a **Next.js frontend** that presents dashboards, entity views, alerts, and strategic briefs. The backend owns all business logic and data persistence; the frontend is a presentation layer that consumes API and WebSocket feeds.

2. **Primary data flow**
   External sources feed the backend ingestion services: **openFDA** (recalls, adverse events, drug labels), **NewsAPI** (pharma news), and **ClinicalTrials.gov** (trial updates). Those raw signals are normalized into event records, stored, broadcast live, and then used as input for clustering and brief generation.

3. **Backend layering**
   The backend is split into a few clear boundaries:
   - `services/` for source polling and intelligence processing
   - `routes/` for HTTP API endpoints
   - `store.py` / `store_supabase.py` for persistence
   - `scheduler.py` for recurring jobs
   - `ws_manager.py` for real-time push updates
   - `models.py` for shared data contracts

4. **Ingestion services**
   Each source has its own monitor:
   - `fda_monitor.py` for recalls and adverse events
   - `label_monitor.py` for label/SPL changes
   - `news_crawler.py` for NewsAPI and event classification
   - `clinical_trials.py` for trial updates  
   These services produce a common event shape so downstream logic does not depend on source-specific formats.

5. **Intelligence pipeline**
   The agentic core lives mainly in `brief_generator.py` and `summarizer.py`. Events are clustered by entity overlap into signal clusters, severity is assigned, and then unbriefed clusters are turned into strategic briefs. This is the main “analysis” boundary of the system, separate from raw ingestion and separate from presentation.

6. **Agentic scheduling**
   `scheduler.py` orchestrates two kinds of background work: frequent source polling and the autonomous scan loop. The scan loop runs every 20 minutes, finds interesting clusters, skips recently briefed entities, and generates up to a few new briefs per cycle. There is also a manual trigger path via API for on-demand polling or brief generation.

7. **Persistence boundary**
   Storage is abstracted behind the store layer. `store_supabase.py` persists to **Supabase/PostgreSQL** using a schema defined in `supabase_schema.sql`, while the app can fall back to an in-memory store if Supabase credentials are absent. This means the rest of the code treats storage as a stable interface rather than depending directly on database details.

8. **Data model**
   `models.py` defines the shared domain objects used across ingestion, API, and UI: events, alerts, entities, signal clusters, briefs, SWOT/Porter/GTM structures, and source status. This keeps the API payloads and frontend TypeScript types aligned with the backend domain model.

9. **API surface**
   The FastAPI routes are organized by concern:
   - `events.py` for event listing, detail, stats, search, trends
   - `alerts.py` for alert rules and dismissals
   - `entities.py` for tracked entities and entity analysis
   - `briefs.py` for briefs, clusters, and scan/generate actions
   - `sources.py` for source health  
   These routes expose both operational data and derived intelligence to the frontend.

10. **Real-time delivery**
   `ws_manager.py` plus the `/ws/feed` endpoint provide a live event feed. New ingested events are pushed to connected clients, so the UI can update without polling. This is a key architectural boundary between batch/background processing and interactive display.

11. **Frontend structure**
   The frontend is a Next.js App Router application. Page routes map directly to the backend concepts: dashboard, briefs, entities, events, alerts, and search. UI components are split into layout shell components, dashboard widgets, and shared event/status badges. The frontend is clearly a consumer of backend intelligence rather than a source of business logic.

12. **Frontend data access**
   `frontend/lib/api.ts` centralizes REST calls, `websocket.ts` handles live feed connections and reconnects, and `hooks.ts` exposes reusable data hooks for pages/components. `types.ts` mirrors backend models so the dashboard, detail pages, and charts can render structured intelligence consistently.

13. **Operational behavior**
   On startup, the backend immediately begins polling source APIs and scheduling the agentic scan. The system also exposes diagnostics and source-status endpoints so operators can see API key health, poll times, and scheduler state. That makes the backend both the runtime engine and the observability point for the app.

14. **Important architectural takeaway**
   The core architecture is an event-to-intelligence pipeline: **external sources → normalized events → persistence/live feed → clustering and brief generation → API + WebSocket delivery → frontend analytics and drill-down views**. The main design boundaries are source adapters, intelligence processing, storage abstraction, and the presentation layer.

Main entry points: [`backend/store.py`](https://github.com/akshat3144/synapse/blob/main/backend/store.py) (Store layer), [`backend/main.py`](https://github.com/akshat3144/synapse/blob/main/backend/main.py) (App entry), [`frontend/lib/api.ts`](https://github.com/akshat3144/synapse/blob/main/frontend/lib/api.ts) (API client), [`backend/scheduler.py`](https://github.com/akshat3144/synapse/blob/main/backend/scheduler.py) (Scheduler)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_backend["Backend"]
  node_backend_main["App entry<br/>FastAPI bootstrap<br/>[main.py]"]
  node_backend_config["Config<br/>[config.py]"]
  node_backend_models["Domain models<br/>shared contracts<br/>[models.py]"]
  node_backend_store[("Store layer<br/>storage interface<br/>[store.py]")]
  node_backend_supabase[("Supabase store<br/>Postgres adapter<br/>[store_supabase.py]")]
  node_backend_schema["DB schema<br/>SQL schema"]
  node_backend_scheduler["Scheduler<br/>background orchestration<br/>[scheduler.py]"]
  node_backend_ws["Live feed<br/>websocket manager<br/>[ws_manager.py]"]
  node_backend_fda["FDA monitor<br/>source adapter<br/>[fda_monitor.py]"]
  node_backend_label["Label monitor<br/>source adapter<br/>[label_monitor.py]"]
  node_backend_news["News crawler<br/>source adapter<br/>[news_crawler.py]"]
  node_backend_trials["Trial monitor<br/>source adapter<br/>[clinical_trials.py]"]
  node_backend_briefgen{{"Brief generator<br/>intelligence engine<br/>[brief_generator.py]"}}
  node_backend_summarizer["Summarizer<br/>analysis helper<br/>[summarizer.py]"]
  node_backend_routes_events["Events API<br/>REST routes<br/>[events.py]"]
  node_backend_routes_briefs["Briefs API<br/>REST routes<br/>[briefs.py]"]
  node_backend_routes_entities["Entities API<br/>REST routes<br/>[entities.py]"]
  node_backend_routes_alerts["Alerts API<br/>REST routes<br/>[alerts.py]"]
  node_backend_routes_sources["Sources API<br/>REST routes<br/>[sources.py]"]
end

subgraph group_frontend["Frontend"]
  node_frontend_app["App shell<br/>Next.js layout<br/>[layout.tsx]"]
  node_frontend_pages["Pages<br/>route views<br/>[page.tsx]"]
  node_frontend_dashboard["Dashboard widgets<br/>ui components<br/>[trend-chart.tsx]"]
  node_frontend_layout["Layout UI<br/>chrome components<br/>[header.tsx]"]
  node_frontend_shared["Shared UI<br/>presentational components<br/>[event-card.tsx]"]
  node_frontend_api["API client<br/>REST client<br/>[api.ts]"]
  node_frontend_ws["WebSocket client<br/>live client<br/>[websocket.ts]"]
  node_frontend_hooks["Data hooks<br/>state hooks<br/>[hooks.ts]"]
  node_frontend_types["UI types<br/>type mirror<br/>[types.ts]"]
end

node_backend_main -->|"loads"| node_backend_config
node_backend_main -->|"serves"| node_backend_routes_events
node_backend_main -->|"serves"| node_backend_routes_briefs
node_backend_main -->|"serves"| node_backend_routes_entities
node_backend_main -->|"serves"| node_backend_routes_alerts
node_backend_main -->|"serves"| node_backend_routes_sources
node_backend_main -->|"starts"| node_backend_scheduler
node_backend_main -->|"exposes"| node_backend_ws
node_backend_routes_events -->|"reads"| node_backend_store
node_backend_routes_briefs -->|"triggers"| node_backend_briefgen
node_backend_routes_briefs -->|"reads/writes"| node_backend_store
node_backend_routes_entities -->|"reads"| node_backend_store
node_backend_routes_alerts -->|"reads/writes"| node_backend_store
node_backend_routes_sources -->|"reads"| node_backend_store
node_backend_scheduler -->|"polls"| node_backend_fda
node_backend_scheduler -->|"polls"| node_backend_label
node_backend_scheduler -->|"polls"| node_backend_news
node_backend_scheduler -->|"polls"| node_backend_trials
node_backend_scheduler -->|"scans"| node_backend_briefgen
node_backend_fda -->|"writes"| node_backend_store
node_backend_label -->|"writes"| node_backend_store
node_backend_news -->|"writes"| node_backend_store
node_backend_trials -->|"writes"| node_backend_store
node_backend_fda -->|"pushes"| node_backend_ws
node_backend_label -->|"pushes"| node_backend_ws
node_backend_news -->|"pushes"| node_backend_ws
node_backend_trials -->|"pushes"| node_backend_ws
node_backend_store -->|"feeds"| node_backend_briefgen
node_backend_briefgen -->|"uses"| node_backend_summarizer
node_backend_briefgen -->|"writes"| node_backend_store
node_backend_briefgen -->|"publishes"| node_backend_ws
node_backend_store -->|"implements"| node_backend_supabase
node_backend_supabase -->|"matches"| node_backend_schema
node_frontend_app -->|"hosts"| node_frontend_pages
node_frontend_pages -->|"fetches"| node_frontend_api
node_frontend_pages -->|"subscribes"| node_frontend_ws
node_frontend_pages -->|"renders"| node_frontend_dashboard
node_frontend_pages -->|"uses"| node_frontend_shared
node_frontend_app -->|"wraps"| node_frontend_layout
node_frontend_pages -->|"uses"| node_frontend_hooks
node_frontend_hooks -->|"calls"| node_frontend_api
node_frontend_hooks -->|"subscribes"| node_frontend_ws
node_frontend_api -.->|"calls"| node_backend_routes_events
node_frontend_api -.->|"calls"| node_backend_routes_briefs
node_frontend_api -.->|"calls"| node_backend_routes_entities
node_frontend_api -.->|"calls"| node_backend_routes_alerts
node_frontend_api -.->|"calls"| node_backend_routes_sources
node_frontend_types -->|"mirrors"| node_backend_models

click node_backend_main "https://github.com/akshat3144/synapse/blob/main/backend/main.py"
click node_backend_config "https://github.com/akshat3144/synapse/blob/main/backend/config.py"
click node_backend_models "https://github.com/akshat3144/synapse/blob/main/backend/models.py"
click node_backend_store "https://github.com/akshat3144/synapse/blob/main/backend/store.py"
click node_backend_supabase "https://github.com/akshat3144/synapse/blob/main/backend/store_supabase.py"
click node_backend_schema "https://github.com/akshat3144/synapse/blob/main/backend/supabase_schema.sql"
click node_backend_scheduler "https://github.com/akshat3144/synapse/blob/main/backend/scheduler.py"
click node_backend_ws "https://github.com/akshat3144/synapse/blob/main/backend/ws_manager.py"
click node_backend_fda "https://github.com/akshat3144/synapse/blob/main/backend/services/fda_monitor.py"
click node_backend_label "https://github.com/akshat3144/synapse/blob/main/backend/services/label_monitor.py"
click node_backend_news "https://github.com/akshat3144/synapse/blob/main/backend/services/news_crawler.py"
click node_backend_trials "https://github.com/akshat3144/synapse/blob/main/backend/services/clinical_trials.py"
click node_backend_briefgen "https://github.com/akshat3144/synapse/blob/main/backend/services/brief_generator.py"
click node_backend_summarizer "https://github.com/akshat3144/synapse/blob/main/backend/services/summarizer.py"
click node_backend_routes_events "https://github.com/akshat3144/synapse/blob/main/backend/routes/events.py"
click node_backend_routes_briefs "https://github.com/akshat3144/synapse/blob/main/backend/routes/briefs.py"
click node_backend_routes_entities "https://github.com/akshat3144/synapse/blob/main/backend/routes/entities.py"
click node_backend_routes_alerts "https://github.com/akshat3144/synapse/blob/main/backend/routes/alerts.py"
click node_backend_routes_sources "https://github.com/akshat3144/synapse/blob/main/backend/routes/sources.py"
click node_frontend_app "https://github.com/akshat3144/synapse/blob/main/frontend/app/layout.tsx"
click node_frontend_pages "https://github.com/akshat3144/synapse/blob/main/frontend/app/page.tsx"
click node_frontend_dashboard "https://github.com/akshat3144/synapse/blob/main/frontend/components/dashboard/trend-chart.tsx"
click node_frontend_layout "https://github.com/akshat3144/synapse/blob/main/frontend/components/layout/header.tsx"
click node_frontend_shared "https://github.com/akshat3144/synapse/blob/main/frontend/components/shared/event-card.tsx"
click node_frontend_api "https://github.com/akshat3144/synapse/blob/main/frontend/lib/api.ts"
click node_frontend_ws "https://github.com/akshat3144/synapse/blob/main/frontend/lib/websocket.ts"
click node_frontend_hooks "https://github.com/akshat3144/synapse/blob/main/frontend/lib/hooks.ts"
click node_frontend_types "https://github.com/akshat3144/synapse/blob/main/frontend/lib/types.ts"

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_backend_main,node_backend_config,node_backend_models,node_backend_store,node_backend_supabase,node_backend_schema,node_backend_scheduler,node_backend_ws,node_backend_fda,node_backend_label,node_backend_news,node_backend_trials,node_backend_briefgen,node_backend_summarizer,node_backend_routes_events,node_backend_routes_briefs,node_backend_routes_entities,node_backend_routes_alerts,node_backend_routes_sources toneBlue
class node_frontend_app,node_frontend_pages,node_frontend_dashboard,node_frontend_layout,node_frontend_shared,node_frontend_api,node_frontend_ws,node_frontend_hooks,node_frontend_types toneAmber
```

## Components

### Backend

FastAPI engine for ingestion, intelligence, persistence, and live delivery.

- [App entry](https://github.com/akshat3144/synapse/blob/main/backend/main.py): FastAPI bootstrap · Starts the backend, wires config, routes, scheduler, and websocket feed. · `backend/main.py`
- [Config](https://github.com/akshat3144/synapse/blob/main/backend/config.py): runtime config · Loads environment-driven settings and service toggles. · `backend/config.py`
- [Domain models](https://github.com/akshat3144/synapse/blob/main/backend/models.py): shared contracts · Defines events, alerts, entities, clusters, briefs, and source status shapes. · `backend/models.py`
- [Store layer](https://github.com/akshat3144/synapse/blob/main/backend/store.py): storage interface · Abstract persistence boundary with in-memory and Supabase-backed implementations. · `backend/store.py`
- [Supabase store](https://github.com/akshat3144/synapse/blob/main/backend/store_supabase.py): Postgres adapter · Persists application data to Supabase/PostgreSQL using the SQL schema. · `backend/store_supabase.py`
- [DB schema](https://github.com/akshat3144/synapse/blob/main/backend/supabase_schema.sql): SQL schema · Defines the Supabase/PostgreSQL tables and migration structure. · `backend/supabase_schema.sql`
- [Scheduler](https://github.com/akshat3144/synapse/blob/main/backend/scheduler.py): background orchestration · Runs source polling and the recurring autonomous scan loop. · `backend/scheduler.py`
- [Live feed](https://github.com/akshat3144/synapse/blob/main/backend/ws_manager.py): websocket manager · Broadcasts newly ingested events to connected clients. · `backend/ws_manager.py`
- [FDA monitor](https://github.com/akshat3144/synapse/blob/main/backend/services/fda_monitor.py): source adapter · Polls openFDA recall and adverse-event data and normalizes it into events. · `backend/services/fda_monitor.py`
- [Label monitor](https://github.com/akshat3144/synapse/blob/main/backend/services/label_monitor.py): source adapter · Tracks drug label and SPL changes as normalized event signals. · `backend/services/label_monitor.py`
- [News crawler](https://github.com/akshat3144/synapse/blob/main/backend/services/news_crawler.py): source adapter · Collects pharma news from NewsAPI and classifies relevant events. · `backend/services/news_crawler.py`
- [Trial monitor](https://github.com/akshat3144/synapse/blob/main/backend/services/clinical_trials.py): source adapter · Ingests ClinicalTrials.gov updates into the common event stream. · `backend/services/clinical_trials.py`
- [Brief generator](https://github.com/akshat3144/synapse/blob/main/backend/services/brief_generator.py): intelligence engine · Clusters events by entity overlap, scores severity, and creates strategic briefs. · `backend/services/brief_generator.py`
- [Summarizer](https://github.com/akshat3144/synapse/blob/main/backend/services/summarizer.py): analysis helper · Produces concise narrative summaries for briefs and clusters. · `backend/services/summarizer.py`
- [Events API](https://github.com/akshat3144/synapse/blob/main/backend/routes/events.py): REST routes · Exposes event lists, details, stats, search, and trends. · `backend/routes/events.py`
- [Briefs API](https://github.com/akshat3144/synapse/blob/main/backend/routes/briefs.py): REST routes · Serves briefs, clusters, and scan or generate actions. · `backend/routes/briefs.py`
- [Entities API](https://github.com/akshat3144/synapse/blob/main/backend/routes/entities.py): REST routes · Provides tracked entities and entity-level analysis. · `backend/routes/entities.py`
- [Alerts API](https://github.com/akshat3144/synapse/blob/main/backend/routes/alerts.py): REST routes · Manages alert rules and dismissals. · `backend/routes/alerts.py`
- [Sources API](https://github.com/akshat3144/synapse/blob/main/backend/routes/sources.py): REST routes · Exposes source health and operational diagnostics. · `backend/routes/sources.py`

### Frontend

Next.js presentation layer for dashboards and drill-down views.

- [App shell](https://github.com/akshat3144/synapse/blob/main/frontend/app/layout.tsx): Next.js layout · Top-level App Router shell for the UI. · `frontend/app/layout.tsx`
- [Pages](https://github.com/akshat3144/synapse/blob/main/frontend/app/page.tsx): route views · Dashboard, briefs, entities, events, alerts, and search screens. · `frontend/app/page.tsx`
- [Dashboard widgets](https://github.com/akshat3144/synapse/blob/main/frontend/components/dashboard/trend-chart.tsx): ui components · Visualizes intelligence with KPIs, trends, entity rankings, and feeds. · `frontend/components/dashboard/trend-chart.tsx`
- [Layout UI](https://github.com/akshat3144/synapse/blob/main/frontend/components/layout/header.tsx): chrome components · Provides header, sidebar, and status bar navigation chrome. · `frontend/components/layout/header.tsx`
- [Shared UI](https://github.com/akshat3144/synapse/blob/main/frontend/components/shared/event-card.tsx): presentational components · Reusable cards, badges, empty states, and loading indicators. · `frontend/components/shared/event-card.tsx`
- [API client](https://github.com/akshat3144/synapse/blob/main/frontend/lib/api.ts): REST client · Centralizes backend HTTP requests for pages and widgets. · `frontend/lib/api.ts`
- [WebSocket client](https://github.com/akshat3144/synapse/blob/main/frontend/lib/websocket.ts): live client · Handles live feed connections, reconnection, and streaming updates. · `frontend/lib/websocket.ts`
- [Data hooks](https://github.com/akshat3144/synapse/blob/main/frontend/lib/hooks.ts): state hooks · Reusable data-fetching and subscription hooks for the UI. · `frontend/lib/hooks.ts`
- [UI types](https://github.com/akshat3144/synapse/blob/main/frontend/lib/types.ts): type mirror · Mirrors backend domain models for consistent frontend rendering. · `frontend/lib/types.ts`

## Connections

- App entry → Config: loads · Bootstraps runtime settings from configuration.
- App entry → Events API: serves · Registers API routes for event access.
- App entry → Briefs API: serves · Registers API routes for briefs and scans.
- App entry → Entities API: serves · Registers API routes for entity drill-downs.
- App entry → Alerts API: serves · Registers API routes for alert management.
- App entry → Sources API: serves · Registers operational and health endpoints.
- App entry → Scheduler: starts · Launches recurring polling and autonomous analysis.
- App entry → Live feed: exposes · Enables the live event feed endpoint.
- Events API → Store layer: reads · Fetches persisted events and derived views.
- Briefs API → Brief generator: triggers · Allows manual scan and brief generation actions.
- Briefs API → Store layer: reads/writes · Persists and retrieves briefs and clusters.
- Entities API → Store layer: reads · Serves entity history and analysis from storage.
- Alerts API → Store layer: reads/writes · Stores alert rules and dismissal state.
- Sources API → Store layer: reads · Returns source status and polling diagnostics.
- Scheduler → FDA monitor: polls · Runs frequent FDA ingestion jobs.
- Scheduler → Label monitor: polls · Runs label change monitoring jobs.
- Scheduler → News crawler: polls · Runs news ingestion jobs.
- Scheduler → Trial monitor: polls · Runs trial update ingestion jobs.
- Scheduler → Brief generator: scans · Invokes the autonomous cluster-to-brief loop.
- FDA monitor → Store layer: writes · Persists normalized event records.
- Label monitor → Store layer: writes · Persists normalized event records.
- News crawler → Store layer: writes · Persists normalized event records.
- Trial monitor → Store layer: writes · Persists normalized event records.
- FDA monitor → Live feed: pushes · Broadcasts newly ingested events live.
- Label monitor → Live feed: pushes · Broadcasts newly ingested events live.
- News crawler → Live feed: pushes · Broadcasts newly ingested events live.
- Trial monitor → Live feed: pushes · Broadcasts newly ingested events live.
- Store layer → Brief generator: feeds · Provides events and prior briefs for analysis.
- Brief generator → Summarizer: uses · Generates concise strategic narrative output.
- Brief generator → Store layer: writes · Stores clusters, briefs, and analysis results.
- Brief generator → Live feed: publishes · Emits new intelligence updates to live clients.
- Store layer → Supabase store: implements · Backed by the Supabase/PostgreSQL adapter when available.
- Supabase store → DB schema: matches · Uses the defined database schema.
- App shell → Pages: hosts · Wraps the route-level application pages.
- Pages → API client: fetches · Loads backend data for screens and detail views.
- Pages → WebSocket client: subscribes · Consumes live feed updates where needed.
- Pages → Dashboard widgets: renders · Composes dashboard analytics and widgets.
- Pages → Shared UI: uses · Reuses common visual components across views.
- App shell → Layout UI: wraps · Provides persistent navigation and status chrome.
- Pages → Data hooks: uses · Coordinates data access and subscriptions.
- Data hooks → API client: calls · Wraps REST access into reusable hooks.
- Data hooks → WebSocket client: subscribes · Wraps websocket updates into reusable hooks.
- API client → Events API: calls · Consumes events endpoints.
- API client → Briefs API: calls · Consumes briefs endpoints.
- API client → Entities API: calls · Consumes entities endpoints.
- API client → Alerts API: calls · Consumes alerts endpoints.
- API client → Sources API: calls · Consumes source health endpoints.
- UI types → Domain models: mirrors · Keeps UI payload shapes aligned with backend domain models.
