PRD: Sales Inquiries
| Module | Customer | PRD ID | PRD-INQ-001 |
| Status | Ready to dev | FEAT | INQ |
| Epic | — | Plane | BANA-1534 |
| Date | 2026-04-06 | Version | v1.0 |
| Packages | @nx/outreach | URD | INQ |
| Surface | Client · Owner/Mgr | ||
| Owner | Phát Nguyễn | ||
TL;DR
A prospect submits a sales inquiry from the public site; the back-office sales team gets a real-time signal the instant the lead lands and works it through a clear NEW → assigned → replied → converted/lost lifecycle - no lead goes unseen, every follow-up is on the record.
1. Context & Problem
The public Overture site is where prospects reach out, but a lead only matters if sales sees it and acts. With no structured capture-and-notify path, inquiries sit in an inbox or force the team to poll a list - leads go stale, ownership is unclear, and nobody records who replied or how it resolved. As BANA targets HKD/SME businesses through self-serve sign-up, the inbound lead funnel has to be reliable and accountable.
This feature stores the inquiry as a first-class record, pushes a real-time signal to admins on submission, and runs each lead through a controlled lifecycle so sales can assign, reply, and resolve.
2. Goals & Non-Goals
Goals
- Capture an inquiry from the public site - contact info, business info, and a message - in a single submit.
- Notify admins in real time the moment a new inquiry lands - no polling.
- Track each lead's assignment, reply, conversion, and lost reason through the NEW → assigned → replied → converted/lost lifecycle.
Non-Goals
- Email / SMS campaign engine (Planned - see URD §7).
- Customer segmentation and targeting.
- Inquiry / lead lifetime-value analytics.
3. Success Metrics
| Metric | Target / signal |
|---|---|
| Notification latency | New inquiries surface to admins in real time (sub-second live push), not by polling |
| Capture completeness | 100% of public submits persist with contact + business info + message |
| Lead accountability | Every inquiry shows an assignee, reply author/timestamp, and a terminal outcome |
| Time to first response | Median NEW → replied time per merchant trends down |
4. Personas & Use Cases
| Persona | Goal in this feature |
|---|---|
| Site Visitor (Lead) | Submit an inquiry from the public site without an account |
| Sales | See new leads instantly, claim them, reply, and resolve as converted or lost |
| Owner / Admin | Watch inbound lead volume and ensure no inquiry goes unhandled |
Core scenarios: a visitor submits an inquiry → it is stored as NEW and admins are notified in real time → a sales rep assigns it to self → replies (author + timestamp recorded) → marks it converted or lost with a reason.
5. User Stories
- As a site visitor, I want to submit an inquiry with my contact and business details and a message, so the business can follow up with me.
- As a sales rep, I want to be notified in real time when a new inquiry arrives, so I can respond quickly without polling a list.
- As a sales rep, I want to assign an inquiry to myself, so ownership is clear.
- As a sales rep, I want to reply to an inquiry and have my reply and timestamp recorded, so the follow-up is auditable.
- As a sales rep, I want to mark an inquiry converted or lost (with a reason), so the lead's outcome is captured.
6. Functional Requirements
| # | Requirement | URD ref |
|---|---|---|
| FR-1 | Capture an inquiry from the public submit with contact info, business info, and message; a new inquiry starts in status NEW | URD-INQ-001 |
| FR-2 | On submission, emit a real-time notification to admins carrying the inquiry id, type, first/last name, email, business name, subject, and created-at | URD-INQ-002 |
| FR-3 | The notification fans out to an all-inquiries channel and a per-inquiry channel, so a specific inquiry can be targeted | URD-INQ-002 |
| FR-4 | Track an inquiry's assignment, reply (author + timestamp), conversion, and lost reason | URD-INQ-003 |
| FR-5 | Track a lead's progression - assignment, reply (author + time), conversion, and lost reason - in dedicated fields rather than in the status value; the underlying status uses generic lifecycle states (NEW → PROCESSING → COMPLETED/CLOSED/CANCELLED), not named assigned/replied/converted/lost values | URD-INQ-004 |
| FR-6 | Manage inquiries (list, view, count, create, update, remove), each gated by an inquiry permission | URD-INQ-003..004 |
Full requirement text and acceptance criteria live in the Customer URD. This PRD references them rather than restating them.
7. Non-Functional Requirements
| Area | Requirement |
|---|---|
| Real-time delivery | The real-time channel runs on a shared backbone in single or cluster mode; notifications fan out across server instances |
| Graceful degradation | If the real-time service is not ready, the submit still persists the inquiry and the notification no-ops with a warning - capture never fails on the notify path |
| Tenancy & authz | Inquiry management is confined to the user's own merchant and gated by inquiry permissions; the public submit is unauthenticated |
| Data integrity | All inquiry records are soft-deletable, preserving lead history |
| i18n | User-facing labels/statuses are bilingual (English / Vietnamese) |
8. UX & Flows
Key screens: the public inquiry form lives on the Overture marketing site; the back-office inquiry list, detail, and lifecycle controls (with a real-time arrival badge/toast) live on the staff surface.
9. Data & Domain
| Concept | Role |
|---|---|
| Inquiry | The lead record - contact info, business info, message, type, status, assignee, reply, and outcome (converted/lost reason) |
| Real-time notification | An inquiry-submitted event that fans out to an all-inquiries channel plus a per-inquiry channel for targeted delivery |
Conceptual only - full data model and invariants in the Outreach domain model.
10. Dependencies & Assumptions
Depends on
- Outreach capability - owns the inquiry record, CRUD lifecycle, and the real-time component.
- Shared core data - the shared inquiry model and the base real-time notification primitives.
- Real-time backbone - fans the notification out across server instances.
Assumptions
- The public Overture site renders the inquiry form and posts the submit.
- A client-side subscriber (sidebar badge / realtime toast) on the staff surface consumes the notification.
- Email delivery is out of scope for this module; follow-up happens through the lifecycle, not via this feature.
11. Risks & Open Questions
| Risk / question | Mitigation / status |
|---|---|
| Real-time service down → admins miss the notification | Submit still persists; notify no-ops with a warning, so the inquiry is never lost - admins still see it in the list |
| Notification fan-out across instances | The shared real-time backbone in cluster mode handles multi-instance delivery |
| Lead spam / abuse on a public endpoint | Open: consider rate-limiting / captcha on the public submit |
| No email follow-up channel | Out of scope; campaign engine is Planned in the URD |
12. Release Plan & Launch Criteria
| Aspect | Plan |
|---|---|
| Phase | P2 - see URD feature catalog (INQ) |
| Rollout | All merchants; no feature flag |
| Migration | None (inquiry fields added to shared core data) |
| Launch criteria | Public submit persists a NEW inquiry; admins receive the real-time notification end-to-end; assign → reply → converted/lost lifecycle verified |
| Monitoring | Inquiry volume per merchant, notification send success/failure rate, NEW → replied time |
13. FAQ
Do admins have to refresh to see a new inquiry? No - a real-time notification is pushed on submission, so a new lead surfaces immediately.
What happens if the real-time service is down when an inquiry is submitted? The inquiry is still persisted; the notification is skipped with a warning. Admins still see it in the inquiry list - capture never depends on the notify path.
Can a visitor submit an inquiry without an account? Yes - the public submit is unauthenticated. Inquiry management (find/assign/reply/resolve) is authenticated and permission-gated.
Does submitting an inquiry send the lead an email? No - there is no email/SMS channel in this module. Follow-up is tracked through the inquiry lifecycle.
What are the inquiry statuses? The underlying status uses generic lifecycle states (NEW → PROCESSING → COMPLETED/CLOSED/CANCELLED). The lead progression an admin cares about - assigned → replied → converted/lost, with a lost reason when applicable - lives in dedicated fields, not in the status value.
References
- URD: Customer - Sales Inquiries (INQ area)
- Module: Customer - URD
- Developer: @nx/outreach · Outreach domain model