Search & discovery
Customer Search
Generated from docs/plan/core/customer-search/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
A fast customer lookup page where merchants can search by name or email and see results instantly. Merchants can click through to view customer details, order history, and profile without manual scrolling.
The problem
Merchants need to find a customer to view orders, send a refund, or update details, but they have no search. They scroll through customer lists alphabetically or guess email addresses. This is error-prone and slow.
What it does
- Search customers by first name, last name, or both (case-insensitive substring match)
- Search customers by email address (exact or substring)
- Display search results with name, email, signup date, and order count
- List all customers with pagination if no search term is entered
- Sort results by name (A-Z or Z-A) or by signup date (newest or oldest)
- Show total customer count and filtered result count
- Click customer to view full profile (name, email, phone, address, order history)
- Quick filters: ‘Customers with no orders’, ‘Signed up this month’ (optional)
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- Does not filter by spending tier or RFM score — that’s paid analytics module.
- Does not recommend follow-up actions or suggest emails — that’s paid CRM.
- Does not bulk import or export customer lists — that’s data integration, separate feature.
- Does not segment customers into audience lists — that’s paid marketing/email module.
- Does not display customer lifetime value or predictive churn — that’s paid analytics.
Data model
No new tables. Requires indexing on existing Customers table: email, firstName, lastName for search performance. Optional index on Customers.createdAt for sorting. No migration if added to new shops.
API
- GET /admin/customers?search=… — search by name or email
- GET /admin/customers — list all with pagination and sort params: page, pageSize, sort, sortDirection
- GET /admin/customers/{id} — view single customer profile
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Customer list page with search bar labeled ‘Name or email’; sort buttons (Name A-Z, Date added); paginated results table showing name, email, signup date, order count; pagination controls; click row to view customer profile. Profile page shows full details: name, email, phone, billing/shipping address, signup date, order history table.
The seam — why this is core
Core owns customer search and listing UI, name/email indexing, and sort logic. No paid module.
Core owns the interface + honest customer finder; customer lookup is infrastructure, not a per-country obligation or credential.
Dependencies
- Customers table (existing)
- Database indexes on firstName, lastName, email
- Orders table (to count orders per customer)
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- Search ‘john’ returns all customers with ‘john’ in firstName or lastName (case-insensitive)
- Search ‘john@example.com’ returns customer(s) with that exact email; partial search ‘john@’ also works
- Search for non-existent customer ‘xyzabc’ returns empty list with message ‘No customers found’ (not 404)
- Sort by name (A-Z) lists customers alphabetically: Alice, Bob, Charlie, etc.
- Pagination with pageSize=25 returns exactly 25 customers per page
- Search results do not include customer order history inline (load on click only, for fast response)
- Total customer count shows accurately (e.g., ‘5 customers’, or ‘1 of 500 customers’ when filtered)
- Clicking a customer name navigates to their profile page with full order history
Risks
If search is not indexed (full-text scan), response time is slow with >1,000 customers. If name search requires exact match, merchants searching ‘jon’ miss ‘john’. If email search is case-sensitive, customers with mixed-case emails are not found. If profile page loads order history synchronously, slow stores may time out.
Commercial context
| Suggested price | free (core) |
| Rival anchor | Shopify: included; Magento: included |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.