ERP enquiry register & document numbering: the top of the admissions funnel¶
Kwilo's enquiry was a bare contact card — name, phone, email, source — so the desk couldn't answer the questions every follow-up call needs: which class are they seeking, where does the child study today? Worse, the pipeline forgot itself: a parent who enquired last month and walked in to register was treated as a stranger. And schools migrating to Kwilo had no way to shape their document numbers — no school prefix, no session token, no way to continue a historical sequence. This doc covers the three fixes: the standard enquiry register, already-enquired detection with prefill on the registration form, and configurable document numbers for enquiry, application, and admission.
Status: built — user-driven (direct product feedback on the staging
enquiry form: missing class/school/address, plus the stated admission-number
struggle). Code PR MySetu-AI/kwiloai_webapp#1473 (branch
feat/erp-enquiry-numbering); this doc lands with it.
Related: erp-registration.md (the registration form this feeds — its deep-link prefill and the "already enquired" banner), erp-student-standard-fields.md (where the data ultimately lands at admit).
Why this exists¶
- Who asked: Direct product feedback while dogfooding staging — "we don't know which class they're enquiring for, where they study, address, email" and "we're struggling with how admission numbers are generated". Grounded in the same school-ERP research as the registration module (SchoolEarth / Fedena / OpenEduCat's ir.sequence).
- User pain: (a) A counsellor calling back an enquiry has no context — the
register can't say which class or school the child is in. (b) A clerk
registering a walk-in retypes everything a colleague captured at enquiry
time, and nothing tells them the enquiry exists. (c) A school whose
admission numbers look like
SIS/2026-27/1450cannot reproduce — or continue — that sequence in Kwilo. - Cost of not doing it: The enquiry register isn't usable as a follow-up tool, double data entry at the desk, and the numbering gap reads as "this ERP can't do our admission numbers" in evaluations.
- Validated: User-stated pain on live staging usage; the field set and numbering behaviours mirror the mainstream school ERPs.
- Worked when: a counsellor can run a follow-up from the register alone;
registering a phone number that already enquired links + prefills in one
click; a school sets
SIS/+ session year + "continue from 1450" and the next admission number isSIS/2026-27/1450. Sean Ellis: remove it and the desk asks "why doesn't it remember this parent enquired last week?"
Mental model¶
Enquiry register. The enquiry stays a 30-second quick capture but now carries the standard particulars: student name (the child — not the caller), parent/guardian name, class seeking admission, current school + class, address, contact, source, notes, follow-ups. Every enquiry gets an enquiry number the moment it's logged.
The funnel remembers. Two directions:
- Enquiry → registration: the deep link prefills the full register (parent → guardian, current school/class → previous school/last class, class applying, address) via one shared map.
- Registration → enquiry: typing a phone that exactly matches an open (non-converted) enquiry surfaces "{name} already enquired on {date} for {class}" with Link & prefill — links the enquiry (converted on save) and fills only empty fields, never overwriting what the clerk typed.
Document numbers — generated at the natural moment, shaped per org:
| Document | Number allocated when | Default |
|---|---|---|
| Enquiry | logged | ENQ000001 |
| Application (registration) | registration created | APP000001 |
| Admission | at admit (the transaction minting the student) | ADM000001 |
erp.number_format_configs (org × doc type) shapes the string: literal
prefix (SIS/), optional Indian session-year token (2026-27/,
April–March), zero-pad width, plus a forward-only next-start that bumps
the existing race-safe counter — continuing a historical sequence or
renumbering at session start. Managed in ERP Settings → Document numbering
with live next-number previews (manager-gated).
Design decisions¶
- No config row = exactly the historical behaviour. Existing tenants see nothing until they opt in.
- No automatic session reset. Schools reset explicitly via next-start — an auto-reset that silently restarts numbering is a support incident waiting to happen.
- Forward-only next-start. Backwards would mint duplicate numbers; the API 422s instead.
- Exact-match phone detection, not fuzzy — a dedup banner must not fire on partial matches; the fuzzy search remains for humans browsing.
- Link fills empty fields only. An explicit link action still must not destroy typed input.
- Manual admission-number override stays (historical imports), dup-checked.
- Enquiry-number backfill: existing enquiries get numbers in creation order per org, and the counter syncs past the max — no unnumbered legacy rows.
Non-goals¶
- Receipt numbers stay
REC######— the config table is doc-type-generic; receipts can join when asked for. - No phone normalization in v1 — detection matches the string as stored; formatting drift between entries defeats it (documented limitation).
- No enquiry-to-application analytics (conversion funnels) — the linkage now exists to build them on.
Risks & mitigations¶
- Number format changes mid-stream produce mixed-format registers. That's inherent (and true of every ERP); the audit trail records each format change.
- Backfill ordering uses
created_at, id— deterministic; the migration is literal SQL with the counter sync in the same transaction.
Rollout¶
erp0025is additive + backfill; deploy-safe ahead of UI.- Formats are opt-in per org via ERP Settings.
- Follow-ups: phone normalization for detection; receipts joining the format system; enquiry→registration conversion metrics.
Changelog¶
- 2026-08-01 — Built end-to-end (register fields, detection + prefill, ENQ/APP/ADM configurable numbering + settings panel). Code PR kwiloai_webapp#1473.