Knowledge > Processes > Admin Dashboard Load Flow
Admin Dashboard Load Flow
How the admin dashboard at /admin/[token] authenticates, loads data, and renders tabs. Both CWA and PewSearch dashboards follow the same pattern with different tab sets.
Step 1: Token Resolution
Admin visits /admin/{token} where token is a UUID.
FUNCTION resolveToken(token: string) -> ResolvedToken | null
PATH A: Check admin_token
query premium_churches
WHERE admin_token = token
SELECT (safe columns), churches.* via FK join
IF found:
RETURN { premium, church, role: "admin", memberName: null }
PATH B: Check team member access_token
query church_team_members
WHERE access_token = token AND is_active = true
SELECT id, premium_id, role, name
IF found:
UPDATE church_team_members SET last_accessed_at = now()
WHERE id = member.id (fire-and-forget)
query premium_churches WHERE id = member.premium_id
with churches FK join
RETURN { premium, church, role: member.role, memberName: member.name }
PATH C: Cookie-based auth (resolveTokenOrHeaders)
IF x-church-id AND x-identity-id headers present (set by middleware):
query premium_churches WHERE church_id = x-church-id
query church_admin_identities WHERE id = x-identity-id for name
RETURN { premium, church, role: x-identity-role, memberName }
IF none matched:
RETURN null → notFound() (404 page)
Step 2: Parallel Data Loading (CWA Dashboard)
After authentication, the server component loads all dashboard data in parallel using Promise.all().
const [
voiceAgent, // church_voice_agents: pastor_name, settings, phone config
metrics, // getDashboardMetrics: call count, prayer count, visitor count
activity, // getRecentActivity: last 20 events across all types (role-filtered)
callsResult, // getCallLogsByChurch: page 0 of call logs
prayerResult, // getRequestsByType("prayer"): prayer requests (role-gated)
visitorResult, // getRequestsByType("visitor"): visitor contacts (role-gated)
callbackResult, // getRequestsByType("callback"): callback requests (role-gated)
careMemberCount, // getCareMemberCount: count of care subscribers
toolUsage, // getToolUsageCounts: chatbot tool usage stats
agentConversations, // getAgentConversationCounts: per-agent conversation counts
orgSettingsResult, // organization_settings: agent_config, agent_tool_config
] = await Promise.all([...11 queries...])
ALSO (CWA only):
hasBackupOwner = query church_admin_identities
WHERE church_id AND is_backup_owner = true AND is_active = true
COUNT > 0 (graceful — catches error if table doesn't exist)
PewSearch Dashboard (simpler variant)
const [
voiceAgent, // church_voice_agents
metrics, // getDashboardMetrics
activity, // getRecentActivity (no role filter in PS version)
callsResult, // page 0 of call logs
prayerResult, // prayer requests (role-gated)
visitorResult, // visitor contacts (role-gated)
callbackResult, // callback requests (role-gated)
chatbotFaqs, // canned_responses WHERE source = "pewsearch_admin"
documentCount, // church_knowledge_base COUNT
careMemberCount, // care subscriber count
] = await Promise.all([...10 queries...])
SECURITY: PewSearch strips admin_token before passing to client:
const { admin_token: _at, ...safePremium } = premium;
Team member access_tokens also stripped from SafeTeamMember
Step 3: Role-Based Tab Filtering
The ROLE_TABS matrix determines which tabs each role can see. Tier restrictions further filter the list.
ROLE_TABS (CWA):
admin: overview, calls, requests, care, training, social, settings, upgrade
office_admin: overview, calls, requests, care, training, social, settings
prayer_team: overview, requests
care_team: overview, requests, care
treasurer: overview
volunteer_coordinator: overview, requests
worship_leader: overview
spiritual_leader: overview, training
care_leader: overview, training
TIER FILTERING (additional restrictions):
free tier: only overview, training, settings, upgrade
ps_pro_website: overview, requests, website, settings, upgrade (no calls)
paid CWA tiers: full role tab list
RESULT: visibleTabs = intersect(ROLE_TABS[role], TIER_ALLOWED_TABS[plan])
Step 4: Tab Content Rendering
Each tab renders its own data, already loaded in step 2.
OVERVIEW TAB (DashboardOverview):
- Metric cards: total calls, prayers, visitors, callbacks
- Activity feed: recent events chronologically
- Completeness donut: profile training completion %
- Founder action banners (if applicable)
CALLS TAB (CallHistory):
- Paginated call log list
- Expandable transcript viewer
- AI-generated call summary + classification
- Category, urgency, sentiment badges
REQUESTS TAB (RequestManager):
- Four sub-tabs: Prayer, Visitors, Callbacks, Safety
- Safety sub-tab (4th): renders ModerationDashboard — visible to admin/office_admin only
- Shows violations from moderation_violations + active blocks from user_restrictions
- Red badge on Requests tab when safety flags exist (counted from moderation_violations)
- SAFETY FLAG [ pattern entries are EXCLUDED from the Callbacks sub-tab
- Role-gated: PASTORAL_ROLES see full text
- Other roles see redacted: "Confidential — contact the pastor"
- Status toggles: new → reviewed → resolved
- URL routing: ?tab=safety and ?tab=moderation both route to the Requests tab (Safety sub-tab)
CARE TAB (CareTab):
- Care toggle (enable/disable)
- Member list with contact info
- Broadcast composer (email + SMS)
TRAINING TAB (now labelled "Staff Practice" in the UI):
- 10-step guided setup wizard — shown until all steps are complete
- Tool management panels (Agents sub-tab) — enable/disable individual AI tools
- Pastor Pulse (weekly sermon topic, series, theme verse, announcement)
- Hours editor
- Staff editor (CRUD with photo upload)
- Ministries editor
- What to Expect editor
- FAQ/canned response editor
- Document upload (knowledge base)
- Staff Practice (formerly "Simulator") — pastoral coaching scenarios, HEAR framework scoring
- ROLE_TRAINING gates which sections each role can edit
- Settings sub-tab selection persists in URL hash
SETTINGS TAB (SettingsTab):
- Basic info, contact, voice config, chatbot config
- Team member management (admin only)
- Integration settings
- ROLE_SETTINGS gates which sections each role can edit
UPGRADE TAB (UpgradeTab):
- Current plan display
- Stripe billing portal link
- Upgrade CTA with plan comparison
WEBSITE TAB (PewSearch only, pro_website plan):
- Design: hero video, template, logo, slideshow
- Content: hours, staff, sermons, events, beliefs, giving, care
- Settings: vanity slug, contact email
Security Invariants
1. Token NEVER sent to client component (stripped before serialization)
2. All data loading happens server-side (React Server Components)
3. Role checks happen at BOTH UI level (tab visibility) AND API level (mutation routes)
4. Confidential data (prayer text, callback reasons) redacted for non-PASTORAL_ROLES
5. Financial data (giving, budget) only visible to FINANCIAL_ROLES (admin, treasurer)
6. Admin pages marked: robots: "noindex", dynamic: "force-dynamic" (no caching)