System Architecture - dinesh-git17/my-progress-planner GitHub Wiki

Deep dive into the technical architecture and design decisions behind My Progress Planner.

🏗️ High-Level Architecture

graph TB
    subgraph "Client Layer"
        A[Next.js Frontend]
        B[Service Worker]
        C[IndexedDB Cache]
    end
    
    subgraph "API Layer"
        D[Next.js API Routes]
        E[Authentication Middleware]
        F[Rate Limiting]
    end
    
    subgraph "External Services"
        G[Supabase Auth]
        H[Supabase Database]
        I[OpenAI GPT-4 API]
        J[Push Notification Service]
    end
    
    subgraph "Infrastructure"
        K[Vercel Edge Functions]
        L[CDN & Caching]
        M[Analytics & Monitoring]
    end
    
    A --> D
    B --> C
    D --> E
    E --> F
    D --> G
    D --> H
    D --> I
    F --> J
    D --> K
    A --> L
    K --> M

🎯 Architecture Principles

1. Privacy by Design

  • Row-level security (RLS) ensures users only access their own data
  • JWT-based authentication with automatic token refresh
  • No third-party analytics that compromise user privacy
  • Local-first data storage with cloud sync

2. Offline-First PWA

  • Service Worker handles caching and offline functionality
  • Background sync for seamless data synchronization
  • IndexedDB for local data persistence
  • App Shell architecture for instant loading

3. AI-Powered Personalization

  • Context-aware responses considering user history and streaks
  • Consistent personality across all AI interactions
  • Fallback mechanisms when AI services are unavailable
  • Response caching to improve performance and reduce costs

4. Scalable & Maintainable

  • TypeScript for type safety and developer experience
  • Modular architecture with clear separation of concerns
  • API-first design for future mobile app development
  • Comprehensive testing at unit, integration, and E2E levels

📱 Frontend Architecture

Component Hierarchy

App Layout
├── Navigation Provider
├── Auth Provider
├── Notification Handler
└── Page Components
    ├── Meal Tracking Pages
    │   ├── MealCard Components
    │   ├── MealInput Components
    │   └── AI Response Components
    ├── Dashboard
    │   ├── Streak Display
    │   ├── Quick Stats
    │   └── Recent Activity
    └── Profile & Settings
        ├── User Profile
        ├── Friend Management
        └── Notification Settings

State Management Strategy

// Context-based state management
interface AppState {
  user: User | null;
  meals: TodaysMeals;
  streak: StreakData;
  offline: boolean;
}

// Local component state for UI interactions
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);

// Server state via SWR for data fetching
const { data: meals, error, mutate } = useSWR('/api/meals/today', fetcher);

Responsive Design System

// Tailwind breakpoint strategy
const breakpoints = {
  sm: '640px',   // Mobile landscape
  md: '768px',   // Tablet
  lg: '1024px',  // Desktop
  xl: '1280px',  // Large desktop
};

// Component example
<div className="
  grid grid-cols-1 gap-4        // Mobile: single column
  md:grid-cols-2 md:gap-6       // Tablet: two columns
  lg:grid-cols-3 lg:gap-8       // Desktop: three columns
">

🔧 API Architecture

Route Structure

/api/
├── auth/
│   └── callback          # OAuth callback handling
├── meals/
│   ├── today            # GET: Today's meals
│   ├── log              # POST: Log new meal
│   └── check            # GET: Check if meal exists
├── ai/
│   ├── chat             # POST: Generate meal response
│   └── quote            # GET: Daily motivational quote
├── user/
│   ├── profile          # GET/PUT: User profile
│   └── friend-code      # GET: User's friend code
├── friends/
│   ├── search           # GET: Find friends by code
│   └── [operations]     # Friend management
├── summaries/
│   ├── [date]           # GET: Specific day summary
│   └── recent           # GET: Recent summaries
├── admin/
│   ├── stats            # GET: System statistics
│   └── [management]     # Admin operations
└── cron/
    ├── lunch            # Meal reminders
    └── dinner           # Meal reminders

Authentication Flow

sequenceDiagram
    participant C as Client
    participant A as API
    participant S as Supabase Auth
    
    C->>A: Request with JWT
    A->>A: Extract JWT token
    A->>S: Validate token
    S->>A: User data or error
    A->>A: Check user permissions
    A->>C: Response or 401

Error Handling Strategy

// Standardized error response format
interface APIError {
  error: string;
  code?: string;
  details?: any;
}

// Error handling middleware
export function withErrorHandling(handler: APIHandler) {
  return async (req: NextRequest) => {
    try {
      return await handler(req);
    } catch (error) {
      console.error('API Error:', error);
      
      if (error instanceof ValidationError) {
        return NextResponse.json(
          { error: error.message, code: 'VALIDATION_ERROR' },
          { status: 400 }
        );
      }
      
      return NextResponse.json(
        { error: 'Internal server error' },
        { status: 500 }
      );
    }
  };
}

💾 Database Architecture

Schema Design Principles

  • UUID primary keys for global uniqueness and security
  • Foreign key constraints for data integrity
  • Indexes on frequently queried columns
  • Triggers for automatic data updates
  • Row-Level Security (RLS) for user data isolation

Performance Optimizations

-- Composite indexes for common queries
CREATE INDEX idx_meals_user_date_type ON meals(user_id, DATE(logged_at), meal_type);

-- Partial indexes for active data
CREATE INDEX idx_active_users ON users(id) WHERE created_at > NOW() - INTERVAL '30 days';

-- Materialized views for analytics
CREATE MATERIALIZED VIEW daily_stats AS
SELECT 
  DATE(logged_at) as date,
  COUNT(*) as meals_logged,
  COUNT(DISTINCT user_id) as active_users
FROM meals 
WHERE logged_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY DATE(logged_at);

Data Lifecycle Management

// Automatic data cleanup policies
interface DataRetentionPolicy {
  meals: '2 years';           // Keep meal logs for 2 years
  summaries: '1 year';        // Keep summaries for 1 year
  sessions: '30 days';        // Clean old sessions
  logs: '90 days';           // Keep application logs for 90 days
}

// Soft delete pattern for important data
interface SoftDeletable {
  deleted_at: Date | null;
  deleted_by: string | null;
}

🤖 AI Integration Architecture

GPT-4 Integration Pipeline

graph LR
    A[Meal Input] --> B[Context Builder]
    B --> C[Prompt Template]
    C --> D[GPT-4 API]
    D --> E[Response Processor]
    E --> F[Cache & Store]
    F --> G[Return to User]
    
    subgraph "Context Builder"
        H[User Streak]
        I[Previous Meals]
        J[Time of Day]
        K[User Preferences]
    end

Prompt Engineering

// Modular prompt system
interface PromptContext {
  mealType: MealType;
  content: string;
  streak: number;
  timeOfDay: 'morning' | 'afternoon' | 'evening';
  previousMeals: Meal[];
  userPreferences?: UserPreferences;
}

// Template system for consistent responses
const PROMPT_TEMPLATES = {
  base: `You are a loving, supportive boyfriend who cares deeply about your partner's wellness journey...`,
  
  breakfast: `{base} They just logged breakfast: "{content}". Consider their {streak}-day streak and respond with encouragement...`,
  
  streak_milestone: `{base} They've reached a {streak}-day streak! Celebrate this achievement...`
};

Response Quality Controls

// Response validation and filtering
interface ResponseValidator {
  minLength: 50;
  maxLength: 200;
  requiredTone: 'encouraging' | 'supportive';
  bannedWords: string[];
  emojiRequired: boolean;
}

// Fallback responses for API failures
const FALLBACK_RESPONSES = {
  breakfast: [
    "What a great way to start your day! 💕",
    "You're taking such good care of yourself! 🌟",
    "Perfect fuel for an amazing day ahead! ✨"
  ]
};

📱 PWA Architecture

Service Worker Strategy

// Multi-layered caching strategy
const CACHE_STRATEGIES = {
  'app-shell': 'cache-first',        // Static app resources
  'api-quotes': 'cache-first',       // Daily quotes (rarely change)
  'api-meals': 'network-first',      // User data (needs freshness)
  'api-streaks': 'stale-while-revalidate', // Updated but can show stale
  'images': 'cache-first',           // Static images
  'ai-responses': 'network-only'     // Always fresh AI responses
};

Offline Data Synchronization

// Background sync for critical operations
interface SyncOperation {
  id: string;
  type: 'meal-log' | 'profile-update' | 'friend-add';
  data: any;
  timestamp: Date;
  retries: number;
}

// Conflict resolution strategy
enum ConflictResolution {
  CLIENT_WINS = 'client',    // User's offline changes take priority
  SERVER_WINS = 'server',    // Server data is authoritative
  MANUAL = 'manual',         // Prompt user to resolve
  MERGE = 'merge'           // Attempt automatic merge
}

Installation & Updates

// Progressive enhancement approach
interface PWAFeatures {
  installPrompt: boolean;      // Show install banner
  backgroundSync: boolean;     // Offline data sync
  pushNotifications: boolean;  // Meal reminders
  periodicSync: boolean;       // Regular data updates
  shareTarget: boolean;        // Share meals from other apps
}

🔐 Security Architecture

Authentication & Authorization

// JWT token structure
interface JWTPayload {
  sub: string;              // User ID
  email: string;
  iat: number;              // Issued at
  exp: number;              // Expires at
  role: 'user' | 'admin';
}

// Permission system
interface Permissions {
  'meals:read': boolean;
  'meals:write': boolean;
  'summaries:read': boolean;
  'admin:stats': boolean;
}

Data Protection

-- Row Level Security policies
CREATE POLICY "Users can only see own meals" ON meals
  FOR ALL USING (auth.uid() = user_id);

-- Sensitive data encryption
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- API rate limiting
CREATE TABLE api_rate_limits (
  user_id UUID,
  endpoint TEXT,
  requests INTEGER DEFAULT 1,
  window_start TIMESTAMP DEFAULT NOW()
);

📊 Monitoring & Observability

Application Metrics

// Key performance indicators
interface AppMetrics {
  // User engagement
  dailyActiveUsers: number;
  mealLogsPerDay: number;
  streakDistribution: number[];
  
  // Technical metrics
  apiResponseTimes: number[];
  errorRates: Record<string, number>;
  uptime: number;
  
  // AI metrics
  aiResponseTimes: number[];
  aiApiCosts: number;
  fallbackResponseRate: number;
}

Error Tracking & Logging

// Structured logging
interface LogEntry {
  timestamp: Date;
  level: 'info' | 'warn' | 'error';
  message: string;
  context: {
    userId?: string;
    endpoint?: string;
    error?: Error;
    metadata?: any;
  };
}

// Performance monitoring
const performanceObserver = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    if (entry.entryType === 'measure') {
      trackMetric('performance', entry.name, entry.duration);
    }
  });
});

🚀 Scalability Considerations

Performance Optimization

// Code splitting strategy
const DashboardPage = lazy(() => import('../pages/Dashboard'));
const MealLogPage = lazy(() => import('../pages/MealLog'));

// Image optimization
const optimizedImages = {
  formats: ['webp', 'avif'],
  sizes: [640, 768, 1024, 1280],
  quality: 80
};

// Database connection pooling
const dbConfig = {
  max: 20,                    // Maximum pool size
  idleTimeoutMillis: 30000,   // Close idle connections
  connectionTimeoutMillis: 2000
};

Horizontal Scaling

# Load balancer configuration
upstream app_servers {
  server app1.example.com:3000;
  server app2.example.com:3000;
  server app3.example.com:3000;
}

# Database read replicas
read_replicas:
  - host: read1.example.com
  - host: read2.example.com

# CDN strategy
cdn_rules:
  - path: "/static/*"
    cache_duration: "1y"
  - path: "/api/ai/*"
    cache_duration: "0"

🔄 Data Flow Examples

Meal Logging Flow

sequenceDiagram
    participant U as User
    participant C as Client
    participant SW as Service Worker
    participant API as API Server
    participant DB as Database
    participant AI as OpenAI
    
    U->>C: Enter meal content
    C->>C: Validate input
    C->>API: POST /api/meals/log
    API->>API: Authenticate user
    API->>DB: Insert meal record
    API->>AI: Generate response
    AI->>API: Return AI response
    API->>DB: Update meal with AI response
    API->>C: Return complete meal data
    C->>SW: Cache response
    C->>U: Show success + AI response

Offline Sync Flow

sequenceDiagram
    participant U as User
    participant C as Client
    participant SW as Service Worker
    participant IDB as IndexedDB
    participant API as API Server
    
    Note over C,IDB: User is offline
    U->>C: Log meal
    C->>IDB: Store pending sync
    C->>U: Show success (pending)
    
    Note over C,API: Connection restored
    SW->>IDB: Get pending syncs
    SW->>API: Sync meal data
    API->>SW: Confirm sync
    SW->>IDB: Clear pending sync
    SW->>C: Update UI status

📞 Architecture Support

For technical architecture questions or suggestions:


This architecture supports our mission of creating a supportive, privacy-first meal tracking experience that works reliably across all devices and network conditions. 🏗️💕