colidevs / colidevs/create-coliapp

nextjs-shadcn-ecommerce-admin: hardening checklist from api/frontend-standard audit (pagination, ETag, headers, dead-code bug)

Open
#55 3 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.