Internal Ops · Azure · Next.js 15

Enterprise Apps Masterview

One dashboard that replaced Azure Portal, Google Sheets, expense email chains, and the Toggl web UI.

Built by 3 Stripes Technologies for internal operations.

← All Work

3 Stripes Technologies

Internal Ops · Azure · Next.js 15

Built for internal use — managing apps, costs, time, and expenses from one place.

4
Production Apps
2
Azure Subscriptions
5
Team Members
Sub-200ms
Dashboard Load

The Problem

Four production apps across two Azure subscriptions. A five-person team. A finance workflow in Google Sheets. Expenses submitted by email. Time tracked in Toggl but only useful after an export-to-Excel session.

Every morning meant opening six tools that didn't talk to each other. The information existed — it was just distributed across Azure Portal, Google Sheets, Google Drive, Toggl, and two email threads. Assembling a clear daily picture took twenty minutes before the real work started.

No off-the-shelf tool fit. The products that exist were built for 500-person companies or solo freelancers. Nothing was designed for a five-person IT firm managing production enterprise apps for Caribbean clients with its own specific billing logic and team structure.

We built it.

The Architecture Decision That Defined Everything

The most important decision: everything syncs to CosmosDB first. The dashboard reads from Cosmos. Nothing calls the Azure APIs live on page load.

Azure APIs are slow, rate-limited, and — in the case of Cost Management — operate with a 24–48 hour data lag anyway. Calling them live would mean slow page loads and no guarantee the data was accurate.

Instead, nightly GitHub Actions workflows sync each data source to Cosmos. The Cost Management sync pulls MTD spend for both subscriptions. The Toggl sync pulls all time entries for the current month. The expense and app health data write to Cosmos in real time as events occur.

The result: dashboard loads consistently under 200ms, even when Azure Monitor is running slow.

Role-Based Access from Day One

Five roles: admin, finance, accountant, engineer, staff. Every API endpoint and every sidebar item gates on the same permission keys via a single can(role, permission) function in lib/rbac.js.

Roles are stored in CosmosDB, not in the JWT. At sign-in, the NextAuth JWT callback looks up the user's role from Cosmos and injects it into the token. When a role changes in the database, the next sign-in reflects it immediately — no token invalidation logic, no lag.

This means the finance person has never opened Azure Portal. She sees cost data, expense submissions, and billing summaries in the dashboard — nothing more, nothing less.

Dashboard Modules

Four problems. One platform.

📊

App Health Dashboard

Live status for four production apps across two Azure subscriptions. Engineers see deployment state, uptime indicators, and resource health at a glance — without opening the portal.

💰

Cost Visibility

MTD Azure spend broken down by product and resource group. Nightly sync from the Cost Management REST API to CosmosDB. Finance has live cost visibility without an Azure account. Dead-spend detector flags any resource under $1/month.

🕐

Time Tracking

Toggl entries synced nightly to CosmosDB. Role-scoped views: staff see their own hours, finance sees everyone. Stacked bar chart by project and a project donut. Monthly billing summaries in seconds, not Excel sessions.

🧾

Expense Workflow

Staff upload PDF receipts. Finance reviews, approves or rejects with a note, and marks paid — all in one view. No email chains, no WhatsApp messages, no separate tracking spreadsheet.

Tech Stack

What it's built on.

Next.js 15Azure CosmosDBAzure Blob StorageAzure Monitor APIAzure Cost Management APIToggl APINextAuth v5TanStack QueryRechartsTailwind + shadcn/uiGitHub ActionsAzure App Service

Roadmap

Three phases. One platform.

Phase 1
Live

Ops Dashboard

App health, cost visibility, time tracking, expense workflow. Five roles with full RBAC. DB-first architecture syncing from Azure Monitor, Cost Management, and Toggl.

Phase 2
In Progress

Accounting Module

General ledger, accounts receivable, accounts payable, bank reconciliation. Full double-entry accounting for a small IT firm — built to fit our actual workflow, not a generic chart of accounts.

Phase 3
Planned

Client Portal

Clients log in to see their Azure IT costs, download invoices, and pay via WiPay. No Azure account required. The goal: stop being a vendor and become an embedded IT department.

Managing Azure apps for your business?

If you're dealing with the same tool sprawl — multiple Azure subscriptions, time tracking, expense management — let's talk about what this could look like for you.

Get in Touch