This commit is contained in:
Nông Đức Huy
2026-08-13 23:20:23 +07:00
parent d9f159a8c3
commit cda5d21d0d
53 changed files with 2711 additions and 162 deletions
+9 -4
View File
@@ -158,7 +158,7 @@ sport-store/
│
├── docs/
│ ├── architecture.md Boundaries, conventions, risks — read this first
│ └── adr/ 22 decision records
│ └── adr/ 23 decision records
│
├── docker-compose.yml Backing services; `--profile full` runs everything
├── turbo.json pnpm-workspace.yaml package.json
@@ -254,10 +254,10 @@ locale-in-path would buy nothing.
| **M5** ✅ | Cart (Redis), guest checkout, orders with stock reservation and an admin order lifecycle |
| **M6** ✅ | Search: PostgreSQL full-text + trigram, diacritic-folded, ranked, with type-ahead and refinable results |
| **M7** ◐ | Discounts end-to-end: one engine, one admin screen, stacking, windows, limits, redemptions. Reviews and CMS remain |
| **M8** | Customer account |
| **M8** ✅ | Customer accounts: registration, profile, address book, order history, wishlist; guest orders adopted on sign-up |
| **M9** | Payments (VNPay, MoMo, ZaloPay, COD), shipping, notifications |
**Recommended next step: M8 (customer accounts).** The store can
**Recommended next step: M9 (payments) — or M10 (shipping), since payments are deferred.** The store can
now be browsed, searched, filled into a bag and checked out, and every order moves stock through a
ledger. What it still cannot do is take money — which is the one gap between this and a shop that
trades.
@@ -270,7 +270,7 @@ Everything below was run, not assumed:
- `pnpm lint` · `pnpm typecheck` · `pnpm test` · `pnpm build` — 27/27 Turborepo tasks pass;
`pnpm format:check` clean
- 10 migrations, 43 tables; seed loads 36 permissions, 6 roles, 3 brands, 8 categories,
- 11 migrations, 44 tables; seed loads 36 permissions, 6 roles, 3 brands, 8 categories,
3 collections, 12 products, **155 variants**, 64 uploaded images and 3 dev accounts
- **78 tests** — RBAC guards, password hashing, translation fallback, `Accept-Language`, the
variant matrix planner, the HTTP client's fetch receiver and retry recursion, the inventory
@@ -312,6 +312,11 @@ through Chrome with the console and network panel open:
at 09:00, not shifted; a discount scheduled for next week reads "Scheduled" and stays out of
the bag; switching one off in admin drops it from a shopper's bag on the next load; retiring
one soft-deletes it, leaving redemptions and the audit trail intact
- **Accounts (M8):** registering with an email that had guest orders adopts them into the new
account's history; a signed-in checkout attaches the order to the customer while a guest
checkout — and one carrying a malformed token — still succeeds unattached; one customer
cannot read another's order by id, address book or wishlist; an admin token is refused on
account routes; the session survives a page reload with the access token held only in memory
- **Content (M7):** a post published in one language still lists on the other locale's journal
rather than vanishing; a body containing `<script>` and `<img onerror>` renders as visible text
and executes nothing; a Markdown link to `/men` keeps its locale prefix; a published page