PRD: Inquiry Management (Back Office)
| Module | Marketing | PRD ID | PRD-CAP-002 |
| Status | Ready to dev | FEAT | CAP |
| Epic | — | Plane | BANA-1741 |
| Date | 2026-06-30 | Version | v1.1 |
| Packages | @nx/outreach | URD | CAP |
| Surface | BO · Ops | ||
| Owner | Phát Nguyễn | ||
TL;DR
Lets our operations team (NEXPANDO & VNPAY) work captured leads from the Back Office: list and filter the inquiries that came in from the public site, edit each inquiry in a single form to assign an owner, record a reply and set its status through a five-status lifecycle (New → In review → Activated / Completed / Closed), and convert a promising inquiry straight into onboarding - pre-filled from what the lead already told us. The Back Office menu carries a real-time badge counting unworked inquiries.
1. Context & Problem
The public site captures inquiries - consult, contact, sales, demo, and partner requests - and stores them (PRD-CAP-001). But once captured, those leads had nowhere to be worked: no place to see the queue, assign an owner, record a reply, complete or close a lead, or - most importantly - turn a "yes" into a live merchant without re-typing everything.
This increment is the operations team's inquiry workbench: it manages a lead's whole lifecycle and bridges straight into onboarding, so a captured lead becomes a running merchant in one continuous path.
2. Goals & Non-Goals
Goals
- An inquiry list with 8 columns, 6 of them filterable (first name, last name, status, type, email, created date).
- Edit an inquiry in a single form - contact and business details plus the working fields (assignee, reply, status, note).
- A five-status lifecycle: New → In review → Activated / Completed / Closed, with a mandatory note on Completed or Closed.
- Convert an inquiry into onboarding, pre-filling the new client from the inquiry.
- A real-time menu badge counting unworked inquiries; a toast when a new inquiry arrives.
Non-Goals
- Public-site capture of inquiries and newsletter sign-ups (PRD-CAP-001).
- Newsletter subscriber management and statistics (PRD-SUB-001).
- Marketing campaigns and automation (
CMP). - The onboarding flow itself - this screen hands off to it (Onboarding).
3. Success Metrics
| Metric | Target / signal |
|---|---|
| Lead worked, not lost | Every inquiry has a clear status and owner; the menu badge shows the unworked count |
| Continuity to onboarding | An inquiry becomes a merchant without re-typing the lead's details |
| Accountability | Who replied and when, and the context on complete/close, are recorded |
4. Personas & Use Cases
| Persona | Goal in this feature |
|---|---|
| Operations team (NEXPANDO & VNPAY) | Work the lead queue and convert promising leads into merchants |
| Manager | See lead status and outcomes (completed / closed with a note) |
Core scenario: an operator sees the unworked-inquiry badge on the menu, filters the list to status New, opens a lead, fills in the assignee and records a reply, then saves; when the lead agrees, the operator clicks Onboard - the onboarding wizard opens with business and contact details pre-filled; if it falls through, the operator sets the status to Closed with a note (and a lost reason if known).
5. User Stories
- As an operator, I want the inquiry list filterable by status and type, so I can work the lead queue with focus.
- As an operator, I want to edit an inquiry's contact and business details, so the record is accurate before I act.
- As an operator, I want to record the assignee, the replier, and the status right in the edit form, so progress is tracked.
- As an operator, I want the system to require a note when I complete or close a lead, so every outcome has context.
- As an operator, I want to convert an inquiry into onboarding pre-filled from the lead, so I don't re-type anything.
- As an operator, I want to be told the moment a new inquiry arrives, so no lead waits long.
6. Functional Requirements
| # | Requirement | Status | URD ref |
|---|---|---|---|
| FR-1 | Inquiry list - 8 columns, 6 filterable | ✅ built | URD-CAP-005 |
| FR-2 | Edit an inquiry in a single form - contact, business, and working fields, with validation | ✅ built | URD-CAP-005 |
| FR-3 | Five-status lifecycle with a mandatory note on Completed or Closed | ✅ built | URD-CAP-005 |
| FR-4 | Convert to onboarding - pre-fill the new client from the inquiry | ✅ built | URD-CAP-006 · URD-BOP-001 |
| FR-5 | Screen is ops-gated; inquiries are created only by public capture, never here | ✅ built | URD-CAP-001 |
| FR-6 | Real-time menu badge + toast when a new inquiry arrives | ✅ built | URD-CAP-001 |
| FR-7 | Assignee / replier picked from the internal user list (upgrade from free text) | 🚧 not built | URD-CAP-005 |
FR-1 - Inquiry list
The table has 8 columns: First name, Last name, Status, Type, Phone, Email, Created at, Last modified at.
- Filterable (6 columns): First name, Last name, Status, Type, Email, Created at.
- Not filterable: Phone, Last modified at.
- Status and Type render as colored labels.
- No create button - inquiries only originate from the public-site capture forms.
- Each row offers two actions: Edit (opens the edit form) and Onboard (opens the onboarding wizard - see FR-4). Both appear on every row, regardless of status.
FR-2 - Edit an inquiry (single form)
Every working operation - assigning an owner, recording a reply, setting the status, noting the outcome - is editing fields within this one form; there are no separate Assign / Reply / Change-status actions.
| Group | Field | Required | Rule |
|---|---|---|---|
| Contact | First name | ✔ | Must not be empty |
| Last name | - | ||
| ✔ | Valid email format | ||
| Phone | ✔ | Valid phone format | |
| Business | Business name | - | |
| Business type | - | ||
| Location count | - | Free entry | |
| Estimated revenue | - | Free entry | |
| Content | Subject | - | |
| Message | - | Multiline | |
| Working | Type | ✔ | One of the 5 types (below) |
| Status | ✔ | One of the 5 statuses (see FR-3) | |
| Assignee | - | Currently free text (upgraded in FR-7) | |
| Replied by | - | Currently free text (upgraded in FR-7) | |
| Replied at | - | Read-only - system-recorded | |
| Lost reason | - | Optional, even on Closed (see FR-3) | |
| Note | ◑ | Multiline; required when Status = Completed or Closed |
Leaving the form with unsaved changes → an unsaved-changes warning.
5 inquiry types: Consult · Contact · Sales · Demo · Partner.
FR-3 - Lifecycle (5 statuses)
| Status | Meaning |
|---|---|
| New | Just arrived from the public site, not yet picked up |
| In review | The operations team has picked it up - assigning an owner, replying to the lead |
| Activated | The inquiry has been converted into an onboarded client |
| Completed | Worked to a good outcome - note required |
| Closed | Work stopped - note required; a lost reason is encouraged but optional |
Rules:
- Moving to Completed or Closed with an empty Note → the save is rejected with an error on the Note field.
- The lost reason stays optional, even on Closed - deliberately, so operators aren't blocked from closing quickly; if it should ever become mandatory, that is a new FR outside this version.
- There is no "Cancelled" status - a lost inquiry is Closed.
FR-4 - Convert to onboarding
- The Onboard button on each list row opens the onboarding wizard.
- The wizard opens with the inquiry's business and contact details pre-filled - the operator re-types nothing.
- The onboarding flow itself belongs to Onboarding (Back Office).
FR-5 - Access gating
- The screen is only available to authenticated operations roles.
- The screen never creates inquiries - only view, filter, edit, convert.
FR-6 - Real-time badge
- The Inquiry entry in the Back Office menu shows the count of inquiries in New or In review.
- When a new inquiry arrives from the public site: the badge count updates and a toast notification appears for operators with the Back Office open.
FR-7 - Pick assignee / replier from the user list (🚧 not built)
- Today both fields are free text - typo-prone and impossible to reconcile against real users.
- Upgrade: pick from the operations team's internal user list; previously free-typed values must still display.
Acceptance criteria
- The list shows all 8 columns; filtering on each of the 6 filterable columns returns correct results; filtering on Phone / Last modified is not offered.
- Saving the form with First name, Email, Phone, Type, or Status empty → a field-level error, no save.
- A malformed email or malformed phone number → a field-level error, no save.
- Setting Status = Completed or Closed with an empty Note → an error on Note, no save; filling the Note → saves.
- With any other status (New / In review / Activated), an empty Note saves normally.
- Closing an inquiry without a Lost reason → still saves (the field is optional).
- Clicking Onboard on a row → the onboarding wizard opens with the inquiry's business and contact details pre-filled.
- The menu badge equals the count of New + In review inquiries; a new inquiry arriving → the badge increments and a toast appears, without a page reload.
- Leaving the edit page with unsaved changes → a warning appears.
7. Non-Functional Requirements
| Area | Requirement |
|---|---|
| Authz | The workbench is gated to operations roles |
| Auditability | Replied-by, replied-at (system-recorded), and the outcome note are stored per inquiry |
| Data quality | Note required on Completed or Closed; email and phone format-checked on edit |
| Continuity | Conversion carries the inquiry's known details into onboarding with no re-entry |
| Real-time | Badge and new-inquiry toast update without a page reload |
| i18n | Labels are bilingual (EN/VI) |
8. UX & Flows
How an operator works a lead - every working operation happens inside one edit form:
The lead lifecycle:
The workbench lives in the Back Office "CRM & Merchant" section. The Onboard action opens the onboarding wizard pre-filled from the inquiry.
9. Data & Domain
| Concept | Role in this screen |
|---|---|
| Inquiry | A captured lead - contact (first name, last name, email, phone), business (name, type, location count, estimated revenue), content (subject, message), and working fields (type, status, assignee, replied-by, replied-at, lost reason, note) |
| Lifecycle | New → In review → Activated / Completed / Closed; a note is mandatory at both terminal statuses |
| Conversion | The hand-off that turns an inquiry into an onboarding, carrying its details forward |
Conceptual only - inquiries originate from public capture; the data model lives in the developer docs.
10. Dependencies & Assumptions
Depends on
- Lead capture (PRD-CAP-001) - creates the inquiries this screen works.
- Onboarding (Onboarding) - the conversion target.
Assumptions
- The operator is authenticated with a role that can work inquiries.
- Inquiries arrive from public capture; this screen does not create them.
11. Risks & Open Questions
| Risk / question | Mitigation / status |
|---|---|
| Leads sitting unattended | The menu badge counts New + In review; status + assignee make the queue owned |
| Closing a lead without context | Note required on Completed or Closed; lost reason optional - revisit as mandatory if it stays empty too often |
| Free-text assignee doesn't match real users | Upgrade to picking from the internal user list (FR-7, 🚧) |
| Re-typing details on conversion | Conversion pre-fills onboarding from the inquiry |
| Duplicate inquiries from the same lead | Out of scope here; capture-side dedupe is in PRD-CAP-001 |
12. Release Plan & Launch Criteria
| Aspect | Plan |
|---|---|
| Phase | P1 - available to the operations team in the Back Office; FR-7 (user picker) not built |
| Rollout | Operations users; no feature flag |
| Migration | None - it works existing captured inquiries |
| Launch criteria | All §6 acceptance criteria pass (except FR-7, not built) |
| Monitoring | Inquiry conversion rate; count of inquiries sitting in New + In review |
13. FAQ
Where do inquiries come from? From the public site's capture forms (PRD-CAP-001); this screen works them, it doesn't create them.
What happens when I convert a lead? The onboarding wizard opens pre-filled with the inquiry's business and contact details.
Why must I add a note on complete or close? So an outcome is never recorded without context - especially a loss.
What does "Activated" mean? That inquiry has been converted into an onboarded client - a trace that the lead moved on into the onboarding flow.
References
- URD: Marketing -
CAP(Lead & Subscriber Capture) - Related: PRD-CAP-001 - Lead & subscriber capture · PRD-SUB-001 - Newsletter subscribers · Onboarding (Back Office)
- Module: Marketing - URD · Roadmap: Phase 2 - By Month
- Developer: @nx/outreach