All Work

BT-ADV Agency Website

A full-stack agency platform with a secure booking wizard, bilingual RTL/LTR UI, and cinema-themed confirmation tickets.

RoleFull-Stack Developer — Architecture, UI/UX, Security, Deployment
Year2026
Duration2.5 Months
TeamSolo
Status✓ Completed
BT-ADV — Homepage with cinema-themed hero banner

At a Glance

12Managed DB Tables
5Security Layers on Booking Endpoint
2Rate Limit Layers in Parallel
3Sentry-Instrumented Runtimes (client, server, edge)

The Problem

BT-ADV is a premium video production and advertising studio. Before this platform, the agency had no structured digital presence — inquiries came through WhatsApp with no way to filter lead quality, capture project context, or confirm meetings with a paper trail. Brand managers commissioning high-budget advertising (EGP 300K–1M+) had no self-service intake flow. There was no central admin view of booking status and no bilingual support for the agency's Arabic-speaking market.

The Solution

A full-stack agency website with a production-quality multi-step booking wizard, cinema-themed confirmation ticket, complete admin CMS, bilingual RTL/LTR, and a hardened security layer. The 4-step wizard pre-qualifies every lead before submission: contact info → company profile → project goals → meeting preferences and budget. Lead qualification is baked into the UX — each step acts as a filter. The dark Navy + Yellow cinema aesthetic communicates premium positioning.

Architecture

Key Features

Screenshots

Code Highlight

Constant-Time CSRF Token Verification to Prevent Timing Attacks
// src/lib/csrf.ts
/**
 * Primitive constant-time string comparison.
 * A naive `tokenA === tokenB` leaks timing information —
 * comparison short-circuits at the first mismatch, letting an
 * attacker measure response latency to brute-force the token.
 *
 * This always iterates every character regardless of where the
 * mismatch occurs, making response time independent of token value.
 */
function timingSafeEqual(a: string, b: string): boolean {
  if (a.length !== b.length) return false;
  let mismatch = 0;
  for (let i = 0; i < a.length; i++) {
    mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);
  }
  return mismatch === 0;
}

export function verifyCsrfToken(req: Request): boolean {
  const cookieHeader = req.headers.get('cookie') ?? '';
  const tokenFromCookie = cookieHeader
    .split(';')
    .map((c) => c.trim())
    .find((c) => c.startsWith(`${CSRF_COOKIE}=`))
    ?.split('=')[1];

  const tokenFromHeader = req.headers.get(CSRF_HEADER);
  if (!tokenFromCookie || !tokenFromHeader) return false;
  return timingSafeEqual(tokenFromCookie, tokenFromHeader);
}

Challenges & Solutions

🎯 Supabase cookie replacement silently discarding the CSRF token on session refresh

The CSRF token is generated before Supabase runs and stored in a local variable (`pendingCsrfToken`). After `supabase.auth.getUser()` resolves (potentially replacing the `response` object), the token is re-applied to whatever the final response is — requiring a deep understanding of Next.js middleware execution order and Supabase's internal cookie mutation pattern.

🎯 Slot double-booking race condition under concurrent load (TOCTOU vulnerability)

The pre-check provides a fast UX error. The real guarantee comes from a PostgreSQL UNIQUE constraint on `(date, time_slot)`. The API catches error code `23505` (unique violation) and returns a typed `SLOT_TAKEN` response — turning a raw DB error into a user-friendly message without exposing internals.

🎯 Admin role check adding DB latency on every Edge middleware request

Implemented a custom Supabase Postgres "Access Token Hook" that embeds the user's role into the JWT's `app_metadata` at issuance time. The Edge middleware reads the role directly from the decoded JWT — zero DB round-trip. A DB fallback is retained for old tokens, making the migration backwards-compatible.

Tech Stack

Next.js 16TypeScript 5Supabase (PostgreSQL + RLS)Tailwind CSS v4Framer Motion 12Zustand 5TanStack Query v5React Hook Form + Zod 4Upstash Redis (rate limiting)Resend (transactional email)CloudinarySentry

What I Learned

Links

Interested in a similar solution?

Let's discuss how I can build something like this for your business.