# Admin Dashboard Implementation Plan
**Created**: October 3, 2025
**Updated**: October 6, 2025 - Separate microservice architecture
**Status**: Planning Phase
**Priority**: High - Multi-tenancy & Administration
**Estimated Effort**: 6-8 weeks (120-160 hours)
---
## ๐ Executive Summary
### Overview
Create a comprehensive **standalone admin service** for managing ParentFlow applications across multiple platforms (web, iOS, Android) with role-based access control (RBAC), user management, system monitoring, and configuration. This service will be deployed independently and manage all ParentFlow instances centrally.
### Architecture Decision
The admin dashboard will be implemented as a **separate microservice** to:
- Manage both web and future mobile applications
- Scale independently from main application
- Provide centralized control across all platforms
- Enable separate deployment and security policies
- Support multi-tenant administration
### Key Features
1. **Invite Code Registration System**: Control user registration with invite codes
2. **User Management**: CRUD operations, data export, anonymization
3. **Role-Based Access Control**: Parent, Guest, Admin roles
4. **Multi-Platform Support**: Manage web, iOS, and Android users
5. **Multi-Profile Support**: Multiple families and account switching
6. **Analytics Dashboard**: Cross-platform usage metrics, AI/voice analytics
7. **System Health Monitoring**: Service status across all platforms
8. **LLM Configuration**: Model settings, API keys, pricing
9. **Content Management**: Legal pages, subscriptions
10. **Email Configuration**: Mailgun settings management
### Goals
- **Security**: Strict admin authentication and audit logging
- **Scalability**: Support growing user base
- **Flexibility**: Easy configuration updates without code changes
- **Compliance**: GDPR/COPPA data management tools
---
## ๐๏ธ Architecture Overview
### Microservice Architecture
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ParentFlow Admin Service โ
โ (Standalone Application) โ
โ admin.parentflowapp.com โ
โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Invite โ โ Users โ โ Analytics โ โ
โ โ Codes โ โ Management โ โ Dashboard โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Platform โ โ System โ โ LLM โ โ
โ โ Manager โ โ Health โ โ Settings โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
Service-to-Service
Communication
โ
โโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ ParentFlow โ โ ParentFlow โ โ ParentFlow โ
โ Web โ โ iOS โ โ Android โ
โ (NestJS) โ โ (Swift) โ โ (Kotlin) โ
โโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโค
โ Validates โ โ Validates โ โ Validates โ
โ invite codes โ โ invite codes โ โ invite codes โ
โ with admin โ โ with admin โ โ with admin โ
โ service โ โ service โ โ service โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ โ โ
โผ โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Shared Database Infrastructure โ
โ โ
โ โข users (cross-platform) โ
โ โข invite_codes (registration control) โ
โ โข platform_sessions (web/ios/android tracking) โ
โ โข admin_audit_log (all admin actions) โ
โ โข system_configurations (per-platform settings) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
### Admin Service Components
```
parentflow-admin-service/
โโโ src/
โ โโโ modules/
โ โ โโโ invite-codes/ # Invite code generation & validation
โ โ โโโ user-management/ # Cross-platform user management
โ โ โโโ platform-manager/ # Web/iOS/Android platform configs
โ โ โโโ analytics/ # Unified analytics across platforms
โ โ โโโ system-health/ # Monitor all platform services
โ โ โโโ llm-config/ # AI configuration
โ โ โโโ subscriptions/ # Subscription management
โ โ โโโ audit/ # Audit logging
โ โโโ common/
โ โ โโโ guards/ # Authentication guards
โ โ โโโ interceptors/ # Service communication
โ โ โโโ decorators/ # Custom decorators
โ โโโ database/
โ โโโ migrations/ # Admin-specific migrations
โโโ admin-ui/ # React admin dashboard
โ โโโ pages/
โ โ โโโ invite-codes/ # Manage invite codes
โ โ โโโ users/ # User management
โ โ โโโ platforms/ # Platform-specific settings
โ โ โโโ analytics/ # Analytics dashboard
โ โโโ components/
โ โโโ shared/ # Shared UI components
โโโ docker-compose.admin.yml # Separate deployment
---
## ๐ฅ Role-Based Access Control (RBAC)
### Role Definitions
#### 1. Parent (Default Role)
**Permissions**:
- Full access to their own families
- Create/manage children
- View all family data (activities, analytics)
- Invite guests to their families
- AI chat, voice commands
- Manage profile and settings
**Database**:
```typescript
enum UserRole {
PARENT = 'parent',
GUEST = 'guest',
ADMIN = 'admin',
}
```
#### 2. Guest (Limited Access)
**Permissions**:
- **CAN DO**:
- Add activities (feeding, sleep, diaper, medication) - manual or voice
- View real-time data for assigned family
- Receive notifications
- **CANNOT DO**:
- View historical data (>24 hours)
- View analytics/insights
- Edit or delete activities (except their own, within 1 hour)
- Manage children profiles
- Access AI chat
- Invite other users
- Change family settings
**Use Cases**:
- Nanny tracking daily activities
- Grandparents helping during visits
- Babysitter logging quick updates
#### 3. Admin (Full System Access)
**Permissions**:
- Access admin dashboard
- Manage all users (CRUD, anonymize, export)
- View system-wide analytics
- Configure LLM models
- Manage subscriptions and trials
- Edit legal pages
- Configure email settings
- View system health
- Audit logs access
**Security**:
- Admins CANNOT access user data without explicit audit trail
- All admin actions logged to `admin_audit_log`
- Require 2FA for admin accounts
---
## ๐๏ธ Invite Code Registration System
### Overview
Control user registration through invite codes to limit initial app access. This feature allows controlled rollout and beta testing across all platforms (web, iOS, Android).
### Features
- **Generate invite codes**: Batch or individual generation
- **Code types**: Single-use, multi-use, unlimited
- **Expiration dates**: Time-limited codes
- **Platform restrictions**: Limit codes to specific platforms
- **Usage tracking**: See who used which code
- **Enable/Disable**: Toggle registration requirement globally
### Database Schema
```sql
-- Invite codes table
CREATE TABLE invite_codes (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
code VARCHAR(20) UNIQUE NOT NULL, -- e.g., "BETA-2025-X7K9"
type VARCHAR(20) NOT NULL, -- 'single', 'multi', 'unlimited'
max_uses INTEGER DEFAULT 1, -- NULL for unlimited
current_uses INTEGER DEFAULT 0,
platform_restrictions VARCHAR(20)[], -- ['web', 'ios', 'android'] or NULL for all
expires_at TIMESTAMP,
metadata JSONB, -- Custom data: { "campaign": "beta", "referrer": "influencer1" }
created_by UUID REFERENCES users(id),
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_invite_codes_code ON invite_codes(code);
CREATE INDEX idx_invite_codes_active ON invite_codes(is_active) WHERE is_active = true;
-- Invite code usage tracking
CREATE TABLE invite_code_usage (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
invite_code_id UUID NOT NULL REFERENCES invite_codes(id),
used_by_user_id UUID NOT NULL REFERENCES users(id),
platform VARCHAR(20) NOT NULL, -- 'web', 'ios', 'android'
device_info JSONB,
ip_address INET,
used_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_invite_code_usage_code ON invite_code_usage(invite_code_id);
CREATE INDEX idx_invite_code_usage_user ON invite_code_usage(used_by_user_id);
-- System configuration for registration
CREATE TABLE registration_config (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
require_invite_code BOOLEAN DEFAULT false,
registration_enabled BOOLEAN DEFAULT true,
custom_message TEXT, -- Message shown when registration is disabled
whitelist_domains VARCHAR(255)[], -- Email domains that bypass invite requirement
updated_by UUID REFERENCES users(id),
updated_at TIMESTAMP DEFAULT NOW()
);
```
### API Endpoints
#### Admin Endpoints
```typescript
// Admin Service API
POST /api/v1/admin/invite-codes // Generate codes
GET /api/v1/admin/invite-codes // List all codes
GET /api/v1/admin/invite-codes/:id // Get code details
PATCH /api/v1/admin/invite-codes/:id // Update code
DELETE /api/v1/admin/invite-codes/:id // Deactivate code
GET /api/v1/admin/invite-codes/:id/usage // Get usage history
// Batch operations
POST /api/v1/admin/invite-codes/batch // Generate multiple codes
POST /api/v1/admin/invite-codes/export // Export codes as CSV
// Configuration
GET /api/v1/admin/registration/config // Get registration settings
PATCH /api/v1/admin/registration/config // Update settings
```
#### Application Endpoints (Web/Mobile)
```typescript
// Public endpoint for all platforms
POST /api/v1/auth/validate-invite-code
{
"code": "BETA-2025-X7K9",
"platform": "ios"
}
// Response
{
"valid": true,
"message": "Code accepted",
"metadata": {
"campaign": "beta"
}
}
// Registration endpoint (modified)
POST /api/v1/auth/register
{
"email": "user@example.com",
"password": "...",
"inviteCode": "BETA-2025-X7K9", // Required if enabled
"platform": "web"
}
```
### Admin UI Components
```typescript
// pages/invite-codes/page.tsx
export default function InviteCodesPage() {
const [requireInvite, setRequireInvite] = useState(false);
return (
{/* Global toggle */}
Registration Settings
Currently: {requireInvite ? 'Invite only' : 'Open registration'}
{/* Code generator */}
Generate Invite Codes
{/* Codes list */}
`${row.current_uses}/${row.max_uses || 'โ'}` },
{ key: 'platforms', label: 'Platforms' },
{ key: 'expires_at', label: 'Expires' },
{ key: 'actions', label: 'Actions' }
]}
data={inviteCodes}
/>
);
}
```
### Implementation in Main Application
```typescript
// src/modules/auth/auth.service.ts (ParentFlow Web/API)
@Injectable()
export class AuthService {
async register(dto: RegisterDto) {
// Check if invite codes are required
const config = await this.getRegistrationConfig();
if (config.requireInviteCode) {
if (!dto.inviteCode) {
throw new BadRequestException('Invite code is required for registration');
}
// Validate with admin service
const validation = await this.adminService.validateInviteCode(
dto.inviteCode,
dto.platform || 'web'
);
if (!validation.valid) {
throw new BadRequestException(validation.message || 'Invalid invite code');
}
// Track usage
await this.adminService.recordInviteCodeUsage(
dto.inviteCode,
userId,
dto.platform
);
}
// Continue with normal registration...
}
private async getRegistrationConfig() {
// Cache this for performance
return await this.adminService.getRegistrationConfig();
}
}
```
### Mobile Integration
```swift
// iOS - RegistrationViewController.swift
func validateInviteCode(_ code: String) async throws -> Bool {
let response = try await AdminAPI.validateInviteCode(
code: code,
platform: "ios"
)
return response.valid
}
func register() async throws {
// Check if invite code is required
if registrationConfig.requireInviteCode {
guard let inviteCode = inviteCodeTextField.text, !inviteCode.isEmpty else {
throw RegistrationError.inviteCodeRequired
}
// Validate before proceeding
let isValid = try await validateInviteCode(inviteCode)
if !isValid {
throw RegistrationError.invalidInviteCode
}
}
// Continue with registration
}
```
### Analytics & Reporting
Track invite code effectiveness:
- **Conversion rate**: Codes generated vs. used
- **Platform distribution**: Usage by platform
- **Time to use**: Average time from generation to use
- **Referral tracking**: Which campaigns/sources are most effective
- **Geographic distribution**: Where users are registering from
---
## ๐๏ธ Database Schema Changes
### New Tables
#### 1. User Role Enhancement
```sql
-- Modify existing users table
ALTER TABLE users
ADD COLUMN global_role VARCHAR(20) DEFAULT 'parent',
ADD COLUMN is_admin BOOLEAN DEFAULT false,
ADD COLUMN admin_permissions JSONB DEFAULT '[]';
-- Add index for admin queries
CREATE INDEX idx_users_global_role ON users(global_role);
CREATE INDEX idx_users_is_admin ON users(is_admin) WHERE is_admin = true;
```
#### 2. Family Membership Roles
```sql
-- Modify family_memberships table
ALTER TABLE family_memberships
ADD COLUMN family_role VARCHAR(20) DEFAULT 'parent', -- parent or guest
ADD COLUMN permissions JSONB DEFAULT '{}',
ADD COLUMN invited_by UUID REFERENCES users(id),
ADD COLUMN access_granted_at TIMESTAMP DEFAULT NOW(),
ADD COLUMN access_expires_at TIMESTAMP NULL;
-- Constraints
ALTER TABLE family_memberships
ADD CONSTRAINT valid_family_role
CHECK (family_role IN ('parent', 'guest'));
```
#### 3. User Profiles (Multi-Profile Support)
```sql
CREATE TABLE user_profiles (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
profile_name VARCHAR(100) NOT NULL,
profile_type VARCHAR(20) NOT NULL, -- 'primary', 'work', 'personal'
default_family_id UUID REFERENCES families(id),
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(user_id, profile_name)
);
CREATE INDEX idx_user_profiles_user_id ON user_profiles(user_id);
```
#### 4. Admin Audit Log
```sql
CREATE TABLE admin_audit_log (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
admin_user_id UUID NOT NULL REFERENCES users(id),
action VARCHAR(50) NOT NULL, -- 'user.create', 'user.delete', 'config.update'
target_entity VARCHAR(50), -- 'user', 'subscription', 'config'
target_id UUID,
changes JSONB, -- before/after values
ip_address INET,
user_agent TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_admin_audit_log_admin_user ON admin_audit_log(admin_user_id);
CREATE INDEX idx_admin_audit_log_created_at ON admin_audit_log(created_at DESC);
CREATE INDEX idx_admin_audit_log_action ON admin_audit_log(action);
```
#### 5. LLM Configuration
```sql
CREATE TABLE llm_config (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
provider VARCHAR(50) NOT NULL, -- 'azure', 'openai', 'anthropic'
service_type VARCHAR(50) NOT NULL, -- 'chat', 'whisper', 'embeddings'
endpoint_url TEXT NOT NULL,
api_key_encrypted TEXT NOT NULL, -- Encrypted with AES-256
model_name VARCHAR(100) NOT NULL,
deployment_name VARCHAR(100), -- For Azure
api_version VARCHAR(20),
price_per_1m_input_tokens DECIMAL(10, 4), -- e.g., 0.0015 for $1.50/1M
price_per_1m_output_tokens DECIMAL(10, 4),
max_tokens INTEGER DEFAULT 4000,
temperature DECIMAL(3, 2) DEFAULT 0.7,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_llm_config_provider_service ON llm_config(provider, service_type);
```
#### 6. Subscription Plans
```sql
CREATE TABLE subscription_plans (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(100) NOT NULL UNIQUE,
description TEXT,
price_monthly DECIMAL(10, 2),
price_yearly DECIMAL(10, 2),
features JSONB, -- Feature flags: { "ai_queries": "unlimited", "voice_commands": 500 }
max_children INTEGER,
max_family_members INTEGER,
ai_query_limit INTEGER, -- NULL = unlimited
voice_command_limit INTEGER,
trial_period_days INTEGER DEFAULT 14,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Add subscription to users
ALTER TABLE users
ADD COLUMN subscription_plan_id UUID REFERENCES subscription_plans(id),
ADD COLUMN subscription_status VARCHAR(20) DEFAULT 'trial', -- trial, active, expired, cancelled
ADD COLUMN subscription_started_at TIMESTAMP,
ADD COLUMN subscription_expires_at TIMESTAMP,
ADD COLUMN trial_ends_at TIMESTAMP;
```
#### 7. Email Configuration
```sql
CREATE TABLE email_config (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
provider VARCHAR(50) DEFAULT 'mailgun',
region VARCHAR(10) DEFAULT 'US', -- US or EU
api_key_encrypted TEXT NOT NULL,
domain VARCHAR(255) NOT NULL,
sender_email VARCHAR(255) NOT NULL,
sender_name VARCHAR(255) NOT NULL,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
```
#### 8. Legal Pages (CMS)
```sql
CREATE TABLE legal_pages (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
slug VARCHAR(100) NOT NULL UNIQUE, -- 'privacy', 'terms', 'eula', 'cookies'
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL, -- Markdown or HTML
language VARCHAR(5) DEFAULT 'en',
version INTEGER DEFAULT 1,
is_published BOOLEAN DEFAULT false,
last_updated_by UUID REFERENCES users(id),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(slug, language)
);
```
---
## ๐ Security & Permissions
### Admin Guard Implementation
**File**: `src/common/guards/admin.guard.ts`
```typescript
import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
import { JwtAuthGuard } from './jwt-auth.guard';
@Injectable()
export class AdminGuard extends JwtAuthGuard {
async canActivate(context: ExecutionContext): Promise {
// First check JWT authentication
const isAuthenticated = await super.canActivate(context);
if (!isAuthenticated) {
return false;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
// Check if user is admin
if (!user.isAdmin) {
throw new ForbiddenException('Admin access required');
}
return true;
}
}
```
### Family Role Guard
**File**: `src/common/guards/family-role.guard.ts`
```typescript
import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
export const RequireFamilyRole = (...roles: string[]) =>
SetMetadata('familyRoles', roles);
@Injectable()
export class FamilyRoleGuard implements CanActivate {
constructor(private reflector: Reflector, private familyService: FamilyService) {}
async canActivate(context: ExecutionContext): Promise {
const requiredRoles = this.reflector.get('familyRoles', context.getHandler());
if (!requiredRoles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
const familyId = request.params.familyId || request.body.familyId;
const membership = await this.familyService.getUserFamilyRole(user.id, familyId);
if (!membership) {
throw new ForbiddenException('Not a member of this family');
}
if (!requiredRoles.includes(membership.familyRole)) {
throw new ForbiddenException(`Requires family role: ${requiredRoles.join(' or ')}`);
}
// Attach to request for use in controllers
request.familyRole = membership.familyRole;
return true;
}
}
```
### Usage Example
```typescript
@Controller('api/v1/analytics')
export class AnalyticsController {
@Get(':childId/insights')
@UseGuards(JwtAuthGuard, FamilyRoleGuard)
@RequireFamilyRole('parent') // Guests cannot access analytics
async getInsights(@Param('childId') childId: string) {
// Only parents can access
}
@Post(':childId/activities')
@UseGuards(JwtAuthGuard, FamilyRoleGuard)
@RequireFamilyRole('parent', 'guest') // Both can add activities
async createActivity(@Param('childId') childId: string) {
// Both parents and guests can add
}
}
```
---
## ๐ Admin Dashboard Features
### 1. User Management
**Endpoint**: `GET /api/v1/admin/users`
**Features**:
- **List Users**: Paginated, searchable, filterable
- **User Details**: Full profile, activity history, subscription
- **Create User**: Manual user creation (for demos, test accounts)
- **Edit User**: Update profile, subscription, role
- **Delete User**: Soft delete with anonymization option
- **Anonymize User**: GDPR compliance - replace PII with anonymized data
- **Export User Data**: Full data export in JSON/CSV
- **Verify User**: Manual email verification override
- **Manage Subscription**: Change plan, extend trial, apply discount
**UI Components**:
```
maternal-web/app/admin/users/
โโโ page.tsx # User list with search/filter
โโโ [userId]/
โ โโโ page.tsx # User detail view
โ โโโ edit/page.tsx # Edit user form
โ โโโ export/page.tsx # Data export interface
โโโ create/page.tsx # Create user form
```
**Backend Module**:
```typescript
// src/modules/admin/user-management/user-management.service.ts
@Injectable()
export class UserManagementService {
async listUsers(filters: UserFilters, pagination: Pagination) {
// Query with filters, sorting, pagination
}
async getUserDetails(userId: string) {
// Full user details including:
// - Profile info
// - Families and roles
// - Subscription status
// - Activity stats
// - AI usage stats
}
async anonymizeUser(userId: string, adminId: string) {
// GDPR compliance
// Replace: name โ "Anonymized User 12345"
// Replace: email โ "anon_12345@maternal.local"
// Keep: aggregated analytics (anonymized)
// Log action in audit_log
}
async exportUserData(userId: string) {
// Full GDPR export
// - User profile
// - Children data
// - Activities
// - AI conversations
// - Photos (URLs)
return { json, csv };
}
async changeSubscription(userId: string, planId: string, adminId: string) {
// Update subscription
// Log in audit trail
}
}
```
---
### 2. Role Management UI
**Components**:
```typescript
// components/admin/RoleSelector.tsx
export function RoleSelector({ userId, currentRole, onRoleChange }) {
return (
);
}
// components/admin/FamilyRoleManager.tsx
export function FamilyRoleManager({ userId, families }) {
// Show user's role in each family
// Allow changing role per family
return (
{families.map(family => (
{family.name}
))}
);
}
```
---
### 3. Multi-Profile Support
**User Stories**:
**Use Case 1**: Multiple Families, One Account
```
User: Sarah (Parent)
โโโ Profile: "Work Family" (childcare at work)
โ โโโ Family: "ABC Daycare"
โ โโโ Child: Emma (not hers, she's a caregiver)
โ โโโ Role: Guest
โโโ Profile: "Home Family" (her own kids)
โโโ Family: "Smith Family"
โโโ Child: Liam
โโโ Child: Olivia
โโโ Role: Parent
```
**Use Case 2**: Multiple Accounts
```
User: John
โโโ Account 1: john@personal.com (Parent in "Doe Family")
โโโ Account 2: john@work.com (Guest in "Work Daycare")
```
**Implementation**:
```typescript
// components/layout/ProfileSwitcher.tsx
export function ProfileSwitcher() {
const { user, profiles, currentProfile, switchProfile } = useAuth();
return (
);
}
```
**Backend API**:
```typescript
// POST /api/v1/profiles
async createProfile(userId: string, dto: CreateProfileDto) {
// Create new profile
// Link to family
// Set default
}
// PATCH /api/v1/profiles/:id/switch
async switchProfile(userId: string, profileId: string) {
// Update user's active profile
// Return new auth context
}
```
---
### 4. Analytics Dashboard
**Metrics to Track**:
#### User Analytics
- Total users (active, inactive, trial, paid)
- New users per day/week/month
- User growth rate
- Churn rate
- Average session duration
- Daily/Monthly Active Users (DAU/MAU)
#### Family & Children Analytics
- Total families
- Average children per family
- Average family size (members)
- Most active families
#### Feature Usage
- Activities logged per day (by type)
- AI queries per day
- Voice commands per day
- Photo uploads per day
- Most used features
#### AI/LLM Analytics
- Total AI queries (by model)
- Average tokens per query (input/output)
- Estimated costs per model
- Average response time
- Error rate
#### Voice Analytics
- Total voice commands
- Success rate (transcription accuracy)
- Most common voice intents
- Average processing time
**UI Components**:
```typescript
// app/admin/analytics/page.tsx
export default function AnalyticsDashboard() {
return (
);
}
```
**Backend**:
```typescript
// src/modules/admin/analytics/analytics-admin.service.ts
@Injectable()
export class AnalyticsAdminService {
async getSystemStats() {
return {
users: await this.getUserStats(),
families: await this.getFamilyStats(),
usage: await this.getUsageStats(),
ai: await this.getAIStats(),
voice: await this.getVoiceStats(),
};
}
async getAIStats() {
// Query from ai_conversations table
// Calculate token usage
// Estimate costs based on llm_config pricing
return {
totalQueries: 15234,
totalInputTokens: 2450000,
totalOutputTokens: 1850000,
estimatedCost: 5.47, // in USD
byModel: [
{ model: 'gpt-4o-mini', queries: 12000, cost: 3.20 },
{ model: 'gpt-4', queries: 3234, cost: 2.27 },
],
};
}
}
```
---
### 5. System Health Monitoring
**Metrics**:
- Service status (backend, database, redis, mongodb)
- API response times (p50, p95, p99)
- Error rates
- Database connection pool status
- Redis cache hit/miss ratio
- Queue depths (background jobs)
- Memory/CPU usage
- Disk space
**Integration with Existing Health Endpoints**:
```typescript
// Reuse existing health endpoints
GET /health # Overall health
GET /health/liveness # Liveness probe
GET /health/readiness # Readiness probe
// New admin-specific endpoint
GET /api/v1/admin/system/health
// Response:
{
"status": "healthy",
"uptime": 345600, // seconds
"services": {
"postgres": { "status": "up", "responseTime": "15ms" },
"redis": { "status": "up", "responseTime": "2ms" },
"mongodb": { "status": "up", "responseTime": "18ms" },
"minio": { "status": "up", "responseTime": "45ms" },
"azureOpenAI": { "status": "up", "responseTime": "120ms" }
},
"metrics": {
"apiResponseTime": { "p50": 85, "p95": 250, "p99": 450 },
"errorRate": 0.02,
"requestsPerMinute": 1250,
"cacheHitRatio": 0.85
},
"resources": {
"memoryUsage": { "used": "2.1GB", "total": "4GB", "percentage": 52.5 },
"cpuUsage": 35.2,
"diskSpace": { "used": "45GB", "total": "100GB", "percentage": 45 }
}
}
```
**UI**:
```typescript
// app/admin/system/health/page.tsx
export default function SystemHealthPage() {
const { data, refetch } = useQuery('/api/v1/admin/system/health', {
refetchInterval: 10000, // Refresh every 10s
});
return (
<>
>
);
}
```
---
### 6. LLM Configuration Management
**UI Features**:
- Add/Edit LLM endpoints
- Manage API keys (encrypted storage)
- Set model names and deployments
- Configure pricing (per 1M tokens)
- Enable/disable models
- Test connections
**Backend**:
```typescript
// src/modules/admin/llm-config/llm-config.service.ts
@Injectable()
export class LLMConfigService {
async createConfig(dto: CreateLLMConfigDto, adminId: string) {
// Encrypt API key
const encryptedKey = await this.encryptionService.encrypt(dto.apiKey);
const config = await this.llmConfigRepository.save({
...dto,
apiKeyEncrypted: encryptedKey,
});
// Audit log
await this.auditService.log({
adminUserId: adminId,
action: 'llm_config.create',
targetId: config.id,
changes: { provider: dto.provider, serviceType: dto.serviceType },
});
return config;
}
async testConnection(configId: string) {
const config = await this.llmConfigRepository.findOne(configId);
const apiKey = await this.encryptionService.decrypt(config.apiKeyEncrypted);
try {
// Test API call
const response = await axios.post(config.endpointUrl, {
messages: [{ role: 'user', content: 'Test' }],
max_tokens: 10,
}, {
headers: { 'api-key': apiKey },
});
return { success: true, latency: response.duration };
} catch (error) {
return { success: false, error: error.message };
}
}
async getEstimatedCosts() {
// Calculate monthly costs based on usage
const usage = await this.getMonthlyTokenUsage();
return usage.map(model => ({
modelName: model.name,
inputTokens: model.inputTokens,
outputTokens: model.outputTokens,
estimatedCost: (
(model.inputTokens / 1000000) * model.pricePerMInput +
(model.outputTokens / 1000000) * model.pricePerMOutput
),
}));
}
}
```
---
### 7. Content Management (Legal Pages)
**Features**:
- Create/Edit legal pages (Privacy Policy, Terms, EULA, Cookies)
- Markdown editor with preview
- Multi-language support
- Version history
- Publish/Unpublish
- SEO metadata
**UI**:
```typescript
// app/admin/pages/[slug]/edit/page.tsx
export default function EditLegalPage({ params }) {
const [content, setContent] = useState('');
const [language, setLanguage] = useState('en');
return (
);
}
```
---
### 8. Subscription Management
**Features**:
- Create subscription plans
- Set pricing (monthly/yearly)
- Define feature limits
- Trial period configuration
- Apply to users
- Discount codes
**Data Model**:
```typescript
interface SubscriptionPlan {
id: string;
name: string; // 'Free', 'Pro', 'Family'
description: string;
priceMonthly: number;
priceYearly: number;
features: {
aiQueries: 'unlimited' | number;
voiceCommands: 'unlimited' | number;
maxChildren: number;
maxFamilyMembers: number;
analytics: boolean;
prioritySupport: boolean;
};
trialPeriodDays: number;
}
```
**UI**:
```typescript
// app/admin/subscriptions/page.tsx
export default function SubscriptionPlansPage() {
return (
<>
>
);
}
```
---
### 9. Email Configuration
**UI**:
```typescript
// app/admin/settings/email/page.tsx
export default function EmailSettingsPage() {
return (
);
}
```
**Backend**:
```typescript
// src/modules/admin/email-config/email-config.service.ts
@Injectable()
export class EmailConfigService {
async updateConfig(dto: UpdateEmailConfigDto, adminId: string) {
const encryptedKey = await this.encryptionService.encrypt(dto.apiKey);
const config = await this.emailConfigRepository.save({
...dto,
apiKeyEncrypted: encryptedKey,
});
// Update EmailService to use new config
await this.emailService.reloadConfig();
// Audit log
await this.auditService.log({
adminUserId: adminId,
action: 'email_config.update',
changes: { region: dto.region, domain: dto.domain },
});
return config;
}
async sendTestEmail(recipientEmail: string) {
try {
await this.emailService.sendEmail({
to: recipientEmail,
subject: 'Test Email from Maternal App Admin',
text: 'If you received this, email configuration is working!',
});
return { success: true };
} catch (error) {
return { success: false, error: error.message };
}
}
}
```
---
## ๐ Deployment Strategy
### Admin Service Deployment
The admin service will be deployed as a **separate microservice**:
#### Infrastructure
```yaml
# docker-compose.admin.yml
version: '3.8'
services:
admin-api:
build: ./parentflow-admin-service
container_name: parentflow-admin-api
ports:
- "4000:4000" # Admin API on separate port
environment:
NODE_ENV: production
DATABASE_URL: postgresql://...
JWT_SECRET: ${ADMIN_JWT_SECRET}
SERVICE_AUTH_KEY: ${SERVICE_AUTH_KEY} # For service-to-service auth
networks:
- parentflow-network
admin-ui:
build: ./parentflow-admin-service/admin-ui
container_name: parentflow-admin-ui
ports:
- "4001:3000" # Admin UI
environment:
REACT_APP_API_URL: http://admin-api:4000
networks:
- parentflow-network
networks:
parentflow-network:
external: true
```
#### Service Communication
```typescript
// Service-to-service authentication
export class AdminServiceClient {
private readonly serviceKey: string;
private readonly adminApiUrl: string;
constructor() {
this.serviceKey = process.env.SERVICE_AUTH_KEY;
this.adminApiUrl = process.env.ADMIN_API_URL || 'http://localhost:4000';
}
async validateInviteCode(code: string, platform: string): Promise {
const response = await axios.post(
`${this.adminApiUrl}/api/v1/internal/validate-invite-code`,
{ code, platform },
{
headers: {
'X-Service-Auth': this.serviceKey,
'X-Service-Name': 'parentflow-web'
}
}
);
return response.data;
}
async getRegistrationConfig(): Promise {
// Cache this for 5 minutes
return this.cache.get('registration-config', async () => {
const response = await axios.get(
`${this.adminApiUrl}/api/v1/internal/registration-config`,
{
headers: {
'X-Service-Auth': this.serviceKey,
'X-Service-Name': 'parentflow-web'
}
}
);
return response.data;
}, 300); // 5 minutes TTL
}
}
```
#### Nginx Configuration
```nginx
# admin.parentflowapp.com
server {
listen 443 ssl http2;
server_name admin.parentflowapp.com;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/admin.parentflowapp.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/admin.parentflowapp.com/privkey.pem;
# IP whitelist for admin access (optional)
allow 10.0.0.0/24; # Office network
allow 192.168.1.0/24; # VPN
deny all;
# Admin UI
location / {
proxy_pass http://localhost:4001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# Admin API
location /api/ {
proxy_pass http://localhost:4000;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
### Deployment Servers
```
Production Environment:
โโโ Admin Service
โ โโโ Server: 10.0.0.241 (separate from main app)
โ โโโ URL: admin.parentflowapp.com
โ โโโ Ports: 4000 (API), 4001 (UI)
โ โโโ Database: Shared with main app (read/write to admin tables)
โ
โโโ Main Applications
โ โโโ Web: 10.0.0.240:3030 โ web.parentflowapp.com
โ โโโ API: 10.0.0.240:3020 โ api.parentflowapp.com
โ โโโ Mobile APIs: Will connect to api.parentflowapp.com
โ
โโโ Shared Infrastructure
โโโ PostgreSQL: 10.0.0.240:5432
โโโ Redis: 10.0.0.240:6379
โโโ MongoDB: 10.0.0.240:27017
```
---
## ๐ Implementation Timeline
### Phase 1: Foundation (Week 1-2)
**Week 1: Database & Backend Core**
- [ ] Create database migrations for new tables
- [ ] Implement role enums and guards
- [ ] Create AdminGuard and FamilyRoleGuard
- [ ] Set up admin API module structure
- [ ] Implement audit logging service
**Week 2: User Management**
- [ ] User management endpoints (CRUD)
- [ ] Anonymization logic
- [ ] Data export functionality
- [ ] Subscription management endpoints
- [ ] Unit tests for user management
---
### Phase 2: Admin UI (Week 3-4)
**Week 3: Admin Dashboard Layout**
- [ ] Admin layout component
- [ ] Navigation sidebar
- [ ] User management UI (list, detail, edit)
- [ ] Role management UI
- [ ] Multi-profile UI components
**Week 4: Analytics & Monitoring**
- [ ] Analytics dashboard UI
- [ ] System health monitoring UI
- [ ] Charts and visualizations
- [ ] Real-time metric updates
---
### Phase 3: Configuration (Week 5-6)
**Week 5: LLM & Email Config**
- [ ] LLM configuration UI
- [ ] API key management (encrypted)
- [ ] Connection testing
- [ ] Email settings UI
- [ ] Test email functionality
**Week 6: Content & Subscriptions**
- [ ] Legal pages CMS
- [ ] Markdown editor integration
- [ ] Subscription plan management UI
- [ ] Trial period configuration
- [ ] Discount codes
---
### Phase 4: Security & Testing (Week 7-8)
**Week 7: Security Hardening**
- [ ] 2FA for admin accounts
- [ ] Admin session timeout (15 min)
- [ ] IP whitelisting option
- [ ] Audit log viewer UI
- [ ] Security testing
**Week 8: Final Testing & Documentation**
- [ ] Integration tests for all admin endpoints
- [ ] E2E tests for critical admin flows
- [ ] Performance testing
- [ ] Admin user documentation
- [ ] Developer API documentation
---
## โ
Acceptance Criteria
### Security
- [ ] Only users with `isAdmin=true` can access admin dashboard
- [ ] All admin actions logged to audit trail
- [ ] API keys encrypted at rest (AES-256)
- [ ] Admin sessions expire after 15 minutes of inactivity
- [ ] 2FA required for admin accounts
### User Management
- [ ] Admin can create/edit/delete users
- [ ] Admin can anonymize user data (GDPR)
- [ ] Admin can export user data in JSON/CSV
- [ ] Admin can change user subscriptions
- [ ] Admin can verify user emails manually
### Role Management
- [ ] Parents have full access to their families
- [ ] Guests can only add activities, no historical data
- [ ] Admins have system-wide access
- [ ] Family roles can be changed per user per family
### Multi-Profile
- [ ] Users can switch between multiple families
- [ ] Users can manage multiple accounts
- [ ] Profile switcher in user menu
- [ ] Default profile saved per user
### Analytics
- [ ] Admin can view user growth metrics
- [ ] Admin can view feature usage stats
- [ ] Admin can view AI/LLM costs and usage
- [ ] Admin can view voice command analytics
- [ ] Real-time metrics with 10s refresh
### System Health
- [ ] Admin can view service status
- [ ] Admin can view API performance metrics
- [ ] Admin can view resource usage
- [ ] Alerts for service degradation
### Configuration
- [ ] Admin can add/edit LLM models
- [ ] Admin can test LLM connections
- [ ] Admin can view estimated AI costs
- [ ] Admin can update email settings
- [ ] Admin can edit legal pages
- [ ] Admin can create subscription plans
---
## ๐ Additional Features (Future Enhancements)
### Advanced Analytics
- [ ] Custom report builder
- [ ] Data export scheduler
- [ ] Cohort analysis
- [ ] Funnel visualization
- [ ] A/B testing dashboard
### Automation
- [ ] Automated user onboarding emails
- [ ] Trial expiration reminders
- [ ] Inactive user re-engagement
- [ ] Subscription renewal reminders
### Advanced Security
- [ ] IP whitelisting for admin access
- [ ] Admin activity anomaly detection
- [ ] Automated threat response
- [ ] SIEM integration
### Support Tools
- [ ] In-app user support chat
- [ ] Impersonate user (for debugging)
- [ ] Feature flag management
- [ ] Rollback deployments
---
## ๐ Related Documentation
- [RBAC Implementation Guide](./RBAC_IMPLEMENTATION.md) (to be created)
- [Audit Logging Standards](./AUDIT_LOGGING.md) (to be created)
- [Data Anonymization Procedures](./DATA_ANONYMIZATION.md) (to be created)
- [API Gateway Architecture](./API_GATEWAY_ARCHITECTURE.md)
---
**Last Updated**: October 3, 2025
**Next Review**: After Phase 1 completion
**Owner**: Backend Team + Admin Team