Internal tool for managing Audius push notifications: one-off announcements and automated re-engagement triggers.
- Framework: Next.js 16 (App Router), React 19, TypeScript (strict)
- Auth/DB/Storage: Supabase (PostgreSQL, Storage for CSV/images)
- State: Zustand (future)
- Styling: Tailwind CSS v4, shadcn/ui (neutral base)
- Charts: Recharts (area chart for historical performance)
- Deploy: Vercel
npm run dev # Dev server (localhost:3000)
npm run build # Production build
npm run lint # ESLint-
Pages:
/overview— High-level metrics dashboard/announcements— List of all announcement notifications with stats table/announcements/new— Create announcement with content form + CSV audience upload + live preview/announcements/[id]— Detail view: delivery funnel, downstream actions, content snapshot/automated— List of automated trigger cards (inactivity-based)/automated/[id]— Trigger detail: historical performance chart, impact metrics, current content
-
API Routes:
POST /api/announcements— Create announcement (FormData: fields + CSV + image)GET/PATCH/DELETE /api/announcements/[id]— CRUD operationsGET/PATCH /api/automated/[id]— Get trigger with performance data, update copy
-
Supabase:
schema.sql— Run in Supabase SQL Editor. Seeds 3 automated triggers + 5 announcements.lib/supabase/admin.ts— Service-role client (server-side, bypasses RLS)lib/supabase/server.ts— SSR client with cookieslib/supabase/client.ts— Browser client
-
Components:
sidebar.tsx— App navigationheader.tsx— Top bar with user avatarstat-card.tsx— Reusable metric carddelivery-funnel.tsx— Horizontal bar funnel chartnotification-preview.tsx— Mobile push notification previewedit-copy-dialog.tsx— Modal for editing automated trigger copy
- Cron:
vercel.json→GET /api/cron/sync-engagement(BearerCRON_SECRET). - Implementation:
src/lib/engagement/syncAnnouncementEngagement.ts,src/lib/discovery/notificationCampaignPushOpens.ts. - Env:
AUDIUS_API_URL,NOTIFICATION_CAMPAIGN_OPEN_METRICS_SECRET(must match APInotificationCampaignOpenMetricsSecret).
- Delivery / Recipients: AWS SNS delivery receipts
- Open rate / unique opens: Discovery (
notification_campaign_push_openvia Audius API); synced into Supabase by cron or manual refresh - Retention Uplift / Disable Rate / Downstream actions: Schema supports these; populate when a pipeline exists
- Historical Performance: Aggregated monthly in
trigger_performancetable
The dashboard stores trigger configs. Actual sending is handled by a pedalboard app (apps/notification-sender) that:
- Uses basekit
.tick()to run on a schedule - Queries the discovery DB for users matching trigger conditions
- Reads current heading/body from dashboard Supabase
- Sends via AWS SNS
- Do NOT commit
.env.localor hardcode Supabase/AWS keys - Do NOT send notifications directly from this dashboard — it manages configs only
- Do NOT modify
schema.sqlwithout checking all typed queries still compile
schema.sqlmust be run manually in Supabase SQL Editor before the app works- Supabase Storage bucket "uploads" must be created via dashboard first
- Service role client bypasses RLS — use carefully
- Stats columns are nullable (populated async after send)
- Read this file at session start
- After features or fixes, run
npm run lint