Web — Web Client
The web app is the primary desktop interface for Made Open. It is a full communication and data portal — contacts, calls, SMS, video, email, calendar, rules, AI, and credential management.
What It Is
A Next.js 15 application. It connects directly to Supabase for data (read-mostly operations) and to the hub for live communication features (calls, rules, AI). Read-only data browsing works even without the hub running.
apps/web/
├── src/app/
│ ├── auth/
│ │ ├── login/ # /auth/login
│ │ └── signup/ # /auth/signup
│ ├── (public)/ # Marketing + docs + help (route group)
│ ├── (app)/ # Authenticated shell (route group)
│ │ ├── dashboard/ # Main dashboard
│ │ ├── contacts/ # Contact list + detail
│ │ ├── inbox/ # Unified inbox (cross-channel)
│ │ ├── conversations/ # SMS threads
│ │ ├── email/ # Full email client
│ │ ├── calls/ # Dialer, call history
│ │ ├── calendar/ # Calendar grid + event detail
│ │ ├── video/ # Meetings
│ │ ├── rules/ # List, [id], new, builder
│ │ ├── ai/, agent/ # AI chat + agent worker
│ │ ├── settings/ # page.tsx + appearance/data/data-quality/org/twilio
│ │ ├── audit/, privacy/ # Compliance
│ │ └── ... # ~50 feature directories total
│ └── video/join/[roomName]/ # Public video join link
├── src/components/ # ~45 component folders (ui/, inbox/, email/, rules/, ...)
├── src/hooks/ # useInbox, useMessages, useRealtimeTable, ...
├── src/lib/ # Supabase + hub clients
└── package.json
Tech Stack
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router) |
| UI | shadcn/ui + Tailwind CSS |
| Auth | Supabase Auth (client) |
| Data | Supabase JS (direct to Supabase for reads) |
| Live updates | Supabase Realtime (WebSocket subscriptions) |
| Hub calls | Fetch → Hub REST API |
| Voice (WebRTC) | Twilio Voice JS SDK |
| Video | Twilio Video JS SDK |
| Language | TypeScript |
All Pages (162 page.tsx files)
The web app contains 162 page.tsx files across the auth/, (public)/, and (app)/ route groups. The authenticated shell alone spans ~50 feature directories under apps/web/src/app/(app)/:
| Group | Pages |
|---|---|
| Core | dashboard, contacts, conversations, calls, calendar, email, inbox, search |
| AI | ai, agent, tools, wiki |
| Communication | video, federation |
| Life | life, health, fitness, nutrition, finance, habits, intentions, projects, journal, knowledge, media, learning, home, environment, capture, collections, relationships, dependents, inventory |
| Commerce | marketplace, coordination, reputation, timebank |
| Governance | governance, disputes |
| Content | documents, workflows, graph |
| Admin | admin (+ analytics/email/errors/flags/infrastructure), audit, settings (+ appearance/data/data-quality/org/twilio), billing, plugins, notifications, privacy, onboarding, developer, status, rules |
See docs/03-projects/web-app-reference.md for the full per-page reference. The authoritative list of all 162 routes is captured in the audit ground-truth manifest.
Feature Sections
Contacts
- List all persons in the knowledge graph (paginated, searchable)
- Full-text search (via hub
/api/search) - Contact detail: all contact info, conversation history, events, notes
- Manual contact creation and editing
- Source attribution (where each field came from: MS Graph, phone, manual)
Calls (Dialer)
- WebRTC softphone powered by Twilio Voice JS SDK
- Dial any contact or phone number
- Active call controls: hold, mute, transfer, add participant
- Call history with recordings (if enabled)
- Inbound call notification (Supabase Realtime subscription to
communication.CallStarted)
Messages (Inbox / Conversations / Email)
The web app has three distinct message surfaces — there is no single /messages page:
/inbox— unified cross-channel inbox (calls, SMS, email, video, voicemail) with filter chips and preview pane/conversationsand/conversations/[id]— SMS thread list and chat bubble view; compose + send SMS/email— full 3-panel email client (folder tree, thread list, reading pane) sourced from MS Graph, with compose/reply/forward modal and attachment preview
Calendar
- Month/week/day views
- Events from MS Graph (Exchange/Outlook)
- Attendees resolved to contacts in the knowledge graph
- Event detail with "call this person" action
Rule Builder
- Visual WHEN/IF/THEN rule editor — no JSON required
- Condition pickers: contact group, location, time-of-day, channel type
- Action pickers: send SMS, place call, send notification
- Preview: "This rule would have fired 3 times in the last week"
- Enable/disable individual rules
Credential Wallet (Settings → Credentials tab)
The /settings page is a tabbed shell (Credentials / Notifications / Privacy / Account). The Credentials tab:
- Shows all credentials currently in the wallet with active capability status
- Add credential flows:
- Twilio: enter Account SID + Auth Token → capabilities activate live
- Microsoft 365: OAuth redirect → access + refresh tokens stored in Vault → capabilities activate
- OpenRouter: enter API key → AI features activate
- Remove credential → capabilities deactivate immediately, running plugins stopped
Credentials are persisted to the hub via POST /api/credentials and stored in Supabase Vault. The Settings page fetches current credential status on load via GET /api/credentials and updates in real-time when credentials are added or removed.
Dashboard
- Shows real-time statistics fetched from
GET /api/stats(contacts, messages, active rules, active credentials) - Active credential badges reflect actual wallet contents
- Stats update on page load — no hardcoded mock data
Audit Log
- Browse all audit log entries (paginated)
- Filter by actor, action, outcome, date range
- Raw entry JSON view for debugging
Shared Design Language with Android
The web and Android apps have a shared visual identity:
- Same color system and semantic tokens
- Same component intent (contact card layout, conversation view, call controls)
- Different implementation (shadcn/ui on web, Jetpack Compose on Android)
This means a user switching between devices experiences a familiar interface without having to relearn layouts.
Real-Time Updates
Supabase Realtime subscriptions power live UI updates:
// Subscribe to capability changes
supabase
.channel('capabilities')
.on('postgres_changes', {
event: '*',
schema: 'public',
table: 'capability_state',
}, (payload) => {
updateCapabilities(payload.new);
})
.subscribe();
// Subscribe to inbound communications
supabase
.channel('communications')
.on('postgres_changes', {
event: 'INSERT',
schema: 'public',
table: 'messages',
filter: `direction=eq.inbound`,
}, (payload) => {
showIncomingNotification(payload.new);
})
.subscribe();
First Testable Workflow
1. pnpm dev # Start hub + web
2. Open http://localhost:4100 # Web app loads
3. Sign up / log in # Supabase Auth
# If using the demo account (demo@made-open.dev / demopassword),
# steps 4-5 are pre-configured with seed data.
4. Settings → Credentials → Add Microsoft 365
└─ OAuth redirect → contacts/calendar/email capabilities activate
└─ Contacts section populates with Exchange contacts
5. Settings → Credentials → Add Twilio
└─ Enter Account SID + Auth Token
└─ Voice/SMS capabilities activate live (no page reload)
6. Open Contacts → verify Exchange contacts visible
7. Open a contact → click "Call" → WebRTC call initiated via Twilio
8. Open Messages → compose SMS → message sent
9. Open Rules → create "DND at work" rule
10. Check Audit Log → verify all actions logged
Running Locally
cd apps/web
pnpm install
pnpm dev
# Requires hub running for communication features
# Can browse contacts/calendar/email without hub