Skip to content

Case study · hero · 2026-05 to present

Kintsu Portal

Built a full-stack internal operations platform for a medical spa from blank schema to 15 deployed pages in 72 hours: deterministic pricing engine, PHI-free architecture enforced in CI, multi-location RLS, and an AI layer bounded by tool contracts.

Role
Founder, sole engineer, product architect
Company
Kintsu Medspa
Dates
2026-05 to present
Bucket
current venture
The Kintsu Portal Today cockpit: a Needs your attention panel flagging two required documents to acknowledge, an AI Morning brief summarizing the day, KPI cards reading 69 active services, 66 percent average net margin, 43 services with custom prices, and 0 price mismatches, and a Pricing anomalies panel below
Kintsu Portal · Daily cockpitThe cockpit, not a config screen. The owner opens the portal and sees what needs action today: documents to acknowledge, margins, custom-priced services, price mismatches. The pricing engine runs backstage.

TL;DR

One-line outcome. Built a full-stack internal operations portal from blank schema to 15 deployed pages in 72 hours: deterministic pricing engine, PHI-free invariant enforced in CI, multi-location RLS, and an AI layer that never touches money math.

Role, dates, scope. Founder, sole engineer, and product architect for the internal operations platform of Kintsu Medical Aesthetics, a physician-led boutique medspa in Manassas Park, Virginia. All 33 database migrations, all 117 TypeScript source files, and all 15 pages authored by Mohsin. Work runs on the feat/foundation branch, built May 28-30, 2026, ahead of the practice grand opening.

Three metric chips.

  • 15 pages shipped in 72 hours across pricing, clinical, financial, compliance, and AI domains. [kintsu-portal-001]
  • 544 tests passing (unit, integration, e2e) at branch merge; 0 PHI detected across 158 columns scanned in CI. [kintsu-portal-002, kintsu-portal-003]
  • 69 services, 3 tiers, 8 provider roles handled by the deterministic engine; 43 curated overrides stored as immutable history. [kintsu-portal-004]

Context

A first-time medspa owner opening in May 2026 had her business model in spreadsheets: 69 services, 8 provider roles, 5 discount tiers, 15 membership tiers, 40 consumables. She had no operational cockpit. Nothing told her what to do today, whether she was making money, which services fell below cost, or when provider credentials expired. Available SaaS tools were built for large chains and surfaced configuration tabs rather than decisions. She needed a system that reduced anxiety, not one that added to it.

Mandate

Build the internal platform the practice would run on: a daily cockpit that surfaces actions, a deterministic pricing engine that enforces her economics, an AI layer she can ask plain-English questions, and a clinical compliance layer the Medical Director could sign off on. Keep it PHI-free by design. Make it ready for a second location before the first one opens.

Scope

Solo build. No team. Mohsin designed, engineered, and deployed every layer. The Medical Director (Dr. Nawal, MD) served as domain authority on clinical scope-of-practice decisions. All 33 database migrations, 117 TypeScript source files, and 15 pages on the feat/foundation branch over three sessions (May 28-30, 2026). The client is the primary daily user.

Key decisions

Cockpit over config. The natural instinct was to lead with the pricing engine: it was the most technically defensible artifact, and the owner had spent months asking about pricing. I chose a dashboard action queue instead. Below-cost services surface as warnings. Reconciliation drift is flagged for action. Expiring provider credentials escalate before they expire. Runway reads from the expense engine. The pricing engine moved backstage. The owner opens the portal and sees what to do, not what to configure.

The Services pricing grid with per-service retail, consumable, labor, and total cost columns plus partner and employee tier prices, several rows carrying custom override badges next to the calculated default price
Deterministic pricing engine · Services gridEvery service priced across tiers by the deterministic engine. Custom overrides layer on top and write to immutable history. This is the surface that got demoted to plumbing so the cockpit could lead.

PHI-free by design, enforced in CI. The Zenoti integration (the practice's appointment software) carries patient data. I built the integration as aggregate-only: daily revenue total, service counts, visit totals, utilization rates. Never appointment-level, never guest names, never invoice details. A pnpm check:phi gate runs after every migration and scans 158 columns against a deny-list. The invariant is in code, not policy.

AI tool contracts with a hard money-math boundary. The AI layer reads Postgres RPCs: query_services(), margin_ladder(), compute_scenario(), list_role_scope(). It never runs free-form SQL and never computes price or commission. Write actions follow propose-confirm-apply: the AI drafts the change, the owner confirms, the apply step re-routes through src/pricing/. The AI cannot bypass the deterministic engine.

Multi-location RLS from the start. The owner has one location now and plans a second within a year. I built location_id into the schema on day one: services and catalog are global per brand, expenses and inventory and compliance are per-location. The location_id lives in the JWT claim (set by a Postgres trigger on user creation), not in query strings. RLS policies enforce it at the database layer. The LocationSwitcher in the navbar is live. Adding branch two is a database row and a new user profile.

DEMO fallback as a first-class mode. Tests cannot burn real API calls; live responses are non-deterministic and expensive. DEMO mode returns canned responses labeled clearly as examples, not live inference. Tools still query real data (margins, service details) but mark their basis as demo. The owner sees the label and knows not to trust the inference. Tests pin to DEMO for determinism. The owner can switch to LIVE with one env variable.

What changed

OPERATIONAL SURFACES · 15 PAGES IN 72 HOURS

The breadth, page by page.

01 / 10
Insights
Memberships
Discounts
Providers
Expenses
Consumables
Compliance
Reconciliation
Audit digest
Login gate

Insights

Margins, breakeven, and runway read at a glance. Below-cost services surface by name.

  • From spreadsheets to a deterministic pricing engine: 69 services x 3 tiers x 8 provider roles, roughly 400 price points, 43 curated overrides stored as immutable history with timestamps and actor traces.
  • From no daily signal to a dashboard action queue: below-cost services flagged by name, reconciliation drift surfaced with a fix path, unsigned attestations escalated, expiring credentials listed, runway and breakeven readable at a glance.
  • From zero to 15 operational pages: services grid, service detail, bundles, memberships, discounts, consumables, expenses, providers, compliance, reconciliation, insights, AskKintsu, audit digest, settings, and the cockpit home.
  • From single-location to multi-location-ready: global catalog, per-location operations, location-scoped RLS, LocationSwitcher live in the navbar.
  • From "ask me" to "ask the system": AskKintsu with suggested prompt chips ("What is my breakeven?", "Which services lose money?", "Can an RN perform this?"), read-only Postgres RPC tools, and an audit digest that narrates the week's changes in plain English.

Measurable outcomes

  • 15 pages shipped in 72 hours, May 28-30, 2026. [kintsu-portal-001]
  • 544 tests passing (unit, integration, e2e) at branch merge on feat/foundation. [kintsu-portal-002]
  • 0 PHI detected across 158 columns scanned by CI after every migration. [kintsu-portal-003]
  • 69 services x 3 tiers x 8 provider roles in the deterministic engine; 43 curated overrides stored as immutable history. [kintsu-portal-004]
  • 33 database migrations (0001-0033) covering schema, RLS hardening, PHI gate, audit triggers, multi-location, and roles. [kintsu-portal-005]
  • 31 of 31 Playwright e2e boot-smoke tests passing. [kintsu-portal-006]

Leadership lens

I reframe what the system is before I start building it. The instinct was to lead with the pricing engine: technically strong, defensible, impressive. The better product decision was to demote it to plumbing and aim the surface at the owner's anxiety. The architecture follows the reframe. That pattern recurs in the work: name the user's actual problem before committing to the technical solution, then build the most powerful version of the right thing.

What I did with my hands

`src/pricing/` -- the deterministic pricing engine. CostInput accepts provider role and cost components; the engine returns a tiered ladder (standard, partner, employee, friend-and-family) plus a provenance trace showing which inputs drove each output. Overrides layer on top and write to service_price_overrides as immutable history. The engine is the only place in the codebase that computes price. Every other surface reads its output.

The HydraFacial Signature service detail: a cost breakdown of consumable and labor cost totaling 75 dollars, a net margin and discount ladder line, and a what-if pricing scenario with retail, consumable, and labor inputs producing calculated partner and employee tier prices
Pricing engine · Service detailOne service, fully traced. The cost breakdown, the tiered ladder with partner and employee prices calculated rather than typed, and a what-if scenario that re-prices every tier live. The provenance is the product.

`getAttentionItems()` in `src/lib/attention.ts` -- the aggregator that reads across five operational domains (services, reconciliation, compliance, consumables, credentials) and returns a ranked list of actions for the dashboard. This function is the product. The cockpit page renders from it. Everything the owner sees as "urgent" passes through this function first.

AI threading

The portal's AI layer runs on Vercel AI SDK over a Deno Edge Function deployed to Supabase. The live provider is FireworksAI (llama-v3p3-70b-instruct); the fallback is DEMO mode (canned responses, labeled, deterministic for tests). The provider swaps via AI_PROVIDER env var with no application-layer changes.

The Ask Kintsu chat surface with the question Which services are losing money right now, and a footer note stating every number is worked out by the price calculator and traceable, and that the assistant never makes prices up
AskKintsu · AI layerThe AI layer answers in plain English but never computes money. Every number traces back to the deterministic pricing engine. The assistant reads typed RPCs, it does not do the math.

Tool design was the deciding factor. I evaluated two approaches: let the AI generate SQL queries directly (flexible, faster to prototype) or bind it to read-only Postgres RPCs (constrained, safer). Chose RPCs. Each tool (query_services, margin_ladder, compute_scenario, list_role_scope) is a typed business-domain function, not a raw query. The AI never writes a WHERE clause. Money math stays in src/pricing/. The boundary holds even when the model is replaced.

The portal itself was built using Claude Code as the orchestrator with parallel subagents handling independent initiatives. Each initiative was scoped, committed separately with a decision log, and tested before the next one started. 33 migrations and 15 pages in 72 hours reflects the throughput of parallel agent teams against a planned initiative list. [kintsu-portal-007]

MOBILE · 390px

The cockpit on a phone.

  1. 01 / 03Today · mobile
    Today · mobile
    The action queue and KPI cards stack cleanly on a phone.
  2. 02 / 03Ask Kintsu · mobile
    Ask Kintsu · mobile
    Plain-English questions, traceable answers, on the go.
  3. 03 / 03Compliance · mobile
    Compliance · mobile
    Credentials and attestations readable at body size.

Reflection

The Zenoti actuals integration is stub-only at launch, pending API credentials from the practice. The runway and forecast engine runs on hand-fed assumptions. The cockpit is honest about projections but not about actuals. I would negotiate integration credentials earlier in the engagement, before writing the forecast layer, so the architecture reflects the real data boundary rather than treating live actuals as a future upgrade. The stub-to-live swap is one function call. The trust question (does the owner believe the numbers?) should have been resolved before the first day of design.