Skip to content

sonnymay/supportops

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

38 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SupportOps

CI Python FastAPI License: MIT Live Demo

A lightweight ticketing and RMA workflow tool built by a tech support engineer, for tech support engineers.

πŸ”— Live demo: supportops.vercel.app πŸ“Έ Screenshots: see below


Table of contents

Roadmap

⏱️ First load can take up to a minute. The demo backend runs on Render's free tier, which sleeps after 15 min of inactivity. The frontend fires a warm-up ping on app load and shows an informative loading state while the server wakes β€” so just give it a moment on the first visit. Subsequent requests are <1s.


Why this exists

After 9 years on the front lines of technical support, I kept hitting the same walls with the tools I was given:

  • Tickets, customers, and devices lived in three different systems that didn't talk to each other.
  • RMA tracking was a spreadsheet someone forgot to update.
  • Status changes had no audit trail when a customer asked "who closed my ticket and why?"
  • The "enterprise" platforms were slow, bloated, and built for managers β€” not the agent actually working the queue.

SupportOps is the tool I wished I had. Tickets, devices, customers, RMAs, and a full status history β€” in one place, fast, and built around how support actually works.


What this code shows

If you're reviewing this as a portfolio piece, the interesting bits are:

  • FastAPI + Pydantic as a thin validation/business-rules layer over Supabase's PostgREST API β€” no ORM, no schema duplication.
  • Automatic audit logging β€” every ticket status change appends a row to ticket_history from the API layer, not the client.
  • AI Resolution Suggester β€” Anthropic Claude (Haiku) reads a ticket plus its full notes history and proposes next steps. Wired in backend/ai.py.
  • Resilient frontend β€” frontend/src/api.js wraps fetch with AbortController timeouts, status checks, and a useApiResource hook that gives every page the same loading / error / retry UX.
  • Cold-start UX β€” the frontend warms the backend on mount and explains the wait, so a sleeping free-tier dyno never silently looks like a broken app.

Features

  • 🎫 Tickets with status, priority, assignee, and linked customer + device
  • πŸ‘₯ Customers directory (name, email, phone, company)
  • πŸ’» Devices tied to customers by serial number and product type
  • πŸ“ Ticket notes for agent-side context and handoffs
  • πŸ•“ Automatic status history β€” every status change is logged with who and when
  • πŸ“¦ RMA tracking β€” RMA number, serial, shipping status, resolution status, linked to the originating ticket
  • πŸ€– AI Suggestions β€” Claude-powered next-step recommendations per ticket

Stack

Layer Tech
Frontend React 19, Vite, Tailwind CSS v4, React Router
Backend FastAPI (Python 3.11+), Pydantic
Database Supabase (Postgres + PostgREST)
AI Anthropic Claude Haiku 4.5
Hosting Vercel (frontend) Β· Render (backend)

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  React + Vite β”‚ ───▢ β”‚   FastAPI    β”‚ ───▢ β”‚   Supabase   β”‚
β”‚   (Vercel)    β”‚      β”‚   (Render)   β”‚      β”‚ (PostgREST)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                       β”‚  Anthropic   β”‚
                       β”‚    Claude    β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The FastAPI layer is intentionally thin β€” it validates with Pydantic, applies business rules (e.g. writing to ticket_history on every status change), proxies CRUD to Supabase's REST API, and brokers calls to Claude for the AI Suggester.


Local development

docker compose up --build

Docker starts the API at http://localhost:8000. Create backend/.env from backend/.env.example before first run.

Prerequisites

  • Python 3.11+
  • Node.js 20+
  • A Supabase project (free tier is fine) β€” grab your SUPABASE_URL and SUPABASE_KEY
  • (Optional) An Anthropic API key if you want the AI Suggester to work locally

Backend

cd backend
python -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
pre-commit install
cp .env.example .env   # then fill in SUPABASE_URL, SUPABASE_KEY, ANTHROPIC_API_KEY
uvicorn main:app --reload

API runs at http://localhost:8000. Health check: GET /health. Interactive docs: /docs.

Frontend

cd frontend
cp .env.example .env   # set VITE_API_BASE_URL=http://localhost:8000
npm install
npm run dev

App runs at http://localhost:5173.


Deployment

  • Frontend β€” Vercel, SPA rewrites in frontend/vercel.json. Env: VITE_API_BASE_URL.
  • Backend β€” Render web service from render.yaml at repo root. Python 3.11.9. Env: SUPABASE_URL, SUPABASE_KEY, ANTHROPIC_API_KEY, ANTHROPIC_MODEL. Health check: /health.

Free-tier dynos sleep after 15 min of inactivity. The frontend warms the backend on app load β€” see frontend/src/api.js (warmupBackend).


API surface

Resource Endpoints
Health GET /health
Dashboard GET /dashboard
Customers GET/POST/PUT/DELETE /customers
Devices GET/POST/PUT /devices
Tickets GET/POST/PUT /tickets, GET /tickets/{id}
Ticket Notes GET /tickets/{id}/notes, POST /notes
Ticket Hist. GET /tickets/{id}/history (auto-appended)
RMAs GET/POST/PUT /rmas
AI POST /tickets/{id}/ai-suggestions

Status changes on tickets automatically append a row to ticket_history.

Full OpenAPI spec available at http://localhost:8000/docs when the backend is running.


Screenshots

Dashboard Ticket Detail AI Suggestions


Roadmap

  • Full-text search across tickets and notes
  • SLA timers with breach alerts
  • Saved views / filters per agent
  • CSV export of tickets and RMAs
  • Role-based permissions (agent / lead / admin)

Contributing

Issues and PRs are welcome β€” especially from anyone who's worked a support queue and has opinions on what's missing. Please open an issue describing the change before sending a large PR.


License

MIT Β© Sonny May

About

Internal support ops portal built with FastAPI, React, and Supabase.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors