Skip to content

Data Model — Entities & Relationships

This document is the canonical map of the TypeORM data model that backs the entire MAS / Mr. Mentor backend. It catalogs every entity under src/entities/ (including the mrlearn/, mrtest/, and workflow/ subfolders), groups them by bounded context, draws per-context ER diagrams, and documents the TypeORM conventions, cross-context foreign keys, Postgres schemas, and status lifecycles that hold the model together. Because this codebase hosts many products in one database, this page is the place to come when you need to understand how a table relates to the rest of the system before you touch it.

Status: documented from source on this branch.


Overview

The backend persists everything to a single PostgreSQL database accessed through TypeORM. There are no separate microservice databases — Mr. Mentor (mentorship), Mr. Hire (recruitment/ATS), the MAS LMS, the Sales CRM, Finance, the AI platform, the workflow engine, the vendor API, and the marketing surfaces all share one connection pool and one DataSource (src/config/database.ts).

Who reads/writes the model: - Students / users (role = USER) — mentorship bookings, course enrollment, quizzes, assignments, applications, tokens. - Mentors / experts (role = EXPERT) — slots, earnings, recordings. - Admins / superadmins (role = ADMIN | SUPERADMIN) — batches, courses, finance, job posts, banners, system config, almost everything. - Sales / sales heads / community managers (role = SALES) — CRM leads, follow-ups, targets, telephony logs. - Background workers & integrations — BullMQ workers, the workflow engine, Mr Learn / Mr Test sync runs, vendor API ingestion, AI calling providers.

The DataSource config sets synchronize: true and logging: false (src/config/database.ts:182-183), so the schema is auto-derived from the entity classes on boot. There are no migration files in dev — entity changes apply directly. The connection pool is min 5 / max 20.

The model spans five Postgres schemas, not just public:

Schema Owner context Example tables
public (default) Mentorship, tokens, LMS, Mr-Hire, AI, marketing, auth users, slots, courses, job_applications
mas_crm Sales CRM + workflow engine raw_leads, lead_call_logs, workflows
superadmin Finance global_payments, gst_state_code, hsn_sac_master, gst_audit_log
mrlearn Mr Learn integration courses, learners, sync_runs
mrtest Mr Test integration online_exams, students, submissions

Because TypeORM synchronize: true does not create non-default Postgres schemas, src/config/database.ts explicitly creates the non-public schemas before synchronize runs (src/config/database.ts:269 and surrounding block).


Key concepts & entities

  • Entity / table — a TypeORM class decorated with @Entity('table_name'). 152 entity files define ~155 tables (a few files declare two entities, e.g. MentorEarnings.ts declares both mentor_earnings and mentor_transactions; StickyBanner.ts and PopupBanner.ts each declare a row table plus a settings table).
  • User is the hub — almost every context has a @ManyToOne(() => User). Students, mentors, admins, salespeople, and candidates are all rows in users distinguished by role (src/entities/User.ts:47).
  • Batch is the cohort spine — LMS courses, exams, applications, PAP workflows, lead assignments, and community managers all reference a batch (src/entities/Batch.ts).
  • RawLead is the CRM spine — all CRM activity logs, follow-ups, and telephony logs hang off raw_leads (src/entities/RawLead.ts).
  • JobApplication is the Mr-Hire spine — resume analysis, screening results, quiz responses, voice interviews, and talent-pool entries all reference a job application.
  • Enums for status — most stateful entities use a Postgres enum column (e.g. Slots.status, Application.status), though some Mr-Hire entities use a TypeScript string-union typed varchar instead (e.g. JobApplication.status: CandidateStatus, src/entities/JobApplication.ts:3).

TypeORM conventions used here

  • Primary keys: almost universally @PrimaryGeneratedColumn('uuid') producing a uuid id. A handful of legacy/lookup tables use auto-increment integers.
  • Timestamps: the common pattern is createdAt/updatedAt columns defaulting to CURRENT_TIMESTAMP, with updatedAt using onUpdate: 'CURRENT_TIMESTAMP' (see src/entities/User.ts:77-81). Some newer entities use @CreateDateColumn / @UpdateDateColumn instead.
  • Column naming: the default strategy maps the TS property name straight to the column name (camelCase columns like mentorId, enrollmentFee). The CRM tables under mas_crm are the exception — they declare explicit snake_case via name: (e.g. @Column({ name: 'session_year' }), src/entities/RawLead.ts:45). There is no global SnakeNamingStrategy.
  • Relations: foreign keys are declared as @ManyToOne(() => X) with a matching @JoinColumn({ name: 'xId' }) and a sibling scalar @Column for the raw id. onDelete is set explicitly (CASCADE, SET NULL, or RESTRICT).
  • Soft refs: many cross-context links are stored as a bare uuid column with no @ManyToOne (e.g. Batch.courseId, JobApplication.jobPostId, User.masBatch) to avoid hard FK coupling across products.
  • JSON columns: heavy use of json / jsonb / simple-json / simple-array for flexible payloads (roadmaps, features, AI configs, RawLead.extraData).
  • Sensitive columns: User.password uses select: false so it is excluded from default queries (src/entities/User.ts:25).

Architecture

How a row gets read or written: routes mount controllers, controllers call services, services use TypeORM repositories obtained from the shared DataSource, which talks to the one Postgres instance. External systems (Razorpay, S3, AI calling, Mr Learn/Test) write back through the same repositories, often via BullMQ workers.

flowchart TD
    subgraph FE["Frontends"]
        W["mas-website-live"]
        MF["mr-mentor-frontend"]
        HF["mr-hire-frontend"]
    end

    subgraph API["mr-mentor-backend (Express)"]
        R["Routes (routes/index.ts)"]
        C["Controllers (42)"]
        S["Services (46+)"]
        WK["BullMQ Workers (5)"]
        WF["Workflow engine"]
    end

    subgraph ORM["Data Access"]
        DS["TypeORM DataSource (src/config/database.ts)"]
        REPO["Repositories per Entity"]
    end

    DB[("PostgreSQL (5 schemas)")]
    RD[("Redis / BullMQ")]
    EXT["External: Razorpay, S3, AI calling, MrLearn, MrTest"]

    W --> R
    MF --> R
    HF --> R
    R --> C --> S
    S --> REPO
    WK --> REPO
    WF --> REPO
    REPO --> DS --> DB
    S --> RD
    WK --> RD
    S --> EXT
    EXT -.->|"webhooks and sync"| WK

Entity catalog

Grouped by bounded context. Table purpose is summarized; key relations name the most important foreign keys (target entity). "soft ref" means a bare uuid column with no enforced FK.

Mentorship & meetings

Entity Context Table purpose Key relations
User (User.ts) auth/mentorship Every person in the system; role distinguishes USER/EXPERT/ADMIN/SUPERADMIN/SALES self FK salesHead; OneToOne Mentor, StudentProfile, Token
Mentor (Mentor.ts) mentorship Mentor profile (bio, expertise, rates) OneToOne User
MentorApplication (MentorApplication.ts) mentorship Mentor onboarding submissions ManyToOne User
Slots (Slots.ts) mentorship A bookable/booked 1:1 meeting slot ManyToOne User (mentor), User (student); OneToOne SlotsFeedBack
RequestedSlot (RequestedSlot.ts) mentorship Student-initiated slot requests ManyToOne User x2
SlotsFeedBack (SlotsFeedBack.ts) mentorship Post-meeting feedback/rating OneToOne Slots; ManyToOne User x2
MeetingLogs (MeetingLogs.ts) mentorship Per-event meeting activity log ManyToOne Slots, User
MeetingRecording (MeetingRecording.ts) mentorship S3 recording metadata + status ManyToOne Slots, User
MeetingActionToken (MeetingActionToken.ts) mentorship One-time email action tokens for meetings ManyToOne Slots, User
SuperMentorAssignment (SuperMentorAssignment.ts) mentorship Assigns a super-mentor to a batch ManyToOne User x2, Batch
SuperMentorMeeting (SuperMentorMeeting.ts) mentorship Group/super-mentor meetings ManyToOne User x2
ProfileView (ProfileView.ts) mentorship Records mentor profile views ManyToOne User x2
Issues (Issues.ts) mentorship User-reported issues ManyToOne User
GoogleAuthTokens (GoogleAuthTokens.ts) mentorship Per-user Google Calendar OAuth tokens ManyToOne User

Token economy & mentor payouts

Entity Context Table purpose Key relations
Token (Tokens.ts) tokens Per-user token wallet balance OneToOne User
PromotionalToken (PromotionalToken.ts) tokens Promotional/free token grants OneToOne User
TokenUsage (TokenUsage.ts) tokens Token spend ledger per booking ManyToOne User, Slots
TokenPurchase (TokenPurchase.ts) tokens/finance Razorpay token purchase record ManyToOne User
TokenAllotmentRequest (TokenAllotmentRequest.ts) tokens Admin/batch token allotment requests ManyToOne User x2, Batch
MentorEarnings (MentorEarnings.ts) tokens Mentor earnings balance + withdrawal status ManyToOne User
MentorTransaction (MentorEarnings.ts) tokens Mentor credit/debit transaction ledger ManyToOne User

Finance (schema superadmin)

Entity Context Table purpose Key relations
GlobalPayment (GlobalPayment.ts) finance Global/international payment records soft refs to user/application
GstStateCode (GstStateCode.ts) finance GST state-code lookup for invoicing lookup
HsnSacMaster (HsnSacMaster.ts) finance HSN/SAC code master for tax lines lookup
GstAuditLog (GstAuditLog.ts) finance Audit trail for GST invoice actions soft ref
DiscountRequest (DiscountRequest.ts) finance Discount approval requests on applications ManyToOne Application, Batch, User x2
PipelineCostLedger (PipelineCostLedger.entity.ts) finance Per-stage external-provider cost ledger soft refs (CostStage/CostProvider enums)

Mr-Hire (recruitment / ATS)

Entity Context Table purpose Key relations
JobPost (JobPost.ts) mr-hire Job opening (roles, salary band, portal) soft ref belongsTo user
JobApplication (JobApplication.ts) mr-hire Candidate application; pipeline status soft ref jobPostId
Application (Application.ts) mr-hire/LMS MAS program application (enrollment funnel) ManyToOne User, Batch
MentorApplication see mentorship
IIMTApplication (IIMTApplication.entity.ts) mr-hire IIMT-specific application form capture standalone
ResumeAnalysis (ResumeAnalysis.entity.ts) mr-hire AI resume parse/score output ManyToOne JobApplication
ResumeReviewRequest (ResumeReviewRequest.ts) mr-hire User-requested resume reviews ManyToOne User x2
ScreeningResult (ScreeningResult.entity.ts) mr-hire AI screening verdict per application ManyToOne JobApplication
AiScreeningConfig (AiScreeningConfig.entity.ts) mr-hire Per-user AI screening configuration ManyToOne User
JobScreeningConfig (JobScreeningConfig.entity.ts) mr-hire Per-job screening configuration ManyToOne JobPost
CandidateQuizResponse (CandidateQuizResponse.ts) mr-hire Candidate quiz answers/score soft ref to application/quiz
QuizTemplate (QuizTemplate.entity.ts) mr-hire Reusable candidate quiz templates standalone
VoiceInterview (VoiceInterview.entity.ts) mr-hire AI voice interview session ManyToOne JobApplication; OneToMany VoiceInterviewMessage
VoiceInterviewMessage (VoiceInterviewMessage.entity.ts) mr-hire Turn-by-turn interview transcript ManyToOne VoiceInterview
TalentPoolEntry (TalentPoolEntry.entity.ts) mr-hire Candidate added to talent pool ManyToOne JobApplication, JobPost
TalentPoolMatch (TalentPoolMatch.entity.ts) mr-hire Match between pool entry and a job ManyToOne TalentPoolEntry, JobPost
SalaryBenchmark (SalaryBenchmark.ts) mr-hire Role/region salary benchmark data lookup
JobTemplate (JobTemplate.ts) mr-hire Reusable job-post templates ManyToOne User
JobPlatformPosting (JobPlatformPosting.ts) mr-hire Job posted to an external platform/account ManyToOne JobPost, Platform, HrPlatformAccount
HrPlatformAccount (HrPlatformAccount.ts) mr-hire Linked external HR-platform account ManyToOne User, Platform
HrCallConfig (HrCallConfig.ts) mr-hire HR phone-call configuration ManyToOne User
AICallPrompt (AICallPrompt.entity.ts) mr-hire Prompt templates for AI calling standalone
AaryaCallBatch (AaryaCallBatch.ts) mr-hire/comms Batch of Aarya AI outbound calls ManyToOne User
MissOzoneCall (MissOzoneCall.entity.ts) mr-hire/comms MissOzone AI call record ManyToOne User x2
ApplicationWhatsAppMessage (ApplicationWhatsAppMessage.entity.ts) mr-hire/comms WhatsApp messages tied to an application ManyToOne Application, User

MAS LMS (courses, batches, learning)

Entity Context Table purpose Key relations
Batch (Batch.ts) lms Cohort/program batch (mas101, etc.) OneToMany Application; soft refs courseId, superMentorId, cmId, batchLeadId
Course (Course.ts) lms Course definition (legacy format) OneToMany Enrollment, Module
NewCourse (NewCourse.ts, table mas_courses) lms New course format (MasCourse) standalone (json modules)
CoursePlan (CoursePlan.ts) lms/ai AI-generated course plan ManyToOne Course, User; OneToMany CoursePlanLecture
CoursePlanLecture (CoursePlanLecture.ts) lms/ai Lecture within a course plan ManyToOne CoursePlan, AiClassroom
Module (Module.ts, table course_modules) lms Course module ManyToOne Course; OneToMany Class, Quiz, Assignment
Class (Class.ts) lms A class/lecture within a module ManyToOne Module
Enrollment (Enrollment.ts) lms User enrolled in a course ManyToOne User, Course
Quiz (Quiz.ts) lms Quiz within a module ManyToOne Module
QuizSubmission (QuizSubmission.ts) lms Quiz attempt by a user ManyToOne Quiz, User
Assignment (Assignment.ts) lms Assignment within a module ManyToOne Module
Announcement (Announcement.ts) lms Course/batch announcements soft refs
Attendance (Attendance.ts) lms Class attendance records ManyToOne User x2
StudentProfile (StudentProfile.ts) lms Extended student profile OneToOne User
StudentActivity (StudentActivity.ts) lms/engagement Student activity feed events ManyToOne User
BatchMeeting (BatchMeeting.ts) lms Batch-level live meetings ManyToOne Batch, User
BatchMrLearnCourse (BatchMrLearnCourse.ts) lms/integration Maps a batch to a Mr Learn course ManyToOne Batch (soft)
BatchMrTestExam (BatchMrTestExam.ts) lms/integration Maps a batch to a Mr Test exam ManyToOne Batch (soft)
SavedCourse (SavedCourse.ts) lms User-bookmarked courses soft refs
CourseInterest (CourseInterest.ts) lms/marketing Course interest leads soft refs
CourseAssignmentHistory (CourseAssignmentHistory.ts) lms History of course assignments soft refs
ExternalCourse (ExternalCourse.ts) lms/integration External course catalog entries standalone
Webinar (Webinar.ts) lms/marketing Webinar definition standalone
WebinarProgress (WebinarProgress.ts) lms/engagement Per-user webinar progress ManyToOne User, Webinar
College (College.ts) lms/metadata College directory (seeded) lookup

Student engagement & gamification

Entity Context Table purpose Key relations
XpEvent (XpEvent.ts) engagement XP award events soft ref user
StudentBadge (StudentBadge.ts) engagement Badges earned ManyToOne User
StudentProgress (StudentProgress.ts) engagement Progress tracking soft refs
StudentRiskScore (StudentRiskScore.ts) engagement Risk/churn scoring soft refs
StudentSkillRating (StudentSkillRating.ts) engagement Skill ratings ManyToOne User x2
StudentQuery (StudentQuery.ts) engagement Student support queries ManyToOne User
Warning (Warning.ts) engagement Disciplinary warnings ManyToOne User x2
WeeklyRating (WeeklyRating.ts) engagement Weekly performance ratings ManyToOne User x2
DailyCard (DailyCard.ts) engagement Daily learning cards ManyToOne User
PerformanceMetric (PerformanceMetric.ts) engagement Per-user performance metrics ManyToOne User
EvalTest (EvalTest.ts) engagement Evaluation test records ManyToOne User

Sales CRM (schema mas_crm)

Entity Context Table purpose Key relations
RawLead (RawLead.ts) sales-crm The CRM lead record (the CRM spine) ManyToOne User (assignee/counsellor/owning head); ManyToMany LeadTag
Lead (Lead.ts) sales-crm Legacy lead tied to a User ManyToOne User x2
CampaignLead (CampaignLead.ts) sales-crm Marketing-campaign lead ManyToOne User
LeadActivityLog (LeadActivityLog.ts) sales-crm Lead activity timeline ManyToOne RawLead, User
LeadFollowUp (LeadFollowUp.ts) sales-crm Scheduled follow-ups ManyToOne RawLead, User
LeadCallLog (LeadCallLog.ts) sales-crm/comms Call records (incl. Exotel) ManyToOne RawLead, User
LeadSmsLog (LeadSmsLog.ts) sales-crm/comms SMS records ManyToOne RawLead, User
LeadEmailLog (LeadEmailLog.ts) sales-crm/comms Email send/track records ManyToOne RawLead, User
LeadWhatsAppLog (LeadWhatsAppLog.ts) sales-crm/comms WhatsApp message records ManyToOne RawLead, User
LeadTag (LeadTag.ts) sales-crm Lead tags (many-to-many) referenced by RawLead
LeadImportBatch (LeadImportBatch.ts) sales-crm Bulk lead import batch ManyToOne User
LeadAssignmentApproval (LeadAssignmentApproval.ts) sales-crm Lead-assignment approval requests ManyToOne User x2
LeadAssignmentHistory (LeadAssignmentHistory.ts) sales-crm History of lead reassignments ManyToOne RawLead, User x2
BatchLeadAssignment (BatchLeadAssignment.ts) sales-crm Bulk lead-to-user assignment ManyToOne User, Batch
SalesHeadProfile (SalesHeadProfile.ts) sales-crm Sales-head metadata ManyToOne User
SalespersonTarget (SalespersonTarget.ts) sales-crm Salesperson targets/quotas ManyToOne User
CommunityManagerAssignment (CommunityManagerAssignment.ts) sales-crm CM-to-batch assignment ManyToOne User x2, Batch
CMNote (CMNote.ts) sales-crm Community-manager notes ManyToOne User x2
AaryaCallBatch (AaryaCallBatch.ts) sales-crm/comms Aarya AI call batch (also Mr-Hire) ManyToOne User

Communications

Entity Context Table purpose Key relations
Notification (Notification.ts) comms In-app notifications ManyToOne User
EmailSent (EmailSent.entity.ts) comms Sent-email audit log ManyToOne User
EmailTemplate (EmailTemplate.entity.ts) comms Reusable email templates standalone
WhatsAppConfig (WhatsAppConfig.entity.ts) comms Per-user WhatsApp config ManyToOne User
WhatsAppMessage (WhatsAppMessage.entity.ts) comms WhatsApp message log ManyToOne User, JobApplication

AI platform

Entity Context Table purpose Key relations
UserLlmKey (UserLlmKey.ts) ai Per-user LLM API keys ManyToOne User
AgentConfiguration (AgentConfiguration.ts) ai Agent config/definition soft refs
AgentConfigurationHistory (AgentConfigurationHistory.ts) ai Versioned agent config history soft ref to config
AskMasLog (AskMasLog.ts) ai "Ask MAS" query/response log soft ref user
AiClassroom (AiClassroom.ts) ai/lms AI classroom definition ManyToOne Course, Module, User
AiClassroomProgress (AiClassroomProgress.ts) ai/engagement Per-user AI classroom progress ManyToOne User, AiClassroom
AiClassroomRequest (AiClassroomRequest.ts) ai AI classroom generation requests ManyToOne User x2
AiForEveryoneInterest (AiForEveryoneInterest.ts) ai/marketing AI-course interest leads standalone

Workflow automation engine (schema mas_crm)

Entity Context Table purpose Key relations
Workflow (workflow/Workflow.entity.ts) workflow Workflow definition (nodes/edges json) soft refs
WorkflowEnrollment (workflow/WorkflowEnrollment.entity.ts) workflow An entity enrolled into a workflow run soft ref to subject (lead/user)
WorkflowNodeRun (workflow/WorkflowNodeRun.entity.ts) workflow Per-node execution record ManyToOne WorkflowEnrollment (soft)
WorkflowRule (WorkflowRule.entity.ts, table workflow_rules) workflow/mr-hire Trigger rules (e.g. on JobPost) ManyToOne JobPost

Vendor API platform

Entity Context Table purpose Key relations
VendorApiKey (VendorApiKey.ts) vendor API key issued to a vendor ManyToOne User x2 (created/updated by)
VendorApiKeyAccessSummary (VendorApiKeyAccessSummary.ts) vendor Usage/access rollups per key ManyToOne VendorApiKey
VendorLead (VendorLead.ts) vendor Lead ingested via a vendor key ManyToOne VendorApiKey

Integrations — Mr Learn (schema mrlearn) & Mr Test (schema mrtest)

Entity Context Table purpose Key relations
MrLearnCourse (mrlearn/MrLearnCourse.ts) integration Synced Mr Learn course standalone
MrLearnLearner (mrlearn/MrLearnLearner.ts) integration Synced Mr Learn learner standalone
MrLearnLearnerReport (mrlearn/MrLearnLearnerReport.ts) integration Learner progress report soft ref learner
MrLearnAuthCredentials (mrlearn/MrLearnAuthCredentials.ts) integration Mr Learn auth credentials standalone
MrLearnSyncConfig (mrlearn/MrLearnSyncConfig.ts) integration Sync configuration standalone
MrLearnSyncRun (mrlearn/MrLearnSyncRun.ts) integration Sync run record standalone
MrLearnReminderLog (mrlearn/MrLearnReminderLog.ts) integration Reminder send log standalone
MrTestOnlineExam (mrtest/MrTestOnlineExam.ts) integration Synced Mr Test exam standalone
MrTestStudent (mrtest/MrTestStudent.ts) integration Synced Mr Test student standalone
MrTestSubmission (mrtest/MrTestSubmission.ts) integration Exam submission soft ref student/exam
MrTestSubmissionReport (mrtest/MrTestSubmissionReport.ts) integration Submission report soft ref submission
MrTestAuthCredentials (mrtest/MrTestAuthCredentials.ts) integration Mr Test auth credentials standalone
MrTestSyncConfig (mrtest/MrTestSyncConfig.ts) integration Sync configuration standalone
MrTestSyncRun (mrtest/MrTestSyncRun.ts) integration Sync run record standalone
Platform (Platform.ts) integration Multi-tenant platform registry referenced by HR postings

Marketing, events & PAP

Entity Context Table purpose Key relations
StickyBanner (StickyBanner.ts) marketing Sticky banner row
StickyBannerSettings (StickyBanner.ts) marketing Sticky banner global settings
PopupBanner (PopupBanner.ts) marketing Popup banner row
PopupBannerSettings (PopupBanner.ts) marketing Popup banner global settings
BannerTemplate (BannerTemplate.ts) marketing Reusable banner templates
LeagueRegistration (LeagueRegistration.ts) events League/event registrations soft refs
EventConfiguration (EventConfiguration.ts) events Event configuration toggles
Mas101PapWorkflow (Mas101PapWorkflow.ts) pap/finance Pay-after-placement agreement workflow ManyToOne Application, User, Batch, Mas101PapAgreementTemplate
Mas101PapAgreementTemplate (Mas101PapAgreementTemplate.ts) pap PAP agreement templates referenced by workflow

Auth & tracking

Entity Context Table purpose Key relations
RefreshToken (RefreshToken.ts) auth JWT refresh tokens ManyToOne User
LoginLog (LoginLog.ts) auth Login/logout audit ManyToOne User
SystemConfig (SystemConfig.ts) auth/config Global key-value system config
QuestionBankCategory (QuestionBankCategory.ts) metadata Quiz question categories OneToMany QuestionBankQuestion
QuestionBankQuestion (QuestionBankQuestion.ts) metadata Quiz question bank ManyToOne QuestionBankCategory

Data model — ER diagrams per context

1. Mentorship & meetings

erDiagram
    USER ||--o| MENTOR : "has profile"
    USER ||--o{ SLOTS : "mentors"
    USER ||--o{ SLOTS : "books as student"
    SLOTS ||--o| SLOTSFEEDBACK : "has feedback"
    SLOTS ||--o{ MEETINGLOGS : "logs"
    SLOTS ||--o{ MEETINGRECORDING : "recordings"
    SLOTS ||--o{ MEETINGACTIONTOKEN : "action tokens"
    USER ||--o{ REQUESTEDSLOT : "requests"
    USER ||--o| GOOGLEAUTHTOKENS : "calendar tokens"

    SLOTS {
        uuid id PK
        uuid mentorId FK
        uuid studentId FK
        timestamp startDateTime
        timestamp endDateTime
        enum status
        boolean earningsCredited
    }
    MENTOR {
        uuid id PK
        uuid userId FK
    }
    SLOTSFEEDBACK {
        uuid id PK
        uuid slotId FK
        enum experience
    }

2. Token economy & payouts

erDiagram
    USER ||--o| TOKEN : "wallet"
    USER ||--o| PROMOTIONALTOKEN : "promo wallet"
    USER ||--o{ TOKENUSAGE : "spends"
    SLOTS ||--o{ TOKENUSAGE : "consumes"
    USER ||--o{ TOKENPURCHASE : "buys"
    USER ||--o{ MENTOREARNINGS : "earns"
    USER ||--o{ MENTORTRANSACTION : "ledger"
    USER ||--o{ TOKENALLOTMENTREQUEST : "requests"
    BATCH ||--o{ TOKENALLOTMENTREQUEST : "for batch"

    TOKEN {
        uuid id PK
        uuid userId FK
        float token
        float resumeToken
    }
    TOKENUSAGE {
        uuid id PK
        uuid userId FK
        uuid slotId FK
        enum type
    }
    TOKENPURCHASE {
        uuid id PK
        uuid userId FK
        enum status
    }

3. Finance (schema superadmin)

erDiagram
    APPLICATION ||--o{ DISCOUNTREQUEST : "discount on"
    BATCH ||--o{ DISCOUNTREQUEST : "for batch"
    USER ||--o{ DISCOUNTREQUEST : "raised by"
    GLOBALPAYMENT }o--|| GSTSTATECODE : "state"
    GLOBALPAYMENT }o--o{ HSNSACMASTER : "tax lines"

    GLOBALPAYMENT {
        uuid id PK
        enum status
    }
    DISCOUNTREQUEST {
        uuid id PK
        uuid applicationId FK
        uuid batchId FK
        enum status
    }
    PIPELINECOSTLEDGER {
        uuid id PK
        enum stage
        enum provider
    }

4. Mr-Hire (recruitment / ATS)

erDiagram
    JOBPOST ||--o{ JOBAPPLICATION : "receives"
    JOBPOST ||--o{ JOBSCREENINGCONFIG : "screening config"
    JOBPOST ||--o{ JOBPLATFORMPOSTING : "posted to"
    PLATFORM ||--o{ JOBPLATFORMPOSTING : "platform"
    HRPLATFORMACCOUNT ||--o{ JOBPLATFORMPOSTING : "via account"
    JOBAPPLICATION ||--o{ RESUMEANALYSIS : "analyzed"
    JOBAPPLICATION ||--o{ SCREENINGRESULT : "screened"
    JOBAPPLICATION ||--o{ VOICEINTERVIEW : "interviewed"
    VOICEINTERVIEW ||--o{ VOICEINTERVIEWMESSAGE : "transcript"
    JOBAPPLICATION ||--o{ TALENTPOOLENTRY : "pooled"
    TALENTPOOLENTRY ||--o{ TALENTPOOLMATCH : "matched"
    JOBPOST ||--o{ TALENTPOOLMATCH : "to job"

    JOBAPPLICATION {
        uuid id PK
        string jobPostId
        string status
        int priority
        string platform
    }
    JOBPOST {
        uuid id PK
        json roles
        string status
        int salaryMin
        int salaryMax
    }
    VOICEINTERVIEW {
        uuid id PK
        uuid jobApplicationId FK
    }

5. MAS LMS (courses & batches)

erDiagram
    COURSE ||--o{ MODULE : "has"
    MODULE ||--o{ CLASS_SESSION : "has"
    MODULE ||--o{ QUIZ : "has"
    MODULE ||--o{ ASSIGNMENT : "has"
    COURSE ||--o{ ENROLLMENT : "enrolls"
    USER ||--o{ ENROLLMENT : "enrolled"
    QUIZ ||--o{ QUIZSUBMISSION : "attempts"
    USER ||--o{ QUIZSUBMISSION : "submits"
    BATCH ||--o{ APPLICATION : "applications"
    BATCH ||--o{ BATCHMEETING : "meetings"
    COURSE ||--o{ COURSEPLAN : "plans"
    COURSEPLAN ||--o{ COURSEPLANLECTURE : "lectures"
    USER ||--o| STUDENTPROFILE : "profile"

    COURSE {
        uuid id PK
        enum level
        enum status
        decimal price
    }
    MODULE {
        uuid id PK
        uuid courseId FK
    }
    ENROLLMENT {
        uuid id PK
        uuid userId FK
        uuid courseId FK
        enum status
    }
    BATCH {
        uuid id PK
        string code UK
        enum status
        decimal enrollmentFee
    }

6. Student engagement & gamification

erDiagram
    USER ||--o{ XPEVENT : "earns xp"
    USER ||--o{ STUDENTBADGE : "badges"
    USER ||--o{ STUDENTPROGRESS : "progress"
    USER ||--o{ STUDENTRISKSCORE : "risk"
    USER ||--o{ STUDENTSKILLRATING : "skills"
    USER ||--o{ WARNING : "warnings"
    USER ||--o{ WEEKLYRATING : "weekly rating"
    USER ||--o{ DAILYCARD : "daily cards"
    USER ||--o{ PERFORMANCEMETRIC : "metrics"
    USER ||--o{ STUDENTQUERY : "queries"

    WARNING {
        uuid id PK
        enum warningType
        enum severity
    }
    STUDENTRISKSCORE {
        uuid id PK
        uuid userId FK
    }

7. Sales CRM (schema mas_crm)

erDiagram
    RAWLEAD ||--o{ LEADACTIVITYLOG : "activity"
    RAWLEAD ||--o{ LEADFOLLOWUP : "follow-ups"
    RAWLEAD ||--o{ LEADCALLLOG : "calls"
    RAWLEAD ||--o{ LEADSMSLOG : "sms"
    RAWLEAD ||--o{ LEADEMAILLOG : "emails"
    RAWLEAD ||--o{ LEADWHATSAPPLOG : "whatsapp"
    RAWLEAD ||--o{ LEADASSIGNMENTHISTORY : "reassigned"
    RAWLEAD }o--o{ LEADTAG : "tagged"
    USER ||--o{ RAWLEAD : "assigned to"
    USER ||--o{ RAWLEAD : "owns as head"
    LEADIMPORTBATCH ||--o{ RAWLEAD : "imported"
    USER ||--o| SALESHEADPROFILE : "head profile"
    USER ||--o{ SALESPERSONTARGET : "targets"
    BATCH ||--o{ COMMUNITYMANAGERASSIGNMENT : "cm assigned"

    RAWLEAD {
        uuid id PK
        string session_year
        string phone
        uuid assigned_to FK
        uuid owning_sales_head_id FK
        enum interestLevel
        enum webinarStatus
    }
    LEADCALLLOG {
        uuid id PK
        uuid rawLeadId FK
        enum outcome
        enum source
    }

8. Communications

erDiagram
    USER ||--o{ NOTIFICATION : "notified"
    USER ||--o{ EMAILSENT : "emails"
    USER ||--o| WHATSAPPCONFIG : "wa config"
    USER ||--o{ WHATSAPPMESSAGE : "wa messages"
    JOBAPPLICATION ||--o{ WHATSAPPMESSAGE : "about application"
    APPLICATION ||--o{ APPLICATIONWHATSAPPMESSAGE : "wa thread"

    NOTIFICATION {
        uuid id PK
        uuid userId FK
        enum type
        enum category
        enum priority
    }
    EMAILSENT {
        uuid id PK
        uuid userId FK
    }

9. AI platform

erDiagram
    USER ||--o{ USERLLMKEY : "llm keys"
    USER ||--o{ AICLASSROOMPROGRESS : "progress"
    AICLASSROOM ||--o{ AICLASSROOMPROGRESS : "tracked"
    COURSE ||--o{ AICLASSROOM : "classroom"
    MODULE ||--o{ AICLASSROOM : "for module"
    USER ||--o{ AICLASSROOMREQUEST : "requests"
    AGENTCONFIGURATION ||--o{ AGENTCONFIGURATIONHISTORY : "versions"

    AICLASSROOM {
        uuid id PK
        uuid courseId FK
        uuid moduleId FK
        enum status
    }
    USERLLMKEY {
        uuid id PK
        uuid userId FK
    }

10. Workflow engine (schema mas_crm)

erDiagram
    WORKFLOW ||--o{ WORKFLOWENROLLMENT : "enrolls"
    WORKFLOWENROLLMENT ||--o{ WORKFLOWNODERUN : "executes nodes"
    JOBPOST ||--o{ WORKFLOWRULE : "trigger rule"

    WORKFLOW {
        uuid id PK
        json definition
    }
    WORKFLOWENROLLMENT {
        uuid id PK
        uuid workflowId FK
        enum status
    }
    WORKFLOWNODERUN {
        uuid id PK
        uuid enrollmentId FK
        enum status
    }

11. Vendor API platform

erDiagram
    USER ||--o{ VENDORAPIKEY : "created by"
    VENDORAPIKEY ||--o{ VENDORLEAD : "ingests"
    VENDORAPIKEY ||--o{ VENDORAPIKEYACCESSSUMMARY : "usage"
    VENDORLEAD }o--o| RAWLEAD : "promoted to lead"

    VENDORAPIKEY {
        uuid id PK
        enum status
    }
    VENDORLEAD {
        uuid id PK
        uuid vendorApiKeyId FK
        enum status
    }

12. Integrations (Mr Learn / Mr Test) & PAP

erDiagram
    BATCH ||--o{ BATCHMRLEARNCOURSE : "mr-learn map"
    BATCH ||--o{ BATCHMRTESTEXAM : "mr-test map"
    MRLEARNLEARNER ||--o{ MRLEARNLEARNERREPORT : "report"
    MRTESTSTUDENT ||--o{ MRTESTSUBMISSION : "submits"
    MRTESTSUBMISSION ||--o| MRTESTSUBMISSIONREPORT : "report"
    APPLICATION ||--o{ MAS101PAPWORKFLOW : "pap workflow"
    BATCH ||--o{ MAS101PAPWORKFLOW : "for batch"
    MAS101PAPAGREEMENTTEMPLATE ||--o{ MAS101PAPWORKFLOW : "template"

    MAS101PAPWORKFLOW {
        uuid id PK
        uuid applicationId FK
        uuid userId FK
        uuid batchId FK
        enum status
        enum paymentOption
    }

Cross-context foreign keys

These are the relationships that stitch the products together. Knowing them is essential before deleting or refactoring a hub table.

flowchart LR
    USER["User (hub)"]
    BATCH["Batch (cohort spine)"]
    RAWLEAD["RawLead (CRM spine)"]
    JOBAPP["JobApplication (ATS spine)"]
    COURSE["Course"]

    USER -->|"mentor / student"| SLOTS["Slots"]
    USER -->|"wallet"| TOKEN["Token"]
    USER -->|"enrolled"| ENR["Enrollment"]
    USER -->|"applicant"| APP["Application"]
    USER -->|"assignee / head"| RAWLEAD
    USER -->|"created by"| VAK["VendorApiKey"]
    USER -->|"llm keys"| LLM["UserLlmKey"]
    USER -->|"30+ engagement tables"| ENG["XP / Warnings / Risk"]

    BATCH -->|"applications"| APP
    BATCH -->|"mr-learn / mr-test"| INTG["Batch integration maps"]
    BATCH -->|"pap"| PAP["Mas101PapWorkflow"]
    BATCH -->|"cm / batch lead (soft ref)"| USER

    COURSE -->|"modules / enrollments"| ENR
    COURSE -->|"ai plans"| CP["CoursePlan"]

    JOBAPP -->|"resume / screening / voice"| AIHIRE["AI Hire pipeline"]
    RAWLEAD -->|"all comms + activity"| CRM["Lead logs"]
    VAK -->|"ingests"| VL["VendorLead"]
    VL -.->|"promoted"| RAWLEAD

Notable rules: - User is referenced by nearly every entity. onDelete: 'CASCADE' on most user-owned rows means deleting a user cascades widely; onDelete: 'SET NULL' is used where the row should survive (e.g. MeetingRecording.uploadedBy, LeadActivityLog.performedBy). - Batch ↔ many products: LMS applications, Mr Learn/Test exam maps, PAP workflows, CM/batch-lead assignment. Most batch links are soft refs (courseId, superMentorId, cmId, batchLeadId) to avoid hard coupling. - RawLead (CRM) and the legacy Lead (tied directly to a User) coexist; CRM comms tables all FK to RawLead with onDelete: 'CASCADE'. - Cross-product soft refs avoid FKs on purpose: JobApplication.jobPostId, Batch.courseId, User.masBatch are plain columns, not enforced FKs.


API surface

The data model itself is not exposed by a single dedicated route group — it is read and written through the per-feature controllers documented in each context doc. The routes most directly tied to schema/data administration are:

Method Path Auth/role Purpose
GET /api/health public Liveness check (confirms DB/Redis reachable)
ALL /api/redis/* admin Redis cache admin
ALL /api/cleanup/* admin Data cleanup operations
GET /admin/queues/* admin Bull Board queue monitoring UI
ALL /api/system-config/* (inferred) superadmin SystemConfig key-value administration

For per-entity CRUD endpoints (users, slots, batches, courses, leads, job posts, etc.) see the corresponding feature docs under ../features/. Do not infer entity endpoints from this page — derive them from the relevant route file and src/routes/index.ts mount prefix.


User journeys

These journeys show how rows are created and mutated across contexts. They are data-model-centric (which tables change, in what order) rather than full UI flows.

Journey 1 — User signup creates the core graph

When a user signs up, several OneToOne satellites are created so the rest of the system can assume they exist.

sequenceDiagram
    participant FE as Frontend
    participant API as Auth Controller
    participant SVC as Auth Service
    participant DB as PostgreSQL

    FE->>API: POST signup with email and password
    API->>SVC: register user
    SVC->>DB: insert into users with role USER and stage SIGNUP
    DB-->>SVC: user row with uuid id
    SVC->>DB: insert token wallet row referencing userId
    SVC->>DB: insert promotional token row referencing userId
    SVC->>DB: insert login_logs row for the signup action
    SVC-->>API: user plus JWT
    API-->>FE: 201 created with access token

Journey 2 — Booking a mentor slot and spending tokens

sequenceDiagram
    participant FE as Frontend
    participant API as Slots Controller
    participant SVC as Slot Service
    participant DB as PostgreSQL

    FE->>API: POST book slot with slotId
    API->>SVC: book slot for student
    SVC->>DB: read token wallet balance for user
    alt insufficient balance
        SVC-->>API: error not enough tokens
        API-->>FE: 402 payment required
    else has balance
        SVC->>DB: update slots set studentId and status confirmed
        SVC->>DB: insert token_usage row linking user and slot
        SVC->>DB: decrement token wallet balance
        SVC->>DB: insert meeting_action_tokens for email actions
        SVC-->>API: booked slot
        API-->>FE: 200 booked
    end

Journey 3 — Meeting completion credits mentor earnings

sequenceDiagram
    participant SOCK as Socket server
    participant SVC as Meeting Service
    participant DB as PostgreSQL

    SOCK->>SVC: meeting ended for slotId
    SVC->>DB: update slots set status completed and actualEndTime
    SVC->>DB: insert meeting_logs end event
    alt earnings not yet credited
        SVC->>DB: insert mentor_transactions credit row
        SVC->>DB: upsert mentor_earnings balance
        SVC->>DB: update slots set earningsCredited true
    else already credited
        Note over SVC: skip to avoid double credit
    end

Journey 4 — Mr-Hire candidate pipeline

A JobApplication.status walks through the CandidateStatus union as AI stages complete, each writing a child row.

sequenceDiagram
    participant FE as Mr-Hire UI
    participant API as Job Application Controller
    participant SVC as Screening Service
    participant Q as resumeAnalysis queue
    participant DB as PostgreSQL

    FE->>API: POST apply with resume file
    API->>DB: insert job_applications status resume_received
    API->>Q: enqueue resume analysis job
    Q->>SVC: process resume for applicationId
    SVC->>DB: insert resume_analyses row
    SVC->>DB: update job_applications status resume_parsed
    SVC->>DB: insert screening_results row
    SVC->>DB: update job_applications status scoring_complete
    alt passes threshold
        SVC->>DB: update status shortlisted
        SVC->>DB: insert talent_pool_entries row
    else below threshold
        SVC->>DB: update status talent_pool
    end

Journey 5 — CRM lead capture, assignment and follow-up

sequenceDiagram
    participant SRC as Vendor or import or webinar
    participant API as Lead Controller
    participant SVC as Lead Service
    participant DB as PostgreSQL (mas_crm)

    SRC->>API: POST new lead payload
    API->>SVC: create raw lead
    SVC->>DB: insert raw_leads with sourceType
    SVC->>DB: insert lead_activity_log created event
    API->>SVC: assign lead to salesperson
    SVC->>DB: update raw_leads set assigned_to and assigned_at
    SVC->>DB: insert lead_assignment_history row
    Note over SVC: salesperson logs a call
    SVC->>DB: insert lead_call_logs with outcome
    SVC->>DB: insert lead_follow_ups scheduled row

Journey 6 — PAP (pay-after-placement) workflow

sequenceDiagram
    participant FE as Student UI
    participant API as PAP Controller
    participant SVC as PAP Service
    participant DB as PostgreSQL

    FE->>API: start pap workflow for application
    API->>DB: insert mas101_pap_workflows status pending_mou_details
    FE->>API: submit MOU details then eSign
    SVC->>DB: update status pending_mou_review with signed document
    Note over SVC: admin reviews and approves
    SVC->>DB: update status mou_signed_approved
    FE->>API: choose payment option upfront or pap
    SVC->>DB: update status pending_pap_approval or pending_upfront_payment
    SVC->>DB: update status enrolled once payment confirmed

Journey 7 — Vendor lead promoted into the CRM

sequenceDiagram
    participant V as Vendor system
    participant API as Vendor API
    participant SVC as Vendor Service
    participant DB as PostgreSQL

    V->>API: POST lead with x-api-key header
    API->>SVC: validate vendor api key
    alt key revoked or disabled
        SVC-->>API: 401 invalid key
        API-->>V: 401
    else key active
        SVC->>DB: insert vendor_leads referencing vendorApiKeyId
        SVC->>DB: upsert vendor_api_key_access_summaries usage
        SVC->>DB: insert raw_leads with sourceType vendor and vendor_lead_id
        SVC-->>API: accepted
        API-->>V: 202 accepted
    end

Background jobs & async

The data model is also mutated outside the request path. Per mr-mentor-backend/CLAUDE.md and the workers under src/workers/:

Worker / source Queue / trigger Tables it writes
email.worker emailQueue emails_sent, notifications
database.worker databaseQueue heavy bulk writes across entities
cleanup.worker cleanupQueue (every 24h) expires/deletes stale slots and related rows
kpi.worker kpiQueue (every 15min) performance_metrics and dashboard rollups
resumeAnalysis.worker resumeAnalysisQueue resume_analyses, screening_results, job_applications
Workflow engine scheduled node runs workflow_enrollments, workflow_node_runs
Mr Learn / Mr Test sync sync runs mrlearn.*, mrtest.*, *_sync_runs
Socket.IO meeting events real-time slots, meeting_logs, meeting_recordings, mentor_*

synchronize: true means the very first write after a deploy that adds a column implicitly ALTERs the table on boot — there is no separate migration step.


External integrations

These third-party systems write back into the model (usually via a worker or webhook). See ../features/ for per-integration detail.

System Tables touched Env / notes
Razorpay token_purchases, applications, global_payments RAZORPAY_KEY_ID/SECRET; status enums track payment lifecycle
AWS S3 meeting_recordings, batch banners, documents AWS_* buckets
Google OAuth / Calendar google_auth_tokens, slots calendar event ids GOOGLE_*
Exotel (telephony) lead_call_logs, lead_sms_logs optional; CRM falls back to tel: links when unset
WhatsApp whatsapp_messages, application_whatsapp_messages, lead_whatsapp_logs per WhatsAppConfig
AI calling (Aarya / MissOzone / ElevenLabs) aarya_call_batches, miss_ozone_calls, voice_interviews Mr-Hire
Leegality (eSign) mas101_pap_workflows (signed document) PAP agreements
Mr Learn / Mr Test mrlearn.*, mrtest.* sync configs + runs
LLM gateway / per-user keys user_llm_keys, agent_configurations, ask_mas_logs AI platform

Status lifecycles

Slot (Slots.status, enum MeetingStatus)

stateDiagram-v2
    [*] --> TENTATIVE
    TENTATIVE --> MEETING_REQUESTED
    MEETING_REQUESTED --> CONFIRMED
    TENTATIVE --> CONFIRMED
    CONFIRMED --> UNDER_REVIEW
    CONFIRMED --> COMPLETED
    CONFIRMED --> CANCELLATION_REQUESTED
    CANCELLATION_REQUESTED --> CANCELLED
    CONFIRMED --> CANCELLED
    COMPLETED --> [*]
    CANCELLED --> [*]

Program application (Application.status, enum ApplicationStatus)

stateDiagram-v2
    [*] --> DRAFT
    DRAFT --> SUBMITTED
    SUBMITTED --> UNDER_REVIEW
    UNDER_REVIEW --> APPROVED
    UNDER_REVIEW --> REJECTED
    APPROVED --> PAYMENT_RECEIVED
    PAYMENT_RECEIVED --> PAID
    PAID --> BATCH_ALLOCATED
    BATCH_ALLOCATED --> ENROLLED
    ENROLLED --> DEBOARDED
    REJECTED --> [*]
    DEBOARDED --> [*]

Mr-Hire candidate (JobApplication.status, union CandidateStatus)

stateDiagram-v2
    [*] --> resume_received
    resume_received --> resume_parsed
    resume_parsed --> outreach_sent
    outreach_sent --> quiz_invited
    quiz_invited --> quiz_completed
    quiz_completed --> voice_interview_scheduled
    voice_interview_scheduled --> voice_interview_completed
    voice_interview_completed --> scoring_complete
    scoring_complete --> shortlisted
    scoring_complete --> talent_pool
    shortlisted --> [*]
    talent_pool --> [*]

PAP workflow (Mas101PapWorkflow.status)

stateDiagram-v2
    [*] --> PENDING_MOU_DETAILS
    PENDING_MOU_DETAILS --> PENDING_MOU_UPLOAD
    PENDING_MOU_UPLOAD --> PENDING_MOU_REVIEW
    PENDING_MOU_REVIEW --> MOU_SIGNED_APPROVED
    MOU_SIGNED_APPROVED --> PENDING_PAYMENT_OPTION
    PENDING_PAYMENT_OPTION --> PENDING_PAP_APPROVAL
    PENDING_PAYMENT_OPTION --> PENDING_UPFRONT_PAYMENT
    PENDING_PAP_APPROVAL --> ENROLLED
    PENDING_UPFRONT_PAYMENT --> ENROLLED
    ENROLLED --> PLACEMENT_UNDER_REVIEW
    PLACEMENT_UNDER_REVIEW --> PAYMENT_COLLECTION_PENDING
    PAYMENT_COLLECTION_PENDING --> [*]

Workflow enrollment (WorkflowEnrollment.status)

stateDiagram-v2
    [*] --> ACTIVE
    ACTIVE --> WAITING
    WAITING --> ACTIVE
    ACTIVE --> PAUSED
    PAUSED --> ACTIVE
    ACTIVE --> COMPLETED
    ACTIVE --> FAILED
    ACTIVE --> CANCELLED
    COMPLETED --> [*]
    FAILED --> [*]
    CANCELLED --> [*]

Other status enums (for reference)

  • MeetingRecording.status: RECORDING, PROCESSING, UPLOADED, FAILED, DELETED.
  • TokenPurchase.status (PaymentStatus): PENDING, COMPLETED, FAILED, CANCELLED.
  • Enrollment.status: NOT_STARTED, IN_PROGRESS, COMPLETED.
  • Batch.status: UPCOMING, ACTIVE, COMPLETED, CANCELLED.
  • Lead.status: ACTIVE, ARCHIVED, DELETED.
  • CoursePlan.status: DRAFT, GENERATING, APPROVED, PAUSED, COMPLETED, FAILED.
  • VendorApiKey.status: ACTIVE, DISABLED, REVOKED.
  • JobPost.status: draft, active, paused, closed.

Edge cases, limits & gotchas

  • synchronize: true in all environments (src/config/database.ts:182). The commented-out env-gated version was replaced by an unconditional true. This means an entity change auto-ALTERs production tables on boot. Renaming a column drops the old one and creates a new (empty) one — never rename a column without a manual data move. Removing a property can drop a column and its data.
  • Non-public schemas must pre-exist. synchronize will not create the mas_crm, superadmin, mrlearn, or mrtest schemas; the DataSource creates them before sync (src/config/database.ts:269). A new schema requires adding it to that bootstrap block.
  • No global naming strategy. Default columns are camelCase, but mas_crm entities use explicit snake_case name:. Do not assume one convention when writing raw SQL across schemas.
  • Two lead models. Lead (legacy, FK to User) and RawLead (the active CRM spine) both exist. New CRM work targets RawLead.
  • Two course models. Course (legacy, with Module/Class children) and NewCourse/mas_courses (MasCourse, json-based) coexist.
  • Soft FKs are unenforced. Batch.courseId, JobApplication.jobPostId, User.masBatch, Mas101PapWorkflow.batchId (nullable SET NULL) may dangle — always null-check joins.
  • User.password is select: false. Authentication code must explicitly add the field to the query to read it (src/entities/User.ts:25).
  • passwordChangedAt invalidates old tokens. Access tokens issued before this instant are rejected by authMiddleware (src/entities/User.ts:30).
  • Cascade deletes are wide. Deleting a User cascades to most owned rows (tokens, slots, usage, CRM logs). Prefer isActive = false over hard delete.
  • Earnings idempotency. Slots.earningsCredited guards against double crediting mentor earnings on repeated meeting-ended events.
  • Multi-tenant platform columns. JobApplication.platform, JobPost.postedOn, and the x-platform request header route behavior across mr-mentor / my-analytics-school via the Platform entity — filter by platform where present.
  • MentorEarnings.ts defines two entities (mentor_earnings, mentor_transactions); likewise StickyBanner.ts/PopupBanner.ts define a row table plus a settings table. The 152 files map to ~155 tables.

  • Architecture overview — service topology and request flow.
  • Feature docs — per-context API surfaces and UI flows that read and write these entities (mentorship, tokens, Mr-Hire, LMS, CRM, finance, AI, workflow, vendor, integrations, marketing).
  • DevOps — deployment, the AWS Secrets Manager env flow, and the blue-green deploy that runs synchronize on boot.
  • Guidelines — conventions for adding entities, services, controllers, and routes.