The merge creates the storefront-content capability (two requirements, five scenarios) and updates the mall's home-page requirement so its banner, promotion, quick-link and floor advert content comes from the content API. openspec validate --all --strict stays green at 12 passed / 0 failed.
3.3 KiB
3.3 KiB
Tasks
1. Schema and seed
- 1.1 Add a migration creating
banners,promos,quick_linksandfloor_advertswith explicit columns (image,url,position,active, pluslabel/glyphon quick links); verified the tables exist aftercargo run -p vmall-api - 1.2 Seed the same migration from the assets the page uses today, matching
pages/index.vue's arrays; verifiedGET /api/content/homereturns 3 banners, 3 promos, 6 quick links and 6 floor adverts. The seeded destinations are valid routes (/seckill,/collective,/integral,/search?sort=price&order=desc) rather than the mock's dangling?category=c1ids and itssort=sales, which the catalog API rejects
2. Shared contract
- 2.1 Add
HomeBanner,HomePromo,HomeQuickLink,FloorAdvert,HomeContent,ContentKindandContentInputByKindtopackages/shared/src/types.ts, with the quick-link label asLocalizedText; verified all three frontends build - 2.2 Add
getHomeContent()andadmin.getContent()/admin.replaceContent(kind, list)to theApiClientinterface andcreateApi, and give the fixed-data client matching implementations so the rollback path keeps serving the current arrays. Also registered acontentdomain in the per-domain switch (plugins/api.tsandnuxt.config.ts) — missed on the first pass and caught by the browser check, where the promos still rendered the mock hrefs because the new method had no live pick
3. Public content read
- 3.1 Add
GET /api/content/homereturning the four active, position-ordered lists, with no authentication; verified it answers with the seeded counts and omits a row once it is marked inactive - 3.2 Return an empty list for any kind with no active entries rather than omitting the key; asserted by
home_content_is_public_and_ordered
4. Admin content management
- 4.1 Add
GET /api/admin/contentreturning every kind including inactive rows, gated toplatform_admin; verified a customer and a shop owner are refused with 403 - 4.2 Add
PUT /api/admin/content/{kind}replacing one kind transactionally, validating each entry and reindexing positions from the submitted order; verified a reordered submission reads back in the new order, and that the rendered page follows - 4.3 Verify an invalid entry (missing
image, or a quick-link label withoutzh) fails without changing the stored list
5. Mall home page
- 5.1 Point
pages/index.vueatgetHomeContent(), delete the three mock arrays from the page, and render the floor advert pool by floor order; verified the page still renders its sidebar and floors, and that a floor renders no advert rather than a broken image when the pool is empty
6. Verification
- 6.1 Run the mall, shop-admin and admin builds, since the shared contract changed; all three pass, and
cargo test -p vmall-apiis green at 23 tests - 6.2 Compared the home page against the pre-change render: 3 banners, 6 quick links, 3 promo tiles and floor adverts 1-6 across 6 floors, visually unchanged. Reordering banners and marking one inactive through the admin API changed the rendered carousel accordingly, then the seed was restored
- 6.3 Verified the rollback: with every domain on fixed data and the backend stopped, the home page still renders all four blocks with no console errors