> case study

Custom Client Portal

89%

on-time client approvals

34%

fewer support follow-ups

52%

faster status visibility

Problem: Client communication lived in scattered email threads, while internal status updates lived in separate tools. Teams and clients were looking at different versions of the same project.

Solution: Built a dedicated portal with milestone timelines, scoped approvals, document history, and role-based views for clients and internal teams.

Result: Clients got one source of truth and teams spent less time on status-chasing. Delivery meetings shifted from updates to decisions because the context was already visible.

Before vs After

Before

  • Approvals and change requests buried in email chains
  • No shared visibility into milestone progress
  • Manual reminders required to keep delivery moving

After

  • Structured approval flow with audit-ready history
  • Live project status visible to every stakeholder
  • Automated reminders and SLA-aware notifications

Technical Approach

Role-based access was the central design constraint — clients needed scoped views of only their own projects, while internal team members could see cross-client context. This was enforced at the data layer using row-level policies rather than application-layer guards, so authorization was consistent regardless of which query path was used.

Approval workflows were modeled as explicit state machines with an audit log attached to each transition. This made it easy to show clients a full change history and gave the internal team a defensible record for scope disputes.

Automated reminders were driven by SLA windows stored per milestone — the notification job ran on a schedule and compared current state against expected state, so no business logic lived inside the email templates.

Stack Used

Next.jsTypeScriptPostgreSQLPrismaResendVercel

Metrics are anonymized from a recent portal modernization engagement.