colidevs / colidevs/create-coliapp
nextjs-shadcn-ecommerce-admin: hardening checklist from api/frontend-standard audit (pagination, ETag, headers, dead-code bug)
- Dominant language
- TypeScript
- Stars
- 2
- Forks
- 0
- Avg merge
- 4h 42m
- Merged PRs (30d)
- 43
Description
## Context
Same audit as #54 (`api-standard-check`/`frontend-standard-check` against ADR 0009-0013/0019-0024, run
on the final branch of the `ecommerce-admin-template` SDD build, PR stack #43-#53). None of these block
that PR stack's review — tracked here as a consolidated follow-up checklist, lowest-to-moderate severity.
## API-side (`apps/api`)
- [ ] **Cursor pagination missing, systemic** — `admin/products`, `admin/orders`, `admin/stock`,
`web/products` all use offset/page pagination (`types.ts`/`repository.ts` in each module,
`openapi/openapi.yaml:342,346,732,736,844,848,942,946`), contrary to ADR 0009's cursor-based default.
Not a hard CI failure (Spectral's own equivalent rule is `severity: warn`), but worth fixing before
`orders` grows large in production — offset scans degrade on an unbounded, growing table.
- [ ] **No ETag/If-Match on admin writes** — `PATCH /stock/:id` and the products update path do an
absolute `SET` with no optimistic-concurrency check (ADR 0012). Real lost-update risk if two admins
edit the same product/stock row concurrently.
- [ ] **No explicit `Cache-Control` anywhere** — `rg -n "Cache-Control" src` = 0 hits. Relies on implicit
non-caching rather than ADR 0012's mandatory explicit `private, no-store` default.
- [ ] **dLocal checkout replay doesn't validate payload match** — `Dlocal/service.ts:20-28` returns the
original order on a same-`orderId` replay without checking `items`/`payer` actually match the new
request (ADR 0009's Idempotency-Key convention: reject param-mismatched replays). Lower real risk since
this endpoint is `serviceAuth`-gated.
- [ ] **DB role split incomplete** — only `app_runtime` exists; no `app_owner`/`app_migrator` per ADR
0014's three-role pattern. `DATABASE_OWNER_URL` is used directly as a login-capable migration
connection. The load-bearing property (zero `app_runtime` membership in an owner role) is intact —
reads as deferred-to-infra provisioning, not a demonstrated privilege-escalation path.
- [ ] **Real dead-code bug, worth fixing even though currently inert**: `src/v1/middlewares/{context,cache}.ts`
are never imported by any route — confirmed via repo-wide import search. If ever wired in,
`context.ts:9`'s `req.originalUrl.split("/")[3]` resolves to the literal string `"admin"` or `"web"`
for every route under those mounts (not the actual resource name) — every admin resource type would
silently collide on the same Redis cache-key namespace. Fix before anyone actually wires this in.
## Frontend-side (`apps/web`)
- [ ] **`next.config.ts` has no security headers at all** — no CSP (`frame-ancestors 'none'`), no
`Permissions-Policy`, no `experimental.serverActions.allowedOrigins` (ADR 0022/0023). Cheap, concrete
fix — worth doing before any real client scaffolds from this template behind nginx-proxy-manager.
- [ ] **`(ecommerce)/layout.tsx:27` sets `export const dynamic = "force-dynamic"` on the whole route-group
layout**, not narrowed to the specific components that need live data (ADR 0024's "narrow the dynamic
surface" rule explicitly calls out layout-level opt-in as the anti-pattern to avoid in favor of
per-component ``).
- [ ] **`checkout/actions.ts:62-63` hand-rolls a Problem→message mapping** instead of reusing the
template's own `toActionState()` bridge (`src/lib/problem.ts`), which is used correctly everywhere else
(`src/modules/categories/actions.ts:59,70`, etc.).
## Meta-finding, not itself a fix item here
`frontend-standard-check`'s own Activation Contract globs only matched 31 of ~130 real frontend files in
this template (its logic mostly lives under `src/modules//`, and no file uses the `.client.tsx`
suffix the checker's globs assume). That's a `colidevs-standard`/hefesto-side coverage gap, not a defect
in this template — tracked separately, not part of this issue.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by reading the API module types.ts and repository.ts files, openapi/openapi.yaml, Dlocal/service.ts, and src/v1/middlewares/context.ts and cache.ts, then inspect next.config.ts, (ecommerce)/layout.tsx, and checkout/actions.ts. Treat the checklist as separate work items and confirm each audit finding is addressed, including the dead-code cache-key issue and frontend security configuration; rerun the relevant standard checks when available.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nextjs, openapi, redis, typescript
- Domain
- api, backend, databases, frontend, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100