feat: implement customer profile management and business application features

- Added customer profile controller with endpoints for retrieving, updating, and deactivating user profiles.
- Introduced address model and routes for managing user addresses.
- Created business application model and service for handling business applications, including approval and rejection processes.
- Developed business contact and credit account models to support business customer functionalities.
- Implemented settlement term model for managing payment terms.
- Added email templates for business application notifications (approved, rejected, received, and status changes).
- Enhanced validation schemas for customer and business inputs to ensure data integrity.
- Created unit tests for business application service and validation schemas to ensure functionality and correctness.
- Added migration scripts to set up new database tables and columns for customer and business features.
This commit is contained in:
Sathira Sri Sathara
2026-09-03 14:58:26 +05:30
parent b6b345f245
commit fd4e324571
36 changed files with 406 additions and 6 deletions
+79
View File
@@ -0,0 +1,79 @@
# ZUMRI Customer and Business API
All endpoints require a Phase 1 access token and are mounted under both `/api` and `/api/v1`; new clients should use `/api/v1`. Examples use placeholders.
## Customer profile
- `GET /api/v1/profile/me`
- `PATCH /api/v1/profile/me`
Editable fields are first/last name, phone, date of birth, `en|si|ta` locale, theme, marketing email/push preference, in-app preference, and owned avatar/background upload IDs. Identity state, type, roles, permissions, tokens, passwords, business review data, partner ID, and credit settings are rejected.
```json
{"firstName":"<first-name>","preferredLanguage":"en","marketingEmailEnabled":false}
```
Media responses contain an upload ID and short-lived authorized URL, never an object key.
## Addresses
- `GET /api/v1/addresses`
- `POST /api/v1/addresses`
- `GET /api/v1/addresses/:id`
- `PATCH /api/v1/addresses/:id`
- `DELETE /api/v1/addresses/:id`
No user ID is accepted. Every query includes the authenticated owner. Setting either default flag clears the prior default under a transaction and User row lock. Deleting a default leaves that default unset. Future orders must snapshot addresses; they must never depend on mutable Address rows.
```json
{"label":"Home","recipientName":"<name>","phoneNumber":"<phone>","addressLine1":"<line>","city":"<city>","countryCode":"LK","isDefaultShipping":true}
```
## Account deactivation
`POST /api/v1/user/me/deactivate` with `{"confirmation":"DEACTIVATE","password":"<current-password>"}`. Password is required for password-based identities. Social-only identities require explicit confirmation. The operation sets DEACTIVATED, increments token version, revokes all sessions, and clears cookies. Self-reactivation is not supported; an authorized manual administrative process is required.
## Business applications
- `POST /api/v1/business/applications`
- `GET /api/v1/business/applications/me`
- `GET /api/v1/business/applications/:id`
Only verified ACTIVE customer accounts can apply. Ownership is applied to ID reads. Concurrent active applications are serialized by locking the applicant User.
```json
{"businessName":"<business>","legalName":"<legal-name>","registrationNumber":"<registration>","businessType":"<type>","contactEmail":"owner@example.com","contactPhone":"<phone>"}
```
Private supporting documents use the Phase 2 upload API with purpose `BUSINESS_REGISTRATION`, `TAX_DOCUMENT`, `IDENTITY_DOCUMENT`, or `OTHER_SUPPORTING_DOCUMENT`. Only the owner or a reviewer with `business.applications.review` can obtain a signed URL.
## Business self-service
- `GET /api/v1/business/me`
- `PATCH /api/v1/business/me`
- `POST /api/v1/business/me/contacts`
- `POST /api/v1/business/me/addresses`
Partner ID, review status, domain status, credit, settlement term, identity type, and approval metadata cannot be changed through self-service.
## Administrative review
- `GET /api/v1/admin/business/applications` — `business.applications.read`
- `GET /api/v1/admin/business/applications/:id` — same permission
- `POST /api/v1/admin/business/applications/:id/approve` — `business.applications.review`
- `POST /api/v1/admin/business/applications/:id/reject` — same permission; requires a reason
- `GET /api/v1/admin/business/accounts` — `business.accounts.read`
- `PATCH /api/v1/admin/business/accounts/:id/status` — `business.accounts.update`
Lists accept bounded `page`, `limit`, status/name filters and allowlisted sorting. Approval atomically locks the application/applicant, creates one profile and disabled credit account, assigns a `ZUM-BIZ-######` partner ID, changes account type to `business_customer`, revokes sessions, and marks the application approved.
## Credit and settlement primitives
- `PATCH /api/v1/admin/business/accounts/:id/credit` — `business.credit.manage`
- `PATCH /api/v1/admin/business/accounts/:id/settlement-term` — `business.settlement.manage`
```json
{"creditLimit":"100000.00","currency":"LKR","status":"ACTIVE"}
```
Credit uses `DECIMAL(15,2)`. There is intentionally no used or available balance until a future authoritative commerce/settlement ledger exists. Settlement terms are seeded configuration records only; this phase creates no invoices or settlements.