From 4e9fe521060b23bb04567d4a93a8c4d4219f4d0b Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 8 Oct 2025 11:10:28 +0000 Subject: [PATCH] chore: Remove development files from git tracking and update .gitignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed from git tracking: - docs/ folder (all planning and implementation documentation) - CLAUDE.md (AI assistant instructions) - start-dev.sh and stop-dev.sh (development scripts) Updated .gitignore to exclude: - Documentation and planning files (docs/, CLAUDE.md) - Development scripts and logs (*.dev.log, start-dev.sh, stop-dev.sh) - Development environment folders (.dev/, dev-data/) - Temporary development files (*.tmp, *.temp, .scratch/) These files remain available locally for development but won't be committed to the repository. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitignore | 19 + CLAUDE.md | 343 --- ..._IMPLEMENTATION_PLAN-20251003104143.195.md | 641 ----- ..._IMPLEMENTATION_PLAN-20251003115405.029.md | 784 ------ docs/ADMIN_DASHBOARD_IMPLEMENTATION.md | 1681 ------------ docs/API_GATEWAY_ARCHITECTURE.md | 943 ------- docs/DATABASE_MIGRATIONS_CONSOLIDATED.md | 251 -- docs/REMAINING_FEATURES.md | 1003 -------- .../ACCESSIBILITY_IMPLEMENTATION_PLAN.md | 670 ----- .../ACCESSIBILITY_PROGRESS.md | 461 ---- .../AI_SAFETY_IMPLEMENTATION_SUMMARY.md | 322 --- .../implementation-docs/AI_SAFETY_STRATEGY.md | 517 ---- docs/implementation-docs/BACKLOG.md | 500 ---- docs/implementation-docs/COMPLETED_TODAY.md | 109 - .../EMBEDDINGS-IMPLEMENTATION.md | 286 --- .../LOCALIZATION_IMPLEMENTATION_PLAN.md | 816 ------ .../PACKAGE_UPGRADE_PLAN.md | 177 -- .../SPRINT_2_ASSESSMENT.md | 362 --- .../STREAMING_IMPLEMENTATION.md | 280 -- docs/implementation-docs/TESTING_STRATEGY.md | 526 ---- .../azure-openai-integration-summary.md | 576 ----- .../azure-openai-integration.md | 481 ---- .../azure-openai-test-results.md | 320 --- .../implementation-gaps.md | 2052 --------------- .../maternal-app-ai-context.md | 551 ---- .../maternal-app-api-spec.md | 939 ------- .../maternal-app-dataflow.txt | 207 -- .../maternal-app-db-migrations.md | 412 --- .../maternal-app-design-system.md | 586 ----- .../maternal-app-env-config.md | 507 ---- .../maternal-app-error-logging.md | 588 ----- .../maternal-app-implementation-plan.md | 783 ------ .../maternal-app-mobile-deployment.md | 590 ----- docs/implementation-docs/maternal-app-mvp.md | 346 --- .../maternal-app-name-and-domain-research.md | 89 - .../maternal-app-state-management.md | 724 ------ .../maternal-app-tech-stack.md | 420 --- .../maternal-app-testing-strategy.md | 575 ----- .../maternal-app-voice-processing.md | 590 ----- .../maternal-web-frontend-plan.md | 1733 ------------- .../mobile-and-web-app-for-mothers.md | 87 - .../mobile-app-best-practices.md | 975 ------- .../multi-child-implementation-plan.md | 2286 ----------------- .../multi-child-implementation.md | 244 -- .../multi-child-phase3-status.md | 367 --- .../multi-child-phase5-status.md | 361 --- .../phase6-testing-summary.md | 429 ---- .../phase8-post-launch-summary.md | 800 ------ .../product-analytics-dashboard.md | 722 ------ ...h_local_apprise_mvp_implementation_plan.md | 291 --- start-dev.sh | 259 -- stop-dev.sh | 172 -- 52 files changed, 19 insertions(+), 30734 deletions(-) delete mode 100644 CLAUDE.md delete mode 100644 docs/.duckversions/LOCALIZATION_IMPLEMENTATION_PLAN-20251003104143.195.md delete mode 100644 docs/.duckversions/LOCALIZATION_IMPLEMENTATION_PLAN-20251003115405.029.md delete mode 100644 docs/ADMIN_DASHBOARD_IMPLEMENTATION.md delete mode 100644 docs/API_GATEWAY_ARCHITECTURE.md delete mode 100644 docs/DATABASE_MIGRATIONS_CONSOLIDATED.md delete mode 100644 docs/REMAINING_FEATURES.md delete mode 100644 docs/implementation-docs/ACCESSIBILITY_IMPLEMENTATION_PLAN.md delete mode 100644 docs/implementation-docs/ACCESSIBILITY_PROGRESS.md delete mode 100644 docs/implementation-docs/AI_SAFETY_IMPLEMENTATION_SUMMARY.md delete mode 100644 docs/implementation-docs/AI_SAFETY_STRATEGY.md delete mode 100644 docs/implementation-docs/BACKLOG.md delete mode 100644 docs/implementation-docs/COMPLETED_TODAY.md delete mode 100644 docs/implementation-docs/EMBEDDINGS-IMPLEMENTATION.md delete mode 100644 docs/implementation-docs/LOCALIZATION_IMPLEMENTATION_PLAN.md delete mode 100644 docs/implementation-docs/PACKAGE_UPGRADE_PLAN.md delete mode 100644 docs/implementation-docs/SPRINT_2_ASSESSMENT.md delete mode 100644 docs/implementation-docs/STREAMING_IMPLEMENTATION.md delete mode 100644 docs/implementation-docs/TESTING_STRATEGY.md delete mode 100644 docs/implementation-docs/azure-openai-integration-summary.md delete mode 100644 docs/implementation-docs/azure-openai-integration.md delete mode 100644 docs/implementation-docs/azure-openai-test-results.md delete mode 100644 docs/implementation-docs/implementation-gaps.md delete mode 100644 docs/implementation-docs/maternal-app-ai-context.md delete mode 100644 docs/implementation-docs/maternal-app-api-spec.md delete mode 100644 docs/implementation-docs/maternal-app-dataflow.txt delete mode 100644 docs/implementation-docs/maternal-app-db-migrations.md delete mode 100644 docs/implementation-docs/maternal-app-design-system.md delete mode 100644 docs/implementation-docs/maternal-app-env-config.md delete mode 100644 docs/implementation-docs/maternal-app-error-logging.md delete mode 100644 docs/implementation-docs/maternal-app-implementation-plan.md delete mode 100644 docs/implementation-docs/maternal-app-mobile-deployment.md delete mode 100644 docs/implementation-docs/maternal-app-mvp.md delete mode 100644 docs/implementation-docs/maternal-app-name-and-domain-research.md delete mode 100644 docs/implementation-docs/maternal-app-state-management.md delete mode 100644 docs/implementation-docs/maternal-app-tech-stack.md delete mode 100644 docs/implementation-docs/maternal-app-testing-strategy.md delete mode 100644 docs/implementation-docs/maternal-app-voice-processing.md delete mode 100644 docs/implementation-docs/maternal-web-frontend-plan.md delete mode 100644 docs/implementation-docs/mobile-and-web-app-for-mothers.md delete mode 100644 docs/implementation-docs/mobile-app-best-practices.md delete mode 100644 docs/implementation-docs/multi-child-implementation-plan.md delete mode 100644 docs/implementation-docs/multi-child-implementation.md delete mode 100644 docs/implementation-docs/multi-child-phase3-status.md delete mode 100644 docs/implementation-docs/multi-child-phase5-status.md delete mode 100644 docs/implementation-docs/phase6-testing-summary.md delete mode 100644 docs/implementation-docs/phase8-post-launch-summary.md delete mode 100644 docs/implementation-docs/product-analytics-dashboard.md delete mode 100644 docs/pwa_web_push_local_apprise_mvp_implementation_plan.md delete mode 100755 start-dev.sh delete mode 100755 stop-dev.sh diff --git a/.gitignore b/.gitignore index 26d9f1f..6664aab 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,22 @@ maternal-web/.cache/ # package-lock.json # yarn.lock # pnpm-lock.yaml + +# Documentation and planning (development only) +docs/ +CLAUDE.md + +# Development scripts and logs +start-dev.sh +stop-dev.sh +*.dev.log +/tmp/*.log + +# Development environment +.dev/ +dev-data/ + +# Temporary development files +*.tmp +*.temp +.scratch/ diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 28ccfc6..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,343 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Project Overview - -This is a planning and documentation repository for an **AI-powered maternal organization app** designed to help parents manage childcare for children aged 0-6 years. The app focuses on reducing mental load through intelligent tracking, real-time family sync, and AI-powered parenting support. - -**Current Status**: Documentation phase - no code implementation yet. All source files are comprehensive planning documents. - -## Core Technology Stack - -### Mobile Application -- **Framework**: React Native with Expo -- **State Management**: Redux Toolkit with offline-first architecture -- **Local Database**: SQLite with TypeORM -- **Navigation**: React Navigation -- **UI Components**: React Native Paper (Material Design) - -### Backend Infrastructure -- **Framework**: NestJS (Node.js) -- **API Style**: Hybrid REST + GraphQL + WebSocket -- **Primary Database**: PostgreSQL 15+ (with partitioned activity tables) -- **Document Store**: MongoDB (for AI chat history) -- **Cache/Queue**: Redis -- **Object Storage**: MinIO (S3-compatible) - -### AI/ML Services -- **LLM**: OpenAI GPT-4 / Anthropic Claude / Google Gemini APIs -- **Framework**: LangChain for context management -- **Voice Recognition**: OpenAI Whisper -- **Pattern Recognition**: Custom algorithms with TensorFlow.js - -### Real-Time Features -- **Sync**: Socket.io for family coordination -- **Push Notifications**: Firebase Cloud Messaging / Expo Notifications - -## Architecture Highlights - -### State Management Design -- **Normalized state shape** with entities stored in `byId` dictionaries -- **Offline-first** with automatic sync queue and conflict resolution -- **Optimistic updates** for instant UI feedback -- Separate slices: auth, user, family, children, activities, ai, sync, offline, ui, notifications, analytics - -### API Architecture -- Base URL: `https://api.{domain}/api/v1` -- GraphQL endpoint for complex queries: `/graphql` -- WebSocket for real-time sync: `wss://api.{domain}/ws` -- **Device fingerprinting** for multi-device auth -- **JWT access tokens** (1h) + refresh tokens with rotation -- Rate limiting: 100 requests/minute per user - -### Database Schema Strategy -- **Partitioned tables** for activities (feeding, sleep, diapers) using monthly partitions -- **Audit logging tables** for COPPA/GDPR compliance -- **Performance indexes** on commonly queried fields (childId, createdAt) -- Migration scripts numbered V001-V007+ for sequential deployment - -### AI Context Management -- **Token budget**: 4000 tokens max per request -- **Priority weighting system** for context selection: - - Current query: 1.0 - - Recent activities (48h): 0.8 - - Child profile: 0.7 - - Historical patterns: 0.6 - - General guidelines: 0.4 -- **Safety boundaries**: Medical disclaimer triggers, mental health resources, prompt injection protection -- **Multi-language support**: 5 languages (English, Spanish, French, Portuguese, Chinese) - -## Key Documentation Files - -### Technical Architecture -- `docs/maternal-app-tech-stack.md` - Complete technology choices with library recommendations -- `docs/maternal-app-implementation-plan.md` - 8-phase development roadmap with deliverables -- `docs/maternal-app-api-spec.md` - REST/GraphQL/WebSocket endpoint specifications -- `docs/maternal-app-db-migrations.md` - Database schema with migration scripts - -### AI/ML Integration -- `docs/maternal-app-ai-context.md` - LangChain configuration, prompt templates, safety boundaries -- `docs/maternal-app-voice-processing.md` - Voice input patterns and NLP processing -- `docs/maternal-app-state-management.md` - Redux Toolkit architecture with offline support - -### UI/UX Design -- `docs/maternal-app-design-system.md` - Material Design system with warm color palette -- `docs/maternal-app-mvp.md` - MVP feature scope and success metrics -- `docs/maternal-app-testing-strategy.md` - Testing approach (unit, integration, E2E) - -### DevOps & Deployment -- `docs/maternal-app-env-config.md` - Environment variables and Docker setup -- `docs/maternal-app-mobile-deployment.md` - iOS/Android build and release process -- `docs/maternal-app-error-logging.md` - Error codes and logging standards - -## Implementation Commands (Future) - -### Project Setup -```bash -# Frontend - React Native with Expo -npx create-expo-app maternal-app --template -cd maternal-app -npm install @reduxjs/toolkit react-redux redux-persist -npm install react-navigation react-native-paper -npm install @react-native-async-storage/async-storage -npm install react-native-sqlite-storage - -# Backend - NestJS -nest new maternal-app-backend -cd maternal-app-backend -npm install @nestjs/typeorm @nestjs/jwt @nestjs/websockets -npm install @nestjs/graphql @apollo/server graphql -npm install pg redis bull socket.io -``` - -### Development Workflow -```bash -# Frontend development -npm start # Start Expo dev server -npm run ios # Run on iOS simulator -npm run android # Run on Android emulator -npm test # Run Jest unit tests - -# Backend development -npm run start:dev # Start NestJS with hot reload -npm run test # Run unit tests -npm run test:e2e # Run integration tests -npm run migration:run # Apply database migrations - -# Docker environment -docker-compose up -d # Start PostgreSQL, Redis, MongoDB, MinIO -``` - -### Testing -```bash -# Unit tests (Jest) -npm test -- --coverage # Run with coverage report - -# E2E tests (Detox for mobile) -detox build --configuration ios.sim.debug -detox test --configuration ios.sim.debug - -# Backend integration tests -npm run test:e2e -``` - -### Database Management -```bash -# Run migrations in sequence -npm run migration:run - -# Rollback last migration -npm run migration:revert - -# Generate new migration -npm run migration:generate -- -n MigrationName -``` - -## Design Principles - -### Mobile UX Requirements -- **One-handed operation**: All critical actions in bottom 60% of screen -- **Interruption-resilient**: Auto-save all inputs, no data loss on app switch -- **Minimum touch targets**: 44x44px (iOS) / 48x48dp (Android) -- **Performance**: 60fps scrolling, <2s load time, skeleton screens for loading states - -### Color Palette (Warm, Nurturing) -- Primary: Peach (#FFB5A0), Coral (#FF8B7D), Rose (#FFD4CC) -- Semantic: Sage green (success), Amber (warning), Soft red (error) -- Material Design principles throughout - -### Accessibility -- WCAG AA/AAA compliance -- Screen reader support -- High contrast mode -- Text size adjustment -- Multi-language support (5 languages in MVP) - -## Security & Compliance - -### Authentication Flow -1. Email/phone signup with verification -2. Device fingerprinting on registration -3. JWT access token (1h) + refresh token -4. Biometric login option (Face ID / Touch ID / Fingerprint) -5. Multi-device session management - -### Privacy Considerations -- **COPPA compliance**: Age verification, parental consent flows -- **GDPR compliance**: Data export, right to deletion, consent management -- **End-to-end encryption** for sensitive child data -- **Audit tables** tracking all data access and modifications -- **No third-party data sharing** without explicit consent - -### Error Handling Standards -- Structured error codes (e.g., `AUTH_DEVICE_NOT_TRUSTED`, `LIMIT_FAMILY_SIZE_EXCEEDED`) -- User-friendly error messages in all 5 languages -- Sentry integration for error tracking -- Audit logging for security events - -## MVP Scope (6-8 Weeks) - -### Core Features -1. **Tracking**: Feeding, sleep, diapers with voice input -2. **AI Assistant**: 24/7 contextual parenting support using LangChain -3. **Family Sync**: Real-time updates via WebSocket -4. **Pattern Recognition**: Sleep predictions, feeding trends -5. **Analytics**: Daily/weekly summaries, exportable reports - -### Success Metrics -- 1,000 downloads in first month -- 60% daily active users -- 70% of users try AI assistant -- <2% crash rate -- 4.0+ app store rating - -### Deferred to Post-MVP -- Meal planning -- Financial tracking -- Community forums -- Smart home integration -- School platform integrations - -## Code Organization (Planned) - -``` -/maternal-app (React Native) - /src - /components - /common # Reusable UI components - /tracking # Activity tracking components - /ai # AI chat interface - /screens # Screen components - /services # API clients, device services - /hooks # Custom React hooks - /redux - /slices # Redux Toolkit slices - /locales # i18n translations - /navigation # React Navigation config - /types # TypeScript definitions - -/maternal-app-backend (NestJS) - /src - /modules - /auth # Authentication & authorization - /users # User management - /families # Family coordination - /children # Child profiles - /tracking # Activity tracking - /ai # AI/LLM integration - /common - /guards # Auth guards - /interceptors # Request/response transformation - /filters # Exception filters - /database - /entities # TypeORM entities - /migrations # Database migrations -``` - -## Development Best Practices - -### Git Workflow -- Branch naming: `feature/`, `bugfix/`, `hotfix/` -- Commit messages: Conventional commits (feat:, fix:, docs:, test:) -- Pre-commit hooks: ESLint, Prettier, type checking - -### Testing Strategy -- **Target**: 80% code coverage -- Unit tests for all services and utilities -- Integration tests for API endpoints -- E2E tests for critical user journeys -- Mock AI responses for predictable testing - -### Performance Optimization -- Redis caching for frequent queries -- Database query optimization with indexes -- Image optimization with Sharp -- Code splitting and lazy loading -- Offline-first architecture with sync queue - -## Multi-Language Support - -### Supported Languages (MVP) -1. English (en-US) - Primary -2. Spanish (es-ES) -3. French (fr-FR) -4. Portuguese (pt-BR) -5. Simplified Chinese (zh-CN) - -### Localization Framework -- i18next for string externalization -- react-i18next for React integration -- react-native-localize for device locale detection -- All strings externalized from day 1 -- Date/time/number formatting per locale -- AI responses localized per user preference - -## Critical Implementation Notes - -### Offline-First Architecture -- All core features (tracking) work offline -- Automatic sync queue when connectivity restored -- Conflict resolution strategy: last-write-wins with timestamp comparison -- Optimistic UI updates for instant feedback - -### Real-Time Family Sync -- WebSocket connection per device -- Event-driven architecture for activity updates -- Presence indicators (who's online) -- Typing indicators for AI chat -- Connection recovery with exponential backoff - -### AI Safety Guardrails -- Medical disclaimer triggers for health concerns -- Crisis hotline integration for mental health -- Rate limiting: 10 AI queries/day (free), unlimited (premium) -- Response moderation and filtering -- Prompt injection protection - -### Data Migration Strategy -- Sequential migration scripts (V001, V002, etc.) -- Rollback procedures for each migration -- Data seeding for development/testing -- Backup verification before production migrations - -## Future Roadmap Considerations - -### Phase 2 (Months 2-3) -- Community features with moderation -- Photo milestone tracking -- Meal planning basics -- Calendar integration (Google, Apple, Outlook) - -### Phase 3 (Months 4-6) -- Financial tracking -- Smart home integration (Alexa, Google Home) -- Professional tools for caregivers -- Telemedicine integration - -### Scalability Preparations -- Kubernetes deployment for horizontal scaling -- Database sharding strategy for multi-tenancy -- CDN for static assets -- Message queue (RabbitMQ/Kafka) for async processing -- Microservices architecture when needed \ No newline at end of file diff --git a/docs/.duckversions/LOCALIZATION_IMPLEMENTATION_PLAN-20251003104143.195.md b/docs/.duckversions/LOCALIZATION_IMPLEMENTATION_PLAN-20251003104143.195.md deleted file mode 100644 index ec1c626..0000000 --- a/docs/.duckversions/LOCALIZATION_IMPLEMENTATION_PLAN-20251003104143.195.md +++ /dev/null @@ -1,641 +0,0 @@ -# Localization Implementation Plan - -**Created**: October 3, 2025 -**Priority**: HIGH (Pre-Launch) -**Estimated Duration**: 2-3 days - -## Overview - -Implement comprehensive internationalization (i18n) support for the Maternal App with 5 languages and measurement unit preferences. - -## Supported Languages - -1. **English (en-US)** - Primary/Default -2. **Spanish (es-ES)** -3. **French (fr-FR)** -4. **Portuguese (pt-BR)** -5. **Simplified Chinese (zh-CN)** - -## Current Status - -### ✅ Already Completed -- Backend multilanguage support for AI responses -- AI safety responses in 5 languages -- MultiLanguageService with language detection - -### ❌ To Be Implemented -- Frontend i18next framework -- Translation files for all UI strings -- Language selector in onboarding -- Language selector in settings -- Date/time localization -- Measurement unit preferences (Metric/Imperial) -- Number formatting per locale - ---- - -## Phase 1: Framework Setup - -### 1.1 Install Dependencies -**Files**: `package.json` - -```bash -npm install i18next react-i18next i18next-browser-languagedetector -npm install date-fns # Already installed, confirm locales -``` - -**Packages**: -- `i18next` - Core i18n framework -- `react-i18next` - React bindings -- `i18next-browser-languagedetector` - Auto-detect user language - -### 1.2 Create i18n Configuration -**File**: `lib/i18n/config.ts` (NEW) - -- Initialize i18next -- Configure language detector -- Set up fallback language (en-US) -- Configure interpolation -- Load translation resources - -### 1.3 Create i18n Provider -**File**: `components/providers/I18nProvider.tsx` (NEW) - -- Wrap app with I18nextProvider -- Initialize i18n on mount -- Handle language loading states - -### 1.4 Update Root Layout -**File**: `app/layout.tsx` (MODIFY) - -- Add I18nProvider to provider stack -- Set html lang attribute dynamically - ---- - -## Phase 2: Translation Files Structure - -### 2.1 Directory Structure -``` -locales/ -├── en/ -│ ├── common.json # Common UI strings (buttons, labels, etc.) -│ ├── auth.json # Authentication pages -│ ├── dashboard.json # Dashboard/home page -│ ├── tracking.json # Activity tracking -│ ├── children.json # Child management -│ ├── family.json # Family management -│ ├── ai.json # AI assistant -│ ├── analytics.json # Analytics/insights -│ ├── settings.json # Settings page -│ ├── onboarding.json # Onboarding flow -│ ├── errors.json # Error messages -│ └── validation.json # Form validation messages -├── es/ -│ └── [same structure] -├── fr/ -│ └── [same structure] -├── pt/ -│ └── [same structure] -└── zh/ - └── [same structure] -``` - -### 2.2 Translation Keys Structure - -**Example - common.json**: -```json -{ - "nav": { - "dashboard": "Dashboard", - "track": "Track", - "children": "Children", - "family": "Family", - "ai": "AI Assistant", - "analytics": "Analytics", - "settings": "Settings" - }, - "buttons": { - "save": "Save", - "cancel": "Cancel", - "delete": "Delete", - "edit": "Edit", - "add": "Add", - "submit": "Submit", - "back": "Back", - "next": "Next", - "confirm": "Confirm" - }, - "units": { - "metric": "Metric", - "imperial": "Imperial", - "ml": "ml", - "oz": "oz", - "cm": "cm", - "in": "in", - "kg": "kg", - "lb": "lb" - } -} -``` - ---- - -## Phase 3: Custom Hooks - -### 3.1 useTranslation Hook -**File**: `hooks/useTranslation.ts` (NEW) - -- Re-export from react-i18next with type safety -- Custom hook for easier usage - -### 3.2 useLocale Hook -**File**: `hooks/useLocale.ts` (NEW) - -- Get current locale -- Change locale -- Get available locales -- Get locale display name - -### 3.3 useFormatting Hook -**File**: `hooks/useFormatting.ts` (NEW) - -- Format dates based on locale -- Format numbers based on locale -- Format currency based on locale -- Format units based on preference - ---- - -## Phase 4: Measurement Unit Preference - -### 4.1 Backend Schema Update -**File**: `src/database/migrations/V0XX_add_measurement_preference.sql` (NEW) - -```sql -ALTER TABLE users ADD COLUMN measurement_unit VARCHAR(10) DEFAULT 'metric'; --- Values: 'metric' or 'imperial' -``` - -### 4.2 Update User Entity -**File**: `src/database/entities/user.entity.ts` (MODIFY) - -Add field: -```typescript -@Column({ name: 'measurement_unit', default: 'metric' }) -measurementUnit: 'metric' | 'imperial'; -``` - -### 4.3 Update User DTOs -**Files**: -- `src/modules/auth/dto/register.dto.ts` (MODIFY) -- `src/modules/auth/dto/update-profile.dto.ts` (MODIFY) - -Add optional `measurementUnit` field. - -### 4.4 API Endpoints -**File**: `src/modules/auth/auth.controller.ts` (MODIFY) - -- PATCH `/api/v1/auth/profile` - Include measurementUnit in update - ---- - -## Phase 5: Frontend User Preferences - -### 5.1 Redux State -**File**: `store/slices/userSlice.ts` (MODIFY) - -Add to user state: -```typescript -interface UserState { - // ... existing fields - language: string; - measurementUnit: 'metric' | 'imperial'; -} -``` - -### 5.2 Language Selector Component -**File**: `components/settings/LanguageSelector.tsx` (NEW) - -Features: -- Dropdown with 5 language options -- Flag icons for each language -- Updates user preference on change -- Persists to backend -- Updates i18n instance - -### 5.3 Measurement Unit Selector Component -**File**: `components/settings/MeasurementUnitSelector.tsx` (NEW) - -Features: -- Toggle or dropdown (Metric/Imperial) -- Updates user preference on change -- Persists to backend -- Shows example conversions - ---- - -## Phase 6: Onboarding Flow Integration - -### 6.1 Update Onboarding Page -**File**: `app/(auth)/onboarding/page.tsx` (MODIFY) - -Add new steps: -1. Language selection (Step 2) -2. Measurement unit selection (Step 3) - -### 6.2 Onboarding Language Step Component -**File**: `components/onboarding/LanguageStep.tsx` (NEW) - -- Large, visual language selector -- Show language names in native script -- Save to Redux state -- Update i18n immediately - -### 6.3 Onboarding Measurement Step Component -**File**: `components/onboarding/MeasurementStep.tsx` (NEW) - -- Visual metric/imperial selector -- Show examples (ml vs oz, cm vs in) -- Save to Redux state - -### 6.4 Update Onboarding API Call -**File**: `app/(auth)/onboarding/page.tsx` (MODIFY) - -Include language and measurementUnit in profile update call. - ---- - -## Phase 7: Settings Page Integration - -### 7.1 Update Settings Page -**File**: `app/settings/page.tsx` (MODIFY) - -Add new sections: -- **Language & Region** section - - Language selector - - Measurement unit selector - -### 7.2 Settings UI Components -**Files**: -- `components/settings/LanguageSettings.tsx` (NEW) -- `components/settings/MeasurementSettings.tsx` (NEW) - ---- - -## Phase 8: Unit Conversion Utilities - -### 8.1 Conversion Utility -**File**: `lib/units/conversions.ts` (NEW) - -Functions: -- `mlToOz(ml: number): number` -- `ozToMl(oz: number): number` -- `kgToLb(kg: number): number` -- `lbToKg(lb: number): number` -- `cmToIn(cm: number): number` -- `inToCm(in: number): number` - -### 8.2 Format Unit Hook -**File**: `hooks/useUnitFormat.ts` (NEW) - -- Get user's measurement preference -- Format value with correct unit -- Convert between units -- Display with locale-specific formatting - ---- - -## Phase 9: Apply Localization Throughout App - -### 9.1 Update All Pages -Replace hardcoded strings with translation keys: - -**Priority Pages**: -1. **Dashboard** (`app/page.tsx`) - - Nav items, headings, button labels - - Activity type labels - - Summary labels - -2. **Authentication** (`app/(auth)/`) - - Login, Register, Forgot Password - - Form labels, placeholders, errors - -3. **Tracking** (`app/track/`) - - Feeding, Sleep, Diaper pages - - Form labels, unit labels - - Apply unit conversions - -4. **Children** (`app/children/page.tsx`) - - Child management labels - - Form fields - -5. **Family** (`app/family/page.tsx`) - - Family management labels - -6. **AI Assistant** (`app/ai-assistant/page.tsx`) - - Chat interface labels - - Placeholder text - -7. **Analytics** (`app/analytics/page.tsx`) - - Chart labels, insights - -8. **Settings** (`app/settings/page.tsx`) - - All settings labels - -### 9.2 Update Components -Replace hardcoded strings in shared components: - -- `components/layouts/AppShell/` (navigation) -- `components/common/` (buttons, dialogs) -- `components/features/` (activity cards, etc.) - ---- - -## Phase 10: Date/Time Localization - -### 10.1 Date Formatting Utility -**File**: `lib/i18n/date-formats.ts` (NEW) - -Using date-fns with locales: -```typescript -import { format } from 'date-fns'; -import { enUS, es, fr, ptBR, zhCN } from 'date-fns/locale'; - -const locales = { en: enUS, es, fr, pt: ptBR, zh: zhCN }; - -export function formatDate(date: Date, formatStr: string, locale: string) { - return format(date, formatStr, { locale: locales[locale] }); -} -``` - -### 10.2 Update Date Displays -Apply locale-aware date formatting: -- Activity timestamps -- Child birth dates -- Analytics date ranges - ---- - -## Phase 11: Number Localization - -### 11.1 Number Formatting Utility -**File**: `lib/i18n/number-formats.ts` (NEW) - -Using Intl.NumberFormat: -```typescript -export function formatNumber(value: number, locale: string) { - return new Intl.NumberFormat(locale).format(value); -} - -export function formatDecimal(value: number, locale: string, decimals = 1) { - return new Intl.NumberFormat(locale, { - minimumFractionDigits: decimals, - maximumFractionDigits: decimals, - }).format(value); -} -``` - -### 11.2 Apply Number Formatting -- Activity amounts (ml/oz) -- Sleep duration (hours) -- Weight/height measurements - ---- - -## Phase 12: Tracking Forms with Unit Preferences - -### 12.1 Update Feeding Form -**File**: `app/track/feeding/page.tsx` (MODIFY) - -- Show ml or oz input based on preference -- Convert to metric for API storage -- Display in user's preferred unit - -### 12.2 Update Child Profile Form -**File**: `app/children/page.tsx` (MODIFY) - -- Weight input (kg/lb) -- Height input (cm/in) -- Convert for API storage - -### 12.3 Universal Input Component -**File**: `components/forms/UnitInput.tsx` (NEW) - -Props: -- `type: 'volume' | 'weight' | 'height'` -- `value: number` -- `onChange: (value: number) => void` -- Auto-convert based on user preference - ---- - -## Phase 13: Translation Files Content - -### 13.1 English Translations (Base) -**Estimate**: ~500-800 translation keys across all files - -Create complete English translations for: -- All UI strings -- All form labels/placeholders -- All error messages -- All validation messages - -### 13.2 Professional Translation -**Recommendation**: Use professional translation service for: -- Spanish (es-ES) -- French (fr-FR) -- Portuguese (pt-BR) -- Simplified Chinese (zh-CN) - -**Alternative**: Use AI-assisted translation + native speaker review - ---- - -## Phase 14: Testing - -### 14.1 Translation Coverage Test -- Verify all strings are externalized -- No hardcoded English strings remain -- All translation keys exist in all languages - -### 14.2 Language Switching Test -- Switch between all 5 languages -- Verify UI updates correctly -- Verify no layout breaks - -### 14.3 Unit Conversion Test -- Test all conversions (ml↔oz, kg↔lb, cm↔in) -- Verify correct rounding -- Verify storage in consistent units (metric) - -### 14.4 Date/Time Test -- Verify dates display correctly per locale -- Test all date formats (short, long, relative) - -### 14.5 RTL Support (Future) -**Note**: Chinese doesn't require RTL, but document for future Arabic support - ---- - -## Phase 15: Documentation - -### 15.1 Update Implementation Gaps -**File**: `docs/implementation-gaps.md` (MODIFY) - -Mark localization as ✅ COMPLETED - -### 15.2 Developer Guide -**File**: `docs/LOCALIZATION_GUIDE.md` (NEW) - -Document: -- How to add new translation keys -- How to add new languages -- Translation file structure -- Best practices - -### 15.3 Update User Documentation -Document language and measurement preferences in user guide - ---- - -## Implementation Order - -### Day 1: Framework & Structure -1. ✅ Install dependencies -2. ✅ Create i18n configuration -3. ✅ Create i18n provider -4. ✅ Create hooks (useTranslation, useLocale, useFormatting) -5. ✅ Set up translation file structure -6. ✅ Create English base translations (common, auth, dashboard) - -### Day 2: Preferences & Components -7. ✅ Backend schema update for measurementUnit -8. ✅ Update User entity and DTOs -9. ✅ Create LanguageSelector component -10. ✅ Create MeasurementUnitSelector component -11. ✅ Update onboarding flow -12. ✅ Update settings page -13. ✅ Create unit conversion utilities - -### Day 3: Apply Throughout App -14. ✅ Update all pages with translations -15. ✅ Apply unit conversions to tracking forms -16. ✅ Apply date/time localization -17. ✅ Complete all English translations -18. ✅ Test language switching -19. ✅ Test unit conversions - -### Post-Implementation (Optional) -20. Professional translation for other 4 languages -21. Native speaker review -22. Documentation updates - ---- - -## Key Files Checklist - -### New Files (27 total) -- [ ] `lib/i18n/config.ts` -- [ ] `components/providers/I18nProvider.tsx` -- [ ] `hooks/useLocale.ts` -- [ ] `hooks/useFormatting.ts` -- [ ] `hooks/useUnitFormat.ts` -- [ ] `lib/units/conversions.ts` -- [ ] `lib/i18n/date-formats.ts` -- [ ] `lib/i18n/number-formats.ts` -- [ ] `components/settings/LanguageSelector.tsx` -- [ ] `components/settings/MeasurementUnitSelector.tsx` -- [ ] `components/settings/LanguageSettings.tsx` -- [ ] `components/settings/MeasurementSettings.tsx` -- [ ] `components/onboarding/LanguageStep.tsx` -- [ ] `components/onboarding/MeasurementStep.tsx` -- [ ] `components/forms/UnitInput.tsx` -- [ ] `locales/en/*.json` (11 files) -- [ ] `locales/es/*.json` (11 files - future) -- [ ] `locales/fr/*.json` (11 files - future) -- [ ] `locales/pt/*.json` (11 files - future) -- [ ] `locales/zh/*.json` (11 files - future) -- [ ] `src/database/migrations/V0XX_add_measurement_preference.sql` -- [ ] `docs/LOCALIZATION_GUIDE.md` - -### Modified Files (15 total) -- [ ] `package.json` -- [ ] `app/layout.tsx` -- [ ] `store/slices/userSlice.ts` -- [ ] `src/database/entities/user.entity.ts` -- [ ] `src/modules/auth/dto/register.dto.ts` -- [ ] `src/modules/auth/dto/update-profile.dto.ts` -- [ ] `app/(auth)/onboarding/page.tsx` -- [ ] `app/settings/page.tsx` -- [ ] `app/page.tsx` (dashboard) -- [ ] `app/track/feeding/page.tsx` -- [ ] `app/track/sleep/page.tsx` -- [ ] `app/track/diaper/page.tsx` -- [ ] `app/children/page.tsx` -- [ ] `app/family/page.tsx` -- [ ] `docs/implementation-gaps.md` - ---- - -## Success Criteria - -### ✅ Functionality -- [ ] All 5 languages selectable and functional -- [ ] Language preference persists across sessions -- [ ] Measurement unit preference persists across sessions -- [ ] All UI strings externalized (no hardcoded English) -- [ ] Unit conversions work correctly (ml↔oz, kg↔lb, cm↔in) -- [ ] Dates display correctly per locale -- [ ] Numbers format correctly per locale - -### ✅ User Experience -- [ ] Language can be selected in onboarding -- [ ] Language can be changed in settings -- [ ] Measurement unit can be selected in onboarding -- [ ] Measurement unit can be changed in settings -- [ ] UI updates immediately when language changes -- [ ] No layout breaks when changing languages -- [ ] Form inputs show correct units based on preference - -### ✅ Technical -- [ ] All translation keys defined -- [ ] No missing translation warnings -- [ ] Type-safe translation usage (TypeScript) -- [ ] Backend stores preferences correctly -- [ ] Redux state syncs with backend - ---- - -## Notes - -### Translation Best Practices -1. Use namespaces to organize translations -2. Use interpolation for dynamic values: `t('welcome', { name })` -3. Use pluralization: `t('items', { count })` -4. Keep keys descriptive: `auth.login.emailLabel` not `auth.e1` -5. Avoid concatenation, use complete sentences - -### Unit Conversion Strategy -- **Storage**: Always store in metric (ml, kg, cm) in database -- **Display**: Convert to user's preferred unit for display -- **Input**: Accept user's preferred unit, convert to metric before API call -- **Consistency**: Ensure all measurements use the same preference - -### Performance Considerations -- Lazy load translation files per namespace -- Cache translations in browser -- Preload critical translations (common, errors) - -### Future Enhancements -- Add more languages (Arabic, German, Hindi, etc.) -- Add more units (temperature: °C/°F) -- Add regional date formats (MM/DD vs DD/MM) -- Add time format preferences (12h vs 24h) - ---- - -**Total Estimated Effort**: 2-3 days -**Complexity**: Medium -**Priority**: HIGH (Pre-Launch) -**Dependencies**: None (can start immediately) diff --git a/docs/.duckversions/LOCALIZATION_IMPLEMENTATION_PLAN-20251003115405.029.md b/docs/.duckversions/LOCALIZATION_IMPLEMENTATION_PLAN-20251003115405.029.md deleted file mode 100644 index 8949da6..0000000 --- a/docs/.duckversions/LOCALIZATION_IMPLEMENTATION_PLAN-20251003115405.029.md +++ /dev/null @@ -1,784 +0,0 @@ -# Localization Implementation Plan - -**Created**: October 3, 2025 -**Priority**: HIGH (Pre-Launch) -**Estimated Duration**: 2-3 days - -## Overview - -Implement comprehensive internationalization (i18n) support for the Maternal App with 5 languages and measurement unit preferences. - -## Supported Languages - -1. **English (en-US)** - Primary/Default -2. **Spanish (es-ES)** -3. **French (fr-FR)** -4. **Portuguese (pt-BR)** -5. **Simplified Chinese (zh-CN)** - -## Current Status - Updated October 3, 2025 - -### ✅ Already Completed (Backend) -- Backend multilanguage support for AI responses -- AI safety responses in 5 languages -- MultiLanguageService with language detection - -### ✅ Completed (Frontend - Phases 1-9) -- ✅ **Phase 1**: i18next framework installed and configured -- ✅ **Phase 2**: Translation files structure created (40 files: 5 languages × 8 namespaces) -- ✅ **Phase 3**: Custom hooks created (useTranslation, useLocale, useFormatting) -- ✅ **Phase 4**: Backend user schema updated with measurementUnit in preferences JSONB -- ✅ **Phase 5**: Language & measurement selectors in Settings page -- ✅ **Phase 7**: Settings page fully localized with preferences -- ✅ **Phase 8**: Measurement unit conversion utilities implemented -- ✅ **Phase 9**: Applied localization to core pages: - - Login & authentication pages - - Dashboard with welcome message, quick actions, summary - - Navigation (AppShell, MobileNav, TabBar) - - Track main page (activity selection) - - Children page (with age formatting & pluralization) - - All connection status indicators - -### ✅ Translation Files Created (40 files) -- `common.json` - UI strings, navigation, connection (all 5 languages) -- `auth.json` - Authentication pages (all 5 languages) -- `dashboard.json` - Dashboard/home page (all 5 languages) -- `tracking.json` - Activity tracking (all 5 languages) -- `children.json` - Child management (all 5 languages) -- `settings.json` - Settings page (all 5 languages) -- `ai.json` - AI assistant (all 5 languages) -- `errors.json` - Error messages (all 5 languages) - -### ⏳ Remaining To Be Implemented -- Language selector in onboarding flow (Phase 6) -- Individual tracking pages (feeding, sleep, diaper, medicine) with unit conversions (Phase 12) -- Family management page localization -- Analytics/insights page localization -- Date/time localization throughout app (Phase 10) -- Number formatting per locale (Phase 11) -- Professional translation review (Phase 13.2) -- Comprehensive testing (Phase 14) - ---- - -## Phase 1: Framework Setup ✅ COMPLETED - -### 1.1 Install Dependencies - latest versions only! ✅ -**Files**: `package.json` - -```bash -npm install i18next react-i18next i18next-browser-languagedetector -npm install date-fns # Already installed, confirm locales -``` - -**Packages**: -- `i18next` - Core i18n framework -- `react-i18next` - React bindings -- `i18next-browser-languagedetector` - Auto-detect user language - -### 1.2 Create i18n Configuration ✅ -**File**: `lib/i18n/config.ts` (CREATED) - -- ✅ Initialize i18next -- ✅ Configure language detector -- ✅ Set up fallback language (en-US) -- ✅ Configure interpolation -- ✅ Load translation resources - -### 1.3 Create i18n Provider ✅ -**File**: `components/providers/I18nProvider.tsx` (CREATED) - -- ✅ Wrap app with I18nextProvider -- ✅ Initialize i18n on mount -- ✅ Handle language loading states - -### 1.4 Update Root Layout ✅ -**File**: `app/layout.tsx` (MODIFIED) - -- ✅ Add I18nProvider to provider stack -- ⏳ Set html lang attribute dynamically (TODO) - ---- - -## Phase 2: Translation Files Structure ✅ COMPLETED - -### 2.1 Directory Structure -``` -locales/ -├── en/ -│ ├── common.json # Common UI strings (buttons, labels, etc.) -│ ├── auth.json # Authentication pages -│ ├── dashboard.json # Dashboard/home page -│ ├── tracking.json # Activity tracking -│ ├── children.json # Child management -│ ├── family.json # Family management -│ ├── ai.json # AI assistant -│ ├── analytics.json # Analytics/insights -│ ├── settings.json # Settings page -│ ├── onboarding.json # Onboarding flow -│ ├── errors.json # Error messages -│ └── validation.json # Form validation messages -├── es/ -│ └── [same structure] -├── fr/ -│ └── [same structure] -├── pt/ -│ └── [same structure] -└── zh/ - └── [same structure] -``` - -### 2.2 Translation Keys Structure - -**Example - common.json**: -```json -{ - "nav": { - "dashboard": "Dashboard", - "track": "Track", - "children": "Children", - "family": "Family", - "ai": "AI Assistant", - "analytics": "Analytics", - "settings": "Settings" - }, - "buttons": { - "save": "Save", - "cancel": "Cancel", - "delete": "Delete", - "edit": "Edit", - "add": "Add", - "submit": "Submit", - "back": "Back", - "next": "Next", - "confirm": "Confirm" - }, - "units": { - "metric": "Metric", - "imperial": "Imperial", - "ml": "ml", - "oz": "oz", - "cm": "cm", - "in": "in", - "kg": "kg", - "lb": "lb" - } -} -``` - ---- - -## Phase 3: Custom Hooks ✅ COMPLETED - -### 3.1 useTranslation Hook ✅ -**File**: `hooks/useTranslation.ts` (CREATED) - -- ✅ Re-export from react-i18next with type safety -- ✅ Custom hook for easier usage - -### 3.2 useLocale Hook ✅ -**File**: `hooks/useLocale.ts` (CREATED) - -- ✅ Get current locale -- ✅ Change locale -- ✅ Get available locales -- ✅ Get locale display name -- ✅ Measurement system management - -### 3.3 useFormatting Hook ✅ -**File**: `hooks/useFormatting.ts` (CREATED) - -- ✅ Format dates based on locale -- ✅ Format numbers based on locale -- ✅ Format currency based on locale -- ✅ Format units based on preference - ---- - -## Phase 4: Measurement Unit Preference ✅ COMPLETED - -### 4.1 Backend Schema Update ✅ -**Implementation**: Used existing `preferences` JSONB column from V005_add_user_preferences.sql -- No new migration needed - reused existing preferences column -- Added `measurementUnit` as optional field in preferences object - -### 4.2 Update User Entity ✅ -**File**: `src/database/entities/user.entity.ts` (MODIFIED) - -Added to preferences type: -```typescript -@Column({ type: 'jsonb', nullable: true }) -preferences?: { - notifications?: boolean; - emailUpdates?: boolean; - darkMode?: boolean; - measurementUnit?: 'metric' | 'imperial'; -}; -``` - -### 4.3 Update User DTOs ✅ -**File**: `src/modules/auth/dto/update-profile.dto.ts` (CREATED) - -Created with validation: -```typescript -export class UserPreferencesDto { - @IsOptional() - @IsIn(['metric', 'imperial']) - measurementUnit?: 'metric' | 'imperial'; -} -``` - -### 4.4 API Endpoints ✅ -**File**: `src/modules/auth/auth.controller.ts` (MODIFIED) - -- PATCH `/api/v1/auth/profile` - Updated to use UpdateProfileDto with measurementUnit support -- Properly typed and validated - ---- - -## Phase 5: Frontend User Preferences ✅ PARTIALLY COMPLETED - -### 5.1 Redux State ⏳ -**File**: `store/slices/userSlice.ts` (TODO) - -Add to user state: -```typescript -interface UserState { - // ... existing fields - language: string; - measurementUnit: 'metric' | 'imperial'; -} -``` - -### 5.2 Language Selector Component ✅ -**File**: `components/settings/LanguageSelector.tsx` (CREATED) - -Features: -- ✅ Dropdown with 5 language options -- ✅ Shows language names in native script -- ✅ Updates user preference on change -- ⏳ Persists to backend (pending backend schema) -- ✅ Updates i18n instance - -### 5.3 Measurement Unit Selector Component ✅ -**File**: `components/settings/MeasurementUnitSelector.tsx` (CREATED) - -Features: -- ✅ Dropdown (Metric/Imperial) -- ✅ Updates user preference on change -- ⏳ Persists to backend (pending backend schema) -- ✅ Shows unit examples - ---- - -## Phase 6: Onboarding Flow Integration ❌ TODO - -### 6.1 Update Onboarding Page -**File**: `app/(auth)/onboarding/page.tsx` (MODIFY) - -Add new steps: -1. Language selection (Step 2) -2. Measurement unit selection (Step 3) - -### 6.2 Onboarding Language Step Component -**File**: `components/onboarding/LanguageStep.tsx` (NEW) - -- Large, visual language selector -- Show language names in native script -- Save to Redux state -- Update i18n immediately - -### 6.3 Onboarding Measurement Step Component -**File**: `components/onboarding/MeasurementStep.tsx` (NEW) - -- Visual metric/imperial selector -- Show examples (ml vs oz, cm vs in) -- Save to Redux state - -### 6.4 Update Onboarding API Call -**File**: `app/(auth)/onboarding/page.tsx` (MODIFY) - -Include language and measurementUnit in profile update call. - ---- - -## Phase 7: Settings Page Integration ✅ COMPLETED - -### 7.1 Update Settings Page ✅ -**File**: `app/settings/page.tsx` (MODIFIED) - -Add new sections: -- ✅ **Preferences** section - - ✅ Language selector - - ✅ Measurement unit selector - -### 7.2 Settings UI Components ✅ -**Files**: -- ✅ `components/settings/LanguageSelector.tsx` (CREATED) -- ✅ `components/settings/MeasurementUnitSelector.tsx` (CREATED) - ---- - -## Phase 8: Unit Conversion Utilities ✅ COMPLETED - -### 8.1 Conversion Utility ✅ -**File**: `lib/utils/unitConversion.ts` (CREATED) - -Functions: -- ✅ `convertWeight` / `convertWeightToKg` -- ✅ `convertHeight` / `convertHeightToCm` -- ✅ `convertTemperature` / `convertTemperatureToCelsius` -- ✅ `convertVolume` / `convertVolumeToMl` -- ✅ `getUnitSymbol` -- ✅ `getConversionFactor` - -### 8.2 Format Unit Hook ✅ -**File**: `hooks/useFormatting.ts` (CREATED) - -- ✅ Get user's measurement preference -- ✅ Format value with correct unit -- ✅ Convert between units -- ✅ Display with locale-specific formatting - ---- - -## Phase 9: Apply Localization Throughout App ✅ PARTIALLY COMPLETED - -### 9.1 Update All Pages - Status - -**✅ Completed Priority Pages**: -1. ✅ **Dashboard** (`app/page.tsx`) - - Welcome message with user name interpolation - - Quick actions (all 6 activity cards) - - Today's summary with child name interpolation - - Next predicted activity with variable interpolation - - All UI labels translated in 5 languages - -2. ✅ **Authentication** (`app/(auth)/login/page.tsx`) - - Login form labels (email, password) - - Submit button, forgot password link - - Social login buttons (Google, Apple) - - Biometric authentication (Face ID/Touch ID) - - Sign up link and all helper text - -3. ✅ **Track Main Page** (`app/track/page.tsx`) - - Track Activity title and subtitle - - All 5 activity type labels (Feeding, Sleep, Diaper, Medicine, Activity) - - Translated in all 5 languages - -4. ✅ **Children** (`app/children/page.tsx`) - - Page title and subtitle - - Add/Edit child buttons - - Empty state messages - - Age calculation with proper pluralization (year/years, month/months) - - All error messages - - Gender labels - -**❌ Remaining Pages**: -5. ⏳ **Individual Tracking Pages** (`app/track/feeding/`, etc.) - - Feeding, Sleep, Diaper, Medicine detail pages - - Form labels, unit labels - - Apply unit conversions (Phase 12) - -6. ❌ **Family** (`app/family/page.tsx`) - - Family management labels - -7. ⏳ **AI Assistant** (`app/ai-assistant/page.tsx`) - - Chat interface already uses AI translations from backend - - Frontend labels may need localization - -8. ❌ **Analytics** (`app/analytics/page.tsx`) - - Chart labels, insights - -9. ✅ **Settings** (`app/settings/page.tsx`) - - Already completed in Phase 7 - -### 9.2 Update Components - Status - -**✅ Completed Components**: -- ✅ `components/layouts/AppShell/AppShell.tsx` - Connection status, presence indicators -- ✅ `components/layouts/MobileNav/MobileNav.tsx` - Navigation menu items, logout -- ✅ `components/layouts/TabBar/TabBar.tsx` - Bottom navigation tabs -- ✅ `components/settings/LanguageSelector.tsx` - Language preference UI -- ✅ `components/settings/MeasurementUnitSelector.tsx` - Measurement preference UI - -**❌ Remaining Components**: -- ⏳ `components/common/` - Common dialogs, buttons (may need review) -- ⏳ `components/features/` - Activity cards, forms (need review) -- ⏳ `components/children/` - Child dialogs (ChildDialog, DeleteConfirmDialog) -- ⏳ `components/family/` - Family components - ---- - -## Phase 10: Date/Time Localization - -### 10.1 Date Formatting Utility -**File**: `lib/i18n/date-formats.ts` (NEW) - -Using date-fns with locales: -```typescript -import { format } from 'date-fns'; -import { enUS, es, fr, ptBR, zhCN } from 'date-fns/locale'; - -const locales = { en: enUS, es, fr, pt: ptBR, zh: zhCN }; - -export function formatDate(date: Date, formatStr: string, locale: string) { - return format(date, formatStr, { locale: locales[locale] }); -} -``` - -### 10.2 Update Date Displays -Apply locale-aware date formatting: -- Activity timestamps -- Child birth dates -- Analytics date ranges - ---- - -## Phase 11: Number Localization - -### 11.1 Number Formatting Utility -**File**: `lib/i18n/number-formats.ts` (NEW) - -Using Intl.NumberFormat: -```typescript -export function formatNumber(value: number, locale: string) { - return new Intl.NumberFormat(locale).format(value); -} - -export function formatDecimal(value: number, locale: string, decimals = 1) { - return new Intl.NumberFormat(locale, { - minimumFractionDigits: decimals, - maximumFractionDigits: decimals, - }).format(value); -} -``` - -### 11.2 Apply Number Formatting -- Activity amounts (ml/oz) -- Sleep duration (hours) -- Weight/height measurements - ---- - -## Phase 12: Tracking Forms with Unit Preferences - -### 12.1 Update Feeding Form -**File**: `app/track/feeding/page.tsx` (MODIFY) - -- Show ml or oz input based on preference -- Convert to metric for API storage -- Display in user's preferred unit - -### 12.2 Update Child Profile Form -**File**: `app/children/page.tsx` (MODIFY) - -- Weight input (kg/lb) -- Height input (cm/in) -- Convert for API storage - -### 12.3 Universal Input Component -**File**: `components/forms/UnitInput.tsx` (NEW) - -Props: -- `type: 'volume' | 'weight' | 'height'` -- `value: number` -- `onChange: (value: number) => void` -- Auto-convert based on user preference - ---- - -## Phase 13: Translation Files Content - -### 13.1 English Translations (Base) -**Estimate**: ~500-800 translation keys across all files - -Create complete English translations for: -- All UI strings -- All form labels/placeholders -- All error messages -- All validation messages - -### 13.2 Professional Translation -**Recommendation**: Use professional translation service for: -- Spanish (es-ES) -- French (fr-FR) -- Portuguese (pt-BR) -- Simplified Chinese (zh-CN) - -**Alternative**: Use AI-assisted translation + native speaker review - ---- - -## Phase 14: Testing - -### 14.1 Translation Coverage Test -- Verify all strings are externalized -- No hardcoded English strings remain -- All translation keys exist in all languages - -### 14.2 Language Switching Test -- Switch between all 5 languages -- Verify UI updates correctly -- Verify no layout breaks - -### 14.3 Unit Conversion Test -- Test all conversions (ml↔oz, kg↔lb, cm↔in) -- Verify correct rounding -- Verify storage in consistent units (metric) - -### 14.4 Date/Time Test -- Verify dates display correctly per locale -- Test all date formats (short, long, relative) - -### 14.5 RTL Support (Future) -**Note**: Chinese doesn't require RTL, but document for future Arabic support - ---- - -## Phase 15: Documentation - -### 15.1 Update Implementation Gaps -**File**: `docs/implementation-gaps.md` (MODIFY) - -Mark localization as ✅ COMPLETED - -### 15.2 Developer Guide -**File**: `docs/LOCALIZATION_GUIDE.md` (NEW) - -Document: -- How to add new translation keys -- How to add new languages -- Translation file structure -- Best practices - -### 15.3 Update User Documentation -Document language and measurement preferences in user guide - ---- - -## Implementation Order - -### Day 1: Framework & Structure -1. ✅ Install dependencies -2. ✅ Create i18n configuration -3. ✅ Create i18n provider -4. ✅ Create hooks (useTranslation, useLocale, useFormatting) -5. ✅ Set up translation file structure -6. ✅ Create English base translations (common, auth, dashboard) - -### Day 2: Preferences & Components -7. ✅ Backend schema update for measurementUnit -8. ✅ Update User entity and DTOs -9. ✅ Create LanguageSelector component -10. ✅ Create MeasurementUnitSelector component -11. ✅ Update onboarding flow -12. ✅ Update settings page -13. ✅ Create unit conversion utilities - -### Day 3: Apply Throughout App -14. ✅ Update all pages with translations -15. ✅ Apply unit conversions to tracking forms -16. ✅ Apply date/time localization -17. ✅ Complete all English translations -18. ✅ Test language switching -19. ✅ Test unit conversions - -### Post-Implementation (Optional) -20. Professional translation for other 4 languages -21. Native speaker review -22. Documentation updates - ---- - -## Key Files Checklist - -### New Files (27 total) -- [ ] `lib/i18n/config.ts` -- [ ] `components/providers/I18nProvider.tsx` -- [ ] `hooks/useLocale.ts` -- [ ] `hooks/useFormatting.ts` -- [ ] `hooks/useUnitFormat.ts` -- [ ] `lib/units/conversions.ts` -- [ ] `lib/i18n/date-formats.ts` -- [ ] `lib/i18n/number-formats.ts` -- [ ] `components/settings/LanguageSelector.tsx` -- [ ] `components/settings/MeasurementUnitSelector.tsx` -- [ ] `components/settings/LanguageSettings.tsx` -- [ ] `components/settings/MeasurementSettings.tsx` -- [ ] `components/onboarding/LanguageStep.tsx` -- [ ] `components/onboarding/MeasurementStep.tsx` -- [ ] `components/forms/UnitInput.tsx` -- [ ] `locales/en/*.json` (11 files) -- [ ] `locales/es/*.json` (11 files - future) -- [ ] `locales/fr/*.json` (11 files - future) -- [ ] `locales/pt/*.json` (11 files - future) -- [ ] `locales/zh/*.json` (11 files - future) -- [ ] `src/database/migrations/V0XX_add_measurement_preference.sql` -- [ ] `docs/LOCALIZATION_GUIDE.md` - -### Modified Files (15 total) -- [ ] `package.json` -- [ ] `app/layout.tsx` -- [ ] `store/slices/userSlice.ts` -- [ ] `src/database/entities/user.entity.ts` -- [ ] `src/modules/auth/dto/register.dto.ts` -- [ ] `src/modules/auth/dto/update-profile.dto.ts` -- [ ] `app/(auth)/onboarding/page.tsx` -- [ ] `app/settings/page.tsx` -- [ ] `app/page.tsx` (dashboard) -- [ ] `app/track/feeding/page.tsx` -- [ ] `app/track/sleep/page.tsx` -- [ ] `app/track/diaper/page.tsx` -- [ ] `app/children/page.tsx` -- [ ] `app/family/page.tsx` -- [ ] `docs/implementation-gaps.md` - ---- - -## Success Criteria - -### ✅ Functionality -- [ ] All 5 languages selectable and functional -- [ ] Language preference persists across sessions -- [ ] Measurement unit preference persists across sessions -- [ ] All UI strings externalized (no hardcoded English) -- [ ] Unit conversions work correctly (ml↔oz, kg↔lb, cm↔in) -- [ ] Dates display correctly per locale -- [ ] Numbers format correctly per locale - -### ✅ User Experience -- [ ] Language can be selected in onboarding -- [ ] Language can be changed in settings -- [ ] Measurement unit can be selected in onboarding -- [ ] Measurement unit can be changed in settings -- [ ] UI updates immediately when language changes -- [ ] No layout breaks when changing languages -- [ ] Form inputs show correct units based on preference - -### ✅ Technical -- [ ] All translation keys defined -- [ ] No missing translation warnings -- [ ] Type-safe translation usage (TypeScript) -- [ ] Backend stores preferences correctly -- [ ] Redux state syncs with backend - ---- - -## Notes - -### Translation Best Practices -1. Use namespaces to organize translations -2. Use interpolation for dynamic values: `t('welcome', { name })` -3. Use pluralization: `t('items', { count })` -4. Keep keys descriptive: `auth.login.emailLabel` not `auth.e1` -5. Avoid concatenation, use complete sentences - -### Unit Conversion Strategy -- **Storage**: Always store in metric (ml, kg, cm) in database -- **Display**: Convert to user's preferred unit for display -- **Input**: Accept user's preferred unit, convert to metric before API call -- **Consistency**: Ensure all measurements use the same preference - -### Performance Considerations -- Lazy load translation files per namespace -- Cache translations in browser -- Preload critical translations (common, errors) - -### Future Enhancements -- Add more languages (Arabic, German, Hindi, etc.) -- Add more units (temperature: °C/°F) -- Add regional date formats (MM/DD vs DD/MM) -- Add time format preferences (12h vs 24h) - ---- - -## Remaining Tasks Summary - -### 🔴 High Priority (Core Functionality) - -1. **Individual Tracking Pages with Unit Conversions** (Phase 12) - - `/app/track/feeding/page.tsx` - Volume conversion (ml ↔ oz) - - `/app/track/sleep/page.tsx` - Duration formatting - - `/app/track/diaper/page.tsx` - Type labels - - `/app/track/medicine/page.tsx` - Dosage with units - - Implement UnitInput component for automatic conversion - - **Estimated Effort**: 4-6 hours - -2. **Child Dialog Components Localization** - - `components/children/ChildDialog.tsx` - Form labels - - `components/children/DeleteConfirmDialog.tsx` - Confirmation text - - **Estimated Effort**: 1 hour - -3. **Date/Time Localization** (Phase 10) - - Apply date-fns with locale to all date displays - - Activity timestamps - - Child birth dates - - Analytics date ranges - - **Estimated Effort**: 2-3 hours - -### 🟡 Medium Priority (Nice to Have) - -4. **Onboarding Flow** (Phase 6) - - Add language selection step - - Add measurement unit selection step - - Save preferences during onboarding - - **Estimated Effort**: 2-3 hours - -5. **Family Management Page** - - `app/family/page.tsx` localization - - Family member labels, invitation flow - - **Estimated Effort**: 1-2 hours - -6. **Number Formatting** (Phase 11) - - Apply Intl.NumberFormat throughout - - Weight/height values - - Activity counts - - **Estimated Effort**: 1-2 hours - -### 🟢 Low Priority (Future Enhancements) - -7. **Analytics/Insights Page** - - Chart labels - - Insight descriptions - - **Estimated Effort**: 2-3 hours - -8. **Professional Translation Review** (Phase 13.2) - - Review all 4 non-English languages - - Native speaker validation - - Cultural appropriateness check - - **Estimated Effort**: External service, 1-2 weeks - -9. **Comprehensive Testing** (Phase 14) - - Translation coverage test - - Language switching test - - Unit conversion test - - Date/time formatting test - - **Estimated Effort**: 2-4 hours - -10. **Documentation** (Phase 15) - - Create LOCALIZATION_GUIDE.md - - Update implementation-gaps.md - - Developer best practices - - **Estimated Effort**: 1-2 hours - -### 📊 Progress Tracking - -**Completed**: 9 phases (1-5, 7-9) -**In Progress**: 0 phases -**Remaining**: 6 major phases (6, 10-15) - -**Overall Completion**: ~65% (core functionality) - -**Estimated Time to Full Completion**: -- High Priority: 8-11 hours -- Medium Priority: 4-7 hours -- Low Priority: 5-9 hours -- **Total Remaining**: 17-27 hours (2-3.5 days) - ---- - -**Total Project Effort**: 2-3 days (completed) + 2-3.5 days (remaining) = 4-6.5 days -**Complexity**: Medium -**Priority**: HIGH (Pre-Launch) -**Current Status**: Core functionality 65% complete, production-ready for MVP diff --git a/docs/ADMIN_DASHBOARD_IMPLEMENTATION.md b/docs/ADMIN_DASHBOARD_IMPLEMENTATION.md deleted file mode 100644 index 5c08bfe..0000000 --- a/docs/ADMIN_DASHBOARD_IMPLEMENTATION.md +++ /dev/null @@ -1,1681 +0,0 @@ -# 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 ( - - - - {currentProfile.name} - - - {profiles.map(profile => ( - switchProfile(profile.id)} - isActive={profile.id === currentProfile.id} - > - - - {profile.name} - - {profile.familyName} · {profile.role} - - - - ))} - - router.push('/add-profile')}> - + Add Profile - - - - ); -} -``` - -**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 - # Dedicated PostgreSQL Server - DATABASE_URL: postgresql://postgres:a3ppq@10.0.0.207:5432/parentflow - DATABASE_HOST: 10.0.0.207 - DATABASE_PORT: 5432 - DATABASE_NAME: parentflow - DATABASE_USER: postgres - DATABASE_PASSWORD: a3ppq - # Redis on 10.0.0.240 - REDIS_HOST: 10.0.0.240 - REDIS_PORT: 6379 - # MongoDB on 10.0.0.240 - MONGODB_URI: mongodb://parentflow_admin:parentflow_mongo_password_2024@10.0.0.240:27017/parentflow_ai_chat?authSource=admin - # Auth keys - JWT_SECRET: ${ADMIN_JWT_SECRET} - SERVICE_AUTH_KEY: ${SERVICE_AUTH_KEY} # For service-to-service auth - networks: - - parentflow-network - extra_hosts: - - "host.docker.internal:host-gateway" # For accessing host services - - 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 - REACT_APP_MAIN_APP_URL: https://web.parentflowapp.com - 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: Connects to dedicated PostgreSQL server -│ -├── 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 -│ -├── Database Infrastructure -│ ├── PostgreSQL: 10.0.0.207:5432 -│ │ ├── Database: parentflow -│ │ ├── User: postgres -│ │ └── Password: a3ppq -│ │ -│ └── Docker on 10.0.0.240 -│ ├── Redis: Port 6379 -│ ├── MongoDB: Port 27017 -│ └── MinIO: Ports 9000/9001 -│ -└── Nginx Proxy Server (Separate) - ├── SSL certificates configured - └── Reverse proxy for all domains -``` - ---- - -## 🚀 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 diff --git a/docs/API_GATEWAY_ARCHITECTURE.md b/docs/API_GATEWAY_ARCHITECTURE.md deleted file mode 100644 index 0d1d197..0000000 --- a/docs/API_GATEWAY_ARCHITECTURE.md +++ /dev/null @@ -1,943 +0,0 @@ - -# API Gateway Architecture & Security Implementation Plan - -**Created**: October 3, 2025 -**Status**: Planning Phase -**Priority**: High - Security & Scalability - ---- - -## 📋 Executive Summary - -### Current State -- **Backend API**: Directly exposed to internet at `https://maternal-api.noru1.ro` -- **Frontend**: Next.js web app making direct API calls from browser -- **Security Risk**: All API endpoints publicly accessible -- **Architecture**: Monolithic - single NestJS backend serving REST, GraphQL, and WebSocket - -### Problem Statement -With the current architecture: -1. Backend API is fully exposed to the internet (security risk) -2. No rate limiting at infrastructure level -3. Direct API access bypasses Next.js middleware/auth checks -4. Future mobile apps will need direct API access -5. WebSocket connections need persistent connection handling -6. GraphQL endpoint requires different security model than REST - -### Proposed Solution -Implement an **API Gateway pattern** with: -- Next.js API routes as BFF (Backend-for-Frontend) for web app -- Direct backend access for mobile apps (with API key + JWT) -- Nginx/Kong as reverse proxy for rate limiting and SSL termination -- WebSocket gateway for real-time features -- Separate security policies for REST vs GraphQL - ---- - -## 🏗️ Architecture Overview - -### Option 1: Next.js API Routes as BFF (Recommended for MVP) - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Internet (HTTPS) │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ - ┌─────────────────┐ - │ Nginx/Cloudflare│ - │ (SSL, WAF, DDoS) │ - └─────────────────┘ - │ - ┌─────────────┴─────────────┐ - │ │ - ▼ ▼ - ┌───────────────────────┐ ┌─────────────────────┐ - │ Next.js Frontend │ │ Mobile Apps │ - │ (Port 3030) │ │ (iOS/Android) │ - │ │ │ │ - │ ┌─────────────────┐ │ └─────────────────────┘ - │ │ /api/* Routes │ │ │ - │ │ (BFF Layer) │ │ │ - │ └─────────────────┘ │ │ - └───────────────────────┘ │ - │ │ - │ (Internal Network) │ (Public API) - │ localhost:3020 │ api.maternal.com - │ │ - └──────────┬───────────────┘ - ▼ - ┌─────────────────────────┐ - │ NestJS Backend │ - │ (Port 3020) │ - │ │ - │ ┌───────────────────┐ │ - │ │ REST API │ │ - │ │ /api/v1/* │ │ - │ └───────────────────┘ │ - │ │ - │ ┌───────────────────┐ │ - │ │ GraphQL │ │ - │ │ /graphql │ │ - │ └───────────────────┘ │ - │ │ - │ ┌───────────────────┐ │ - │ │ WebSocket │ │ - │ │ /ws │ │ - │ └───────────────────┘ │ - └─────────────────────────┘ - │ - ▼ - ┌──────────────────┐ - │ PostgreSQL │ - │ Redis │ - │ MongoDB │ - └──────────────────┘ -``` - -### Option 2: Kong API Gateway (Production-Ready) - -``` -┌─────────────────────────────────────────────────────────────┐ -│ Internet (HTTPS) │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ - ┌─────────────────────┐ - │ Kong API Gateway │ - │ (Port 443/8000) │ - │ │ - │ Plugins: │ - │ - Rate Limiting │ - │ - JWT Auth │ - │ - CORS │ - │ - Request Transform │ - │ - Response Cache │ - └─────────────────────┘ - │ - ┌─────────────┴─────────────┐ - │ │ - ▼ ▼ - ┌───────────────────────┐ ┌─────────────────────┐ - │ Next.js Frontend │ │ Mobile Apps │ - │ (Internal) │ │ (External) │ - └───────────────────────┘ └─────────────────────┘ - │ │ - └──────────┬───────────────┘ - ▼ - ┌─────────────────────────┐ - │ NestJS Backend │ - │ (Internal Network) │ - │ Not exposed to web │ - └─────────────────────────┘ -``` - ---- - -## 🎯 Recommended Architecture: Hybrid Approach - -### Phase 1: MVP (Current State + BFF) -1. **Web App**: Next.js API routes as BFF (proxy to backend) -2. **Mobile Apps**: Direct backend access with API keys -3. **Backend**: Exposed only to mobile, hidden from web -4. **Timeline**: 1-2 weeks - -### Phase 2: Production (Kong Gateway) -1. **All Clients**: Route through Kong API Gateway -2. **Backend**: Completely internal, not exposed -3. **Security**: Centralized auth, rate limiting, logging -4. **Timeline**: 4-6 weeks (post-MVP) - ---- - -## 📝 Implementation Plan: Phase 1 (BFF Pattern) - -### Step 1: Create Next.js API Routes as BFF - -**Goal**: Proxy all backend requests through Next.js to hide backend URL - -**Files to Create**: -``` -maternal-web/ -├── app/api/ -│ ├── proxy/ -│ │ ├── route.ts # Generic proxy handler -│ │ └── [...path]/route.ts # Catch-all proxy -│ ├── graphql/ -│ │ └── route.ts # GraphQL proxy -│ └── ws/ -│ └── route.ts # WebSocket upgrade handler -``` - -**Implementation**: - -#### 1.1 Generic REST API Proxy - -**File**: `maternal-web/app/api/proxy/[...path]/route.ts` - -```typescript -import { NextRequest, NextResponse } from 'next/server'; - -const BACKEND_URL = process.env.BACKEND_API_URL || 'http://localhost:3020'; - -export async function GET( - request: NextRequest, - { params }: { params: { path: string[] } } -) { - return proxyRequest(request, params.path, 'GET'); -} - -export async function POST( - request: NextRequest, - { params }: { params: { path: string[] } } -) { - return proxyRequest(request, params.path, 'POST'); -} - -export async function PATCH( - request: NextRequest, - { params }: { params: { path: string[] } } -) { - return proxyRequest(request, params.path, 'PATCH'); -} - -export async function DELETE( - request: NextRequest, - { params }: { params: { path: string[] } } -) { - return proxyRequest(request, params.path, 'DELETE'); -} - -async function proxyRequest( - request: NextRequest, - pathSegments: string[], - method: string -) { - const path = pathSegments.join('/'); - const url = new URL(request.url); - const backendUrl = `${BACKEND_URL}/api/v1/${path}${url.search}`; - - // Forward headers (excluding host) - const headers = new Headers(); - request.headers.forEach((value, key) => { - if (key.toLowerCase() !== 'host' && key.toLowerCase() !== 'connection') { - headers.set(key, value); - } - }); - - // Add internal API key for backend authentication - headers.set('X-Internal-API-Key', process.env.INTERNAL_API_KEY || ''); - - try { - const body = method !== 'GET' ? await request.text() : undefined; - - const response = await fetch(backendUrl, { - method, - headers, - body, - }); - - // Forward response headers - const responseHeaders = new Headers(); - response.headers.forEach((value, key) => { - responseHeaders.set(key, value); - }); - - const responseBody = await response.text(); - - return new NextResponse(responseBody, { - status: response.status, - statusText: response.statusText, - headers: responseHeaders, - }); - } catch (error) { - console.error('Proxy error:', error); - return NextResponse.json( - { error: 'Internal proxy error' }, - { status: 502 } - ); - } -} -``` - -#### 1.2 GraphQL Proxy - -**File**: `maternal-web/app/api/graphql/route.ts` - -```typescript -import { NextRequest, NextResponse } from 'next/server'; - -const BACKEND_URL = process.env.BACKEND_API_URL || 'http://localhost:3020'; - -export async function POST(request: NextRequest) { - const backendUrl = `${BACKEND_URL}/graphql`; - - const headers = new Headers(); - headers.set('Content-Type', 'application/json'); - headers.set('Authorization', request.headers.get('Authorization') || ''); - headers.set('X-Internal-API-Key', process.env.INTERNAL_API_KEY || ''); - - try { - const body = await request.text(); - - const response = await fetch(backendUrl, { - method: 'POST', - headers, - body, - }); - - const responseBody = await response.text(); - - return new NextResponse(responseBody, { - status: response.status, - headers: { - 'Content-Type': 'application/json', - }, - }); - } catch (error) { - console.error('GraphQL proxy error:', error); - return NextResponse.json( - { errors: [{ message: 'GraphQL proxy error' }] }, - { status: 502 } - ); - } -} - -// Support GraphQL Playground in development -export async function GET(request: NextRequest) { - if (process.env.NODE_ENV !== 'production') { - const backendUrl = `${BACKEND_URL}/graphql`; - const response = await fetch(backendUrl); - const html = await response.text(); - return new NextResponse(html, { - headers: { 'Content-Type': 'text/html' }, - }); - } - - return NextResponse.json( - { error: 'GraphQL Playground disabled in production' }, - { status: 403 } - ); -} -``` - -#### 1.3 WebSocket Proxy (Next.js Limitation Workaround) - -**Note**: Next.js API routes don't support WebSocket upgrades directly. We need to use a custom server or keep WebSocket on backend. - -**Option A**: Keep WebSocket endpoint on backend (simpler) -**Option B**: Use Next.js custom server with `ws` library (complex) - -**Recommended**: Keep WebSocket on backend, add authentication layer - -**File**: `maternal-app-backend/src/families/families.gateway.ts` (modify) - -```typescript -import { WebSocketGateway, WebSocketServer, OnGatewayConnection } from '@nestjs/websockets'; -import { Server, Socket } from 'socket.io'; - -@WebSocketGateway({ - cors: { - origin: [ - 'http://localhost:3030', - 'https://maternal.noru1.ro', - 'https://maternal-web.noru1.ro', - ], - credentials: true, - }, -}) -export class FamiliesGateway implements OnGatewayConnection { - @WebSocketServer() - server: Server; - - async handleConnection(client: Socket) { - // Verify internal API key or JWT token - const apiKey = client.handshake.headers['x-internal-api-key']; - const token = client.handshake.auth.token; - - if (!apiKey && !token) { - client.disconnect(); - return; - } - - // Authenticate based on mobile (token) or web (API key) - const isValid = await this.validateConnection(apiKey, token); - if (!isValid) { - client.disconnect(); - } - } -} -``` - ---- - -### Step 2: Update Frontend to Use BFF - -**Files to Modify**: -- `lib/api/client.ts` -- `lib/apollo-client.ts` -- All API utility files - -**Changes**: - -```typescript -// lib/api/client.ts (before) -const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3020'; - -// lib/api/client.ts (after) -const API_BASE_URL = '/api/proxy'; // Use Next.js BFF - -// lib/apollo-client.ts (before) -uri: process.env.NEXT_PUBLIC_GRAPHQL_URL || 'http://localhost:3020/graphql', - -// lib/apollo-client.ts (after) -uri: '/api/graphql', // Use Next.js GraphQL proxy -``` - -**Environment Variables**: -```bash -# maternal-web/.env.local -# Remove NEXT_PUBLIC_API_URL (security - don't expose backend URL to browser) -# NEXT_PUBLIC_API_URL=https://maternal-api.noru1.ro # DELETE THIS - -# Add backend URL for server-side only -BACKEND_API_URL=http://localhost:3020 -INTERNAL_API_KEY=your-secret-internal-key-12345 - -# For WebSocket, keep exposed for now (will secure later) -NEXT_PUBLIC_WS_URL=https://maternal-api.noru1.ro -``` - ---- - -### Step 3: Add Internal API Key Authentication to Backend - -**Goal**: Backend validates requests from Next.js BFF using internal API key - -**File**: `maternal-app-backend/src/common/guards/internal-api-key.guard.ts` (new) - -```typescript -import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -@Injectable() -export class InternalApiKeyGuard implements CanActivate { - constructor(private configService: ConfigService) {} - - canActivate(context: ExecutionContext): boolean { - const request = context.switchToHttp().getRequest(); - const apiKey = request.headers['x-internal-api-key']; - const expectedKey = this.configService.get('INTERNAL_API_KEY'); - - if (!expectedKey) { - // If not configured, allow (development mode) - return true; - } - - if (apiKey !== expectedKey) { - throw new UnauthorizedException('Invalid internal API key'); - } - - return true; - } -} -``` - -**Usage** (apply to all controllers): - -```typescript -import { Controller, UseGuards } from '@nestjs/common'; -import { InternalApiKeyGuard } from '../common/guards/internal-api-key.guard'; - -@Controller('api/v1/children') -@UseGuards(InternalApiKeyGuard) // Add this to all controllers -export class ChildrenController { - // ... -} -``` - ---- - -### Step 4: Configure Mobile App Direct Access - -**Goal**: Mobile apps bypass BFF and call backend directly with API key + JWT - -**Backend Configuration**: - -```typescript -// app.module.ts -app.enableCors({ - origin: [ - 'http://localhost:3030', // Next.js dev - 'https://maternal.noru1.ro', // Production web - 'capacitor://localhost', // iOS mobile - 'http://localhost', // Android mobile - 'ionic://localhost', // Ionic mobile - ], - credentials: true, -}); -``` - -**Mobile App Configuration** (future): - -```typescript -// mobile-app/src/config/api.ts -const API_CONFIG = { - baseUrl: 'https://api.maternal.noru1.ro', // Direct backend access - graphqlUrl: 'https://api.maternal.noru1.ro/graphql', - wsUrl: 'wss://api.maternal.noru1.ro', - headers: { - 'X-API-Key': process.env.MOBILE_API_KEY, // Different from internal key - }, -}; -``` - ---- - -### Step 5: Nginx Configuration for Production - -**Goal**: Use Nginx as reverse proxy for SSL termination and basic security - -**File**: `/etc/nginx/sites-available/maternal-app` - -```nginx -# Upstream backends -upstream nextjs_backend { - server 127.0.0.1:3030; -} - -upstream nestjs_backend { - server 127.0.0.1:3020; -} - -# Redirect HTTP to HTTPS -server { - listen 80; - server_name maternal.noru1.ro; - return 301 https://$server_name$request_uri; -} - -# Main web application (Next.js) -server { - listen 443 ssl http2; - server_name maternal.noru1.ro; - - ssl_certificate /etc/letsencrypt/live/maternal.noru1.ro/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/maternal.noru1.ro/privkey.pem; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Content-Type-Options "nosniff" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header Referrer-Policy "strict-origin-when-cross-origin" always; - - # Rate limiting - limit_req_zone $binary_remote_addr zone=web_limit:10m rate=100r/m; - limit_req zone=web_limit burst=20 nodelay; - - location / { - proxy_pass http://nextjs_backend; - 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; - 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; - } -} - -# API backend (for mobile apps only - optional) -server { - listen 443 ssl http2; - server_name api.maternal.noru1.ro; - - ssl_certificate /etc/letsencrypt/live/api.maternal.noru1.ro/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/api.maternal.noru1.ro/privkey.pem; - - # Stricter rate limiting for API - limit_req_zone $binary_remote_addr zone=api_limit:10m rate=60r/m; - limit_req zone=api_limit burst=10 nodelay; - - # Only allow mobile app user agents (optional) - if ($http_user_agent !~* (Maternal-iOS|Maternal-Android|curl)) { - return 403; - } - - location / { - proxy_pass http://nestjs_backend; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } - - # WebSocket support - location /ws { - proxy_pass http://nestjs_backend; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; - } -} -``` - ---- - -## 🔒 Security Enhancements - -### 1. API Key Management - -**Environment Variables**: -```bash -# Backend (.env.production) -INTERNAL_API_KEY= -MOBILE_API_KEY= - -# Next.js (.env.local) -INTERNAL_API_KEY= -BACKEND_API_URL=http://localhost:3020 # or internal network IP -``` - -**Generation**: -```bash -# Generate secure API keys -openssl rand -base64 32 -``` - ---- - -### 2. Rate Limiting Strategy - -| Client Type | Rate Limit | Enforcement | -|-------------|------------|-------------| -| Web (BFF) | 100 req/min per IP | Nginx | -| Mobile (Direct) | 60 req/min per API key | Nginx + NestJS | -| GraphQL | 30 queries/min | NestJS middleware | -| WebSocket | 10 connections per user | NestJS gateway | - -**Implementation** (NestJS): - -```typescript -// src/common/middleware/rate-limit.middleware.ts -import { Injectable, NestMiddleware } from '@nestjs/common'; -import { Request, Response, NextFunction } from 'express'; -import { Redis } from 'ioredis'; - -@Injectable() -export class ApiKeyRateLimitMiddleware implements NestMiddleware { - constructor(private redis: Redis) {} - - async use(req: Request, res: Response, next: NextFunction) { - const apiKey = req.headers['x-api-key']; - - if (!apiKey) { - return next(); - } - - const key = `rate_limit:api_key:${apiKey}`; - const count = await this.redis.incr(key); - - if (count === 1) { - await this.redis.expire(key, 60); // 1 minute window - } - - if (count > 60) { - return res.status(429).json({ - error: 'Rate limit exceeded', - retryAfter: await this.redis.ttl(key), - }); - } - - next(); - } -} -``` - ---- - -### 3. CORS Configuration - -**Strict CORS for Production**: - -```typescript -// main.ts -app.enableCors({ - origin: (origin, callback) => { - const allowedOrigins = [ - 'https://maternal.noru1.ro', - 'https://maternal-web.noru1.ro', - ]; - - // Allow mobile apps (check user agent) - if (!origin || allowedOrigins.includes(origin)) { - callback(null, true); - } else if (origin.includes('capacitor://')) { - callback(null, true); // Ionic/Capacitor - } else { - callback(new Error('Not allowed by CORS')); - } - }, - credentials: true, - methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], - allowedHeaders: [ - 'Content-Type', - 'Authorization', - 'X-API-Key', - 'X-Internal-API-Key', - ], -}); -``` - ---- - -## 📱 Mobile App Integration - -### React Native / Expo Configuration - -```typescript -// mobile-app/src/services/api.ts -import axios from 'axios'; -import Constants from 'expo-constants'; - -const API_CONFIG = { - baseURL: Constants.expoConfig?.extra?.apiUrl || 'https://api.maternal.noru1.ro', - headers: { - 'X-API-Key': Constants.expoConfig?.extra?.apiKey, - 'User-Agent': `Maternal-${Platform.OS}/${Constants.expoConfig?.version}`, - }, -}; - -const apiClient = axios.create(API_CONFIG); - -// Add JWT token to requests -apiClient.interceptors.request.use((config) => { - const token = getAuthToken(); // From AsyncStorage - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - return config; -}); -``` - -**WebSocket Connection** (mobile): - -```typescript -import io from 'socket.io-client'; - -const socket = io('wss://api.maternal.noru1.ro', { - auth: { - token: getAuthToken(), - }, - transports: ['websocket'], - reconnection: true, - reconnectionAttempts: 5, -}); -``` - ---- - -## 🔍 Monitoring & Logging - -### 1. Request Logging (Nginx) - -```nginx -log_format api_log '$remote_addr - $remote_user [$time_local] ' - '"$request" $status $body_bytes_sent ' - '"$http_referer" "$http_user_agent" ' - 'api_key=$http_x_api_key ' - 'request_time=$request_time'; - -access_log /var/log/nginx/maternal_api_access.log api_log; -``` - -### 2. Backend Request Tracking - -```typescript -// src/common/middleware/request-logger.middleware.ts -import { Injectable, NestMiddleware, Logger } from '@nestjs/common'; - -@Injectable() -export class RequestLoggerMiddleware implements NestMiddleware { - private logger = new Logger('HTTP'); - - use(req: Request, res: Response, next: NextFunction) { - const { method, originalUrl, headers } = req; - const userAgent = headers['user-agent']; - const apiKey = headers['x-api-key']; - const isInternal = headers['x-internal-api-key'] ? 'internal' : 'external'; - - const start = Date.now(); - - res.on('finish', () => { - const { statusCode } = res; - const duration = Date.now() - start; - - this.logger.log( - `${method} ${originalUrl} ${statusCode} ${duration}ms - ${isInternal} - ${apiKey?.substring(0, 8)}...` - ); - }); - - next(); - } -} -``` - ---- - -## 🚀 Deployment Strategy - -### Phase 1: MVP Deployment (Week 1-2) - -**Week 1**: -- [x] Create Next.js API proxy routes -- [x] Update frontend to use BFF -- [x] Add internal API key guard to backend -- [x] Test web app with new architecture - -**Week 2**: -- [x] Configure Nginx reverse proxy -- [x] Set up SSL certificates -- [x] Deploy to production -- [x] Monitor and fix issues - -### Phase 2: Mobile App Support (Week 3-4) - -**Week 3**: -- [ ] Create mobile API keys -- [ ] Configure CORS for mobile -- [ ] Set up mobile-specific rate limits -- [ ] Test with React Native/Expo - -**Week 4**: -- [ ] Add mobile user agent detection -- [ ] Implement mobile analytics -- [ ] Load testing with mobile traffic -- [ ] Documentation for mobile devs - -### Phase 3: Kong Gateway (Month 2-3) - -**Month 2**: -- [ ] Set up Kong API Gateway -- [ ] Configure plugins (rate limit, JWT, logging) -- [ ] Migrate Next.js BFF to Kong routes -- [ ] Test parallel deployment - -**Month 3**: -- [ ] Full cutover to Kong -- [ ] Remove Next.js BFF (optional) -- [ ] Advanced features (caching, GraphQL federation) -- [ ] Performance optimization - ---- - -## 📊 Performance Considerations - -### Latency Impact - -| Architecture | Latency | Notes | -|--------------|---------|-------| -| Direct Backend | 50-100ms | Current (baseline) | -| Next.js BFF | +20-40ms | Acceptable for web | -| Kong Gateway | +10-20ms | Production-optimized | - -### Caching Strategy - -**Next.js Edge Caching**: -```typescript -// app/api/proxy/[...path]/route.ts -export const revalidate = 60; // Cache for 60 seconds - -// Or per-route -if (path.startsWith('children')) { - return NextResponse.json(data, { - headers: { - 'Cache-Control': 'public, s-maxage=300, stale-while-revalidate=600', - }, - }); -} -``` - -**Redis Caching** (backend): -```typescript -// Already implemented in backend -@UseInterceptors(CacheInterceptor) -@CacheTTL(300) -async getChildren() { - // ... -} -``` - ---- - -## ✅ Acceptance Criteria - -### Security -- [ ] Backend not directly accessible from browser (except WebSocket for now) -- [ ] Internal API key required for BFF → Backend -- [ ] Mobile API key required for mobile → Backend -- [ ] Rate limiting enforced at Nginx and NestJS levels -- [ ] CORS configured for web and mobile origins -- [ ] SSL/TLS for all external connections - -### Functionality -- [ ] Web app works through BFF without code changes to components -- [ ] GraphQL queries work through proxy -- [ ] WebSocket connections remain stable -- [ ] Mobile apps can connect directly to backend -- [ ] Real-time sync works across web and mobile - -### Performance -- [ ] Latency increase < 50ms for BFF -- [ ] No degradation in WebSocket performance -- [ ] API response times within SLA (<200ms p95) - -### Monitoring -- [ ] Request logs include API key and source -- [ ] Rate limit violations logged -- [ ] Error tracking for proxy failures -- [ ] Metrics dashboard shows BFF vs direct traffic - ---- - -## 🔧 Troubleshooting - -### Common Issues - -**1. WebSocket Connections Failing** -- **Symptom**: Socket.io connection refused -- **Fix**: Ensure WebSocket endpoint bypasses BFF (direct backend connection) -- **Config**: Update `NEXT_PUBLIC_WS_URL` to backend URL - -**2. CORS Errors on Mobile** -- **Symptom**: OPTIONS preflight fails -- **Fix**: Add mobile origins to CORS whitelist -- **Config**: Check `capacitor://localhost` is allowed - -**3. Rate Limiting Too Aggressive** -- **Symptom**: 429 errors during normal usage -- **Fix**: Adjust Nginx `limit_req` or NestJS throttler -- **Config**: Increase burst size or rate - -**4. GraphQL Subscriptions Not Working** -- **Symptom**: Subscriptions disconnect immediately -- **Fix**: GraphQL subscriptions need WebSocket, can't go through HTTP proxy -- **Solution**: Use Apollo Client with split link (HTTP for queries, WS for subscriptions) - ---- - -## 📚 References - -- [Next.js API Routes Documentation](https://nextjs.org/docs/api-routes/introduction) -- [Kong API Gateway](https://konghq.com/products/kong-gateway) -- [Nginx Reverse Proxy Guide](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) -- [NestJS Guards](https://docs.nestjs.com/guards) -- [Socket.io CORS Configuration](https://socket.io/docs/v4/handling-cors/) - ---- - -**Last Updated**: October 3, 2025 -**Review Date**: Post-MVP Launch -**Owner**: Backend Team diff --git a/docs/DATABASE_MIGRATIONS_CONSOLIDATED.md b/docs/DATABASE_MIGRATIONS_CONSOLIDATED.md deleted file mode 100644 index ae330e9..0000000 --- a/docs/DATABASE_MIGRATIONS_CONSOLIDATED.md +++ /dev/null @@ -1,251 +0,0 @@ -# Database Migrations Consolidation - -**Generated**: October 6, 2025 -**Purpose**: Consolidated database migration strategy for fresh installs and upgrades - -## Current Migration Issues - -### Duplicate Version Numbers -The following version numbers have multiple migration files: -- **V008**: 4 different migrations - - V008_create_photos.sql - - V008_create_data_deletion_requests.sql - - V008_add_user_photo_url.sql - - V008_add_eula_acceptance.sql -- **V009**: 3 different migrations - - V009_create_activity_partitions.sql - - V009_add_photo_alt_text.sql - - V009_add_performance_indexes.sql -- **V010**: 3 different migrations - - V010_create_ai_conversations.sql - - V010_add_mfa_fields.sql - - V010_create_user_preferences.sql -- **V011**: 2 different migrations - - V011_create_password_reset_tokens.sql - - V011_add_webauthn_credentials.sql - -## Consolidated Migration Order - -### Phase 1: Core Authentication & Users -``` -V001_create_core_auth.sql -V002_create_family_structure.sql -V003_create_refresh_tokens.sql -``` - -### Phase 2: Activity Tracking -``` -V004_create_activity_tracking.sql -V005_add_user_preferences.sql -V006_create_audit_log.sql -``` - -### Phase 3: Communications & Media -``` -V007_create_notifications.sql -V008_create_photos.sql -``` - -### Phase 4: User Profile Enhancements -``` -V009_add_user_photo_url.sql -V010_add_photo_alt_text.sql -V011_add_eula_acceptance.sql -``` - -### Phase 5: Security Enhancements -``` -V012_add_mfa_fields.sql -V013_add_webauthn_credentials.sql -V014_create_password_reset_tokens.sql -``` - -### Phase 6: AI Features -``` -V015_create_ai_conversations.sql -V016_create_voice_feedback.sql -V017_create_conversation_embeddings.sql -``` - -### Phase 7: Compliance & Privacy -``` -V018_create_data_deletion_requests.sql -V019_create_deletion_requests.sql -V020_add_coppa_compliance.sql -``` - -### Phase 8: Performance & Preferences -``` -V021_create_activity_partitions.sql -V022_add_performance_indexes.sql -V023_create_user_preferences.sql -``` - -### Phase 9: Additional Features -``` -V024_add_medicine_activity_types.sql -V025_add_child_display_preferences.sql -V026_create_multi_child_preferences.sql -V027_add_activity_bulk_operations.sql -``` - -## Renaming Strategy - -To fix the duplicate version numbers, here's the renaming plan: - -| Old Name | New Name | Purpose | -|----------|----------|---------| -| V001_create_core_auth.sql | V001_create_core_auth.sql | No change | -| V002_create_family_structure.sql | V002_create_family_structure.sql | No change | -| V003_create_refresh_tokens.sql | V003_create_refresh_tokens.sql | No change | -| V004_create_activity_tracking.sql | V004_create_activity_tracking.sql | No change | -| V005_add_user_preferences.sql | V005_add_user_preferences.sql | No change | -| V006_create_audit_log.sql | V006_create_audit_log.sql | No change | -| V007_create_notifications.sql | V007_create_notifications.sql | No change | -| V008_create_photos.sql | V008_create_photos.sql | Keep first V008 | -| V008_add_user_photo_url.sql | V009_add_user_photo_url.sql | Rename | -| V009_add_photo_alt_text.sql | V010_add_photo_alt_text.sql | Rename | -| V008_add_eula_acceptance.sql | V011_add_eula_acceptance.sql | Rename | -| V010_add_mfa_fields.sql | V012_add_mfa_fields.sql | Rename | -| V011_add_webauthn_credentials.sql | V013_add_webauthn_credentials.sql | Rename | -| V011_create_password_reset_tokens.sql | V014_create_password_reset_tokens.sql | Rename | -| V010_create_ai_conversations.sql | V015_create_ai_conversations.sql | Rename | -| V012_create_voice_feedback.sql | V016_create_voice_feedback.sql | Rename | -| V014_create_conversation_embeddings.sql | V017_create_conversation_embeddings.sql | Rename | -| V008_create_data_deletion_requests.sql | V018_create_data_deletion_requests.sql | Rename | -| V015_create_deletion_requests.sql | V019_create_deletion_requests.sql | Rename (duplicate?) | -| V016_add_coppa_compliance.sql | V020_add_coppa_compliance.sql | Rename | -| V009_create_activity_partitions.sql | V021_create_activity_partitions.sql | Rename | -| V009_add_performance_indexes.sql | V022_add_performance_indexes.sql | Rename | -| V010_create_user_preferences.sql | V023_create_user_preferences.sql | Rename | -| V013_add_medicine_activity_types.sql | V024_add_medicine_activity_types.sql | Rename | -| V017_add_child_display_preferences.sql | V025_add_child_display_preferences.sql | Rename | -| V018_create_multi_child_preferences.sql | V026_create_multi_child_preferences.sql | Rename | -| V019_add_activity_bulk_operations.sql | V027_add_activity_bulk_operations.sql | Rename | - -## Master Migration Script - -For fresh installations, we need a single script that runs all migrations in order: - -```bash -#!/bin/bash -# master-migration.sh - Run all migrations for fresh install - -DATABASE_NAME="${DATABASE_NAME:-parentflow_production}" -DATABASE_USER="${DATABASE_USER:-parentflow_user}" -DATABASE_HOST="${DATABASE_HOST:-localhost}" -DATABASE_PORT="${DATABASE_PORT:-5432}" - -MIGRATION_DIR="./src/database/migrations" - -# Array of migrations in correct order -MIGRATIONS=( - "V001_create_core_auth.sql" - "V002_create_family_structure.sql" - "V003_create_refresh_tokens.sql" - "V004_create_activity_tracking.sql" - "V005_add_user_preferences.sql" - "V006_create_audit_log.sql" - "V007_create_notifications.sql" - "V008_create_photos.sql" - "V009_add_user_photo_url.sql" - "V010_add_photo_alt_text.sql" - "V011_add_eula_acceptance.sql" - "V012_add_mfa_fields.sql" - "V013_add_webauthn_credentials.sql" - "V014_create_password_reset_tokens.sql" - "V015_create_ai_conversations.sql" - "V016_create_voice_feedback.sql" - "V017_create_conversation_embeddings.sql" - "V018_create_data_deletion_requests.sql" - "V019_create_deletion_requests.sql" - "V020_add_coppa_compliance.sql" - "V021_create_activity_partitions.sql" - "V022_add_performance_indexes.sql" - "V023_create_user_preferences.sql" - "V024_add_medicine_activity_types.sql" - "V025_add_child_display_preferences.sql" - "V026_create_multi_child_preferences.sql" - "V027_add_activity_bulk_operations.sql" -) - -echo "Starting database migration..." -echo "Database: $DATABASE_NAME@$DATABASE_HOST:$DATABASE_PORT" - -for migration in "${MIGRATIONS[@]}"; do - echo "Running migration: $migration" - psql -h "$DATABASE_HOST" -p "$DATABASE_PORT" -U "$DATABASE_USER" -d "$DATABASE_NAME" -f "$MIGRATION_DIR/$migration" - if [ $? -ne 0 ]; then - echo "ERROR: Migration $migration failed!" - exit 1 - fi - echo "✓ Migration $migration completed" -done - -echo "All migrations completed successfully!" -``` - -## Migration Tracking Table - -Create a migration tracking table to record which migrations have been applied: - -```sql --- V000_create_migration_tracking.sql -CREATE TABLE IF NOT EXISTS schema_migrations ( - version VARCHAR(10) PRIMARY KEY, - filename VARCHAR(255) NOT NULL, - applied_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - checksum VARCHAR(64), - description TEXT -); - --- Index for quick lookup -CREATE INDEX idx_schema_migrations_applied_at ON schema_migrations(applied_at); -``` - -## Action Items - -1. **Rename duplicate migration files** to use sequential versioning -2. **Create migration tracking table** (V000_create_migration_tracking.sql) -3. **Create master migration script** for fresh installs -4. **Update TypeORM configuration** to use renamed migrations -5. **Test migration sequence** on fresh database -6. **Document rollback procedures** for each migration - -## Rollback Strategy - -Each migration should have a corresponding rollback script: - -``` -migrations/ - V001_create_core_auth.sql - V001_create_core_auth.rollback.sql - V002_create_family_structure.sql - V002_create_family_structure.rollback.sql - ... -``` - -## Notes for Developers - -1. Always use sequential version numbers (V001, V002, etc.) -2. Never reuse version numbers -3. Include descriptive names after version number -4. Always test migrations on a copy of production data -5. Include both upgrade and rollback scripts -6. Document any data transformations -7. Check for dependencies between migrations - -## Migration Validation Checklist - -Before running migrations on production: - -- [ ] All migrations tested on staging environment -- [ ] Backup of production database taken -- [ ] Rollback scripts prepared and tested -- [ ] Migration order verified -- [ ] No duplicate version numbers -- [ ] All foreign key constraints validated -- [ ] Indexes created for performance -- [ ] Data migration scripts tested (if applicable) -- [ ] Application code compatible with schema changes -- [ ] Monitoring alerts configured for migration issues \ No newline at end of file diff --git a/docs/REMAINING_FEATURES.md b/docs/REMAINING_FEATURES.md deleted file mode 100644 index 5bd5185..0000000 --- a/docs/REMAINING_FEATURES.md +++ /dev/null @@ -1,1003 +0,0 @@ -# Remaining Features - Maternal App - -**Generated**: October 3, 2025 -**Last Updated**: October 6, 2025 (Production deployment infrastructure completed) -**Status**: 57 features remaining out of 139 total (59%) -**Completion**: 82 features completed (59%) -**Urgent**: ✅ ALL HIGH-PRIORITY UX/ACCESSIBILITY & INFRASTRUCTURE COMPLETE! 🎉🚀 - -This document provides a clear roadmap of all remaining features, organized by priority level. Use this as a tracking document for ongoing development. - ---- - -## 📊 Summary - -### Feature Status by Category -- **Bugs**: ✅ 0 critical bugs (all fixed!) -- **Backend**: 29 remaining / 55 total (47% complete) -- **Frontend**: 23 remaining / 52 total (56% complete) -- **Infrastructure**: 6 remaining / 21 total (71% complete) -- **Testing**: 13 remaining / 18 total (28% complete) - -### Priority Breakdown -- **🔴 Critical (Pre-Launch)**: ✅ ALL COMPLETE! -- **🔥 Urgent Bugs**: ✅ ALL FIXED! -- **🟠 High Priority**: ✅ **ALL COMPLETE!** (18 features completed! 🎉🎨🚀) -- **🟡 Medium Priority**: ✅ **SMART FEATURES COMPLETE!** (4 features completed! 🧠) -- **🟢 Low Priority (Post-MVP)**: 40 features - ---- - -## 🔴 CRITICAL PRIORITY (Pre-Launch) ✅ - -### All Critical Features Complete! - -The following critical features have been successfully implemented: -- ✅ Testing Foundation (80%+ coverage achieved) -- ✅ COPPA/GDPR Compliance (data export, deletion, consent) -- ✅ Redux Persist (state persistence) -- ✅ Accessibility Foundation (WCAG 2.1 AA Phase 1) -- ✅ Real-Time Sync (WebSocket room management) -- ✅ AI Safety Integration (medical disclaimers, crisis hotlines) -- ✅ LangChain Context Management (4000 token budget) -- ✅ Security Hardening (Helmet.js, CSP, CORS) -- ✅ Localization (95% complete - 77 files, 7 languages) - -**Status**: ✅ **LAUNCH READY** - All critical features implemented! - ---- - -## 🔥 URGENT BUGS (0 Critical Issues) ✅ - -### All Critical Bugs Fixed! - -#### ✅ BUG-1. Voice Tracking Not Saving Activities - FIXED -**Fixed**: October 4, 2025 -**Solution**: -- Fixed data format transformation (timestamp/data instead of startedAt/metadata) -- Added sleep duration → startTime/endTime conversion -- Removed duplicate voice button from mobile menu - -**Commits**: -- `53e3757` - feat: Add status dot indicator and fix voice tracking data format -- `962d0fb` - fix: Transform sleep voice command duration to startTime/endTime format - ---- - -#### ✅ BUG-2. Session Persistence After Revocation - FIXED -**Fixed**: October 3, 2025 -**Solution**: Added logout() calls after revoking sessions/devices to clear tokens and redirect to login - -**Files Modified**: -- `maternal-web/components/settings/SessionsManagement.tsx` -- `maternal-web/components/settings/DeviceTrustManagement.tsx` - -**Commit**: `2ab9874` - fix: Fix 3 critical bugs - ---- - -#### ✅ BUG-3. Voice Modal Status Not Updating - FIXED -**Fixed**: October 3, 2025 -**Solution**: Set identifiedActivity state in handleApprove and handleEdit to show proper status - -**Files Modified**: -- `maternal-web/components/voice/VoiceFloatingButton.tsx` - -**Commit**: `2ab9874` - fix: Fix 3 critical bugs - ---- - -## 🟠 HIGH PRIORITY (16 Features) - -### New User-Requested Features (8 features) - -#### ✅ 9. User Profile Photo Upload - COMPLETED -**Category**: Profile Management -**Completed**: October 4, 2025 -**Files**: -- `app/settings/page.tsx` ✅ -- `components/common/PhotoUpload.tsx` ✅ -- Backend: `src/modules/auth/auth.controller.ts` ✅ - -**Implementation**: -- Base64 photo upload (max 5MB) -- Photo preview before saving -- Photo displayed in header avatar -- Photo stored in PostgreSQL TEXT column -- API endpoint: PATCH /api/v1/auth/me - -**Completed Criteria**: -- ✅ Photo upload button in settings -- ✅ Preview before save -- ✅ Photo appears in user menu -- ✅ API endpoint implemented -- ✅ Base64 encoding for storage - ---- - -#### ✅ 10. Child Photo Upload Enhancement - COMPLETED -**Category**: Child Management -**Completed**: October 4, 2025 -**Files**: -- `components/features/children/ChildForm.tsx` ✅ -- `components/features/children/ChildCard.tsx` ✅ -- `components/common/PhotoUpload.tsx` ✅ - -**Implementation**: -- Reusable PhotoUpload component -- Base64 encoding (max 5MB) -- Photo displayed on child cards -- Default avatar fallback -- Camera icon upload interface - -**Completed Criteria**: -- ✅ Photo upload in child create/edit form -- ✅ Photo preview in form -- ✅ Photo displayed on child card -- ✅ Default avatar fallback -- ✅ Backend API support - ---- - -#### ✅ 11. Mobile View Grid Layout (2 Cards per Row) - COMPLETED -**Category**: UI/UX - Mobile -**Completed**: October 4, 2025 -**Files**: -- `app/children/page.tsx` ✅ - -**Implementation**: -- Grid layout with responsive breakpoints -- xs={6} for 2 cards per row on mobile -- sm={6} for 2 cards per row on tablet -- md={4} for 3 cards per row on desktop -- Responsive spacing: `spacing={{ xs: 2, sm: 3 }}` -- Framer Motion animations on card mount - -**Completed Criteria**: -- ✅ 2 cards per row on mobile (xs={6}) -- ✅ 2 cards per row on tablet (sm={6}) -- ✅ 3 cards per row on desktop (md={4}) -- ✅ Proper gap spacing (16px on mobile, 24px on larger) -- ✅ Smooth animations and transitions - ---- - -#### ✅ 12. Secondary Color Palette & Accessibility Toggle - COMPLETED -**Category**: UI/UX - Theming -**Completed**: October 4, 2025 -**Effort**: 4 hours -**Files**: -- `app/globals.css` ✅ -- `app/settings/page.tsx` ✅ -- `contexts/ThemeContext.tsx` ✅ (new) -- `components/ThemeRegistry.tsx` ✅ -- `styles/themes/purpleTheme.ts` ✅ (new) -- `styles/themes/highContrastTheme.ts` ✅ (new) - -**Implementation**: -- **Default Theme**: Purple/pink gradient (#8b52ff → #ff7094) - - Modern, vibrant aesthetic with 5 gradient colors - - Full MUI theme configuration -- **High Contrast Theme**: Warm peach (original theme) - - 7.5% larger text for accessibility - - Stronger shadows and bolder fonts - - Optimized for readability -- **Theme Context**: React context with useThemeContext hook -- **Settings Toggle**: Switch in Preferences section -- **Persistence**: localStorage with key maternal_theme_preference -- **Instant Switching**: No page reload required - -**Completed Criteria**: -- ✅ Secondary color palette designed (5 purple/pink gradient colors) -- ✅ Settings toggle: "High Contrast Mode" / "Standard Mode" -- ✅ High contrast colors and larger text (7.5% increase) -- ✅ Larger font sizes in high contrast mode -- ✅ User preference saved to localStorage -- ✅ Theme applied consistently across all pages -- ✅ Smooth theme transitions -- ✅ No flash of wrong theme on load - ---- - -#### ✅ 13. Legal Pages & User Menu - COMPLETED -**Category**: Compliance -**Completed**: October 4, 2025 -**Files**: -- `app/legal/privacy/page.tsx` ✅ -- `app/legal/terms/page.tsx` ✅ -- `app/legal/eula/page.tsx` ✅ -- `app/legal/cookies/page.tsx` ✅ -- `app/legal/page.tsx` (Legal Hub) ✅ -- `components/legal/PrivacyContent.tsx` ✅ -- `components/legal/TermsContent.tsx` ✅ -- `components/legal/EULAContent.tsx` ✅ -- `components/layouts/AppShell/AppShell.tsx` ✅ - -**Implementation**: -- Comprehensive GDPR/COPPA compliant Privacy Policy -- Complete Terms of Service with medical disclaimers -- Detailed EULA with AI feature disclaimers -- Cookie Policy with opt-out instructions -- Legal hub with card-based navigation -- "Legal & Privacy" link in user menu -- Full AppShell layout on all legal pages -- ParentFlow branding throughout -- Contact: hello@parentflow.com, Serbota 3, Bucharest - -**Completed Criteria**: -- ✅ Privacy Policy with GDPR/COPPA disclosures -- ✅ Terms of Service with 18 sections -- ✅ EULA with acceptance language -- ✅ Cookie Policy with management instructions -- ✅ Links in user menu (Legal & Privacy) -- ✅ Mobile-responsive layout with AppShell -- ✅ Last updated: October 4, 2025 -- ✅ Cross-linked legal documents - ---- - -#### ✅ 14. EULA Agreement Popup on First Login - COMPLETED -**Category**: Compliance -**Completed**: October 4, 2025 -**Last Updated**: October 4, 2025 (Fixed persistence bug) -**Files**: -- `components/legal/EULADialog.tsx` ✅ -- `components/legal/EULACheck.tsx` ✅ -- `components/legal/LegalDocumentViewer.tsx` ✅ -- `app/layout.tsx` (integrated EULACheck) ✅ -- Backend: `src/database/entities/user.entity.ts` ✅ -- Backend: `src/modules/auth/auth.service.ts` ✅ -- Backend: `src/modules/auth/auth.controller.ts` ✅ -- Migration: `V008_add_eula_acceptance.sql` ✅ - -**Implementation**: -- Welcome dialog with 3 checkboxes (Terms, Privacy, EULA) -- Inline document viewer in nested modal -- Full legal content displayed in scrollable modal -- Blocks app usage until accepted -- Database fields: eulaAcceptedAt, eulaVersion -- API endpoint: POST /api/v1/auth/eula/accept -- Audit logging for EULA acceptance -- "Decline & Exit" logs user out -- **Fixed**: Uses refreshUser() instead of window.location.reload() for seamless acceptance - -**Completed Criteria**: -- ✅ EULA dialog shows on first login -- ✅ Three separate checkboxes for legal agreements -- ✅ Links open legal docs in nested modal -- ✅ "I Accept" disabled until all checked -- ✅ EULA acceptance timestamp in database -- ✅ Version tracking (2025-10-04) -- ✅ Dialog only shows once (fixed persistence bug) -- ✅ Full document content viewable -- ✅ No page reload required (smooth UX) - ---- - -#### ✅ 15. Cookie Consent Banner - COMPLETED -**Category**: Compliance -**Completed**: October 4, 2025 -**Files**: -- `components/common/banners/CookieConsent.tsx` ✅ -- `app/layout.tsx` ✅ - -**Implementation**: -- Slide-up banner with Material UI Paper component -- Three cookie categories: Essential (locked), Analytics, Marketing -- Three action buttons: Reject All, Customize, Accept All -- Collapsible customize section with toggle switches -- LocalStorage for preference persistence (parentflow_cookie_consent) -- 1-second delay before showing banner -- Link to /legal/cookies page -- Cookie icon and clean UI - -**Completed Criteria**: -- ✅ Banner shows on first visit (1s delay) -- ✅ Three toggle options: Essential (always on), Analytics, Marketing -- ✅ "Accept All" accepts all cookies -- ✅ "Reject All" only accepts essential -- ✅ "Customize" shows collapsible detailed preferences -- ✅ Preferences saved to localStorage -- ✅ Console logging for analytics state -- ✅ Link to full Cookie Policy (/legal/cookies) - ---- - -#### ✅ 16. Collapsible Active Sessions Section - COMPLETED -**Category**: UI/UX - Settings -**Completed**: October 4, 2025 (pre-existing) -**Files**: -- `components/settings/SessionsManagement.tsx` ✅ -- `components/settings/DeviceTrustManagement.tsx` ✅ - -**Implementation**: -- MUI Accordion component with expand/collapse -- AccordionSummary shows "Active Sessions" with count chip -- ExpandMore icon for visual feedback -- AccordionDetails contains full session list -- Same implementation for Trusted Devices - -**Completed Criteria**: -- ✅ Active Sessions section is collapsible -- ✅ Shows "Active Sessions" with count chip `{sessions.length}` -- ✅ ExpandMore chevron icon -- ✅ Smooth MUI Accordion animation -- ✅ Trusted Devices section also collapsible -- ✅ Both integrated in settings page - ---- - -### Existing High Priority Features (8 features) - -### Backend (2 features) - -#### ✅ 1. AI Personalization System - COMPLETED -**Category**: AI Features -**Completed**: October 4, 2025 (Pre-existing) -**Files**: -- `src/modules/ai/personalization.service.ts` ✅ -- `src/database/entities/user-preferences.entity.ts` ✅ - -**Implementation**: -- ✅ Full PersonalizationService with preference tracking -- ✅ Response style adaptation (Concise/Detailed/Balanced) -- ✅ Tone customization (Friendly/Professional/Casual/Empathetic) -- ✅ Topic weight learning from user interactions -- ✅ Formatting preferences (bullets, step-by-step, examples) -- ✅ Feedback integration ready (learnFromFeedback method) -- ✅ Personalized prompt generation - -**Acceptance Criteria**: -- ✅ Preference tracking for tone/style -- ✅ Feedback integration for learning -- ✅ Personalized prompt generation -- ✅ Topic weights and avoided topics - ---- - -#### ✅ 2. Growth Spurt Detection - COMPLETED -**Category**: Analytics -**Completed**: October 4, 2025 (Pre-existing) -**Files**: -- `src/modules/analytics/pattern-analysis.service.ts` ✅ -- `components/features/analytics/GrowthSpurtAlert.tsx` ✅ -- `app/analytics/page.tsx` ✅ - -**Implementation**: -- ✅ Feeding frequency spike detection (>20% increase) -- ✅ Sleep pattern disruption detection -- ✅ Age-based growth spurt probability (2,3,6,12,16,24,36 weeks) -- ✅ Confidence scoring (0-1) with multiple indicators -- ✅ Smart recommendations generation -- ✅ Alert component with collapsible details -- ✅ Integrated into analytics dashboard - -**Acceptance Criteria**: -- ✅ Feeding frequency spike detection (>20% increase) -- ✅ Sleep pattern disruption detection -- ✅ Growth spurt probability calculation -- ✅ Smart notification generation - ---- - -### Frontend (3 features) - -#### ✅ 3. AI Response Feedback UI - COMPLETED -**Category**: AI Features -**Completed**: October 4, 2025 -**Effort**: 2 hours -**Files**: -- `components/features/ai-chat/AIChatInterface.tsx` ✅ -- `components/features/ai-chat/MessageFeedback.tsx` ✅ -- `locales/en/ai.json` ✅ - -**Implementation**: -- ✅ Created MessageFeedback component with thumbs up/down buttons -- ✅ Positive feedback submits immediately with visual confirmation -- ✅ Negative feedback opens dialog for optional text input -- ✅ Success Snackbar shows "Thank you for your feedback!" -- ✅ Full API integration with POST /api/v1/ai/feedback -- ✅ Translation keys added to ai.json - -**Acceptance Criteria**: -- ✅ Thumbs up/down buttons on assistant messages -- ✅ Feedback modal for additional comments -- ✅ Success toast on submission -- ✅ API integration with POST /feedback - ---- - -#### ✅ 4. Touch Target Verification - COMPLETED -**Category**: Accessibility -**Completed**: October 4, 2025 -**Effort**: 3 hours -**Files**: -- `app/children/page.tsx` ✅ -- `components/features/ai-chat/AIChatInterface.tsx` ✅ -- `components/features/analytics/WeeklyReportCard.tsx` ✅ -- `components/features/analytics/MonthlyReportCard.tsx` ✅ -- `components/legal/LegalDocumentViewer.tsx` ✅ - -**Implementation**: -- Fixed 14 undersized interactive elements across 5 files -- Changed all `size="small"` IconButtons to `size="medium"` -- Added `sx={{ minWidth: 48, minHeight: 48 }}` to all IconButtons -- Updated Button components to `size="medium"` with `minHeight: 48` -- All touch targets now meet 48×48px minimum (iOS 44px, Android 48px) - -**Completed Criteria**: -- ✅ Audited all clickable elements (144 IconButton usages found) -- ✅ Fixed all undersized touch targets (14 elements updated) -- ✅ All interactive elements meet 48×48px minimum -- ✅ Consistent sizing across all pages - ---- - -#### ✅ 5. Alt Text for Images - COMPLETED -**Category**: Accessibility -**Completed**: October 4, 2025 -**Effort**: 2 hours -**Files**: -- `components/common/PhotoUpload.tsx` ✅ -- `components/children/ChildDialog.tsx` ✅ -- `app/children/page.tsx` ✅ -- `components/layouts/AppShell/AppShell.tsx` ✅ -- `components/layouts/MobileNav/MobileNav.tsx` ✅ -- `components/features/ai-chat/AIChatInterface.tsx` ✅ -- Backend: `src/database/entities/child.entity.ts` ✅ -- Migration: `V009_add_photo_alt_text.sql` ✅ - -**Implementation**: -- Added `photoAlt` field to children table and entity -- PhotoUpload component now includes alt text input field -- All Avatar components have meaningful alt text -- Default alt text generation: `Photo of ${childName}` -- User avatars: `${userName}'s profile photo` -- AI assistant avatars labeled appropriately -- Helper text guides users to describe photos - -**Completed Criteria**: -- ✅ Alt text on all image components (Avatar, img tags) -- ✅ Photo upload form includes alt text field with helper text -- ✅ Default alt text generation for child photos -- ✅ WCAG 2.1 compliant image accessibility - ---- - -#### ✅ 6. Form Accessibility Enhancement - COMPLETED -**Category**: Accessibility -**Completed**: October 4, 2025 -**Effort**: 2 hours -**Files**: -- `app/(auth)/login/page.tsx` ✅ -- `app/(auth)/register/page.tsx` ✅ -- `components/children/ChildDialog.tsx` ✅ -- `app/track/feeding/page.tsx` ✅ -- `app/track/sleep/page.tsx` ✅ - -**Implementation**: -- Added `aria-required="true"` to all required form fields -- Added `aria-invalid` attributes that update based on validation errors -- Added `aria-describedby` linking error messages to inputs -- Added unique `id` attributes to FormHelperText for error association -- Added `role="alert"` to error messages for screen reader announcements -- Updated Select components with `labelId` for proper label association -- Added `noValidate` to forms to use custom validation - -**Completed Criteria**: -- ✅ All inputs have associated labels (htmlFor via MUI TextField, labelId for Select) -- ✅ Error messages linked with aria-describedby -- ✅ Required fields marked with aria-required -- ✅ Form validation errors announced with role="alert" -- ✅ Login form: email, password fields -- ✅ Registration form: name, email, password, DOB, parental email, checkboxes -- ✅ Child dialog: name, birthdate, gender fields -- ✅ Tracking forms: child selector, feeding/sleep specific fields - ---- - -### Infrastructure (0 high-priority features remaining) - -#### ✅ 7. Production Deployment Infrastructure - COMPLETED -**Category**: Deployment -**Completed**: October 6, 2025 -**Deployment Strategy**: PM2 + Docker on dedicated production server - -**Production Server Configuration**: -- **Server IP**: 10.0.0.240 -- **Frontend**: Port 3030 → web.parentflowapp.com -- **Backend**: Port 3020 → api.parentflowapp.com -- **Process Manager**: PM2 -- **Databases**: Docker Compose - -**Files Created**: -- `docker-compose.production.yml` ✅ - Production database containers -- `.env.production.example` ✅ - Environment variables template -- `start-production.sh` ✅ - Automated startup script -- `stop-production.sh` ✅ - Graceful shutdown script -- `PRODUCTION_DEPLOYMENT.md` ✅ - Complete deployment guide -- `scripts/master-migration.sh` ✅ - Database migration runner -- `scripts/check-migrations.sh` ✅ - Migration status checker -- `docs/DATABASE_MIGRATIONS_CONSOLIDATED.md` ✅ - Migration documentation - -**Implementation Details**: -- ✅ Docker Compose for databases (PostgreSQL with pgvector, Redis, MongoDB, MinIO) -- ✅ All containers with health checks and restart policies -- ✅ PM2 ecosystem configuration for production -- ✅ Automated startup script with health verification -- ✅ Database migration consolidation (27 migrations tracked) -- ✅ Migration tracking table (V000_create_migration_tracking.sql) -- ✅ CORS configuration for parentflowapp.com domains -- ✅ JWT secrets configured in ecosystem.config.js -- ✅ Database connection pooling configured -- ✅ Environment variables documentation -- ✅ Nginx reverse proxy configuration guide -- ✅ SSL certificate setup instructions (Certbot) -- ✅ Backup strategy documented -- ✅ Troubleshooting guide -- ✅ Security checklist - -**Deployment Environment**: -- **Development**: - - Backend: PM2 (port 3015) → maternal-api.noru1.ro - - Frontend: PM2 (port 3005) → maternal.noru1.ro - - Databases: Docker containers (ports 5555, 6666, 27777, 9002) - -- **Production** (Ready to Deploy): - - Server: 10.0.0.240 - - Backend: PM2 (port 3020) → api.parentflowapp.com - - Frontend: PM2 (port 3030) → web.parentflowapp.com - - Databases: Docker (PostgreSQL:5432, Redis:6379, MongoDB:27017, MinIO:9000) - -**Completed Tasks**: -- ✅ Create production Docker Compose file -- ✅ Create production environment variables template -- ✅ Configure PM2 ecosystem for production server -- ✅ Create deployment scripts (start/stop) -- ✅ Document Nginx reverse proxy setup -- ✅ Document SSL certificate setup -- ✅ Implement database migration system -- ✅ Add health checks and monitoring guide -- ✅ Create comprehensive deployment documentation - -**Remaining Tasks** (Deployment to 10.0.0.240): -- ⏳ Create Gitea Actions workflow for automated deployment -- ✅ SSH access configured: root@10.0.0.240 (password: a3pq5t50yA@#) -- ⏳ Deploy to production server 10.0.0.240 -- ✅ Nginx reverse proxy already configured (dedicated proxy server) -- ✅ SSL certificates already configured (dedicated proxy server) -- ✅ Dedicated PostgreSQL server: postgresql://postgres:a3ppq@10.0.0.207:5432/parentflow - ---- - -#### 8. Integration & E2E Testing -**Category**: Testing -**Effort**: 12 hours -**Priority**: High - -**Requirements**: -- Integration tests for API flows -- E2E tests for critical user journeys -- Test coverage reports -- CI/CD integration - -**Files to Create**: -- `test/integration/` (multiple test files) -- `test/e2e/` (Playwright/Cypress tests) - -**Acceptance Criteria**: -- [ ] Integration tests for auth flow -- [ ] Integration tests for activity tracking -- [ ] E2E test: User registration to first activity -- [ ] E2E test: AI chat conversation -- [ ] E2E test: Family invitation flow -- [ ] Coverage reports in CI/CD - -**Testing Tools**: -- Jest (integration tests) -- Playwright or Cypress (E2E tests) -- Coverage: Jest + Istanbul - ---- - -## 🟡 MEDIUM PRIORITY (18 Features) - -### Backend Features (10 features) - -#### 9. Meal Planning System -**Category**: Tracking Features -**Effort**: 8 hours - -**Requirements**: -- Weekly meal planning interface -- Recipe suggestions by age group -- Nutritional tracking -- Shopping list generation -- Family meal coordination - -**Files to Create**: -- `src/modules/meal-planning/meal-planning.module.ts` -- `src/modules/meal-planning/meal-planning.service.ts` -- `src/modules/meal-planning/meal-planning.controller.ts` -- `src/database/entities/meal-plan.entity.ts` - ---- - -#### 10. Financial Tracking -**Category**: Tracking Features -**Effort**: 6 hours - -**Requirements**: -- Track child-related expenses -- Budget planning -- Cost per child reports -- Category breakdown -- Monthly summaries - ---- - -#### 11. Calendar Integration -**Category**: Integrations -**Effort**: 6 hours - -**Requirements**: -- Google Calendar sync -- Apple Calendar sync (CalDAV) -- Outlook Calendar sync -- Appointment tracking -- Reminder sync - ---- - -#### 12. Smart Home Integration -**Category**: Integrations -**Effort**: 8 hours - -**Requirements**: -- Alexa skill for voice tracking -- Google Home actions -- Voice commands for common activities -- Voice query responses - ---- - -#### 13. Email Digests -**Category**: Notifications -**Effort**: 4 hours - -**Requirements**: -- Daily/weekly email summaries -- Activity highlights -- Pattern insights -- Customizable frequency - ---- - -#### 14. Photo Tagging System -**Category**: Photos -**Effort**: 4 hours - -**Requirements**: -- Tag people in photos -- Tag activities/events -- Tag milestones -- Search photos by tags - ---- - -#### 15. Advanced Export Formats -**Category**: Analytics -**Effort**: 3 hours - -**Requirements**: -- Export to CSV -- Export to JSON -- Generate PDF reports -- Custom date ranges -- Multi-child exports - ---- - -#### 16. Medication Reminders Enhanced -**Category**: Notifications -**Effort**: 3 hours - -**Requirements**: -- Recurring medication schedules -- Dosage tracking -- Refill reminders -- Multiple medications per child - ---- - -#### 17. GraphQL Subscriptions -**Category**: API Enhancement -**Effort**: 4 hours - -**Requirements**: -- Real-time data updates via GraphQL subscriptions -- Activity creation subscriptions -- Family sync subscriptions -- Notification subscriptions - ---- - -#### 18. Voice Suggested Prompts -**Category**: Voice Features -**Effort**: 2 hours - -**Requirements**: -- Context-aware voice suggestions -- Common phrase templates -- Recent activity suggestions -- Time-based suggestions - ---- - -### Frontend Features (5 features) - -#### ✅ 19. Suggested Follow-Up Questions (AI Chat) - COMPLETED -**Category**: AI UX -**Completed**: October 4, 2025 -**Effort**: 3 hours -**Files**: -- `components/features/ai-chat/SuggestedQuestions.tsx` ✅ -- `lib/ai/suggestedQuestions.ts` ✅ -- `components/features/ai-chat/AIChatInterface.tsx` ✅ - -**Implementation**: -- ✅ Created SuggestedQuestions component with animated Chip buttons -- ✅ Context-aware question generation based on topic detection -- ✅ 7 topic categories: sleep, feeding, development, health, crying, schedule, growth -- ✅ 3 suggestions per AI response (configurable) -- ✅ One-tap to ask follow-up (auto-sends message) -- ✅ Smart question selection based on response keywords -- ✅ Framer Motion animations for smooth appearance -- ✅ Glass morphism design with hover effects - -**Acceptance Criteria**: -- ✅ Quick reply buttons in AI chat -- ✅ Context-aware suggestions (topic detection) -- ✅ 3 suggestions per response -- ✅ One-tap to ask follow-up - ---- - -#### ✅ 20. Enhanced Analytics Dashboard - COMPLETED -**Category**: Analytics UI -**Completed**: October 6, 2025 -**Effort**: 6 hours -**Files**: -- `components/features/analytics/EnhancedInsightsDashboard.tsx` ✅ (new) -- `components/features/analytics/UnifiedInsightsDashboard.tsx` ✅ -- `components/analytics/TrendAnalysisChart.tsx` ✅ -- `lib/api/analytics.ts` ✅ -- `locales/*/insights.json` ✅ (5 languages) - -**Implementation**: -- ✅ Created EnhancedInsightsDashboard with multiple chart types: - - Area charts with gradients for activity trends - - Radar chart for weekly activity patterns - - 24-hour heatmap visualization - - Bubble/scatter chart for correlations - - Time of day distribution bar chart -- ✅ Toggle between basic and enhanced chart views -- ✅ Export functionality (PNG/PDF) with html2canvas and jspdf -- ✅ Fixed API endpoint URLs (circadian-rhythm, query params) -- ✅ Fixed component library conflicts (shadcn/ui → MUI) -- ✅ Comprehensive null safety for timestamp handling -- ✅ Alert type translations in all 5 languages -- ✅ Consistent minimum width styling (400px charts, 200px stats) -- ✅ Framer Motion animations for smooth transitions -- ✅ Custom tooltips and responsive containers - -**Acceptance Criteria**: -- ✅ Multiple advanced chart types (area, radar, heatmap, bubble, bar) -- ✅ Toggle between basic and enhanced views -- ✅ Export charts as PNG/PDF -- ✅ Responsive design with minimum widths -- ✅ Smooth animations and transitions -- ✅ Error-free with null safety throughout - ---- - -#### 21. Meal Planning UI -**Category**: Tracking Features -**Effort**: 6 hours - -**Requirements**: -- Weekly calendar view -- Recipe cards -- Drag-and-drop meal assignment -- Shopping list view -- Nutritional summaries - ---- - -#### 22. Financial Tracking UI -**Category**: Tracking Features -**Effort**: 5 hours - -**Requirements**: -- Expense entry form -- Budget dashboard -- Category breakdown charts -- Monthly reports -- Export functionality - ---- - -#### 23. Photo Tagging UI -**Category**: Photos -**Effort**: 4 hours - -**Requirements**: -- Tag input on photo view -- Auto-complete for existing tags -- Tag filtering in gallery -- Bulk tagging support - ---- - -#### 24. Community Forums UI (Post-MVP) -**Category**: Social Features -**Effort**: 8 hours - -**Requirements**: -- Topic-based discussion forums -- Post creation/editing -- Comment threading -- Moderation tools -- Topic subscriptions - ---- - -#### 25. Calendar Integration UI -**Category**: Integrations -**Effort**: 4 hours - -**Requirements**: -- Calendar connection settings -- Event sync status -- Appointment list view -- Sync conflict resolution UI - ---- - -### Infrastructure (2 features) - -#### 26. Performance Monitoring Dashboard -**Category**: Monitoring -**Effort**: 4 hours - -**Requirements**: -- Visualization of request duration metrics -- Slow query dashboard -- Cache hit/miss rates -- Error rate tracking -- Real-time updates - ---- - -#### 27. Load Testing -**Category**: Testing -**Effort**: 6 hours - -**Requirements**: -- k6 or Artillery setup -- API load testing -- Database stress testing -- WebSocket load testing - ---- - -## 🟢 LOW PRIORITY - Post-MVP (40 Features) - -### Backend Features (18 features) - -28. Community Forums Backend -29. Advanced Pattern Recognition -30. Vaccination Tracking -31. Multi-Language Content Translation -32. Advanced Voice Features -33. AI Training Data Export -34. Third-Party Integrations (Fitbit, Apple Health) -35. Telemedicine Integration -36. School/Daycare Integration -37. Advanced Analytics (peer comparison) -38. Gamification System -39. Advanced Notifications (smart timing) -40. Data Science Features (predictive modeling) -41. Video Storage -42. Advanced Security (E2E encryption) -43. Performance Optimization (CDN, caching) -44. Microservices Architecture -45. Multi-Tenancy Support - ---- - -### Frontend Features (15 features) - -46. Advanced Data Visualization (D3.js) -47. Offline Mode Enhancements -48. Advanced Accessibility (high contrast, reduced motion) -49. Animations & Micro-interactions -50. Customization Features (themes) -51. Multi-Child Views (side-by-side) -52. Advanced Search -53. Sharing Features -54. Tutorial System -55. Voice UI Enhancements -56. Notification Center -57. Quick Actions Dashboard -58. Profile Customization -59. Advanced Settings - ---- - -### Infrastructure & Testing (7 features) - -60. Code Coverage Dashboard -61. Blue-Green Deployment -62. Mobile App Store Distribution -63. Fastlane Automation -64. TestFlight & Beta Distribution -65. CodePush OTA Updates -66. Advanced Monitoring (APM) -67. Security Auditing - ---- - -## 📋 Implementation Checklist - -### Next Steps (Recommended Order) - -**Week 1-2: High Priority UX Polish** ✅ -- ✅ AI Response Feedback UI (2h) - COMPLETED -- ✅ Touch Target Verification (3h) - COMPLETED -- ✅ Alt Text for Images (2h) - COMPLETED -- ✅ Form Accessibility Enhancement (2h) - COMPLETED - -**Week 3-4: Infrastructure Hardening** -- [ ] Docker Production Images (3h) -- [ ] Integration & E2E Testing (12h) - -**Week 5-6: Medium Priority Features** ✅ -- ✅ Growth Spurt Detection (3h) - COMPLETED (pre-existing) -- ✅ AI Personalization System (4h) - COMPLETED (pre-existing) -- ✅ Suggested Follow-Up Questions (3h) - COMPLETED -- ✅ Enhanced Analytics Dashboard (6h) - COMPLETED - -**Week 7-8: Post-MVP Planning** -- [ ] Meal Planning System (8h backend + 6h frontend) -- [ ] Financial Tracking (6h backend + 5h frontend) - ---- - -## 📊 Pre-Launch Checklist - -- ✅ Unit test coverage > 80% -- ⏳ Integration test coverage > 60% (current: 0%) -- ⏳ E2E test coverage for critical paths (current: 0%) -- ✅ WCAG 2.1 AA compliance (Phase 1) -- ✅ Security scan passed -- ✅ Performance budget met -- ✅ COPPA/GDPR compliance verified -- ⏳ Load testing completed (not yet) -- ⏳ Mobile app store ready (post-MVP) - ---- - -## 🔗 Related Documentation - -- **Main Plan**: [implementation-gaps.md](./implementation-gaps.md) -- **API Spec**: [maternal-app-api-spec.md](./maternal-app-api-spec.md) -- **Tech Stack**: [maternal-app-tech-stack.md](./maternal-app-tech-stack.md) -- **Testing Strategy**: [maternal-app-testing-strategy.md](./maternal-app-testing-strategy.md) -- **Accessibility Progress**: [ACCESSIBILITY_PROGRESS.md](./ACCESSIBILITY_PROGRESS.md) -- **Backup Strategy**: [BACKUP_STRATEGY.md](./BACKUP_STRATEGY.md) - ---- - -**Last Updated**: October 6, 2025 -**Next Review**: Weekly during active development diff --git a/docs/implementation-docs/ACCESSIBILITY_IMPLEMENTATION_PLAN.md b/docs/implementation-docs/ACCESSIBILITY_IMPLEMENTATION_PLAN.md deleted file mode 100644 index 47ed1df..0000000 --- a/docs/implementation-docs/ACCESSIBILITY_IMPLEMENTATION_PLAN.md +++ /dev/null @@ -1,670 +0,0 @@ -# Accessibility Implementation Plan - Maternal App - -**Created**: October 2, 2025 -**Target**: WCAG 2.1 AA Compliance -**Priority**: CRITICAL (Launch Blocker) - ---- - -## Executive Summary - -This document outlines the comprehensive accessibility implementation plan to achieve WCAG 2.1 AA compliance for the Maternal App. Accessibility is a **critical launch requirement** for legal compliance (ADA, Section 508) and to ensure the app is usable by all parents, including those with disabilities. - -**Current Status**: No accessibility implementation detected -**Target**: Full WCAG 2.1 AA compliance -**Timeline**: 2 weeks (Phases 1-3) - ---- - -## Table of Contents - -1. [Why Accessibility Matters](#why-accessibility-matters) -2. [WCAG 2.1 AA Requirements](#wcag-21-aa-requirements) -3. [Current State Assessment](#current-state-assessment) -4. [Implementation Phases](#implementation-phases) -5. [Technical Requirements](#technical-requirements) -6. [Testing Strategy](#testing-strategy) -7. [Success Metrics](#success-metrics) - ---- - -## Why Accessibility Matters - -### Legal Requirements -- **ADA (Americans with Disabilities Act)**: Web accessibility is legally required -- **Section 508**: Federal compliance for government users -- **WCAG 2.1 AA**: International standard for web accessibility - -### User Impact -- **15% of the population** has some form of disability -- **New parents** may have temporary disabilities (sleep deprivation, holding baby) -- **Situational disabilities**: Using app in bright sunlight, noisy environments -- **Assistive technology users**: Screen readers, keyboard-only, voice control - -### Business Benefits -- Larger addressable market -- Better SEO (semantic HTML) -- Improved UX for all users -- Legal risk mitigation -- Positive brand reputation - ---- - -## WCAG 2.1 AA Requirements - -### Four Core Principles (POUR) - -#### 1. **Perceivable** -- Text alternatives for non-text content -- Captions and alternatives for multimedia -- Adaptable content (can be presented in different ways) -- Distinguishable (easy to see and hear) - -#### 2. **Operable** -- Keyboard accessible (all functionality available via keyboard) -- Sufficient time (users have enough time to read and use content) -- Seizures and physical reactions (nothing that causes seizures) -- Navigable (users can navigate, find content, and determine where they are) -- Input modalities (make it easier to operate functionality through various inputs) - -#### 3. **Understandable** -- Readable (text content is readable and understandable) -- Predictable (web pages appear and operate in predictable ways) -- Input assistance (help users avoid and correct mistakes) - -#### 4. **Robust** -- Compatible (maximize compatibility with current and future user agents) - ---- - -## Current State Assessment - -### What We Have ✅ -- **Material-UI (MUI)**: Built-in accessibility features -- **React 18**: Modern framework with good accessibility support -- **Semantic HTML**: Some usage of proper HTML5 elements -- **Next.js 13**: Server-side rendering for better screen reader support - -### What's Missing ❌ - -#### **Critical Issues** -1. ❌ No ARIA labels on interactive elements -2. ❌ No keyboard navigation support -3. ❌ No focus indicators -4. ❌ No screen reader testing -5. ❌ Missing alt text on images/icons -6. ❌ Poor color contrast (not verified) -7. ❌ No skip navigation links -8. ❌ Forms lack proper labels and error messages -9. ❌ No focus management for dialogs/modals -10. ❌ No reduced motion support - -#### **High Priority Issues** -- Missing landmark regions (header, nav, main, footer) -- No heading hierarchy verification -- Missing aria-live regions for dynamic content -- No keyboard shortcuts documentation -- Touch targets not verified (44x44px minimum) - ---- - -## Implementation Phases - -### **Phase 1: Foundation (Week 1, Days 1-3)** 🏗️ - -#### **Goal**: Establish accessibility infrastructure and fix critical keyboard/focus issues - -**Tasks:** - -1. **Setup Accessibility Tools** (Day 1 Morning) - - Install `eslint-plugin-jsx-a11y` (React accessibility linting) - - Install `axe-core` and `@axe-core/react` (runtime accessibility testing) - - Configure ESLint rules for accessibility - - Install `jest-axe` for automated testing - - Add accessibility check to CI/CD - -2. **Keyboard Navigation** (Day 1 Afternoon - Day 2) - - Implement focus trap for modals/dialogs - - Add visible focus indicators (outline/ring) - - Create skip navigation link - - Fix tab order across all pages - - Add keyboard shortcuts for common actions - - Document keyboard navigation patterns - -3. **ARIA Labels & Semantic HTML** (Day 2 - Day 3) - - Audit all interactive elements (buttons, links, inputs) - - Add aria-label/aria-labelledby where needed - - Fix heading hierarchy (h1 → h2 → h3) - - Add landmark regions (header, nav, main, footer) - - Convert icon-only buttons to have text alternatives - - Add aria-describedby for form hints - -4. **Focus Management** (Day 3) - - Implement focus management for route changes - - Focus first heading on page load - - Trap focus in modals/dialogs - - Return focus when closing modals - - Manage focus for toast notifications - -**Deliverables:** -- ESLint accessibility rules configured -- Axe-core integrated into dev environment -- All pages keyboard navigable -- Focus indicators visible -- Skip navigation link added - ---- - -### **Phase 2: Content & Forms (Week 1, Days 4-5)** 📝 - -#### **Goal**: Make all content accessible and improve form usability - -**Tasks:** - -1. **Alternative Text** (Day 4 Morning) - - Audit all images for alt text - - Add descriptive alt text to photos - - Mark decorative images as `alt=""` - - Add aria-label to icon buttons - - Document icon meanings - -2. **Form Accessibility** (Day 4 Afternoon - Day 5 Morning) - - Add explicit labels to all inputs - - Associate labels with inputs (htmlFor/id) - - Add aria-required to required fields - - Improve error messages with aria-invalid - - Add aria-describedby for help text - - Group related inputs with fieldset/legend - - Add autocomplete attributes - -3. **Color Contrast** (Day 5 Morning) - - Audit color contrast ratios (WCAG AA: 4.5:1 for text, 3:1 for large text) - - Fix low-contrast text - - Ensure error states don't rely on color alone - - Add patterns/icons to supplement color coding - -4. **Live Regions** (Day 5 Afternoon) - - Add aria-live to toast notifications - - Add aria-live to loading states - - Add aria-live to activity feed updates - - Add status messages for async operations - -**Deliverables:** -- All images have appropriate alt text -- All forms fully accessible -- Color contrast meets WCAG AA -- Live regions for dynamic content - ---- - -### **Phase 3: Testing & Polish (Week 2, Days 1-3)** ✅ - -#### **Goal**: Comprehensive testing and documentation - -**Tasks:** - -1. **Automated Testing** (Day 1) - - Write jest-axe tests for all pages - - Add axe-core checks to E2E tests - - Run Lighthouse accessibility audits - - Fix all automated test failures - - Add accessibility tests to CI/CD - -2. **Screen Reader Testing** (Day 2) - - Test with NVDA (Windows) - - Test with JAWS (Windows) - - Test with VoiceOver (macOS/iOS) - - Test with TalkBack (Android) - - Document screen reader issues - - Fix critical screen reader bugs - -3. **Manual Testing** (Day 2-3) - - Test all pages with keyboard only (no mouse) - - Test with browser zoom (up to 200%) - - Test with high contrast mode - - Test with reduced motion - - Test with different viewport sizes - - Test all user flows - -4. **Documentation** (Day 3) - - Create accessibility statement page - - Document keyboard shortcuts - - Add ARIA patterns guide for developers - - Create accessibility testing checklist - - Document known issues (if any) - -**Deliverables:** -- Automated accessibility tests passing -- Screen reader testing complete -- Manual testing checklist complete -- Accessibility documentation published - ---- - -### **Phase 4: Advanced Features (Week 2, Days 4-5)** 🚀 - -#### **Goal**: Enhanced accessibility features - -**Tasks:** - -1. **Reduced Motion Support** (Day 4 Morning) - ```css - @media (prefers-reduced-motion: reduce) { - * { - animation-duration: 0.01ms !important; - animation-iteration-count: 1 !important; - transition-duration: 0.01ms !important; - } - } - ``` - - Detect `prefers-reduced-motion` - - Disable animations for users who prefer reduced motion - - Keep essential motion (loading indicators) - -2. **Text Scaling** (Day 4 Afternoon) - - Test with browser text zoom up to 200% - - Use relative units (rem, em) instead of px - - Ensure layout doesn't break at 200% zoom - - Test with browser zoom (page zoom) - -3. **Touch Target Sizes** (Day 5 Morning) - - Audit all interactive elements - - Ensure minimum 44x44px (iOS) / 48x48dp (Android) - - Add padding to small targets - - Increase spacing between adjacent targets - -4. **Additional Enhancements** (Day 5 Afternoon) - - Add high contrast mode support - - Add visual focus indicators for mouse users - - Implement focus-within for nested focus - - Add aria-current for navigation - -**Deliverables:** -- Reduced motion support implemented -- Text scaling verified up to 200% -- Touch targets meet minimum sizes -- Enhanced accessibility features live - ---- - -## Technical Requirements - -### **1. Dependencies to Install** - -```bash -# Linting and Testing -npm install --save-dev eslint-plugin-jsx-a11y -npm install --save-dev jest-axe -npm install --save-dev @axe-core/react - -# Runtime Testing -npm install --save @axe-core/react - -# Focus Management -npm install react-focus-lock focus-trap-react - -# Reduced Motion Hook -npm install framer-motion # Already installed, use useReducedMotion -``` - -### **2. ESLint Configuration** - -Add to `.eslintrc.json`: - -```json -{ - "extends": [ - "plugin:jsx-a11y/recommended" - ], - "plugins": ["jsx-a11y"], - "rules": { - "jsx-a11y/anchor-is-valid": "error", - "jsx-a11y/aria-props": "error", - "jsx-a11y/aria-proptypes": "error", - "jsx-a11y/aria-unsupported-elements": "error", - "jsx-a11y/heading-has-content": "error", - "jsx-a11y/img-redundant-alt": "error", - "jsx-a11y/label-has-associated-control": "error", - "jsx-a11y/no-autofocus": "warn", - "jsx-a11y/no-static-element-interactions": "error" - } -} -``` - -### **3. Axe-Core Integration (Development)** - -Create `components/providers/AxeProvider.tsx`: - -```typescript -'use client'; - -import React, { useEffect } from 'react'; - -export function AxeProvider({ children }: { children: React.ReactNode }) { - useEffect(() => { - if (process.env.NODE_ENV === 'development') { - import('@axe-core/react').then((axe) => { - axe.default(React, require('react-dom'), 1000); - }); - } - }, []); - - return <>{children}; -} -``` - -### **4. Focus Visible Styles** - -Add to `globals.css`: - -```css -/* Focus indicators */ -*:focus { - outline: 2px solid #FF8B7D; /* Coral from design system */ - outline-offset: 2px; -} - -/* Focus visible (keyboard only) */ -*:focus:not(:focus-visible) { - outline: none; -} - -*:focus-visible { - outline: 2px solid #FF8B7D; - outline-offset: 2px; -} - -/* Skip link */ -.skip-link { - position: absolute; - top: -40px; - left: 0; - background: #000; - color: white; - padding: 8px; - text-decoration: none; - z-index: 100; -} - -.skip-link:focus { - top: 0; -} -``` - -### **5. Accessibility Utilities** - -Create `lib/accessibility.ts`: - -```typescript -/** - * Accessibility utility functions - */ - -// Announce to screen readers -export function announceToScreenReader(message: string, priority: 'polite' | 'assertive' = 'polite') { - const announcement = document.createElement('div'); - announcement.setAttribute('role', 'status'); - announcement.setAttribute('aria-live', priority); - announcement.setAttribute('aria-atomic', 'true'); - announcement.className = 'sr-only'; - announcement.textContent = message; - - document.body.appendChild(announcement); - - setTimeout(() => { - document.body.removeChild(announcement); - }, 1000); -} - -// Check if reduced motion is preferred -export function prefersReducedMotion(): boolean { - return window.matchMedia('(prefers-reduced-motion: reduce)').matches; -} - -// Get contrast ratio between two colors -export function getContrastRatio(color1: string, color2: string): number { - // Implementation using relative luminance formula - // WCAG requires 4.5:1 for normal text, 3:1 for large text -} - -// Trap focus within an element -export function trapFocus(element: HTMLElement) { - const focusableElements = element.querySelectorAll( - 'a[href], button, textarea, input, select, [tabindex]:not([tabindex="-1"])' - ); - - const firstElement = focusableElements[0] as HTMLElement; - const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement; - - element.addEventListener('keydown', (e) => { - if (e.key === 'Tab') { - if (e.shiftKey && document.activeElement === firstElement) { - e.preventDefault(); - lastElement.focus(); - } else if (!e.shiftKey && document.activeElement === lastElement) { - e.preventDefault(); - firstElement.focus(); - } - } - }); -} -``` - ---- - -## Testing Strategy - -### **1. Automated Testing** - -#### **ESLint (Static Analysis)** -```bash -npm run lint # Check for accessibility violations -``` - -#### **jest-axe (Unit Tests)** -```typescript -import { render } from '@testing-library/react'; -import { axe, toHaveNoViolations } from 'jest-axe'; - -expect.extend(toHaveNoViolations); - -test('Dashboard should be accessible', async () => { - const { container } = render(); - const results = await axe(container); - expect(results).toHaveNoViolations(); -}); -``` - -#### **Playwright (E2E Tests)** -```typescript -test('should pass accessibility audit', async ({ page }) => { - await page.goto('/dashboard'); - const accessibilityScanResults = await page.evaluate(async () => { - const axe = await import('axe-core'); - return await axe.run(); - }); - expect(accessibilityScanResults.violations).toEqual([]); -}); -``` - -#### **Lighthouse CI** -```bash -npm install --save-dev @lhci/cli -lhci autorun --collect.url=http://localhost:3000 --assert.preset=lighthouse:accessibility -``` - -### **2. Manual Testing Checklist** - -#### **Keyboard Navigation** -- [ ] All interactive elements are keyboard accessible -- [ ] Tab order is logical -- [ ] Focus indicators are visible -- [ ] Skip navigation link works -- [ ] No keyboard traps -- [ ] Escape key closes modals -- [ ] Enter/Space activate buttons - -#### **Screen Reader Testing** -- [ ] Page title is announced -- [ ] Headings are in logical order -- [ ] Form labels are announced -- [ ] Error messages are announced -- [ ] Status updates are announced -- [ ] Images have alt text -- [ ] Links have descriptive text - -#### **Visual Testing** -- [ ] Color contrast meets 4.5:1 (normal text) -- [ ] Color contrast meets 3:1 (large text, 18pt+) -- [ ] Content readable at 200% zoom -- [ ] No horizontal scrolling at 320px width -- [ ] Touch targets are 44x44px minimum - -#### **Assistive Technology** -- [ ] Works with NVDA (Windows) -- [ ] Works with JAWS (Windows) -- [ ] Works with VoiceOver (Mac/iOS) -- [ ] Works with TalkBack (Android) -- [ ] Works with Dragon NaturallySpeaking (voice control) -- [ ] Works with browser zoom - -### **3. Browser Testing Matrix** - -| Browser | Screen Reader | Platform | Status | -|---------|---------------|----------|--------| -| Chrome | NVDA | Windows | TODO | -| Firefox | NVDA | Windows | TODO | -| Edge | JAWS | Windows | TODO | -| Safari | VoiceOver | macOS | TODO | -| Safari | VoiceOver | iOS | TODO | -| Chrome | TalkBack | Android | TODO | - ---- - -## Success Metrics - -### **Quantitative Metrics** - -1. **Lighthouse Accessibility Score**: 100/100 ✅ -2. **Axe-core Violations**: 0 critical, 0 serious ✅ -3. **ESLint jsx-a11y Errors**: 0 ✅ -4. **Color Contrast**: 100% WCAG AA compliant ✅ -5. **Keyboard Navigation**: 100% of features accessible ✅ - -### **Qualitative Metrics** - -1. **Screen Reader Testing**: All critical user flows pass ✅ -2. **User Testing**: Test with 3-5 users with disabilities ✅ -3. **WCAG 2.1 AA Audit**: External audit (optional but recommended) ✅ - -### **Key User Flows to Test** - -1. ✅ **Sign Up / Log In** - - Keyboard accessible - - Error messages announced - - Form labels clear - -2. ✅ **Add Activity (Feeding/Sleep/Diaper)** - - Voice input accessible - - Form fully keyboard accessible - - Success message announced - -3. ✅ **View Dashboard** - - Stats cards readable - - Charts have text alternatives - - Navigation clear - -4. ✅ **AI Assistant Chat** - - Chat input keyboard accessible - - Responses announced to screen reader - - Conversation history navigable - -5. ✅ **Settings & Account** - - All settings keyboard accessible - - Toggle buttons have clear states - - Dialogs trap focus properly - ---- - -## Priority Order (Critical Path) - -### **Day 1 (Must Have)** -1. ESLint jsx-a11y setup -2. Visible focus indicators -3. Skip navigation link -4. Basic ARIA labels on buttons/links - -### **Days 2-3 (Critical)** -5. Keyboard navigation for all pages -6. Focus management for modals -7. Form labels and error messages -8. Heading hierarchy fixes - -### **Days 4-5 (High Priority)** -9. Alt text for all images -10. Color contrast fixes -11. Live regions for dynamic content -12. Automated tests (jest-axe) - -### **Week 2 (Testing & Polish)** -13. Screen reader testing -14. Manual keyboard testing -15. Reduced motion support -16. Documentation - ---- - -## Risk Mitigation - -### **Potential Risks** - -1. **Risk**: Breaking existing functionality - - **Mitigation**: Comprehensive testing after each change - -2. **Risk**: Time overrun - - **Mitigation**: Focus on critical items first (Days 1-3) - -3. **Risk**: Lack of screen reader expertise - - **Mitigation**: Use automated tools, watch video tutorials, hire consultant - -4. **Risk**: Design conflicts (e.g., focus indicators affect design) - - **Mitigation**: Work with design to create accessible alternatives - ---- - -## Resources - -### **Tools** -- [Axe DevTools Browser Extension](https://www.deque.com/axe/devtools/) -- [WAVE Browser Extension](https://wave.webaim.org/extension/) -- [Color Contrast Analyzer](https://www.tpgi.com/color-contrast-checker/) -- [Lighthouse](https://developers.google.com/web/tools/lighthouse) - -### **Documentation** -- [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/) -- [MDN Accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility) -- [A11y Project Checklist](https://www.a11yproject.com/checklist/) -- [ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/) - -### **Screen Readers** -- [NVDA (Free, Windows)](https://www.nvaccess.org/) -- [JAWS (Trial, Windows)](https://www.freedomscientific.com/products/software/jaws/) -- VoiceOver (Built-in, macOS/iOS) -- TalkBack (Built-in, Android) - ---- - -## Next Steps - -1. ✅ **Review and approve this plan** -2. 🔄 **Start Phase 1, Day 1**: Install accessibility tools -3. 🔄 **Daily standups**: Review progress, adjust as needed -4. 🔄 **Test continuously**: Don't wait until the end - ---- - -**Document Owner**: Development Team -**Stakeholders**: Product, Design, QA, Legal -**Review Cadence**: Daily during implementation, weekly post-launch - -**Let's make the Maternal App accessible to ALL parents!** 🌟 diff --git a/docs/implementation-docs/ACCESSIBILITY_PROGRESS.md b/docs/implementation-docs/ACCESSIBILITY_PROGRESS.md deleted file mode 100644 index 8069526..0000000 --- a/docs/implementation-docs/ACCESSIBILITY_PROGRESS.md +++ /dev/null @@ -1,461 +0,0 @@ -# Accessibility Implementation Progress - -**Last Updated**: 2025-10-02 -**Status**: Phase 1 Complete ✅ (Days 1-3) -**Target**: WCAG 2.1 AA Compliance - ---- - -## Executive Summary - -**Phase 1 Foundation (Days 1-3) - ✅ COMPLETE** - -### What Was Accomplished: -- ✅ **Accessibility tools setup** - ESLint jsx-a11y, Axe-core, jest-axe -- ✅ **Skip navigation** - WCAG 2.4.1 compliance -- ✅ **ARIA labels** - 45+ ARIA attributes across 9 components -- ✅ **Keyboard navigation** - Fixed critical issues (Quick Actions), verified MUI support -- ✅ **Color contrast** - All colors meet WCAG AA 4.5:1 (tested with Axe) -- ✅ **Heading hierarchy** - Proper h1→h2 structure across all pages -- ✅ **Semantic landmarks** - header, nav, main regions -- ✅ **Focus management** - Automatic focus on route changes, screen reader announcements - -### Files Created: 7 -1. `.eslintrc.json` - Accessibility linting rules -2. `components/providers/AxeProvider.tsx` - Dev-time testing -3. `components/common/SkipNavigation.tsx` - Skip link -4. `lib/accessibility.ts` - Utility functions (9 functions) -5. `hooks/useFocusManagement.ts` - Focus management hooks (173 lines) -6. `components/providers/FocusManagementProvider.tsx` - Provider wrapper -7. `docs/ACCESSIBILITY_PROGRESS.md` - This document - -### Files Modified: 17 -- `app/layout.tsx` - AxeProvider, SkipNavigation, FocusManagementProvider, main landmark -- `app/globals.css` - 119 lines accessibility styles -- `app/page.tsx` - Quick Actions keyboard accessible, color contrast, headings -- `app/(auth)/login/page.tsx` - Password toggle aria-label, h1 heading -- `app/activities/page.tsx` - h1 heading -- `app/children/page.tsx` - h1 + h2 headings -- `app/family/page.tsx` - h1 + h2 headings -- `app/settings/page.tsx` - h1 + h2 headings -- `styles/themes/maternalTheme.ts` - Text colors (contrast) -- `components/common/EmailVerificationBanner.tsx` - Button contrast -- `components/layouts/MobileNav/MobileNav.tsx` - Header, nav landmarks -- `components/layouts/TabBar/TabBar.tsx` - Nav landmark -- `components/children/ChildDialog.tsx` - ARIA labels -- `components/family/InviteMemberDialog.tsx` - ARIA labels -- `components/children/DeleteConfirmDialog.tsx` - ARIA + alertdialog -- `components/family/RemoveMemberDialog.tsx` - ARIA + alertdialog -- `components/family/JoinFamilyDialog.tsx` - ARIA labels -- `components/auth/MFAVerificationDialog.tsx` - ARIA labels -- `components/voice/VoiceFloatingButton.tsx` - ARIA + live regions - -### Metrics: -| Metric | Value | -|--------|-------| -| **Total Files Created** | 7 | -| **Total Files Modified** | 17 | -| **Lines of Code Added** | ~970+ | -| **ARIA Attributes Added** | 45+ | -| **Components Improved** | 15 | -| **WCAG Success Criteria Met** | 8 | - -### WCAG 2.1 Success Criteria Addressed: - -**Level A:** -- ✅ **1.3.1 Info and Relationships** - Semantic HTML, ARIA labels on dialogs -- ✅ **2.1.1 Keyboard** - All interactive elements keyboard accessible -- ✅ **2.4.1 Bypass Blocks** - Skip navigation link -- ✅ **4.1.2 Name, Role, Value** - ARIA labels, roles on interactive elements - -**Level AA:** -- ✅ **1.4.3 Contrast (Minimum)** - All text meets 4.5:1 ratio (tested with Axe) -- ✅ **2.4.3 Focus Order** - Logical tab order, focus management on route changes -- ✅ **2.4.6 Headings and Labels** - Descriptive headings, proper hierarchy -- ✅ **2.4.7 Focus Visible** - CSS focus indicators with :focus-visible - ---- - -## Overview - -This document tracks progress toward full WCAG 2.1 Level AA accessibility compliance for the Maternal App. Implementation follows the phased approach outlined in `ACCESSIBILITY_IMPLEMENTATION_PLAN.md`. - ---- - -## Phase 1: Foundation (Days 1-3) - -### ✅ Day 1 - Completed - -#### 1. Accessibility Tools Setup - -**Installed Dependencies:** -```json -{ - "devDependencies": { - "eslint-plugin-jsx-a11y": "^6.10.2", - "jest-axe": "^10.0.0", - "@axe-core/react": "^4.10.2", - "eslint-config-next": "^15.5.4" - }, - "dependencies": { - "react-focus-lock": "^2.13.6", - "focus-trap-react": "^11.0.4" - } -} -``` - -**ESLint Configuration** (`.eslintrc.json`): -- Extended `plugin:jsx-a11y/recommended` -- Configured 18 accessibility rules: - - `jsx-a11y/anchor-is-valid`: error - - `jsx-a11y/aria-props`: error - - `jsx-a11y/aria-proptypes`: error - - `jsx-a11y/aria-unsupported-elements`: error - - `jsx-a11y/heading-has-content`: error - - `jsx-a11y/img-redundant-alt`: error - - `jsx-a11y/label-has-associated-control`: error - - `jsx-a11y/no-autofocus`: warn - - `jsx-a11y/no-static-element-interactions`: error - - `jsx-a11y/alt-text`: error - - `jsx-a11y/click-events-have-key-events`: error - - `jsx-a11y/interactive-supports-focus`: error - - `jsx-a11y/no-noninteractive-element-interactions`: error - - `jsx-a11y/no-noninteractive-tabindex`: error - - `jsx-a11y/role-has-required-aria-props`: error - - `jsx-a11y/role-supports-aria-props`: error - - `jsx-a11y/tabindex-no-positive`: error - -**Development Testing** (`components/providers/AxeProvider.tsx`): -- Auto-loads `@axe-core/react` in development mode -- Logs violations to console for immediate feedback -- Configured rules: color-contrast, label, button-name, link-name -- Only runs in development to avoid production performance impact - -**Accessibility Utilities** (`lib/accessibility.ts`): -- `announceToScreenReader()` - Screen reader announcements with aria-live -- `prefersReducedMotion()` - Detects user motion preferences -- `trapFocus()` - Focus trap for modals/dialogs -- `getFocusableElements()` - Query focusable elements -- `getContrastRatio()` - WCAG contrast ratio calculator -- `meetsContrastRequirements()` - AA/AAA compliance checker -- `generateA11yId()` - Unique IDs for ARIA attributes -- `isElementFocusable()` - Visibility and focusability checker -- `focusElement()` - Smart focus with scroll behavior - -**Global CSS** (`app/globals.css`) - 119 lines added: -- Focus indicators: `:focus-visible` with coral outline (#FF8B7D) -- Skip navigation link with keyboard-only visibility -- Screen reader only class (`.sr-only`) -- Reduced motion support (`@media (prefers-reduced-motion: reduce)`) -- High contrast mode support -- Touch target helper class (44x44px minimum) - -#### 2. Skip Navigation - -**Component Created** (`components/common/SkipNavigation.tsx`): -- "Skip to main content" link for keyboard users -- Visually hidden until focused -- Smooth scroll to `#main-content` -- Meets WCAG 2.4.1 (Bypass Blocks) Level A requirement - -**Root Layout Integration** (`app/layout.tsx`): -- Wrapped app with `AxeProvider` for dev-time testing -- Added `SkipNavigation` component at top of body -- Wrapped children in `
` -- Provides skip target and programmatic focus capability - -#### 3. ARIA Labels & Dialog Accessibility - -**Dialogs Updated** (6 components): -1. **ChildDialog** (`components/children/ChildDialog.tsx`): - - Added `aria-labelledby="child-dialog-title"` - - Added `aria-describedby="child-dialog-description"` - - Error alerts with `role="alert"` - -2. **InviteMemberDialog** (`components/family/InviteMemberDialog.tsx`): - - Added `aria-labelledby="invite-dialog-title"` - - Added `aria-describedby="invite-dialog-description"` - - Error alerts with `role="alert"` - -3. **DeleteConfirmDialog** (`components/children/DeleteConfirmDialog.tsx`): - - Added `role="alertdialog"` for destructive action - - Added `aria-labelledby` and `aria-describedby` - - Warning icon with `aria-hidden="true"` - -4. **RemoveMemberDialog** (`components/family/RemoveMemberDialog.tsx`): - - Added `role="alertdialog"` - - Added ARIA labels - - Warning icon with `aria-hidden="true"` - -5. **JoinFamilyDialog** (`components/family/JoinFamilyDialog.tsx`): - - Added `aria-labelledby` and `aria-describedby` - - Error alerts with `role="alert"` - -6. **MFAVerificationDialog** (`components/auth/MFAVerificationDialog.tsx`): - - Added `aria-labelledby` and `aria-describedby` - - Verification code input with `aria-label="Six digit verification code"` - - Loading indicator with `role="status"` and `aria-label` - - Security icon with `aria-hidden="true"` - - Error alerts with `role="alert"` - -**Voice Input Accessibility** (`components/voice/VoiceFloatingButton.tsx`): -- Voice dialog with `aria-labelledby` and `aria-describedby` -- Microphone button with `aria-label` and `aria-pressed` -- Status text with `role="status"` and `aria-live="polite"` -- Classification result with `role="status"` -- Error messages with `role="alert"` -- Processing indicators with `aria-hidden="true"` on CircularProgress -- Unknown command dialog with ARIA labels -- Activity type select with `labelId` and `aria-label` - ---- - -## ESLint Results - -**Accessibility Warnings Found**: 7 instances of `jsx-a11y/no-autofocus` - -**Analysis**: -- All autofocus instances are intentional and improve UX -- Used in dialogs where immediate keyboard input is expected: - - Login/register forms - - MFA verification code input - - Child creation dialog - - Family invitation dialog - - Password reset forms -- Configured as "warn" rather than "error" to allow intentional use -- Each instance provides clear context and expected behavior - -**Other Linter Issues** (non-accessibility): -- 38 unescaped quote errors (cosmetic, not accessibility) -- 15 React Hook dependency warnings (functionality, not accessibility) - ---- - -## Files Modified/Created - -### Created (4 files): -1. `/root/maternal-app/maternal-web/.eslintrc.json` - ESLint config with jsx-a11y -2. `/root/maternal-app/maternal-web/components/providers/AxeProvider.tsx` - Dev-time testing -3. `/root/maternal-app/maternal-web/components/common/SkipNavigation.tsx` - Skip link -4. `/root/maternal-app/maternal-web/lib/accessibility.ts` - Utility functions - -### Modified (9 files): -1. `/root/maternal-app/maternal-web/app/layout.tsx` - AxeProvider + SkipNavigation + main landmark -2. `/root/maternal-app/maternal-web/app/globals.css` - 119 lines of a11y styles -3. `/root/maternal-app/maternal-web/components/children/ChildDialog.tsx` - ARIA labels -4. `/root/maternal-app/maternal-web/components/family/InviteMemberDialog.tsx` - ARIA labels -5. `/root/maternal-app/maternal-web/components/children/DeleteConfirmDialog.tsx` - ARIA + alertdialog -6. `/root/maternal-app/maternal-web/components/family/RemoveMemberDialog.tsx` - ARIA + alertdialog -7. `/root/maternal-app/maternal-web/components/family/JoinFamilyDialog.tsx` - ARIA labels -8. `/root/maternal-app/maternal-web/components/auth/MFAVerificationDialog.tsx` - ARIA labels -9. `/root/maternal-app/maternal-web/components/voice/VoiceFloatingButton.tsx` - ARIA + live regions - -### Package Dependencies: -- `/root/maternal-app/maternal-web/package.json` - Added eslint-config-next - ---- - -## WCAG Success Criteria Addressed (So Far) - -### Level A: -- ✅ **1.3.1 Info and Relationships** - Semantic HTML, ARIA labels on dialogs -- ✅ **2.1.1 Keyboard** - Material-UI components have built-in keyboard support -- ✅ **2.4.1 Bypass Blocks** - Skip navigation link implemented -- ✅ **4.1.2 Name, Role, Value** - ARIA labels, roles on interactive elements - -### Level AA: -- ✅ **2.4.7 Focus Visible** - CSS focus indicators with `:focus-visible` -- 🔄 **1.4.3 Contrast (Minimum)** - Utility function created, audit pending - ---- - -## Metrics - -| Metric | Value | -|--------|-------| -| Files Created | 4 | -| Files Modified | 9 | -| Lines of Code Added | ~580 | -| ARIA Attributes Added | 45+ | -| Focus Management Improvements | 9 components | -| Accessibility Rules Configured | 18 | -| Utility Functions Created | 9 | - ---- - -### ✅ Day 1-2 - Color Contrast & Heading Hierarchy Fixes - -**User Testing with Axe**: -- Fixed password visibility button (added `aria-label`) -- Fixed missing h1 headings on login and home pages -- Fixed color contrast violations: - - Updated theme `text.secondary` color: #718096 → #4A5568 (7:1+ contrast) - - Fixed "Maternal" header color in MobileNav - - Fixed "Resend Email" button contrast in EmailVerificationBanner - - Updated all Quick Action card colors to WCAG AA (4.5:1 minimum) -- Fixed heading hierarchy issues: - - Changed stat numbers from h5 to div with aria-labels - - Added proper h2 headings with component prop - -**Files Modified**: -- `app/(auth)/login/page.tsx` - Password toggle aria-label, h1 heading -- `app/page.tsx` - Quick Action colors, heading hierarchy, stat aria-labels -- `styles/themes/maternalTheme.ts` - Theme text colors -- `components/common/EmailVerificationBanner.tsx` - Button contrast -- `components/layouts/MobileNav/MobileNav.tsx` - Header color - ---- - -### ✅ Day 2 - Keyboard Navigation Audit (In Progress) - -**Audit Findings**: - -✅ **Navigation Components** - Good keyboard support: -- `TabBar.tsx` - MUI BottomNavigation has built-in keyboard support -- `MobileNav.tsx` - MUI Drawer and List components are keyboard accessible -- All navigation items are properly focusable with Tab key - -✅ **Dialogs & Modals** - Excellent keyboard support: -- MUI Dialog components have built-in focus trap -- Escape key to close -- Tab key cycles through dialog elements -- All 6 updated dialogs (Child, InviteMember, DeleteConfirm, RemoveMember, JoinFamily, MFAVerification) - -✅ **Voice Input** - Good keyboard support: -- VoiceFloatingButton uses MUI Fab (keyboard accessible) -- Dialog keyboard navigation works properly - -❌ **Critical Issue Fixed** - Quick Action Cards: -- **Problem**: Used `` which is not keyboard accessible -- **Solution**: Changed to `` with: - - `onKeyDown` handler for Enter and Space keys - - `aria-label` for screen readers - - `:focus-visible` styles with white outline - - Proper focus indicator matching hover state -- **File**: `app/page.tsx` (lines 136-173) - -✅ **List Items** - Good keyboard support: -- Activities list uses MUI ListItem components -- Properly keyboard navigable - -**Keyboard Navigation Checklist**: -- [x] Audit tab order across all pages -- [x] Verify keyboard access to all interactive elements -- [x] Test modal/dialog keyboard navigation (MUI built-in) -- [x] Fix non-keyboard accessible elements (Quick Actions fixed) -- [ ] Document keyboard shortcuts for users - -### ✅ Day 2-3 - Semantic HTML & Landmarks - -**Landmark Regions Added**: -- ✅ `
` - Added to MobileNav AppBar (component="header") -- ✅ `