Cluster
Detail
CLUSTER 1IdentityCLUSTER 2AcademicCLUSTER 3RequestCLUSTER 4Evidenceholds1:Nscopes1:Nsigns in as1:0..1teaches1:Nrules on1:Nenrols1:Nowns1:Npopulates1:Npopulates1:Npopulates1:Napproves1:Ndeclares1:Nis taught as1:Ndates1:Nis mapped in1:Nis judged in1:Npins version1:Nrequests1:Nhosts1:Ndecided by1:Nnotifies1:Nevidenced by1:1verified by1:Nconfirms1:Nfans out to1:Nwrites1:Nis verified via1:Nrecords1:Nusers2 idx_idId<"users">subjectstringemailstringdisplayNamestringstatusactive | inactivecreatedAtnumberroleAssignments2 idx_idId<"roleAssignments">userIdId<"users">roleenum · 5scopeTypeenum · 3scopeIdstringgrantedById<"users">grantedAtnumberrevokedAt?numberdepartments_idId<"departments">namestringschoolstringcodestringrosterImports_idId<"rosterImports">uploadedById<"users">fileNamestringfileHashstring · sha256scopeSelectorstringstatusenum · 3rowCountnumbercreatedCountnumberupdatedCountnumberdeactivatedCountnumbercreatedAtnumberpolicies_idId<"policies">versionstringeffectiveFromnumberthresholdsThreshold[]departmentId?Id<"departments">createdById<"users">students2 idx_idId<"students">userId?Id<"users">registrationNostring · uniquenamestringprogrammestringspecializationstringsemesternumbersectionstringdepartmentIdId<"departments">statusactive | inactivecourses1 idx_idId<"courses">codestringtitlestringcreditsnumberdepartmentIdId<"departments">semesternumbercourseOutcomes_idId<"courseOutcomes">courseIdId<"courses">coIdCO1 … CO4textstringcontactHoursnumberteachingAssignments2 idx_idId<"teachingAssignments">courseIdId<"courses">teacherUserIdId<"users">sectionstringtermIdId<"terms">terms_idId<"terms">namestringstartsOnnumberendsOnnumberisCurrentbooleannocRequests3 idx_idId<"nocRequests">studentIdId<"students">stageStage · 10blockersBlocker[] · 5companyIdId<"companies">rolestringstartDatenumberendDatenumbermodeenum · 3stipendnumberpolicyVersionstringmappedPercent?numbersubmittedAtnumberdecidedAt?numberfingerprintstringcompanies2 idx_idId<"companies">legalNamestringwebsitestringdomainstringstatusenum · 3registeredAt?numberaddedById<"users">approvals_idId<"approvals">requestIdId<"nocRequests">approverUserIdId<"users">decisionenum · 3reasonsRejectionReason[]notestringsnapshotHashstringdecidedAtnumbernotifications_idId<"notifications">requestIdId<"nocRequests">userIdId<"users">channelenum · 3eventstringsentAtnumberreadAt?numberofferLettersSecurity note_idId<"offerLetters">requestIdId<"nocRequests">storageIdId<"_storage">mimeTypestringsizeBytesnumbersha256stringuploadedAtnumbercompanyVerifications_idId<"companyVerifications">requestIdId<"nocRequests">companyIdId<"companies">contactNamestringhrEmailstringchannelenum · 3sentAtnumberrespondedAt?numberoutcomeenum · 4evidencestringflagsstring[]verifiedById<"users">mappingTasks2 idx_idId<"mappingTasks">requestIdId<"nocRequests">courseIdId<"courses">teacherUserIdId<"users">statusenum · 6dueAtnumberremindedAt?numbermappingRulings_idId<"mappingRulings">taskIdId<"mappingTasks">coIdId<"courseOutcomes">coverageenum · 3note?stringauditLog_idId<"auditLog">requestIdId<"nocRequests">actorUserIdId<"users">actionstringfromStageStagetoStageStagereasonstringsnapshotHashstringprevHashstringatnumberverificationTokens_idId<"verificationTokens">tokenstring · opaquerequestIdId<"nocRequests">purposeenum · 2expiresAtnumberrevokedAt?numbermaxUsesnumberusedCountnumberSecurity note — offerLettersConvex ctx.storage.getUrl() returns aPERMANENT, PUBLIC url with no expiry.So an offer letter must be served onlythrough an authenticated httpAction —never by handing the storage URL to abrowser.