Skip to content

Repository files navigation

OpsFlow

OpsFlow

AI-assisted field operations, with a human approval boundary.

Live Demo · 90-Second Walkthrough · View Source · Architecture · Engineering Case Study · Portfolio

CI status

130 tracked automated test/spec files · 18 PostgreSQL-backed integration suites · 8 Playwright scenarios across 6 workflow specs · CI exercises real PostgreSQL, Nginx, and Chromium

OpsFlow is a production-style, multi-tenant platform for field-service teams: customers, jobs, schedules, assignments, field evidence, and completion review in one operational workflow.

Its differentiator: AI prepares the plan; people approve the change. The in-app Web Agent and a local MCP server share one tenant-aware Tool Registry, and every AI-initiated business change stops at a structured proposal until an Owner or Manager reviews and confirms it. How the boundary works →

OpsFlow dashboard showing today's dispatch board, schedule summary cards, and crew status for the Acme Home Services workspace

The Owner dashboard: today's dispatch context, schedule movement, and the entry point into AI-assisted planning.

Recommended: choose Start a quick demo on the landing page. It opens a guided, prefilled workspace without registration.

Each Quick Demo launch creates an isolated workspace that expires after 60 minutes, allows up to 6 AI Planner requests, and is removed by bounded background cleanup. The shared role accounts below remain available for the multi-role walkthrough; use fictional sample data in every demo environment.

What this project demonstrates

  • An end-to-end product loop: intake, dispatch, field execution, completion review, audit, and notifications work as one system rather than disconnected CRUD screens.
  • Real SaaS boundaries: tenant context comes from authenticated membership, role checks are enforced server-side, and job transitions follow a domain state machine.
  • Human-approved AI actions: model-initiated writes become reviewable proposals instead of direct operational mutations.
  • Portable AI tooling: the Web Agent and local MCP adapter consume the same Zod contracts, role policies, and domain handlers.
  • Production-minded delivery: PostgreSQL migrations, database-backed integration tests, request IDs, structured logs, Docker, GitHub Actions, and an AWS deployment are part of the repository.

90-second walkthrough

  1. Open the demo; OpsFlow prepares an isolated workspace and opens the guided AI Planner flow.
  2. Open AI Planner and select the Golden Demo prompt for Aiden Murphy and Sofia Nguyen.
  3. Inspect the structured proposal. At this point, the requested customer or job change has not been applied.
  4. Review the resolved customer, job, assignee, schedule, blockers, and warnings, then select Confirm plan.
  5. Open the affected job to inspect its assignment, status, workflow history, and notifications.

For the full role-based loop, continue as Staff to progress an assigned job, upload evidence, and submit completion notes. Then return as Manager or Owner to approve the work or send it back for rework.

Role Email Password Best for
Owner owner@acme.example owner-password-123 AI planning, workspace controls, and the complete demo
Manager manager@acme.example manager-password-123 Dispatch, assignment, scheduling, and completion review
Staff staff@acme.example staff-password-123 Assigned work, evidence, and field workflow

The differentiator: safe AI writes

OpsFlow treats model output as an untrusted plan, not as permission to operate the business.

AI Planner proposal card: a Create Job approval for an air conditioner service, listing resolved target objects, a field-by-field diff of what will change, and a Confirm plan button — with no business data changed yet

The AI Planner stops at a structured proposal: resolved targets, a field-by-field diff, and candidate selection. Nothing changes until an Owner or Manager selects Confirm plan.

AI read tools see only role-appropriate, tenant-scoped data, and AI write tools go no further than persisting a proposal. Executing one is a separate authenticated step: the strongest path is the Web Confirm plan button, which does not depend on an LLM interpreting consent, and a limited set of job proposals can also be confirmed conversationally against a strict server-side allowlist. At confirmation time, OpsFlow claims the proposal with a single-execution guard, reloads current tenant-scoped targets, re-checks domain rules, and applies the change inside a database transaction.

flowchart LR
  Intent["Natural-language request"] --> Web["Web Agent"]
  Host["External MCP host"] --> Mcp["Local stdio MCP adapter"]
  Web --> Registry["Shared Tool Registry"]
  Mcp --> Registry
  Registry --> Reads["Tenant-aware read tools"]
  Registry --> Proposal["Persisted pending proposal"]
  Proposal --> WebReview["Web Confirm plan (no LLM)"]
  Proposal --> LaterConfirm["Later explicit confirmation"]
  LaterConfirm --> Execute["execute_proposal (eligible types)"]
  WebReview --> Recheck["Current targets + domain checks"]
  Execute --> Recheck
  Recheck --> Mutation["Transactional business change"]
Loading

The MCP adapter shares the same registry but exposes a deliberately narrower surface, and an external MCP host remains an explicit, documented trust boundary. The full confirmation semantics — eligible proposal types, the confirmation-phrase allowlist, post-proposal message matching, and host responsibilities — are specified in MCP design and security boundary.

Risk → Control → Evidence

Risk Control Repository evidence
A model applies an unintended business change AI write tools persist a pending proposal; execution is a separate non-LLM Web action or an allowlisted, post-proposal conversational confirmation Proposal tools, confirmation boundary
A caller invokes a hidden or role-restricted tool directly Audience and role policies are checked during discovery and checked again during Registry execution; inputs and outputs are validated with Zod Tool Registry
A proposal points to stale or invalid operational data Confirmation reloads key tenant-scoped targets and enforces active-staff, target-safety, and workflow rules before commit Proposal confirmation
Two requests try to confirm the same proposal A conditional PENDING → CONFIRMING transition allows only one confirmation path to proceed Confirmation guard
An external host misrepresents user consent The server rejects non-allowlisted confirmation text; provenance stays a documented host responsibility, with Web confirmation as the stronger fallback MCP trust boundary
Web and MCP behavior drift apart Both adapters use the same canonical tool schemas, access policies, and execution handlers MCP architecture
Invocation audit duplicates raw customer or job values The dedicated ToolInvocation record stores source, status, duration, correlation IDs, and top-level field names rather than raw argument or result values Invocation audit

The PII-minimized statement applies to ToolInvocation metadata; conversations, proposals, and tool traces are persisted so the workflow stays recoverable and reviewable.

One operational loop, three roles

Customer intake → Job creation → Assignment and scheduling
→ Field evidence → Completion review → Audit and notifications
  • Owners manage the workspace, team access, and operational controls.
  • Managers coordinate customers, jobs, schedules, assignments, and completion review.
  • Staff see assigned work, progress jobs, upload evidence, and submit completion notes.

Jobs list with search, status and customer filters, pagination, and tenant-scoped job rows The same dashboard rendered on a phone viewport

The same tenant-scoped workflows on desktop and a phone viewport; mobile layouts are covered by an axe accessibility smoke test in CI.

The product also includes tenant invitations, customer archiving, schedule conflict checks, authenticated notification streaming, activity history, and request IDs that connect frontend errors to structured backend logs.

Engineering evidence

Boundary Implementation
Tenant isolation Web and MCP calls revalidate current membership and tenant state; business queries and relationships remain tenant-scoped
Authorization Server routes, domain services, and AI tools enforce role-aware access for Owner, Manager, and Staff
Workflow integrity Job status transitions are constrained, recorded in history, and surfaced in the UI
Client server state TanStack Query caches are scoped by tenant, user, and role; mutations reconcile entity caches and invalidate affected workflows
Persisted AI workflow Conversations, tool traces, proposals, review state, and confirmation evidence are stored in PostgreSQL
Operational debugging API responses carry X-Request-Id; error responses and client error surfaces preserve it; backend request and error logs are structured
Delivery CI validates client and server builds, the real Nginx ingress boundary, PostgreSQL-backed integration tests, deterministic Chromium workflows, and a mobile axe smoke check

The public application is deployed to AWS with EC2, RDS, Docker Compose, Nginx, and HTTPS. The codebase stays a modular monolith so domain boundaries are explicit without introducing distributed-system complexity that the current product does not need.

AI evaluation

OpsFlow evaluates the AI workflow as a product boundary, not only as a collection of model calls. The current suite contains 13 regression scenarios covering Proposal routing, customer/job/staff resolution, schema guards, schedule conflicts, duplicate prevention, explicit confirmation, rejection, ambiguity, and revision requests.

Two modes keep deterministic regression checks separate from provider variability:

Mode Purpose CI policy
cheap Runs deterministic resolvers, Proposal persistence/execution, and safety policies against PostgreSQL without calling a model Required in the PostgreSQL CI job; a failure blocks the change
llm Exercises the same high-value scenarios through the configured Anthropic model Manual only; useful for model/provider validation but deliberately not a PR gate

Each run produces machine-readable JSON and a Markdown summary under server/test-results/ai-evals/. The report includes scenario and assertion pass rates, per-category regression rates, risk labels, failures, and duration. CI publishes the Markdown to the GitHub Actions job summary and retains both files as a commit-specific artifact for 30 days; generated reports remain ignored locally rather than being committed as changing snapshots.

Run the deterministic suite against a local or disposable PostgreSQL database:

pnpm --dir server ai:eval:cheap

Run the provider-backed suite explicitly:

RUN_LLM_EVALS=true ANTHROPIC_API_KEY=... pnpm --dir server ai:eval:llm

The report describes regression pass rates over defined scenarios, not a general claim of “AI accuracy.” See the Eval cases, report generator, and testing strategy.

Five-minute code tour

  • Tenant membership revalidation — Web and MCP calls re-establish current tenant, membership, and role context before protected work.
  • Job state machine — operational status changes are constrained by domain rules.
  • Canonical Tool Registry — Web and MCP tools share schemas, audience rules, role rules, execution, and invocation audit hooks.
  • Proposal confirmation — approved plans re-check key targets and execute through transactional domain services.
  • Authorization-scoped Query keys — REST caches include tenant, user, and role context before domain and request parameters.
  • Database-backed CI — migrations and integration tests run against a real PostgreSQL service.
  • Role workflow E2E — Owner dispatch, Staff evidence and completion submission, and Manager approval run as one browser scenario.
  • Safe AI E2E — proposal-first writes, explicit approval, conversational confirmation safeguards, and idempotent replay are verified without a live LLM.
  • API security integration — cross-tenant ID probes, stale authorization, Request ID correlation, and Proposal idempotency run through the HTTP stack.
  • Database tenant integrity — composite foreign keys reject cross-tenant child records at the PostgreSQL boundary.
  • Mobile accessibility smoke — the landing page, sign-in, and authenticated Dashboard are checked at a phone viewport with axe.
  • Nginx ingress smoke — the deployable proxy is exercised for forwarded IP normalization, spoof-resistant rate-limit keys, 10 MiB multipart uploads, finite body limits, host routing, and unbuffered SSE.
  • Testing strategy — explains the test layers, CI jobs, deterministic fixtures, database guardrails, and deliberate limits.
  • OpenAPI contract — the implemented HTTP surface is documented as a machine-readable contract.

Tech stack

  • Frontend: Next.js 16, React 19, TypeScript, Tailwind CSS, TanStack Query, Zustand, React Hook Form, Zod
  • Backend: Express 5, TypeScript, Prisma, PostgreSQL
  • AI: Anthropic SDK, Model Context Protocol TypeScript SDK, shared Zod Tool Registry, SSE streaming
  • Testing: Vitest, Testing Library, Supertest, Playwright, PostgreSQL integration tests
  • Infrastructure: Docker Compose, GitHub Actions, AWS EC2, Amazon RDS, Nginx, Certbot

Run locally

cp .env.example .env
docker compose -f docker-compose.dev.yml up --build -d

The containers apply database migrations automatically. To create the local demo accounts and seeded workspace, run:

docker compose -f docker-compose.dev.yml exec server pnpm db:reset

db:reset is destructive. Use it only against the local Docker development database.

Open:

Stop the stack:

docker compose -f docker-compose.dev.yml down

Validate the project

node scripts/verify-docs.mjs

pnpm --dir client lint
pnpm --dir client typecheck
pnpm --dir client test
pnpm --dir client build

pnpm --dir server typecheck
pnpm --dir server test
pnpm --dir server build
pnpm --dir server ai:eval:cheap

infra/nginx/smoke/run.sh

In addition to the documentation contract and fast client/server jobs, four heavier validation layers run in CI: database integration tests against disposable PostgreSQL (cross-tenant attack probes, Quick Demo isolation, constraint checks, MCP authorization revocation, and concurrency/idempotency coverage — see the test notes for local flags); deterministic AI evals in the same PostgreSQL job; Playwright coverage of the Owner → Staff → Manager loop and guarded AI proposal flow with a network-free Fake AI provider (see testing strategy and E2E notes); and an isolated Nginx smoke through the production proxy template.

Current scope

OpsFlow is production-shaped rather than presented as production-complete.

  • MCP currently uses local stdio; remote transport, public client registration, and OAuth are deferred.
  • Evidence storage is local-disk behind an abstraction; an S3-compatible implementation is a planned upgrade.
  • Advanced route optimization, third-party integrations, payments, and a customer portal are outside the current case-study scope.
  • Quick demo workspaces are short-lived and isolated, while the optional role accounts remain shared; neither is a place for real customer or operational data.

Deeper documentation

About and contribution

OpsFlow is an independently owned portfolio engineering case study by Wenduo Wang. I defined the product and architecture, implemented and reviewed the system, set its security boundaries, and own verification and final acceptance. AI tools assisted design exploration, implementation, and review; the Engineering Case Study explains that workflow and the decisions that remained mine.

Released under the MIT License.

GitHub profile · Project source · Portfolio

About

A multi-tenant service operations platform built with a modern full-stack architecture.

Resources

Stars

Watchers

Forks

Contributors

Languages