Files
Zumri-Backend/Documentation/CURRENT_BACKEND_STATUS.md
T
Sathira Sri Sathara f920ca8920
CI / test (push) Successful in 10m22s
CI / test (pull_request) Successful in 10m53s
feat: Implement Phase 10 support and recommendations features
- Added models for support messages, SLA policies, tickets, ticket events, and ticket links.
- Created routes for help, help admin, newsletter, recommendations, and support for both customer and admin.
- Developed services for help, marketing (newsletter), and recommendations.
- Introduced support service for ticket management, including creation, replies, transitions, and attachments.
- Added validation schemas for support recommendations and ticket management.
- Implemented a cron job for support reconciliation and recommendation cleanup.
- Created migration for new support and recommendation database tables.
- Added unit tests for validation and policy checks related to Phase 10 features.
2026-09-09 16:07:31 +05:30

447 lines
53 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ZUMRI Current Backend Status
## Phase 4 Completion Update
Completion date: 2026-09-03. Module 03 (product catalogue) is approximately 84%; Module 04 (multi-language content) is approximately 82%. Phase 4 adds 18 catalogue models covering brands, hierarchical localized categories, products/translations/multi-category joins, DECIMAL-price variants, configurable options and attributes, owned media, scheduled localized collections, structured size guides, explicit relations, and moderated reviews.
Public APIs now provide active/public product lists and slug detail, safe search/filter/sort/pagination, locale fallback, categories, brands, current collections, signed media DTOs, price ranges, and approved review summaries. Permission-gated admin APIs cover product lifecycle, variants/options/media/relations, brands, cycle-safe categories, collections, size guides, and review moderation. No inventory quantity, wholesale pricing, promotion, or shopping behavior was introduced.
The mocked regression suite passes 15 suites/78 tests and syntax validation covers 204 JavaScript files. The Phase 4 migration is forward-only and was not executed. Restored-staging migration checks, permission seeding, real MySQL query/concurrency testing, and signed-media volume validation remain required before Phase 5. See `Documentation/PHASE_4_CATALOGUE_CONTENT.md` and `Documentation/API_CATALOGUE.md`.
## Phase 3 Completion Update
Completion date: 2026-09-03. Module 02 (customer profile/address management) is now approximately 88%; Module 13 (business accounts) is approximately 78%. Customer profile/preferences, structured owned addresses with transactional defaults, secure self-deactivation, business applications, permission-gated transactional approval, immutable partner identity, business profiles/contacts/addresses, domain status, DECIMAL credit configuration, and settlement-term primitives are implemented.
Security impact: all customer resource identity is derived from Phase 1 authentication; mutation schemas are strict; profile media is owner-validated; address/application IDOR is constrained in queries; approval/deactivation revoke sessions after identity-boundary changes; and business financial/review fields are excluded from self-service. Six models were added and two existing models extended. Customer/business and admin APIs are documented in `Documentation/API_CUSTOMER_BUSINESS.md`.
The complete mocked regression suite passes 12 suites/57 tests, and syntax validation passes 171 JavaScript files. The Phase 3 migration is forward-only and was not executed. Staging must resolve legacy business/profile/address pre-checks, seed/grant permissions, and validate MySQL concurrency plus Redis/S3/SMTP flows before Phase 4. See `Documentation/PHASE_3_CUSTOMER_BUSINESS_FOUNDATIONS.md`.
## Phase 2 Completion Update
Completion date: 2026-09-03. Phase 2 hardens the existing shared-service foundation without adding commerce domains. Module 14 (notifications) is now approximately 72%; Module 19 (file/media) 82%; Module 20 (audit/config/logging) 68%; and Module 21 (background jobs) 78%. The document subsystem is approximately 82%.
Storage now has a reusable S3/S3-compatible boundary, actual-content validation, controlled keys, checksums, owner/status metadata, compensation, and authorization-safe signed URLs. Email is routed through BullMQ with delivery status and final-failure persistence. Notifications have fixed aliases, unique assignment migration, self-only inbox/read operations, announcement support, and preference policy. Queue defaults, idempotent job IDs, Bull Board registration, safe failure handling, stronger append-only activity records, and structured redacted logs are in place. Documents now have ownership, controlled registry validation, persisted generation lifecycle, safe status, and non-destructive signed download.
The full mocked suite contains 10 suites/40 tests and passes; syntax checks cover 153 JavaScript files. The new migration was not executed. Remaining work is staging migration/data pre-checks plus real MySQL, Redis, S3-compatible, SMTP, PDF/browser, retention-volume, and concurrency validation. After those operational checks and permission seeding, it is safe to begin Phase 3. See `Documentation/PHASE_2_CROSS_CUTTING_SERVICES.md` and `Documentation/API_CROSS_CUTTING_SERVICES.md`.
Audit date: 2026-09-03
Scope: repository source, configuration, lockfile, existing documentation, safe syntax/test/dependency checks. No database, Redis, S3, email, or other external service was mutated.
## 1. Executive Summary
This repository is an early modular-monolith foundation, not yet an e-commerce backend. It contains working-shaped user registration/email verification, OTP login, basic profiles, RBAC tables/controllers, notifications, activity logging, S3 upload plumbing, document generation, Redis/BullMQ workers, and one cron. Important pieces are incomplete or broken in integration. The estimated completion against the 25-module ZUMRI target is **about 12%**.
No original development-plan day is fully complete. Day 1 is approximately 55%: Express, Sequelize/MySQL, Redis/BullMQ, a Dockerfile, and a health route exist, but Swagger, robust health checks, Node 22 alignment, production bootstrap/error handling, Compose/Nginx, migrations, and tests do not. Day 2 is approximately 38%; Day 3 approximately 18%; notification/job/file/document/audit foundations from later days were built early.
The code still carries prior-project terminology (`Oceanic Titan`, `oceanic-db`, Oceanic demo URL) and role names that conflict with the actual user ENUM. Future work should preserve usable primitives, but first complete and secure foundation/authentication.
Status terms: **COMPLETE** = end-to-end implementation is credible from source; **PARTIAL** = meaningful code exists but requirements/integration are incomplete; **STUB** = structure only; **MISSING** = no implementation; **BROKEN** = known source/integration defect.
## 2. Current Architecture
- `server.js` loads `.env`, imports `app.js`, and listens on `0.0.0.0:${PORT|3070}`.
- `app.js` authenticates Sequelize and calls unrestricted `sequelize.sync()` in an unawaited startup IIFE, then starts cron jobs. The HTTP listener starts independently, so requests can arrive before database readiness, and DB failure does not stop the process.
- Middleware order is cookie parser, CORS, JSON parser, Morgan, `/health`, `/api`, static documentation, then Bull Board. There is no URL-encoded parser, request ID, Helmet, compression, rate limiting, global 404 handler, or global error handler.
- API base path is `/api` (not versioned). Routes delegate mostly directly to Sequelize-backed controllers; there is only a permission service and activity service.
- Redis connections are created at module import. One shared client is used by queues/workers, while password reset and S3 utilities create additional clients.
- Workers are a separate `npm run worker` process. The server does not start them. Activity, log, and document consumers exist.
- Cron runs in every API process after DB sync; there is no distributed lock, so multi-instance deployments duplicate scheduling.
- Sequelize models are registered centrally and their `associate` functions are invoked. No migrations are present.
- Environment keys exist locally; `.env` is ignored/untracked. `.env.sample` is tracked. No actual secret values are reproduced here.
### Bootstrap and operational findings
| Concern | Status | Evidence / impact |
|---|---|---|
| Express start and base path | Partial | `server.js`, `app.js`; `/api` and `/health` |
| JSON / cookies / CORS / logging | Partial | JSON, cookies, single-origin credentialed CORS, Morgan `dev`; no body-size configuration or URL-encoded parser |
| Security middleware | Missing | No Helmet or API rate limiter |
| 404/global errors | Missing | Errors depend on individual controllers; unmatched routes use Express defaults |
| Database readiness | Broken | Listener is not gated on authenticate/sync; failure is logged only |
| Redis readiness | Partial | Event logging exists; health endpoint never checks Redis |
| BullMQ/workers | Partial | Separate process required and undocumented operationally; retries only on document jobs |
| Cron initialization | Partial | Starts after DB sync, once per server process, with no leader lock |
| Health check | Broken | Sends response before asynchronous DB authentication completes and hardcodes mail/Redis as OK |
| Graceful shutdown | Missing | No SIGTERM/SIGINT cleanup for server, Sequelize, Redis, workers, or cron |
| Process errors | Missing | No `unhandledRejection`/`uncaughtException` policy |
## 3. Existing Infrastructure
| Component | Status | Files | Notes |
|---|---|---|---|
| Express API | Partial | `server.js`, `app.js`, `app/routes/*` | Express 5; no versioning/global errors/security middleware |
| MySQL/Sequelize | Partial | `app/config/db.config.js`, `app/models/index.js` | Pool configured; runtime `sync()`, no migrations |
| Redis | Partial | `redis.config.js`, `redisClient.js` | Functional client pattern; excessive clients, no shutdown/readiness |
| BullMQ | Partial | `app/queues/*`, `app/workers/*` | Three queues and matching consumers; only document jobs have attempts/backoff/retention |
| Bull Board | Broken/unsafe | `bullBoard.config.js`, `app.js` | Only activity queue shown; `/admin/queues` has no authentication |
| Cron | Partial | `cron/*` | Transactional notification deletion; no distributed lock or retention-age policy |
| Email | Partial | `mail.config.js`, `mail.util.js`, templates | SMTP/template sender exists; verifies on import, sends inline, no queue/retry/escaping |
| S3 storage | Broken | `s3.config.js`, `s3Upload.utill.js` | S3 client is entirely commented out, so `s3.send` fails |
| Uploads | Broken | upload middleware/controller/model | MIME/size checks exist; account guard is incompatible; no magic-byte validation/cleanup/ownership |
| Documents | Partial/broken | document controller, logic, templates, queue/worker | PDF/Excel framework is substantive; S3 breaks completion; access is overly broad and role guards mismatch |
| Notifications | Partial | notification models/controller/cron | In-app records only; no assignment API/service, email/FCM/preferences/delivery tracking |
| Activity/audit | Partial | activity service/model/queue/worker/controller | Async append-only-shaped records; no actor/IP/change metadata, integrity/retention, or broad coverage |
| Logging | Partial | console utility/log queue/worker | Local daily files; may receive sensitive payloads; no rotation/structured sink |
| API docs | Partial | `Documentation/*`, docs routes | Handwritten Markdown/HTML, not Swagger/OpenAPI; docs auth is forgeable |
| Tests | Missing | package script only | Jest finds zero tests; Supertest is not installed |
| Docker | Partial | `Dockerfile` | Uses Node 20 instead of target Node 22; API image only; no healthcheck/non-root user |
| Nginx/Compose/CI/CD | Missing | none | No reverse proxy, service orchestration, or pipeline files |
| Payments/FCM/OpenAI | Missing | none | No dependencies, config, models, or consumers |
Queue behavior: `document-generation` has 3 exponential attempts (2s base), completed retention, and retained failures. `activity-queue` and `logQueue` have consumers but no explicit retry/backoff/retention/dead-letter policy and are not idempotent. Re-delivery can duplicate activity rows or log lines. Queue event listeners attached to `Queue` are not a reliable substitute for `QueueEvents` for all lifecycle events. Worker failures are logged only. Document status is not reconciled on job failure/success.
## 4. Existing Database Models
All models use timestamps and none uses `paranoid`. Aside from the unique flags noted below, explicit indexes are absent.
| Model / table | Key and important fields | Purpose | Important relations | Status |
|---|---|---|---|---|
| User / `users` | PK string `id`; names, unique email, password, accountType ENUM, accountStatus ENUM, emailVerifiedAt | Identity/account | hasOne Profile; hasMany UserPermission | Partial; no role FK/`roleID` despite service/controller use, no sessions/tokenVersion/social IDs |
| Profile / `profiles` | PK `profile_id`; unique `user_id`; theme, notificationsEnabled, image IDs, DOB, phone | Basic preferences/profile | belongsTo User | Partial; no gender/language/address; image IDs lack FKs |
| UserActivity / `UserActivity` | integer PK; user/name/description/type/module/date/time | Activity trail | None | Partial; user FK absent, redundant time fields, no indexes |
| Upload / `uploads` | integer PK; S3 path/type/size/name/use/uploaded_by | Media metadata | None | Partial; uploader/user and ownership FKs absent |
| Permission / `permission` | PK `permission_id`; name/page/module/action | Permission definition | hasMany role/user grants | Partial |
| Role / `roles` | PK `role_id`; name/description | Named role | hasMany role grants | Partial; User has no role association |
| RolePermission / `rolePermission` | PK `rp_id`; role_id, permission_id | Role grant | belongsTo Role/Permission | Partial; no composite unique constraint |
| UserPermission / `userPermission` | integer PK; user_id, permission_id | Direct additive grant | belongsTo User/Permission | Partial; no composite unique; cannot deny/expire grants |
| Document / `Document` | PK `doc_id`; reference_no, doc_type, JSON data, status | Saved business documents | None | Partial; status/type unconstrained, no creator/owner/FKs/indexes |
| DocumentType / `DocumentType` | integer PK; nullable name, JSON description | Document registry metadata | None | Partial; name is neither required nor unique |
| ReferenceNumber / `referenceNumbers` | PK string; unique sequence_key, integer counter, last value | Atomic sequence generation | None | Reusable; transaction/row locking implemented by utility |
| Notification / `notification` | PK string; headline/body, USER/ANNOUNCEMENT ENUM, active/date | In-app notification content | hasMany UserNotification as `users` | Partial |
| UserNotification / `user_notification` | integer PK; user_id, notification_id, isRead | Per-user notification state | belongsTo User; belongsTo Notification | Partial; constraints disabled, no composite unique/index; include alias is inconsistent (controller asks `notification`, association defines no alias) |
Association registration does execute. However, User's `roleID` is not a declared attribute or FK, notifications deliberately disable FK constraints, activities/uploads/documents have no user association, and join-table uniqueness is not enforced. `sequelize.sync()` masks the absence of schema migrations and makes production schema evolution unsafe.
## 5. Existing API Endpoints
All paths below are derived from actual mounting. “Self-or-admin” is not implemented anywhere; parameterized user endpoints generally trust the requested ID after coarse account-type checks.
| Method | Endpoint | Auth | Permission / guard | Status | Notes |
|---|---|---|---|---|---|
| GET | `/health` | No | None | Broken | Returns before DB check; Redis/mail are hardcoded OK |
| GET | `/api/auth/me` | Yes | None | Partial | Returns token payload plus effective permissions |
| POST | `/api/auth/req-otp` | No | None | Partial/unsafe | Password + in-memory OTP; logs OTP; enumeration; no attempts/rate limit/status check |
| POST | `/api/auth/login` | No | None | Partial/unsafe | OTP to one-day access cookie; no refresh/session/rotation/status check |
| POST | `/api/auth/logout` | No | None | Partial | Clears cookie only; bearer tokens remain valid |
| POST | `/api/user` | No | None | Partial/bug | Registration + profile + verification; activity uses undefined `req.user` after commit |
| POST | `/api/user/verify-email` | No | None | Partial | Redis one-use hashed token; no resend endpoint |
| GET | `/api/user` | Yes | accountType `admin` | Partial | Paginated list |
| GET | `/api/user/:id` | Yes | listed legacy types | Broken/IDOR | Most listed types cannot exist; no ownership enforcement |
| PATCH | `/api/user/:id` | Yes | listed legacy types | Broken/privilege escalation | Mass updates accountType/undeclared role fields; no ownership/field validation; early returns leak transaction |
| DELETE | `/api/user/:id` | Yes | `admin` | Partial | Hard delete; related profile handling depends on DB state; early return leaks transaction |
| GET | `/api/activity` | Yes | `admin` | Partial | Full audit list, no pagination |
| GET | `/api/activity/user/:userId` | Yes | `admin` | Partial | No paging/index |
| POST | `/api/upload` | Yes | `admin` or nonexistent `staff` | Broken | S3 client undefined; DB requires `use_for`; upload not transactional |
| GET | `/api/upload/signed-url/:id` | Yes | `admin` or nonexistent `staff` | Broken | S3 undefined; catch sends no response; no ownership check |
| GET | `/api/document/types` | Yes | admin or nonexistent legacy types | Partial | Effectively admin-only under current ENUM |
| POST | `/api/document/saved` | Yes | same | Partial | Body filter on a read operation; no owner/pagination; Sequelize `exclude` placed incorrectly |
| POST | `/api/document/generate` | Yes | same | Broken | Queues correctly, but worker S3 upload fails; validation shallow |
| POST | `/api/document/draft` | Yes | same | Partial | Saves arbitrary JSON; no ownership/validation |
| GET | `/api/document/reference-number/:documentType` | Yes | same | Partial | Consumes sequence on GET |
| GET | `/api/document/job/:jobId/status` | Yes | same | Partial/IDOR | Exposes stacktrace and any job by ID |
| GET | `/api/document/download/:uuid` | Yes | same | Broken/unsafe | S3 undefined; deletes shared object after response; no ownership |
| DELETE | `/api/document/job/:jobId` | Yes | same | Partial/IDOR | Any allowed user can remove any removable job |
| GET | `/api/document/:docId` | Yes | same | Partial/IDOR | Arbitrary document access |
| POST | `/api/docs/login` | No | Static credentials | Unsafe | Sets unsigned boolean cookie; no expiry/rate limiting |
| POST | `/api/docs/logout` | No | None | Partial | Clears cookie |
| GET | `/api/docs/markdown-files` | docs cookie | `docsAuth === "true"` | Unsafe | Cookie can be forged by client |
| GET | `/api/docs/view/:file` | docs cookie | same | Partial | Extension/path checks; auth is weak |
| POST | `/api/profile/req-reset-password` | No | None | Partial/unsafe logging | Enumeration-resistant response; raw reset token is logged |
| POST | `/api/profile/reset-password` | No | None | Partial | Hashed one-use Redis token; new password is not policy-validated |
| POST | `/api/profile/change-password` | Yes | legacy account types | Broken/partial | Effectively admin-only; no new-password validation/session revocation |
| GET | `/api/profile/avatar/:userId` | Yes | legacy account types | Broken | S3 undefined, missing upload null check, wrong `profile.userId` property, IDOR |
| GET | `/api/profile/background/:userId` | Yes | legacy account types | Broken | Same issues |
| POST | `/api/notification` | Yes | admin or nonexistent `management` | Partial | Creates content only; no user assignment |
| GET | `/api/notification/announcements` | Yes | legacy account types | Partial | Effectively admin-only |
| GET | `/api/notification/user/:userId` | Yes | legacy account types | Broken/IDOR | Include alias mismatch likely throws; no ownership |
| PATCH | `/api/notification/user/:userId/notification/:notificationId/read` | Yes | legacy account types | Broken/IDOR | No ownership; effectively admin-only |
| ALL | `/admin/queues/*` | No | None | Unsafe | Bull Board exposed; only activity queue registered |
| GET | `/Documentation/*` | No | Blocks `.md` only | Partial | Static HTML documentation is public |
### Defined but unreachable permission routes
`app/routes/permission.routes.js` defines 18 endpoints under the intended permission router (permission CRUD/bulk; role CRUD and grants; user grants CRUD/bulk), but `app/routes/index.js` imports `permissionRoutes` and never calls `router.use(...)`. Therefore none has an actual URL and all are **BROKEN/unreachable**. If mounted as `/permission`, their paths would be `/`, `/bulk`, `/:permissionId`, `/roles`, `/roles/:roleId`, `/roles/:roleId/permissions`, `/roles/permissions/bulk`, `/users/:userId/permissions`, `/users/permissions`, `/users/permissions/bulk`, and `/users/permissions/:upId` with the methods declared in that file. Read endpoints require authentication; mutations require accountType exactly `admin`. Controllers are substantial CRUD logic, but integration, uniqueness, cache invalidation, validation, and transactions are inconsistent.
## 6. Development Plan Status
| Module | Completion | Status | Evidence | Remaining Work |
|---|---:|---|---|---|
| 01 Authentication & Authorization | 38% | Partial | Password hashing, register/verify, OTP access JWT, middleware, RBAC structures | Refresh/session lifecycle, OAuth/Apple, durable OTP/limits, status enforcement, role linkage, mount/fix RBAC |
| 02 Customer Profile & Address Management | 22% | Foundation | User/Profile with phone, DOB, images/preferences | Self-service ownership, addresses/default, gender/language, deactivation, robust image flow |
| 03 Product Catalogue Management | 0% | Missing | No models/routes | Full catalogue/category/variant/review/SEO model and APIs |
| 04 Multi-Language Content | 0% | Missing | No content translation system | Locale strategy and translated content |
| 05 Inventory Management | 0% | Missing | No inventory entities | Stock, reservations, warehouses, adjustments |
| 06 Cart & Wishlist | 0% | Missing | None | Entire module |
| 07 Promotions, Coupons & Banners | 0% | Missing | None | Entire module |
| 08 Checkout | 0% | Missing | None | Pricing/shipping/tax/transaction orchestration |
| 09 Order Management | 0% | Missing | Document names are not commerce orders | Full order state machine and returns |
| 10 Payment Management | 0% | Missing | No provider code/dependencies | PayHere/Stripe, webhooks, idempotency, refunds |
| 11 Delivery & Rider Management | 2% | Foundation only | `rider` account ENUM; document templates named delivery/dispatch | Rider profiles, assignments, tracking, zones/rates |
| 12 Loyalty, Reward Points & Membership | 0% | Missing | None | Ledger, tiers, generic earn rules, rewards/vouchers |
| 13 Wholesale / Business Accounts | 2% | Foundation only | `business_customer` ENUM only | Approval/profile/pricing/MOQ/tiers/credit/settlements/invoices/analytics |
| 14 Notification System | 28% | Partial | Notification/user join models, CRUD/read endpoints, cleanup cron, mail utility | Fix aliases/ownership; assignment and preferences; FCM/email jobs/templates/status |
| 15 Support Ticket System | 0% | Missing | None | Tickets, messages, SLA/escalation/help center |
| 16 AI Customer Support Chatbot | 0% | Missing | No OpenAI integration | Conversations, tools, safety, human escalation |
| 17 Product Recommendations | 0% | Missing | None | Events and recommendation service |
| 18 Admin Dashboard & Analytics | 1% | Foundation | Admin user type and raw activity endpoint | Metrics, aggregation, secured dashboard APIs |
| 19 File & Media Management | 25% | Broken foundation | Multer, Upload model, S3/presigned utilities | Restore/configure client, ownership, object validation/lifecycle, media transformations |
| 20 Audit Logging & System Configuration | 22% | Partial | Async activity records/log queue | Full audit schema/coverage, immutability, config models, secure structured logging |
| 21 Background Jobs & Queues | 35% | Partial | Redis, 3 queues/consumers, worker entry, document retry | Idempotency, policies for every queue, monitoring auth, graceful shutdown, scheduler topology |
| 22 Security | 15% | Weak foundation | bcrypt, JWT verification, HttpOnly cookie, basic MIME limits | Findings in §10; headers, throttles, validation, authorization, secrets/token discipline |
| 23 Testing & Quality Assurance | 2% | Missing | Jest dependency/script only | Tests, Supertest, fixtures, lint/type/static checks, CI |
| 24 API Documentation | 18% | Partial | Handwritten endpoint Markdown/HTML | OpenAPI/Swagger, synchronization, schemas/security/error contracts |
| 25 Deployment & Infrastructure | 18% | Partial | Dockerfile | Node 22, Compose, Nginx, healthcheck, non-root, migrations, CI/CD, observability |
## 7. Original 15-Day Plan Status
| Day | Intended Scope | Completion | Notes |
|---|---|---:|---|
| 1 | Foundation | 55% | Express/Sequelize/MySQL/Redis/BullMQ/Docker present; health broken; Swagger/Compose/migrations/production lifecycle missing |
| 2 | Authentication | 38% | Basic verified registration and OTP access JWT; core session/OAuth/security requirements incomplete |
| 3 | Customer + business accounts | 18% | Basic user/profile and enum only; no addresses/business domain |
| 4 | Products/categories/variants | 0% | Missing |
| 5 | Inventory/admin products | 0% | Missing |
| 6 | Cart/wishlist | 0% | Missing |
| 7 | Promotions/checkout | 0% | Missing |
| 8 | Orders | 0% | Missing |
| 9 | Payments | 0% | Missing |
| 10 | Delivery/rider | 2% | Rider enum and unrelated document templates only |
| 11 | Loyalty | 0% | Missing |
| 12 | Notifications/support | 16% | Partial in-app notification foundation; support absent |
| 13 | AI/recommendations | 0% | Missing |
| 14 | Analytics/security | 8% | Raw activities and scattered security controls only |
| 15 | QA/production | 5% | Dockerfile only; no tests/CI/Nginx/production hardening |
**Last genuinely complete day: none.** Development reached partway through Day 1 and Day 2, with selected infrastructure from Days 12, 14, and 15 implemented early.
## 8. Demo Website Requirement Gaps
| Feature | Present on Demo | Present Backend | Original Plan | Action Needed |
|---|---|---|---|---|
| Email/password login | Yes | Partial (password then email OTP) | Auth | Clarify desired login flow; secure OTP/session lifecycle |
| Remember me | Yes | No | Auth | Add session-specific lifetime safely |
| Forgot/reset password | Yes | Partial | Auth | Stop token logging, validate password, revoke sessions |
| Google sign-in | Yes | No | Auth | Add provider verification/linking |
| Apple sign-in | Yes | No | Potential added requirement | Add to auth scope explicitly |
| Account overview/recent orders/counts | Yes | No | Customer/orders | Aggregate dashboard endpoint after domain models |
| Points/vouchers/membership/progress | Yes | No | Loyalty | Ledger, tier/rule/reward architecture |
| Default address/profile/addresses | Yes | Profile partial; addresses absent | Customer | Ownership-safe profile and address CRUD/default constraint |
| Wishlist/order history/sign out | Yes | Sign-out cookie only; rest absent | Cart/orders/auth | Implement modules and true session revocation |
| Silver/Gold/Platinum tiers/benefits | Yes | No | Loyalty | Configurable tiers; do not hardcode demo examples |
| Point transaction history | Yes | No | Loyalty | Immutable ledger |
| Purchases/reviews/referrals/birthdays earning | Yes | No | Loyalty/reviews | Generic earn-source rules with idempotency |
| Reward redemption/vouchers/shipping rewards | Yes | No | Loyalty/promotions | Reward definitions, redemption transaction, vouchers |
| Business approval/Partner ID/tier | Yes | Account enum only | Wholesale | Business profile and approval workflow |
| Monthly/history/discount/top buyers/orders | Yes | No | Wholesale/analytics | Wholesale aggregates and reporting |
| Credit limit/available/utilization | Yes | No | Wholesale | Credit account/ledger and authorization rules |
| Settlement terms/dates/invoices | Yes | No | Wholesale/payment | Terms, statements, invoice/payment lifecycle |
| Wholesale catalogue/MOQ/pricing tiers/bulk | Yes | No | Wholesale/catalogue | Customer-segment pricing and volume tiers |
| Featured inventory/reorder | Yes | No | Inventory/wholesale | Stock and reorder workflows |
| Shipping thresholds/methods/zones/fees | Yes | No | Checkout/delivery | Configurable rate engine |
| International shipping/duties display | Yes | No | Delivery/checkout | Destination rules and duty estimate representation |
| Order tracking | Yes | No | Orders/delivery | Shipment event timeline |
| 30-day return/eligibility/reason/status | Yes | No | Orders (gap detail) | Configurable returns/RMA state machine |
| Pickup/refund/exchange | Yes | No | Delivery/payment/orders | Integrate RMA, courier, payment refund, exchange order |
| Help center/FAQs/sizing/payment help | Yes | No | Support/content | CMS/help content APIs |
| Email support/tickets | Yes | No | Support | Ticket/conversation/SLA module |
| AI Style Assistant/human escalation | Yes | No | AI/support | AI conversation with ticket/advisor handoff |
| Newsletter consent lifecycle | Yes | No | Demo gap | Dedicated subscriber consent/status/source/language model; not profile notification preference |
| New/featured/sale products | Yes | No | Catalogue/promotions | Merchandising fields/rules |
| Category/editorial collections | Yes | No | Catalogue/content | Collections and ordered merchandising |
| Related products | Yes | No | Recommendations/catalogue | Explicit and computed relations |
| Reviews/verified purchase reviews | Yes | No | Catalogue/recommendations | Review moderation and verified-order link |
| Size guides | Yes | No | Catalogue/content | Structured, category/product-linked guides |
| Product SEO | Yes | No | Catalogue | Slugs/meta/canonical data |
| Banners | Yes | No | Promotions | Placement, locale, schedule, targeting |
| Multiple languages | Yes | No | Multi-language | Localized product/content model |
Current order/delivery architecture cannot support shipping or returns: no commerce Order, OrderItem, Shipment, Address, Return, Refund, or state-transition entities exist. The similarly named generated documents are generic JSON documents and should not be treated as domain substitutes.
## 9. Technical Debt
### CRITICAL
- Restore a valid S3 client before any upload/document endpoint can work.
- Align authorization vocabulary and enforce ownership; current legacy guards, IDORs, and accountType mutation enable denial of access or privilege escalation.
- Remove raw OTP/reset-token and decoded-auth logging; rotate any credentials if operational logs captured them.
- Replace production `sequelize.sync()` with migrations and gate server readiness on required services.
- Implement a real access/refresh session model with rotation, revocation, account-status enforcement, and secure logout.
### HIGH
- Mount and repair permission routes; add User-role linkage and grant uniqueness/cache invalidation.
- Add validation schemas and centralized error handling; prevent arbitrary field updates.
- Protect Bull Board and documentation sessions.
- Fix notification association alias and user ownership checks.
- Add rate limits for login, OTP, verification, reset, docs login, and general API traffic.
- Add tests for auth/authorization, transactions, uploads/jobs, and failure paths.
- Fix transaction leaks on early returns in user update/delete.
### MEDIUM
- Standardize response/error formats and status codes; stop returning internal error messages/stack traces.
- Consolidate Redis connections and add lifecycle/readiness handling.
- Make jobs idempotent and add retry/backoff/retention/dead-letter/alert policies.
- Move email to a job and add retry/delivery tracking and safe template escaping.
- Add pagination/indexes to activity, notification, document, and user queries.
- Remove legacy Oceanic naming and reconcile API versioning.
### LOW
- Correct mojibake in source/log messages, inconsistent singular/plural table names, and `*.utill.js` spelling.
- Remove unused imports/constants and dead/commented code.
- Split giant permission controller and move business logic into services after behavior is tested.
## 10. Security Findings
- No tracked `.env` was detected. `.env.sample` is tracked. Potential secret-bearing configuration exists in local `.env`; values were not inspected/reproduced. If this file has ever been shared or committed elsewhere, rotate credentials.
- JWT falls back to a public placeholder secret if configuration is missing. There is no issuer/audience/session ID/tokenVersion or refresh-token revocation.
- Login OTP uses `Math.random`, process memory, and no attempt/rate limit; it fails across instances/restarts and is logged in plaintext.
- Password reset token is logged in plaintext. Reset/change paths do not validate the new password policy or revoke existing access tokens.
- Login does not reject pending, suspended, or deactivated accounts.
- User update allows coarse-authorized callers to target arbitrary IDs and set `accountType`, a privilege-escalation and IDOR risk. Many profile/notification/document endpoints have the same ownership defect.
- Bull Board is public. Docs protection is an unsigned client cookie equal to `true`; credentials are brute-forceable without rate limiting.
- CORS is a single credentialed origin and cookie flags are reasonable for cross-site production, but CSRF protection/origin validation is absent for cookie-authenticated mutations.
- Multer limits size and declared MIME, but image wildcard acceptance lacks content sniffing, image decompression safeguards, antivirus scanning, extension normalization policy, and object lifecycle cleanup.
- S3 `PutObject` sets no ACL (good default if bucket blocks public access), but actual bucket policy/encryption cannot be verified. Signed URLs are cached; authorization is checked only before URL issuance and ownership is not checked.
- Controllers expose `error.message`; job status exposes stack traces. Production Sequelize logging is inverted to `true`, which can leak query data.
- Request validation is handwritten and sparse; mass assignment exists in user update. Sequelize query values are generally parameterized, so no direct raw-SQL injection was found.
- Foreign-key constraints are disabled for notification joins; missing uniqueness and transactions create races/duplicates in grants and notifications.
- No Helmet, API rate limiting, CSRF strategy, audit integrity, session revocation, or centralized security error policy exists.
## 11. Broken / Suspicious Implementations
- `app/config/s3.config.js`: the entire client/export is commented; every S3 caller receives `{}`.
- `app/routes/index.js`: imports `permissionRoutes` but never mounts it.
- `app/utils/documentJob.util.js`: requires nonexistent `../queues/pdf.queue`; currently appears orphaned.
- `app/services/permission.service.js#getEffectivePermissions`: queries `user.roleID`, which is not a User model attribute; role grants cannot reliably apply.
- `app/routes/{user,profile,document,notification}.routes.js`: guards use `management`, `team_head`, `user`, or `staff`, none of which is in the User ENUM. Valid `manager`, `customer`, `business_customer`, `rider`, `support_agent`, and `superadmin` are largely excluded.
- `user.controller#createNewUser`: calls `logActivity({user: req.user})` on a public route, causing a post-commit exception after the account has been created; client may receive 500 and retry.
- `user.controller#updateUser`: accepts accountType and undeclared role/department fields; does not update email despite destructuring it; opens transaction before lookups and does not roll back early 404 responses.
- `user.controller#deleteUser`: early 404 does not roll back; hard delete may conflict with Profile because cascade is unspecified.
- `profile.controller#getProfileAvatar/getProfileBackgroundImage`: assumes upload exists, uses wrong `profile.userId` response property, lacks ownership, and reaches broken S3.
- `upload.controller#getFileUrl`: empty catch block can leave requests hanging.
- `notification.controller#getUserNotifications`: requests association alias `notification`, but `belongsTo` defines no alias; likely Sequelize eager-loading error.
- `notification.controller`: USER notifications are created but never assigned to users through an endpoint/service.
- `app.js#/health`: asynchronous DB result races with response; reports `N/A`/hardcoded OK rather than real readiness.
- `app.js` bootstrap: server listens before DB boot finishes; DB errors are swallowed; each instance starts cron.
- `app/middleware/permission.middleware.js`: unused `hasPermission`; admin bypass only recognizes `admin`, not `superadmin`; wildcard logic differs between helper and actual check.
- `docsSession.middleware.js`: trusts an unsigned, client-set boolean cookie.
- `document.controller#getSavedDocuments`: `exclude` is not nested under `attributes`, so JSON data may still be fetched; filter is in POST body despite message saying query parameter.
- `document.controller#downloadDocument`: destructive read deletes the object after delivery and lacks job/user ownership.
- `app/logic/documents/registry.js`: catches module load failure but still registers undefined functions, deferring failure to runtime.
- `consoleLog.utill.js` and auth/reset utilities: log pipelines may persist secrets and full error objects.
- Production DB logging is enabled while non-production logging is disabled, likely inverted.
Orphaned or unused-looking code includes `documentJob.util.js`, `notification.utill.js` (empty), `logic/documents/engine/pdf.engine.js` (generation uses `pdfGenerator.js`), several Excel/id/vendor/calendar/basis utilities not referenced by mounted features, `Assets` in upload controller (unregistered), imported `PERMISSIONS`/`checkPermission` in routes where checks are absent/commented, and unused dependencies likely including `pdfmake` and `nodeman`. `nodemon` is incorrectly a production dependency. Static analysis cannot prove every dynamic/template use; confirm before removal.
## 12. Reusable Existing Components
- Sequelize model registry/association convention can be extended after migrations replace runtime sync.
- User/Profile registration transaction, bcrypt utility, hashed one-use email verification token, and hashed password-reset-token concepts are sound foundations once error/logging/session issues are fixed.
- Cookie-or-Bearer authentication middleware structure is reusable after it loads current user/session/status and applies token claims.
- Permission, role, role-grant, and user-grant models/controllers/service are worth repairing rather than rebuilding; add role linkage, constraints, mounting, validation, and cache invalidation.
- Shared Redis factory/client and permission/user cache helpers can be consolidated and retained.
- Activity queue/service/worker is a useful async audit foundation; extend its schema and coverage.
- BullMQ worker entry pattern and document queue retry/backoff settings are reusable; standardize them across queues.
- Upload metadata model, Multer memory-storage limits, S3 key generation, and presigned URL caching are reusable after the S3 client and authorization/content validation are fixed.
- Document registry, PDF/Excel generators, templates, queue/worker, Document/DocumentType models, and atomic reference-number generator are substantive reusable subsystems. They are auxiliary business-document infrastructure, not order/payment replacements.
- Notification/UserNotification models, read-state concept, announcement query, and transactional cleanup cron can be repaired and extended for channel delivery.
- Email transport/template system and existing verification/reset/welcome templates can be moved behind an email queue.
## 13. Recommended Next Development Phase
Continue with a **Foundation, security, and authentication completion phase** before starting catalogue work.
First make startup deterministic and production-safe: Node 22 alignment, validated environment configuration, migrations, real readiness/liveness checks, global 404/errors, Helmet/rate limits, protected operations dashboards, graceful shutdown, and a test harness. Then complete identity: Redis-backed cryptographic OTP with limits, account-status checks, access/refresh sessions with rotation/revocation, secure logout/reset, validation, ownership rules, and a repaired/mounted role-permission system. Repair S3 only as part of restoring already-promised profile/media/document behavior.
After that baseline passes integration tests, finish customer/business profile and address primitives, reusing User/Profile, auth middleware, Redis, permission service, upload system, activity logger, email templates, queues, and reference-number utility. Only then begin catalogue/product models.
## 14. Recommended Updated Roadmap
1. **Phase 0 — Stabilize foundation:** Node 22, env validation, migrations, startup/readiness, global errors/security middleware, graceful shutdown, protected Bull Board, baseline Jest/Supertest and CI.
2. **Phase 1 — Complete identity and authorization:** OTP/session/refresh rotation, status checks, logout/revocation, password recovery hardening, OAuth Google/Apple, ownership rules, repaired roles/permissions.
3. **Phase 2 — Repair existing cross-cutting services:** S3/media, email jobs, notification aliases/assignment, queue reliability/idempotency, audit schema, document ownership and job lifecycle.
4. **Phase 3 — Customer and business foundations:** Profile completion, addresses/defaults, preferences/deactivation, business approval/partner identity/credit and settlement primitives.
5. **Phase 4 — Catalogue/content:** Categories, products, variants, media, localized content, SEO, size guides, collections, reviews.
6. **Phase 5 — Inventory and merchandising:** Warehouses/stock/reservations, wholesale pricing/MOQ/volume tiers, banners/promotions/coupons.
7. **Phase 6 — Shopping and checkout:** Cart, wishlist, pricing, shipping zones/rates/duties, checkout transactions.
8. **Phase 7 — Orders/payments:** Order state machine, PayHere/Stripe webhook idempotency, invoices, refunds, returns/exchanges.
9. **Phase 8 — Delivery/rider:** Assignments, tracking events, pickup/return logistics.
10. **Phase 9 — Loyalty and wholesale completion:** Generic earn ledger, tiers, rewards/vouchers/referrals; credit utilization/settlements/analytics.
11. **Phase 10 — Support/AI/recommendations:** Help content, tickets/SLA, advisor escalation, AI assistant, recommendation events/services.
12. **Phase 11 — Analytics and production QA:** Dashboards, security testing, load/integration/e2e tests, observability, Nginx/Compose/deployment/runbooks.
## 15. Do Not Rebuild List
Preserve and extend these concepts/files after adding tests: centralized Sequelize registration; User/Profile base tables; bcrypt helper; Redis connection/cache helpers; email verification/password-reset token hashing; auth middleware extraction of cookie/Bearer tokens; RBAC model/controller foundation; activity queue/service/worker; document registry/generators/templates/queue/worker; reference-number sequencing; Upload metadata/Multer limits/S3 utility interface; Notification/UserNotification read-state model; cleanup cron transaction; mail templates/transport interface; Docker Chromium setup for Puppeteer.
## Verification and Dependency Audit
- `node --check` passed for every repository JavaScript file.
- `npm test -- --runInBand` failed because Jest found **0 tests**.
- `npm ls --depth=0` completed without reporting missing installed top-level packages.
- `npm audit --omit=dev` reported **28 production dependency vulnerabilities**: 19 high, 8 moderate, 1 low, 0 critical. Dependency upgrades were intentionally not performed.
- Broken local import scan found active-looking `documentJob.util.js -> ../queues/pdf.queue`; the commented future `email.worker` reference is not an active defect.
- Targeted dependency observations: Supertest, Swagger/OpenAPI tooling, Helmet, rate limiting, FCM, payment SDKs, and OpenAI SDK are missing. `nodemon` should be dev-only; `nodeman` and `pdfmake` appear unused. Confirm with runtime coverage before removal.
## Phase 0 Completion Update
**Date:** 2026-09-03
**Revised Day 1 completion:** approximately **92%**.
Phase 0 stabilized the existing foundation without adding commerce modules. Node/Docker now target Node 22; Zod validates required startup configuration and feature-gated mail/S3 configuration; unsafe JWT secret fallbacks are removed. Express construction is independent from listening, and `server.js` waits for successful MySQL authentication and Redis connectivity before accepting traffic. Runtime `sequelize.sync()` was removed and Sequelize CLI plus a non-destructive current-model baseline migration were added.
New `/health/live` and `/health/ready` routes provide real liveness/readiness behavior, while `/health` remains a liveness compatibility alias. Request IDs, Helmet, explicit body limits, general and sensitive rate limits, centralized 404/error handling, safer production request logging, configurable cron startup, and API/worker graceful shutdown are now present. Bull Board requires an authenticated `admin` or `superadmin` and displays all three existing queues. The existing router is available on both `/api` and `/api/v1`.
Deployment additions include a hardened Node 22/Chromium/non-root Dockerfile with healthcheck, API/worker/MySQL/Redis Compose configuration, an Nginx reverse-proxy example, and a Gitea Actions CI baseline. Jest/Supertest tests now cover environment validation, liveness/readiness, errors/404, protected routes, Bull Board denial, and request correlation. The first test run exposed incompatible ESM-only `uuid@13`; it was safely pinned to CommonJS-compatible v11. `nodemon` moved to devDependencies.
Remaining foundation-adjacent work is intentionally deferred: production database baseline verification, distributed cron locking, full queue policy/idempotency, stronger documentation sessions, permission-router/role integration, and the Phase 1 authentication/ownership/security issues. The original audit above remains the historical baseline; statements such as “missing tests/Helmet/migrations” are superseded by this update and `Documentation/PHASE_0_FOUNDATION_STABILIZATION.md`.
## Phase 1 Completion Update
**Date:** 2026-09-03
**Authentication completion:** approximately **91%**.
**Revised Day 2 completion:** approximately **90%**.
Phase 1 replaced process-memory OTP and refresh sessions with Redis hash-only login challenges and durable MySQL auth-session families. OTP now uses `crypto.randomInt`, challenge UUIDs, TTL, atomic verification, bounded attempts, and no plaintext logging. Refresh tokens are opaque random values stored only by SHA-256 hash; row-locked transaction rotation detects replay and revokes the family. Access JWTs are short-lived, issuer/audience/algorithm constrained, and bound to `sub`, live session ID, and User token version. Middleware enforces current account state and session revocation.
New `auth_sessions`, `user_identities`, and `user_roles` models/tables support devices, Remember Me, Google/Apple stable subjects, and configurable roles. The User security migration adds token version/last login, expands canonical account types, and adds RBAC unique indexes. Permission routes are mounted behind SUPER_ADMIN, permission resolution now uses UserRole, and cache invalidation covers assignments/grants. Customer self-service update is allowlisted and ID-based mutation is privileged, closing the audited identity IDOR/mass-assignment path.
Auth endpoints now cover customer registration, verification/resend, password-to-OTP challenge, OTP completion, refresh rotation, current/all-device logout, forgot/reset/change password, Google, Apple, `/me`, and shared admin/rider compatibility flows. Both `/api` and `/api/v1` remain. Security-focused unit/integration tests were added without real providers/email/database/Redis.
Remaining identity work is operational: validate/deduplicate deployed RBAC data before migration, run staging MySQL/Redis concurrency tests, seed initial privileged assignments securely, configure provider audiences/mail, and design manual privileged OAuth linking and email change if required. Module 01 is now approximately 91%; migration/staging validation prevents claiming 100% production completion.
## Phase 5 Completion Update
Date: 2026-09-03. Inventory/reservation foundations, business pricing, promotions/coupons, and localized scheduled banners are implemented behind new permissions and a forward-only migration. Phase 5 adds 13 models, secured administration routes, public availability/banner projections, audit calls, a bounded expiry reconciliation cron, and Phase 6 pricing/reservation service boundaries. Module 05 is 85%, Module 07 is 78%, and Module 13 is 75%. Inventory is 90%, reservations 90%, business pricing 82%, promotions/coupons 78%, and banners 82%. Automated verification: 18 suites and 89 tests passed; syntax passed for 232 JavaScript files. Migration was not executed. Staging must precheck legacy stock/pricing/promotion/banner data, apply the migration, seed permissions/default warehouse, and test genuine MySQL locking plus cron behavior before Phase 6 production use.
## Phase 6 Completion Update
Date: 2026-09-03. Module 06 is 91%, Module 08 is 84%, and Module 07 is revised to 86%. Authenticated cart is 92%, wishlist 92%, shipping 86%, checkout 88%, and reservation integration 90%. Nine models, a forward-only migration, owner-scoped shopping APIs, permission-protected shipping administration, server-authoritative totals, atomic inventory reservation composition, idempotent checkout creation, and bounded expiry/cancellation release are implemented. Verification passes 20 suites/95 tests and 258 JavaScript syntax checks. The migration was not executed. Before Phase 7, staging must precheck legacy shopping/shipping tables and address/currency compatibility, seed shipping configuration/permissions, apply migrations, and validate real multi-connection InnoDB concurrency plus multi-instance expiry behavior.
## Phase 7 Completion Update
Date: 2026-09-09. Module 09 is 86%, Module 10 is 76%, and Module 13 is revised to 82%. Orders are 90%, payments 78%, invoices 72%, refunds 68%, returns 82%, coupon redemption 80%, and verified-purchase reviews 90%. Eleven commerce models, a forward-only migration, transactional checkout conversion, owner/admin APIs, explicit state machines, verified/idempotent webhook processing, payment-time inventory consumption, invoice sequencing, itemized refund validation, RMA handling, and return-only restocking were added. Migration and real provider/MySQL/document-worker validation remain staging requirements. Module 16 AI Customer Support Chatbot is intentionally excluded from this backend and planned as a separate service.
## Phase 8 Completion Update
Date: 2026-09-09. Module 11 is 88%; shipments are 90%, riders 86%, assignment/dispatch 86%, tracking 88%, proof of delivery 82%, and return logistics 84%. Module 09 is revised to 90% through physical fulfillment integration. Six logistics models, a forward-only migration, explicit shipment states/actions, partial fulfillment, locked rider capacity/assignment, append-only events, proof media validation, safe tracking, and approved-return pickup were added. Automated checks pass 25 suites/123 tests with 305 JavaScript files syntax-checked. The migration was not executed. Staging must validate real InnoDB concurrency, multi-instance idempotency, proof storage, notification fan-out, permission seeding, and return handoff before production or Phase 9 rollout. Module 16 AI Customer Support Chatbot remains excluded from this backend and will be developed separately.
## Phase 9 Completion Update
Date: 2026-09-09. Module 12 is 86% and Module 13 is revised to 88%. Loyalty accounts are 92%, points ledger 90%, earning rules 86%, membership 88%, rewards/redemption 86%, referrals 82%, birthday rewards 80%, and expiry 80%. Business tiers are 84%, business credit 84%, settlements 78%, wholesale dashboard 82%, and wholesale analytics 76%. Module 07 is revised to 82% through coupon-entitlement foundations; Modules 09/10 are unchanged except for paid-event loyalty and internal-credit integration. Fourteen models, a forward-only migration, bounded cron reconciliation, new owner/admin APIs, and immutable concurrency-safe ledgers were added. Migration and real MySQL/cron/document/notification validation remain staging requirements. Module 16 AI Customer Support Chatbot remains intentionally excluded and will be developed separately.
## Phase 10 Completion Update
Date: 2026-09-09
- Module 15 Support Ticket: **84%**
- Module 17 Product Recommendations: **78%**
- Support tickets 90%; messages 88%; assignment 86%; SLA/escalation 74%; attachments 82%; related-resource integration 78%.
- Help center 84%; help localization 86%; help search 76%; newsletter consent 84%.
- Recommendation events 80%; related 86%; recently viewed 84%; trending 78%; popular 74%; personalized deterministic 70%.
- Module 14 notifications is unchanged: event/template delivery fanout remains outstanding.
- Module 03 catalogue relationships are reused without a revised completion claim.
- Module 04 localization infrastructure is reused without a revised completion claim.
- Verification: **28 suites / 145 tests passing**; syntax passed for **373 JavaScript files**; `npm ls --depth=0` reports no dependency problems.
- Migration: `20260909100000-phase-10-support-recommendations.js` created but **not executed**. Phase 0–9 migrations were not changed.
- Staging requirements: legacy-data precheck; real MySQL migration/FK/query-plan and row-lock validation; Redis/BullMQ/cron multi-instance validation; S3 signed-download and file-content validation; SMTP notification wiring; business-price projection; authoritative shopping/commerce recommendation events; IDOR/E2E/concurrency tests.
- Phase 11 readiness: safe to begin hardening after the Phase 10 migration and infrastructure checks are scheduled; Phase 10 is not a production-readiness claim.
Module 16 AI Customer Support Chatbot is intentionally excluded from this backend. It will be developed as a separate service.