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.tsdeclares bothmentor_earningsandmentor_transactions;StickyBanner.tsandPopupBanner.tseach declare a row table plus a settings table). Useris the hub — almost every context has a@ManyToOne(() => User). Students, mentors, admins, salespeople, and candidates are all rows inusersdistinguished byrole(src/entities/User.ts:47).Batchis the cohort spine — LMS courses, exams, applications, PAP workflows, lead assignments, and community managers all reference a batch (src/entities/Batch.ts).RawLeadis the CRM spine — all CRM activity logs, follow-ups, and telephony logs hang offraw_leads(src/entities/RawLead.ts).JobApplicationis 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
enumcolumn (e.g.Slots.status,Application.status), though some Mr-Hire entities use a TypeScript string-union typedvarcharinstead (e.g.JobApplication.status: CandidateStatus,src/entities/JobApplication.ts:3).
TypeORM conventions used here¶
- Primary keys: almost universally
@PrimaryGeneratedColumn('uuid')producing auuidid. A handful of legacy/lookup tables use auto-increment integers. - Timestamps: the common pattern is
createdAt/updatedAtcolumns defaulting toCURRENT_TIMESTAMP, withupdatedAtusingonUpdate: 'CURRENT_TIMESTAMP'(seesrc/entities/User.ts:77-81). Some newer entities use@CreateDateColumn/@UpdateDateColumninstead. - Column naming: the default strategy maps the TS property name straight to
the column name (camelCase columns like
mentorId,enrollmentFee). The CRM tables undermas_crmare the exception — they declare explicit snake_case vianame:(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@Columnfor the raw id.onDeleteis set explicitly (CASCADE,SET NULL, orRESTRICT). - Soft refs: many cross-context links are stored as a bare
uuidcolumn 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-arrayfor flexible payloads (roadmaps, features, AI configs,RawLead.extraData). - Sensitive columns:
User.passwordusesselect: falseso 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_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: truein all environments (src/config/database.ts:182). The commented-out env-gated version was replaced by an unconditionaltrue. 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-
publicschemas must pre-exist.synchronizewill not create themas_crm,superadmin,mrlearn, ormrtestschemas; 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_crmentities use explicit snake_casename:. Do not assume one convention when writing raw SQL across schemas. - Two lead models.
Lead(legacy, FK toUser) andRawLead(the active CRM spine) both exist. New CRM work targetsRawLead. - Two course models.
Course(legacy, withModule/Classchildren) andNewCourse/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.passwordisselect: false. Authentication code must explicitly add the field to the query to read it (src/entities/User.ts:25).passwordChangedAtinvalidates old tokens. Access tokens issued before this instant are rejected byauthMiddleware(src/entities/User.ts:30).- Cascade deletes are wide. Deleting a
Usercascades to most owned rows (tokens, slots, usage, CRM logs). PreferisActive = falseover hard delete. - Earnings idempotency.
Slots.earningsCreditedguards against double crediting mentor earnings on repeated meeting-ended events. - Multi-tenant
platformcolumns.JobApplication.platform,JobPost.postedOn, and thex-platformrequest header route behavior across mr-mentor / my-analytics-school via thePlatformentity — filter by platform where present. MentorEarnings.tsdefines two entities (mentor_earnings,mentor_transactions); likewiseStickyBanner.ts/PopupBanner.tsdefine a row table plus a settings table. The 152 files map to ~155 tables.
Related docs¶
- 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
synchronizeon boot. - Guidelines — conventions for adding entities, services, controllers, and routes.