# Data Model Documentation ## Overview Complete Prisma schema with 13 entities, 10 enums, and comprehensive relationships for the Math Learning Platform. --- ## Entities ### 1. User (users) User accounts with authentication and profile information. **Fields:** - `id` (String, @id, @default(cuid)) - `email` (String, @unique) - `username` (String, @unique) - `passwordHash` (String) - `telegramChatId` (String?, @unique, hidden from users) - `isActive` (Boolean, @default(true)) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) - `lastLoginAt` (DateTime?) **Relationships:** - Has many ExerciseAttempt - Has many Progress - Has many UserAchievement - Has many Ranking - Has many Notification **Indexes:** - email - username - isActive --- ### 2. Module (modules) Pedagogical modules containing educational content. **Fields:** - `id` (String, @id, @default(cuid)) - `name` (String) - `description` (String) - `type` (ModuleType, enum) - `order` (Int) - `isPublished` (Boolean, @default(false)) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) - `introduction` (String?, Text, LaTeX supported) - `examples` (Json?, array of examples with formulas) - `exercises` (Json?, exercise sections) - `answers` (Json?, answer keys) - `estimatedHours` (Int?, @default(0)) - `difficultyLevel` (ExerciseDifficulty, @default(INTERMEDIATE)) - `totalExercises` (Int, @default(0)) **Relationships:** - Has many Topic - Has many Exercise - Has many Progress - Has many Ranking **Indexes:** - type+order (unique) - type - order - isPublished **Modules:** 1. FUNDAMENTOS - Vectores and Matrices 2. SISTEMAS_ESPACIOS - Sistemas and Espacios Vectoriales 3. APLICACIONES - Programación Lineal --- ### 3. Topic (topics) Mathematical topics within modules. **Fields:** - `id` (String, @id, @default(cuid)) - `moduleId` (String, foreign key) - `name` (String) - `type` (TopicType, enum) - `order` (Int) - `description` (String?) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) - `theoryContent` (Json?, theory with formulas) - `formulas` (Json?, LaTeX formulas) - `keyPoints` (Json?, key learning points) - `commonMistakes` (Json?, common errors) **Relationships:** - Belongs to Module (onDelete: Cascade) - Has many Exercise **Indexes:** - moduleId+order (unique) - moduleId - type **Topics:** 1. VECTORES 2. MATRICES 3. SISTEMAS 4. ESPACIOS_VECTORIALES 5. PROGRAMACION_LINEAL --- ### 4. Exercise (exercises) Mathematical exercises with LaTeX formulas. **Fields:** - `id` (String, @id, @default(cuid)) - `moduleId` (String, foreign key) - `topicId` (String?, foreign key) - `type` (ExerciseType, enum) - `difficulty` (ExerciseDifficulty, enum) - `order` (Int) - `statement` (String, Text, LaTeX supported) - `correctAnswer` (String, Text, LaTeX supported) - `solutionSteps` (Json?, step-by-step solutions) - `formulas` (Json?, related formulas) - `hints` (Json?, hints with costs) - `isAIGenerated` (Boolean, @default(false)) - `isPublished` (Boolean, @default(false)) - `points` (Int, @default(10)) - `timeLimitSeconds` (Int?) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) - `multipleChoiceOptions` (Json?, for multiple choice) - `proofRequirements` (Json?, for proof exercises) - `calculationSteps` (Json?, for calculation exercises) **Relationships:** - Belongs to Module (onDelete: Cascade) - Belongs to Topic (onDelete: SetNull) - Has many ExerciseAttempt **Indexes:** - moduleId+order (unique) - moduleId - topicId - type - difficulty - isPublished - isAIGenerated --- ### 5. ExerciseAttempt (exercise_attempts) User attempts at exercises. **Fields:** - `id` (String, @id, @default(cuid)) - `userId` (String, foreign key) - `exerciseId` (String, foreign key) - `userAnswer` (String, Text) - `status` (AttemptStatus, enum) - `pointsEarned` (Int, @default(0)) - `timeSpentSeconds` (Int) - `hintsUsed` (Int, @default(0)) - `feedback` (String?, Text) - `createdAt` (DateTime, @default(now)) - `attemptNumber` (Int) - `isPerfect` (Boolean, @default(false)) - `skipped` (Boolean, @default(false)) **Relationships:** - Belongs to User (onDelete: Cascade) - Belongs to Exercise (onDelete: Cascade) **Indexes:** - userId+exerciseId+attemptNumber (unique) - userId - exerciseId - status - createdAt - userId+exerciseId --- ### 6. Progress (progress) User progress tracking per module. **Fields:** - `id` (String, @id, @default(cuid)) - `userId` (String, foreign key) - `moduleId` (String, foreign key) - `exercisesCompleted` (Int, @default(0)) - `totalExercises` (Int, @default(0)) - `points` (Int, @default(0)) - `percentage` (Float, @default(0)) - `isStarted` (Boolean, @default(false)) - `isCompleted` (Boolean, @default(false)) - `startedAt` (DateTime?) - `completedAt` (DateTime?) - `lastAccessedAt` (DateTime?) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) - `averageScore` (Float?) - `totalTimeSpent` (Int, @default(0), seconds) - `perfectExercises` (Int, @default(0)) - `attemptsCount` (Int, @default(0)) **Relationships:** - Belongs to User (onDelete: Cascade) - Belongs to Module (onDelete: Cascade) **Indexes:** - userId+moduleId (unique) - userId - moduleId - isCompleted - points --- ### 7. Achievement (achievements) Gamification badges and achievements. **Fields:** - `id` (String, @id, @default(cuid)) - `code` (String, @unique) - `name` (String) - `description` (String) - `category` (AchievementCategory, enum) - `rarity` (AchievementRarity, enum) - `icon` (String, emoji or icon name) - `requirementType` (RequirementType, enum) - `requirementValue` (Int) - `points` (Int, @default(0)) - `metadata` (Json?, {color, animation, tooltip, unlockMessage}) - `isActive` (Boolean, @default(true)) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) **Relationships:** - Has many UserAchievement **Indexes:** - category - rarity - isActive - code **Achievements (18 total):** - Exercises: FIRST_EXERCISE, TEN_EXERCISES, HUNDRED_EXERCISES, FIVE_PERFECT - Modules: FIRST_MODULE, ALL_MODULES, PERFECT_MODULE - Streaks: THREE_DAY_STREAK, WEEK_STREAK, MONTH_STREAK - Ranking: TOP_10, PODIUM, CHAMPION - Special: EARLY_BIRD, NIGHT_OWL, AUTODIDACT --- ### 8. UserAchievement (user_achievements) Unlocked achievements for users. **Fields:** - `id` (String, @id, @default(cuid)) - `userId` (String, foreign key) - `achievementId` (String, foreign key) - `progress` (Int, @default(0)) - `unlockedAt` (DateTime?) - `metadata` (Json?, {unlockedDetails, relatedStats}) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) **Relationships:** - Belongs to User (onDelete: Cascade) - Belongs to Achievement (onDelete: Cascade) **Indexes:** - userId+achievementId (unique) - userId - achievementId - unlockedAt --- ### 9. Ranking (rankings) Leaderboard positions (global and per-module). **Fields:** - `id` (String, @id, @default(cuid)) - `userId` (String, foreign key) - `moduleId` (String?, foreign key, null=global) - `position` (Int) - `points` (Int, @default(0)) - `exercisesCompleted` (Int, @default(0)) - `streak` (Int, @default(0)) - `lastUpdated` (DateTime, @default(now)) - `perfectExercises` (Int, @default(0)) - `averageScore` (Float?) - `totalAttempts` (Int, @default(0)) - `achievementsUnlocked` (Int, @default(0)) **Relationships:** - Belongs to User (onDelete: Cascade) - Belongs to Module (onDelete: Cascade) **Indexes:** - userId+moduleId (unique) - moduleId - position - points - streak --- ### 10. Notification (notifications) Telegram notifications (backend only). **Fields:** - `id` (String, @id, @default(cuid)) - `type` (NotificationType, enum) - `title` (String) - `message` (String, Text) - `telegramChatId` (String, foreign key to User.telegramChatId) - `status` (NotificationStatus, enum, @default(PENDING)) - `priority` (Int, @default(0)) - `metadata` (Json?, {userId, relatedData, actionUrl}) - `attempts` (Int, @default(0)) - `lastAttemptAt` (DateTime?) - `sentAt` (DateTime?) - `errorMessage` (String?, Text) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) **Relationships:** - Belongs to User (via telegramChatId, onDelete: Cascade) **Indexes:** - status - type - telegramChatId - createdAt - priority --- ### 11. ProcessedPdf (processed_pdfs) PDF processing metadata. **Fields:** - `id` (String, @id, @default(cuid)) - `fileName` (String, @unique) - `originalPath` (String) - `type` (PdfType, enum) - `topicType` (TopicType?, enum) - `isProcessed` (Boolean, @default(false)) - `processingStartedAt` (DateTime?) - `processingCompletedAt` (DateTime?) - `errorMessage` (String?, Text) - `extractedText` (Json?, {pages: [...]}) - `exercisesDetected` (Json?, array of exercises) - `formulasExtracted` (Json?, array of formulas) - `metadata` (Json?, {author, pages, isbn, year, edition}) - `totalPages` (Int?) - `processingVersion` (String?) - `checksum` (String?) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) **Indexes:** - type - topicType - isProcessed - fileName --- ### 12. SystemConfig (system_config) System configuration key-value storage. **Fields:** - `id` (String, @id, @default(cuid)) - `key` (String, @unique) - `value` (String, Text) - `description` (String?) - `category` (String?) - `isPublic` (Boolean, @default(false)) - `createdAt` (DateTime, @default(now)) - `updatedAt` (DateTime, @updatedAt) **Indexes:** - category - key --- ### 13. AuditLog (audit_logs) Audit trail for system events. **Fields:** - `id` (String, @id, @default(cuid)) - `userId` (String?) - `action` (String) - `entityType` (String) - `entityId` (String?) - `metadata` (Json?) - `ipAddress` (String?) - `userAgent` (String?) - `createdAt` (DateTime, @default(now)) **Indexes:** - userId - action - entityType - createdAt --- ## Enums ### ModuleType - FUNDAMENTOS - SISTEMAS_ESPACIOS - APLICACIONES ### TopicType - VECTORES - MATRICES - SISTEMAS - ESPACIOS_VECTORIALES - PROGRAMACION_LINEAL ### ExerciseType - MULTIPLE_CHOICE - OPEN_RESPONSE - CALCULATION - PROOF - TRUE_FALSE ### ExerciseDifficulty - BASIC - INTERMEDIATE - ADVANCED - EXPERT ### AttemptStatus - CORRECT - INCORRECT - PARTIAL - PENDING ### AchievementCategory - EXERCISES - MODULES - STREAKS - RANKING - SPECIAL ### AchievementRarity - COMMON - RARE - EPIC - LEGENDARY ### RequirementType - EXERCISES_COMPLETED - MODULES_COMPLETED - PERFECT_SCORES - STREAK_DAYS - RANKING_POSITION - EXERCISES_WITHOUT_HINTS - EARLY_BIRD - NIGHT_OWL - PERFECT_MODULE ### NotificationType - NEW_USER - EXERCISE_COMPLETED - MODULE_COMPLETED - ACHIEVEMENT_UNLOCKED - SYSTEM_ERROR - DAILY_SUMMARY - RANKING_CHANGED ### NotificationStatus - PENDING - SENT - FAILED ### PdfType - TEXTBOOK - PRACTICE - PRACTICE_ANSWERS - EXAM - ADDITIONAL_MATERIAL --- ## Key Relationships ### User Progress Flow 1. User → ExerciseAttempt (many) 2. User → Progress (one per module) 3. User → UserAchievement (many) 4. User → Ranking (one global + one per module) ### Module Content Flow 1. Module → Topic (many) 2. Module → Exercise (many) 3. Topic → Exercise (many) 4. Exercise → ExerciseAttempt (many) ### Gamification Flow 1. Achievement → UserAchievement (many) 2. ExerciseAttempt → triggers Achievement check 3. Progress → triggers Ranking update ### Notification Flow 1. ExerciseAttempt → triggers Notification 2. Progress → triggers Notification 3. UserAchievement → triggers Notification --- ## JSON Fields Structure ### Module.examples ```json [ { "title": "string", "content": "string", "latexFormula": "string", "explanation": "string", "difficulty": "BASIC|INTERMEDIATE|ADVANCED|EXPERT" } ] ``` ### Exercise.solutionSteps ```json [ { "step": 1, "explanation": "string", "latexFormula": "string" } ] ``` ### Exercise.hints ```json [ { "hint": "string", "cost": 2 } ] ``` ### ProcessedPdf.extractedText ```json { "pages": [ { "page": 1, "text": "string", "tables": [...], "images": [...] } ] } ``` --- ## Performance Optimization ### Indexes All foreign keys and frequently queried fields are indexed. ### Cascade Deletes - User deletion → all related data deleted - Module deletion → topics, exercises, progress deleted - Exercise deletion → attempts deleted ### JSON Fields Used for flexible content storage (formulas, examples, solutions). --- ## Data Integrity ### Unique Constraints - User email, username - User telegramChatId - Achievement code - ProcessedPdf fileName - Module type+order - Topic moduleId+order - Exercise moduleId+order - UserProgress userId+moduleId - UserAchievement userId+achievementId - Ranking userId+moduleId ### Required Fields All critical fields have @default or are required. --- ## Future Enhancements ### Potential Additions 1. Exercise comments/discussions 2. User social features (follow, share) 3. Course enrollments 4. Certificate generation 5. Analytics dashboard 6. Content versioning 7. Multi-language support ### Scalability Considerations 1. Partitioning for large tables (ExerciseAttempt) 2. Archival strategy for old data 3. Caching layer for frequently accessed data 4. Read replicas for reporting queries --- **Schema Version**: 1.0.0 **Last Updated**: 2026-03-23 **Total Entities**: 13 **Total Enums**: 10 **Total Relationships**: 20+