Skip to content

All work

AI-visibility dashboard

An AI-visibility dashboard for Mulberry Marketing Communications

A client dashboard for an agency partner, where the database, not the page, decides who can see which client's audit results.

How it fits together

  1. Inputs

    • Audit runs

      Results from the scored audit engine arrive through an ingest script and an internal API that requires a secret header.

      • n8n
    • Agency staff and their clients

      People sign in with a magic link. There are no passwords to store or reset.

  2. Engine

    Client dashboard

    Scores, check results, and history for each client site, by role.

    • Next.js
    1. Row-level security as the boundary

      The app connects as a restricted role, and each request carries the user's id into its transaction, so policies scope every client table through membership.

      • PostgreSQL
    2. Viewer, editor, and admin

      Each person has one role, and only administrators can manage clients and who belongs to them.

    3. Refresh on request

      A user can ask for a fresh audit, limited to one per site per day and recorded before the call goes out.

  3. Outputs

    • Client-ready reporting

      Each client sees only its own sites and results.

    • Audit log

      Every tool run and approval is recorded, and the app's database role cannot delete history.

Guardrails

  • One client can never read another client's data
  • Internal endpoints reject calls without the shared secret
  • No stored passwords

The problem

Mulberry Marketing Communications, a B2B marketing agency, wanted to offer AI-visibility audits to its own clients. That needed a place where each client could see its results and nobody else's, with access managed in one place.

What I built

  • A Next.js dashboard with magic-link sign-in, database sessions, and viewer, editor, and admin roles.
  • A Postgres schema where row-level security, not application code, decides which rows a signed-in person can read or change.
  • An ingest path for audit runs and an internal API guarded by a secret header.
  • A rate-limited refresh request and an append-only record of every tool run and approval.

How I built it

I built it under a technical partnership with Mulberry. The dashboard runs on Next.js and PostgreSQL, and the scores come from the same scored audit engine described on this site. The tenant boundary lives in the database so that a bug in a page cannot leak one client's results to another.

What it shows

I put access rules where they cannot be skipped, and I build multi-client products that a partner can put in front of its own customers.