Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion BUILD_SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This document lists all the features, integrations, database schemas, and workfl
---

## 🛠️ Repository & Architecture

- **GitHub Monorepo Structure**: Set up with `pnpm` workspaces and `Turborepo` containing:
- `apps/web`: Next.js 14 dashboard app.
- `apps/agents`: Trigger.dev/cron scraping workers.
Expand All @@ -16,6 +17,7 @@ This document lists all the features, integrations, database schemas, and workfl
---

## 🗄️ Database (Supabase / PostgreSQL)

- **Schema & Migrations**: Designed, migrated, and verified the relational schema ([001_initial_schema.sql](file:///Users/joel-bmn/adonisagent/backend/migrations/001_initial_schema.sql)):
- `hospitals`: Profiles, website URLs, and account type support.
- `ae_users`: Role permissions (admin vs AEs) and Slack credentials.
Expand All @@ -27,6 +29,7 @@ This document lists all the features, integrations, database schemas, and workfl
---

## ⚙️ Ingestion & Classification Pipeline

- **Hospital Scrapers**: Automated news scraping utilizing `serper.dev` and `NewsAPI` queries.
- **Deterministic Rules Engine**: Python rules engine evaluating 8 keyword pattern rules to bypass Claude AI for deterministic high-confidence signals (CRO executive hires, epic go-lives, restructuring, vendor disputes).
- **Claude AI Classifier**: Fallback classifier calling Claude 3.5 Sonnet, returning:
Expand All @@ -39,6 +42,7 @@ This document lists all the features, integrations, database schemas, and workfl
---

## 🔌 FastAPI Backend Server

- **Core Endpoints**:
- `GET /api/v1/hospitals`: Hospital list filterable by AE territory.
- `GET /api/v1/hospitals/{id}/signals`: Ordered signal feed.
Expand All @@ -48,13 +52,14 @@ This document lists all the features, integrations, database schemas, and workfl
- `POST /api/v1/copilot`: Scaffolds LLM chat completions for territory insights.
- `GET /api/v1/export/csv`: Bulk CSV downloader for signals.
- **Performance**: Added response-level TTL caching (`@ttl_cache(60.0)`) and CORS preflight caching.
- **Robustness**:
- **Robustness**:
- Automated exponential backoff retry handler wrapping Claude API requests.
- Global FastAPI exception handler dispatching unhandled 500 stack trace alerts to Danielle's Slack DM.

---

## 🎨 Next.js Frontend Dashboard

- **Sidebar & Roster Layout**: Fully responsive viewport rendering:
- Left panel shows hospital list, filterable by Michael, David, or Jeff's territories.
- Main signal feed display with color-coded urgency badges (Urgent red, Worth Knowing blue, Low gray) and source links.
Expand All @@ -66,13 +71,15 @@ This document lists all the features, integrations, database schemas, and workfl
---

## 💬 Slack Integration & Bot

- **Weekly Digest DM**: Compiles and sends a combined weekly digest DM to AEs every Monday morning, containing account grouping and UTM-tagged URLs.
- **Immediate Urgent Alerts**: Direct DMs sent to AEs in real-time when an `Urgent` signal is scraper-detected.
- **Digest Send Guard**: Enforces that the Monday digest only sends once Danielle's pending review queue is completely empty.

---

## 🧪 Testing & Verification

- Over **190 unit and integration tests** verifying:
- Rules engine keyword matching and exceptions.
- Route authentication and pagination.
Expand Down
1 change: 0 additions & 1 deletion apps/web/src/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,3 @@ export default async function LoginPage({
</div>
);
}

1 change: 0 additions & 1 deletion apps/web/src/components/UserProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,3 @@ export default function UserProvider({ children }: { children: React.ReactNode }
<UserContext.Provider value={{ userId, userName, isAdmin }}>{children}</UserContext.Provider>
);
}

4 changes: 1 addition & 3 deletions apps/web/src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ export const SIGNAL_TYPE_LABELS: Record<SignalType, string> = {
filtered_out: 'Filtered out',
};



async function getAuthToken() {
if (typeof window !== 'undefined') {
const { createClient } = await import('@/utils/supabase/client');
Expand All @@ -135,7 +133,7 @@ async function apiFetch<T>(
init?: RequestInit
): Promise<T> {
const nextConfig = init?.cache === 'no-store' ? undefined : { revalidate: 60 };

const token = await getAuthToken();
const headers: Record<string, string> = {
'Content-Type': 'application/json',
Expand Down
1 change: 0 additions & 1 deletion apps/web/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ export async function middleware(request: NextRequest) {
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};

2 changes: 1 addition & 1 deletion backend/signals_dump.json
Original file line number Diff line number Diff line change
Expand Up @@ -503,4 +503,4 @@
"hospital_id": "a17f653f-8479-4159-9149-63e65d2d50a2",
"created_at": "2026-06-20T23:25:54.951551+00:00"
}
]
]
Loading