Trường Số PRD/11 Data and API
Trường Số · Product Requirements · 09/2026

PRD 11 · Data model and API

Consolidated entity list with relationships, the existing /v3 surface versus the endpoints each module needs, API conventions, and the migration toolkit for importing a center from Excel: students, guardians, classes, enrollments, opening balances and staff.

Key facts, origin and limits
Status
Draft v1
Owner module
Platform
Backend
staging /v3 · 182 paths · 504 schemas
Phase
P1
Depends on
all module PRDs

Drafted by an AI assistant in a single session on 10/09/2026, from the original request quoted verbatim on the hub page; the Proposed design section was added on 16/09/2026. A proposal for team discussion, not a decision of the product team.

Sources

  • Public competitor research (PSE ONE, pse4.one), the center-crm-frontend codebase and the staging /v3 OpenAPI specification (182 paths), as of 10/09/2026.
  • The existing / extend / new tags on this page come from a comparison with the staging /v3 specification at that date.
  • The endpoint counts per group in section 3 (Crm 148, Teacher 73, Parent 5, Payment 1) are counted from the staging spec of 10/09/2026.
  • The import order in section 4 follows how the competitor guides its own customers through data onboarding.

Limits

  • Verification pending in-app survey, because automated login to the reference product was not authorised in the drafting session:
    • Competitor's import templates per entity (column names, required fields) to align the migration path for centers switching.
    • Their export formats, to build an importer for switching customers.
    • Identifier formats (student code, class code, receipt number).

Proposed design

This PRD has no screens of its own: it is shared platform material. The design for each feature sits in the "Proposed design" section that opens every module PRD (00 to 10 and 13 to 19).

1API conventions

2Entity catalog

Origin: existing = present in the /v3 API; extend = existing with new fields; new = to be created. Key fields only; full field lists are in the module PRDs.

EntityOriginIdentityKey relationshipsPRD
Center (tenant)extendcenter_id stringhas many School; Users; CRM config00, 10
School (branch) + branch_profileextendschool_id int64belongs to Center; has Students, Classes, Sessions, Tuition, Rooms, Cash accounts00, 10
SaleProfile (staff user) + user_branch_scopeextendsale_profile_id int64, user_idroles; branches; owns Leads; maps to Staff10
Role, Permission catalogextendrole id, codepermissions with scope10
Customer (lead) + prospect_learnersextenduuid, codestage, status, source, channel, tags, assignees, interactions, placement tests, learners link, trial bookings, conversions01
Pipeline, Stage, Status, Source, Channel, Tag, CustomField, Package (sales)existinguuidtenant catalogs01, 10
Interaction (call, meeting, task, note)existinguuidcustomer, actor01
PlacementTestextenduuidcustomer, learner link, FLYER report01
TrialBookingnewuuidcustomer, prospect, class, session01, 03
Conversionnewuuidcustomer → student, guardian, enrollment, tuition01
LearnerProfile (FLYER)existinglearner_profile_id int64StudentProfile; scores; reports02
Student (operational record)newuuid, codeschool; learner profile; guardians; enrollments; packages; balance; documents; notes; status history02
Guardian, student_guardian, Consentnewuuidstudents; portal sessions; messages02, 07
Courseextenduuidfee plans; classes03, 05
Levelnewcodecourses, classes, students, placement mapping03
Class + class_profileextendclass_id int64school; course; room; staff; sessions; enrollments; ClassSchedule (FLYER program)03
Room, Holidaynewuuidschool03
Sessionnewuuidclass; room; main and substitute staff; attendance sheet; timesheet lines; trial and make-up bookings03, 04, 06
Enrollmentnewuuidstudent; class; fee plan03
MakeupBooking, Excusenewuuidstudent; sessions03, 04
AttendanceSheet, AttendanceRecord (+history)newuuidsession; student; package consumption; messages04
FeePlannewuuidcourse; tuition lines; packages05
Tuition (invoice) + linesextenduuid, payment_codestudent; class; course; fee plan; payments; credit notes; e-invoice; group invoice05
Payment (TuitionTransaction)extenduuid, receipt_notuition; cash account; cashier; SePay id05
GroupInvoiceexistinguuidtuitions; classes05
SessionPackage, SessionConsumptionnewuuidstudent; tuition; attendance records05
CreditNote, Refund, Expense, ExpenseCategory, CashAccount, CashClose, UnmatchedTransaction, VoucherGroup, Voucher, VoucherUsenewuuidfinance05
SchoolBankAccount, SchoolCompanyexistinguuidschool05, 10
Staff, JobTitle, StaffContract, PayRule (+override), Timesheet (+lines, adjustments), EvaluationTemplate, Evaluation, StaffDocumentnewuuidwraps TeacherProfile and SaleProfile; sessions06
TeacherProfile, RollupTeacherexistingint64classes; KPIs06
MessageTemplate, Message, Announcement, ProgressReportBatch, ProgressReport, ParentRequest, ZaloOAConnection, PortalSessionnewuuidguardians; students; sources07
InventoryItem, Category, Document, Movementnewuuidschool; students; tuition lines08
agg_daily_school, report jobs, digest settingsnew09
Invitation, Integration, OnboardingChecklist, AuditLognewuuidcenter; actors10, 12
Notification, Mention, Discussion, CustomerFile, ViewConfig, ImportJob, TodayPlanexistingCRM support objects, reused by new modules where noted01, 09, 11

Relationship diagram

CenterSchool (branch)Customer (lead)StudentEnrollmentClass GuardianTuition / PaymentAttendanceSession MessageSession packageTimesheetStaffRole / User has studentsconvertsenrollsingeneratesrosterconsumespaysbilledpayerreceivescreditsdeductsscoped by
Primary relationships. Center owns Schools and Users; a Student belongs to one School and links to one FLYER learner; Sessions are the hub for attendance, packages and pay.

3API surface: existing versus needed

Existing endpoints by group: Crm 148, Teacher 73, Parent 5, Payment 1. The table lists what each module reuses and how many new endpoints it introduces (from the module PRDs).

ModuleExisting reusedExtendedNewNotes
01 Admissionscustomers (60+), pipelines, stages, statuses, sources, channels, tags, custom fields, packages, interactions, quick actions, placement tests, imports, search, notifications, today plan, dashboardcustomers (prospect_learners), interactions filters, placement tests (suggested_level), pipelines (trial stage)do-not-call, transfer-school, trial-bookings (3), convertcloses frontend references to non-spec endpoints
02 Studentsschool-finance students, stats, tuitions, courses; parent reports; quick-search; learners searchnonestudents (7), guardians (3), consents, documents, notes, balance, anonymise, credentialsstudent wraps learner profile
03 Classesteacher classes, class-schedules (FLYER program), coursescourses, classes listclasses (5), sessions (5), enrollments (2), roster, makeups, rooms, holidays, levels, timetable, icssessions materialised
04 Attendanceschool-configschool-config policyattendance (9), excuses, parent attendanceno existing entity
05 Financetuitions (10), group invoices, bank accounts, company, link-token, payment QR, parent tuitionstuitions list/create/detail/pay/notify, group invoice create, parent tuitionsfee plans, void, approve, receipts, debt, payment plan, packages, credit notes, refunds, expenses, cashbook, cash accounts, unmatched, vouchers, e-invoice, finance report (about 25)reuses Tuition as invoice
06 Staffschools, rollup-teachers, sale profiles, rolesnonestaff (6), contracts, pay rules, timesheets (7), evaluations, documentsP2
07 Parentstuition notify, class remind, exam notify, parent tuitions and reports, notification configschool-config notifications, parent tuitionstemplates, messages, announcements, progress reports, requests, zalo integration, parent auth and views, inbox, consents, webhook (about 20)message layer wraps existing notify
08 Inventorystudents, classes pickers, tuition createnoneitems, categories, stock, documents, issue, movements, materials, export (13)P2
09 Reportscrm dashboard (5), tuition stats, rollups, view configsnoneexecutive, home, reports/{key}, jobs, digestaggregates
10 Settingsroles, permissions catalog, sale profiles, centers, sources, channels, tags, custom fields, packages, pipelines, school-config, companypermissions catalog, roles permissions with scope, me/permissions, centers PATCH, school-configbranches, invitations, sale-profile branches, deactivate, catalogs (levels, rooms, job titles, expense categories, fee plans, holidays), audit logs, integrations, checklist, full exportreplaces mocks
11 Importsimports (customers)imports (entity types)import templates per entity, validate, commitbelow

The full list of endpoints with request and response shapes is in each PRD's API section. The backend team should generate the OpenAPI additions first so the frontend keeps its generated-hook workflow.

4Migration and Excel import

Most centers arrive with Excel sheets or an export from another system. The existing import wizard handles leads with a template, preview, dedupe strategy (skip, merge, overwrite), round-robin assignment and an error report. The same job pattern is extended to the school entities, in a fixed order (staff, classes, students, courses, tuition, remaining sessions, attendance).

Import order and templates

StepEntityTemplate columns (VI header · key)RequiredDedupe keyValidation
1StaffHọ tên · full_name; Mã NV · code; Chức danh · job_title; Loại hình · employment_type; Chi nhánh · branch_code; SĐT · phone; Email · email; Ngày bắt đầu · start_date; Là giáo viên · is_teacher; Tạo tài khoản · create_account; Vai trò · role_codefull_name, phone, branch_codephonebranch exists; role exists
2Courses and fee plansTên khoá · course_name; Trình độ · level; Số buổi · lessons; Thời lượng (phút) · duration; Tên gói · plan_name; Loại gói · plan_type; Giá · price; Số buổi gói · sessions; Hạn (tháng) · validity_monthscourse_name, plan_name, plan_type, pricecourse_name + plan_nameplan_type enum
3RoomsChi nhánh · branch_code; Phòng · name; Sức chứa · capacitybranch_code, namebranch + name
4ClassesMã lớp · code; Tên lớp · name; Chi nhánh · branch_code; Khoá · course_name; Trình độ · level; GV chính · teacher_phone; Phòng · room; Lịch · pattern ("T3 18:00-19:30; T5 18:00-19:30"); Khai giảng · start_date; Kết thúc · end_date; Sĩ số · capacitycode, name, branch_code, pattern, start_datecodeteacher exists; room exists; pattern parses; sessions generated from max(start_date, import date) onward, earlier sessions imported as held without attendance unless step 8 provides it
5Students and guardiansMã HV · code; Họ tên · display_name; Ngày sinh · birthday; Giới tính · gender; Chi nhánh · branch_code; Trạng thái · status; Trình độ · level; Trường · school_name; Địa chỉ · address; PH1 họ tên · g1_name; PH1 SĐT · g1_phone; PH1 quan hệ · g1_relationship; PH1 email · g1_email; PH1 Zalo đồng ý · g1_zalo; PH2 ... · g2_*; Tài khoản FLYER · flyer_username; Ghi chú · notedisplay_name, birthday, branch_code, g1_phone (unless age ≥ 18)code, else display_name + birthday + g1_phonestatus enum; learner created or linked by username; guardians merged by phone
6EnrollmentsMã HV · student_code; Mã lớp · class_code; Ngày bắt đầu · start_date; Ngày kết thúc · end_date; Gói · plan_namestudent_code, class_code, start_datestudent + class + startcapacity warning (not blocking on import)
7Opening balancesMã HV · student_code; Gói · plan_name; Buổi còn lại · sessions_remaining; Hết hạn · expires_on; Còn nợ · debt_amount; Hạn nợ · debt_due; Ghi chú · notestudent_code and at least one of sessions_remaining, debt_amountstudent + plancreates a package with sessions_total = sessions_remaining and a tuition "Số dư đầu kỳ" for debt, both flagged is_opening
8Attendance history (optional)Mã lớp · class_code; Ngày · date; Mã HV · student_code; Trạng thái · status (Có mặt/Muộn/Vắng/Có phép)allclass + date + studentsession must exist for (class, date); creates sheets marked by "Import"
9Inventory opening stock (P2)Chi nhánh; Mã hàng; Tên; Danh mục; Đơn vị; Giá bán; Giá vốn; Tồncode, name, branchcodestock-in document "Số dư đầu kỳ"

Wizard behaviour

  1. Choose entity; download template (xlsx with header row, example row, and a hidden sheet of allowed values for enums and branch codes); upload xlsx or csv.
  2. Column mapping: auto-map by header, manual remap, unmapped columns listed; custom fields supported for students as for leads.
  3. Validation preview: row-level errors and warnings with counts; download error file; "Bỏ qua dòng lỗi" toggle.
  4. Dedupe strategy per entity (skip, merge, overwrite) as today; for students, merge updates profile fields left blank and adds guardians.
  5. Commit runs as a job (existing ImportJob with new entity_type); progress, success and failed counts; detail page with succeeded and failed tabs (existing pages reused); cancel while pending.
  6. Rollback: an import can be reverted within 24 h if none of the created records were modified afterwards (deletes created rows, keeps merged ones with audit note).

Data quality rules

API

MethodPathRequest / responseStatus
GET/POST/v3/crm/imports; GET /{id}; POST /{id}/cancel; GET /{id}/errors, /error-reportadd entity_type enum(customers, staff, courses, rooms, classes, students, enrollments, balances, attendance, inventory) and mappingextend
GET/v3/school/imports/templates/{entity_type}.xlsxtemplate with allowed values for the tenantnew
POST/v3/school/imports/validate{entity_type, rows[], mapping, dedupe_strategy} → {valid, errors[], warnings[], duplicates[]} (no write)new
POST/v3/school/imports/{id}/rollbacknew
POST/v3/crm/imports/bulk-customersunchanged for leadsexisting

5Data retention and identifiers

DataRetentionIdentifier format
Leadsanonymise 24 months after last activity if not woncustomer code as today
Students, guardiansactive + 5 years, then anonymise on request or after 5 years inactiveHV-000123 per tenant
Attendance5 yearssession uuid
Finance documents10 yearsPT-<branch>-YYYYMM-####, PC-..., HĐ = payment_code
Messages12 months rendered content, 5 years metadatauuid
Audit log5 yearsuuid, request_id

Trường Số (truongso.net) · FLYER internal