Skip to content

reference data models

Sergey Bogorad edited this page Jul 29, 2026 · 3 revisions

Data models

Kognitika uses Prisma 7 with PostgreSQL 15. The schema is defined in prisma/schema.prisma. There are 12 models.

User

The core identity model. Public auth uses Brain ID; email and password fields exist only for legacy administrative access.

Fields: id, name, email (legacy, nullable, unique), password (legacy, nullable), brainId (nullable, unique), pseudonym (nullable), image (nullable), level (default 1), experience (default 0), rating (default 1000), bonuses (default 0), streakDays (default 0), lastPlayedAt (nullable), role (default "USER"), createdAt.

Relations: sessions (GameSession[]), achievements (UserAchievement[]), xpEvents (XpEvent[]), feedback (Feedback[]), messages (Message[]), ideas (Idea[]), ideaVotes (IdeaVote[]).

GameSession

Records each completed training session. Used by the analytics export, leaderboard, progress tracking, and daily trajectory services.

Fields: id, userId, gameType (enum GameType), score, timeMs, isCompleted (default false), metadata (JSON), createdAt.

The gameType enum has 24 variants: SCHULTE, SCHULTE_GORBOV, NUMERICAL_ANALYSIS, LOGICAL_SEQUENCE, SITUATIONAL_JUDGMENT, STROOP, N_BACK, OBJECTIVE_FILTER, PROFILING_RICE, ANOMALY_DETECTOR, DIALOGUE_2_1, SPEED_TYPING, SPATIAL_CONCEALMENT, TOPOLOGY_MEMORY, COLLISION_DETECTOR, ASYNC_DISPATCHER, NOISE_REDUCTION, LANGUAGE_SCANNER, DECRYPTOR, REALITY_CHECK, MENTAL_MATH, SCHULTE_90, ALPHABET_TABLE, STROOP_ALPHABET.

XpEvent

Tracks experience point changes for the leveling system.

Fields: id, userId, amount, reason, createdAt.

LeaderboardEntry

Denormalized leaderboard rows updated on session completion.

Fields: id, pseudonym (unique), xp, rank, updatedAt.

Feedback

User-submitted feedback with admin response tracking.

Fields: id, userId, type, content, trackingNum (unique), status (default "new"), adminResponse (nullable), createdAt.

Idea

User-submitted feature ideas with voting.

Fields: id, userId, title, description, status (default "PENDING"), createdAt.

Canonical statuses: PENDING, IN_PROGRESS, DONE, REJECTED.

IdeaVote

Tracks upvotes on ideas. One vote per user per idea (enforced by unique constraint on [ideaId, userId]).

Fields: id, ideaId, userId, createdAt.

Achievement

Defines unlockable achievements that can be earned by users.

Fields: id, code (unique), title, description, iconUrl.

UserAchievement

Junction table linking users to their unlocked achievements.

Fields: id, userId, achievementId, unlockedAt.

Message

Chat messages used in the SymbolChat real-time feature.

Fields: id, userId, content, room (default "global"), createdAt.

SessionAnalyticsSummary

Analytics results computed by the analytics worker for each completed session. Stores computed metrics from raw click event data.

Fields: id, jobId (unique), sourceSessionId, moduleId, category, completed, createdAt, eventCount, clickCount, durationMs, p50ReactionMs, p95ReactionMs, speedSlope, accuracy, fatigueIndex, engagementIndex, suspiciousPatternScore, recommendationSignals (JSON).

Mapped to table name session_analytics_summaries.

DailyPracticePlan

Daily practice recommendations generated by the weakest-zone algorithm.

Fields: id, userId, date (Date), items (JSON), createdAt.

Unique constraint on [userId, date]. Mapped to table name daily_practice_plans.

Relationship summary

User ──< GameSession
User ──< XpEvent
User ──< Feedback
User ──< Idea
User ──< IdeaVote
User ──< Message
User ──< UserAchievement >── Achievement
User ──< SessionAnalyticsSummary (via GameSession)
User ──< DailyPracticePlan
LeaderboardEntry (denormalized from User + GameSession)

Clone this wiki locally