AZ
Back to constellation
CommercePublished

Golden Bite

A premium treats/catering business in Abuja delivered as three surfaces in one Next.js 16 app — storefront, ops dashboard, and staff app — and the origin of the "per-operation" arch.

Next.js 16TypeScriptMongoose 9ioredisZodSWR + axiosPrometheusPlaywright
Read the write-up

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.

Related write-ups