Overview
What it is
Golden Bite is a premium treats, platters and event-catering business in Kubwa,
Abuja, built as three surfaces in one Next.js 16 App-Router app: a customer
storefront, an operations/admin dashboard, and a staff (kitchen + delivery) app.
It was refactored (a "Wave 3 carbon-clone") to mirror the Managerenta reference
patterns, and it is the origin of the "Golden Bite arch" that Adverta later
clones — a dedicated src/server/ layer with databases/ + runtime/, an
ioredis singleton, a structured Redis-key cache with explicit invalidation,
Prometheus metrics, extracted Zod validators, and withApiHandler on every route.
The per-operation service + IAM discipline
The name is literal: services are one file per operation plus a barrel. E.g.
services/orders/ holds createOrder, updateOrderStatus, checkOrderCapacity,
computeOrderTotals, ordersForKanban, attachDriver, setDeliveryProof,
todaysOrders, … re-exported per namespace (export * as orders from "./orders").
Below them, the models layer is likewise per-operation *DB functions, each
Prometheus-instrumented. IAM is a 5-role union
(customer | kitchen | delivery | manager | owner) with role groups defined once
(STAFF_ROLES, ADMIN_ROLES). Two enforcement styles coexist: a
withAuth(handler, ...roles) wrapper and inline sentinel-error checks inside
handlers — so the shape is one operation → one service call → one role gate →
one audit action:
export function withAuth(handler: TAuthedHandler, ...roles: TRole[]) {
return async (req: Request) => {
const session = await getSessionUser();
if (!session) return fail(401, "Not authenticated");
if (roles.length && !roles.includes(session.role)) return fail(403, "Forbidden");
return handler(req, session);
};
}
The edge proxy.ts (Next 16's renamed middleware) does only a cheap
cookie-presence redirect and is explicitly not a security boundary — the role
is re-checked in every handler. Each write is independently gated and audited:
export const POST = withApiHandler(
{ route: "/api/admin/menu/products" },
auditAdmin(postHandler, { action: "product.create", targetType: "product", captureBody: true }),
);
The cross-cutting spine
withApiHandler wraps every route with a fixed order of work — a Redis
fixed-window rate limit (default 100/min/IP, emitting X-RateLimit-* +
Retry-After), then the inner handler, then handleError to the canonical
envelope, then a Prometheus observation that always fires. Reads are
cache-first per operation: listProducts builds a namespaced key, returns a
presigned cache hit, or runs the DB work and sets a 5-minute TTL:
const key = getQueryKey({ categorySlug, query, featured, limit });
if (!refreshCache) {
const cached = await redisRetrieveKeyString<IProduct[]>(key);
if (cached) return presignAssetFieldsList(cached, ASSET_FIELDS, CACHE_TTL_SECONDS);
}
// … DB read …
await redisUpdateKeyString<IProduct[]>(key, result, true, CACHE_TTL_SECONDS);
The ioredis singleton runs a 5-second boot ping that throws loudly rather than
falling back to memory; Zod validators are .strict() per operation; SWR + a
withCredentials axios client (with a loop-guarded 401→login interceptor) drive
the client; two Prometheus histograms (http_request_duration_seconds,
database_request_duration_seconds) make every route and every DB call
independently observable; and parallel auditAdmin/auditUser streams fire in a
finally so they survive a throw.
Testing & security posture
Coverage is Playwright e2e only (auth, admin pages, admin-nav layering, order
lifecycle, session persistence), serial on a dedicated port 3007 with a
hermetic S3 fallback (the config blanks AWS creds). Honest flags carried into the
case study: there is no unit-test runner (no Vitest/Jest — automated coverage
is Playwright + ts.check only), and /api/metrics plus the dev
otp-peek/reset-token-peek routes are unauthenticated and should be
prod-disabled or protected at ingress. Auth is jose HS256 sessions
(httpOnly + sameSite=lax, secure gated by env), bcryptjs passwords, and
OTP/reset flows with TTLs; sentinel errors map to a {code,message,data} envelope
via handleError.