Skip to content
Dimitri Robiere PerrietD. R. PerrietCaen, FR — --:--:--EN · FR

Custom Next.js intranet for a web agency

Under contract · Mediapilote● Live
Client
Mediapilote
Role
Full-stack developer
Duration
ongoing
Year
2026
Stack
Next.js · React · TypeScript · Cloudflare Workers · Cloudflare D1 · Drizzle ORM · Auth.js · Vercel AI SDK
Custom Next.js intranet for a web agency — illustration
Fig. 01 — Custom Next.js intranet for a web agency, illustration
(00) — In short

A custom Next.js intranet for the Mediapilote agency: clients, projects, tickets and time tracking, now also the OIDC identity provider for its other tools.

(01)

Context

Before this custom intranet, Mediapilote tracked its projects, support tickets and time on an old platform that no longer matched how the agency worked. It needed a single tool for project managers, developers and support staff, without losing the history.

At the same time, the agency built other internal tools: SEO, GEO, Google Business Profile, advertising, backlinks, image generation. They all needed the same clients, the same accounts and the same Google access. The intranet became the foundation these platforms rely on.

(02)

Challenge

The first issue was the data migration. In the old database, “projects” were actually clients and tasks were projects, while support contracts had to become tickets rather than projects.

The second was architectural. Once the intranet became the identity provider and source of truth for several satellite apps, every change had to stay compatible with them. It also had to work within Cloudflare’s limits: D1 query size, maximum Workflow duration, Worker memory.

(03)

Approach

I built the app in Next.js with Server Actions validated by Zod and Drizzle ORM, then wrote an import script with a dry-run mode to bring over the old database. Four roles control access (admin, project manager, developer, support), and modules were added as needs arose: time tracking, quotes, newsletters and landing pages with collaborative editing, maintenance of a fleet of WordPress sites through an in-house plugin, AI assistants connected to the wiki.

For the other platforms, I turned the intranet into an OpenID Connect identity provider and exposed a partner API documented in a Scalar portal, with service credentials scoped to what each app needs. A Google token vault is shared between the tools, long AI scans are split into resumable passes to fit Workflow limits, and all AI calls go through AI Gateway to OpenRouter.

(04) — Results

Key figures
940
commits
4
access roles
OIDC
identity provider for internal tools
2026 →
in production
← Previous project36 · MyDigitalHorse, object-oriented programming in PHPNext project02Welva, an iOS nutrition and workout app in SwiftUI