All projects
O

Enterprise · Cloud · Full-Stack

Production

OpFix

A cloud-based Maintenance Management System — FastAPI, PostgreSQL and React with a multi-stage job workflow.

Role
Full-Stack Engineer — Final-Year Project
Timeline
Dissertation project
Year
2025
Status
Production
FastAPIPostgreSQLReactSQLAlchemyRender

01 — Overview

Overview

OpFix is a cloud-based Maintenance Management System: stores raise maintenance jobs, admins triage them, contractors and engineers carry out the work, and an accounts office handles invoicing — all tracked through one auditable workflow.

I built it as my BSc Computer Science final-year project and dissertation: a FastAPI backend over PostgreSQL with SQLAlchemy and Alembic, a React + Vite + Tailwind single-page app, JWT authentication with TOTP two-factor, a pytest suite, and a deployment on Render backed by Supabase Postgres.

02 — Problem

The problem

Maintenance work in a multi-site business passes through many hands — the store that reports a fault, the admin who approves it, the contractor and engineer who fix it, and the accounts team who get paid. Run that on phone calls and spreadsheets and jobs stall, accountability blurs, and there is no reliable record.

OpFix needed to make the correct path the only path: a single system where every job moves through defined stages, every role sees exactly what it should, and every significant action is logged.

03 — Requirements

Requirements

  • Role-based access for admins, engineers, clients/stores, contractors and accounts.
  • A defined, enforced job workflow from report through completion to payment.
  • Comments, file attachments and per-job history.
  • Role-specific dashboards, KPIs and exportable reports.
  • Secure authentication with JWT, hashed passwords and 2FA.
  • A complete, tamper-evident audit trail.

04 — Research

Research & planning

  • Compared RBAC approaches and chose a role + permission model resolved server-side on every request.
  • Designed the job lifecycle as an explicit state machine before writing endpoints, including the contractor and accounts stages.
  • Evaluated hosting and settled on Render for compute with Supabase-managed PostgreSQL.

05 — Solution

The solution

A FastAPI backend organises the domain into models, Pydantic schemas, routers and a services layer, with dependencies for the database session, the current user and role requirements.

Every maintenance job is driven by an explicit status enum — from NEW → ASSIGNED → IN_PROGRESS → ON_HOLD → COMPLETED/CANCELLED, extended with the full contractor-and-accounts flow (approval, sent-to-contractor, engineer-on-site, confirmed-by-store, sent-to-accounts, queried, paid) and post-completion states like reopened, recalled and reassigned.

Access is governed by roles and permissions checked in FastAPI dependencies, and new users go through an approval step before they can act. Sensitive changes write to an `audit_logs` table.

A React SPA consumes the API, holding the JWT in context and rendering role-specific dashboards, job boards, comments and exports.

06 — Architecture

System architecture

The backend is a FastAPI application factory with CORS and modular routers. Business logic lives in a services layer (auth, jobs, users, audit), data access goes through SQLAlchemy models, and requests are shaped by Pydantic schemas. Alembic manages migrations.

Authentication issues JWTs; a `require_role` dependency resolves the caller's role and permissions on every protected route, and a `get_current_user` dependency loads the account. TOTP provides two-factor auth, and real-time updates are pushed over WebSockets.

The frontend is a React + Vite + Tailwind SPA that keeps the JWT in an auth context and calls the API through typed axios wrappers. The whole system is deployed on Render with Supabase-managed PostgreSQL.

Loading diagram…
High-level system architecture

07 — Data

Database design

A user has a role and belongs to an organisational structure (company, store, contractor department, region) and can report to another user. Maintenance jobs carry a priority and a status, and accumulate assignments, comments, attachments and activity. Audit events reference the acting user and the affected job.

Roles and permissions are first-class tables, so access rules are data rather than scattered conditionals — and jobs, users and most entities support soft deletion for a recoverable history.

Loading diagram…
Entity-relationship model

08 — Features

Key features

Role-based access control

Admin, Engineer, Client/store, contractor and accounts roles, enforced server-side via FastAPI dependencies.

Multi-stage job workflow

An explicit state machine spanning report, approval, contractor, engineer, store confirmation and accounts.

Priorities & SLAs

Jobs carry LOW/MEDIUM/HIGH/CRITICAL priority with SLA configuration and tracking.

Comments & attachments

Per-job comments and file uploads (JPEG/PNG/PDF/DOCX, up to 5 MB), with internal engineer notes.

Dashboards & KPIs

Role-specific dashboards with totals, status breakdowns and per-engineer performance.

Audit logging

Every significant action is recorded in an append-only audit_logs table.

JWT auth + 2FA

Token-based auth with bcrypt hashing, TOTP two-factor, and a user-approval step before access.

Exports & reporting

Excel and PDF exports plus scheduled reports for management.

Real-time notifications

WebSocket-pushed updates so job changes surface immediately.

09 — Engineering

Implementation decisions

Explicit state machine

The job status enum encodes every valid stage — including the contractor and accounts flow and recall/reopen — so invalid transitions can't happen.

Permissions as data

Roles and permissions are database tables resolved in a require_role dependency, not conditionals sprinkled through routes.

Layered FastAPI structure

Models, Pydantic schemas, routers and a services layer keep business logic testable and separate from transport.

Migrations & tests

Alembic manages schema evolution and a pytest suite covers the core auth and job logic.

Managed cloud deploy

Deployed on Render with Supabase-managed PostgreSQL for a low-ops production setup.

10 — Challenges

Challenges & how I solved them

Modelling a multi-party workflow

The real process crosses stores, admins, contractors, engineers and accounts. Encoding it as one explicit status enum — with a query-and-resubmit loop for invoices — turned a tangle of edge cases into defined transitions.

Getting RBAC right

With several roles and an org hierarchy, I moved permission checks into FastAPI dependencies backed by role/permission tables, so authorisation is consistent and central.

Auditability without clutter

Writing audit events on the same path as the changes they describe kept the trail complete without scattering logging calls everywhere.

11 — Security

Security & correctness

  • JWT authentication with bcrypt-hashed passwords and TOTP two-factor.
  • A user-approval workflow so new accounts can't act until approved.
  • Server-side role and permission checks on every protected route.
  • Append-only audit logging of significant actions.
  • File uploads constrained by type and size (JPEG/PNG/PDF/DOCX, 5 MB).
  • Soft deletes to preserve a recoverable, tamper-evident history.

12 — Interface

Screenshots

OpFix regional manager reporting dashboard
Regional-manager reporting: jobs by priority, store breakdown and contractor completion rates.
OpFix store manager job detail with recall workflow
A store-manager job detail — converted from a quote, with purchase order and post-completion recall.
OpFix two-factor authentication settings
TOTP two-factor authentication in the security settings — one layer of the auth model.
OpFix accounts finance reports with CSV, Excel and PDF export
The accounts office finance reports, with CSV / Excel / PDF export.

13 — Outcome

Results

  • A complete, deployed Maintenance Management System delivered as a final-year dissertation project.
  • A rigorous RBAC model and an explicit multi-party job workflow that eliminates invalid states.
  • A production cloud deployment on Render + Supabase, backed by migrations and an automated test suite.
  • Open source on GitHub as a demonstrable, end-to-end full-stack build.

14 — Reflection

Lessons learned

01

An explicit state machine is the single highest-leverage decision in a workflow system.

02

Treating permissions as data keeps authorisation consistent as roles multiply.

03

A layered backend (models · schemas · services · routers) pays off the moment you start testing.

15 — What's next

Future improvements

  • A configurable workflow builder so admins can adjust stages without code.
  • Deeper analytics and SLA-breach alerting on top of the activity history.
  • Mobile-optimised engineer views for on-site updates.

16 — Toolchain

Technology stack

Backend

FastAPISQLAlchemyAlembicPydanticpython-jose (JWT)

Frontend

ReactViteTailwind CSSAxiosAuth context

Data

PostgreSQLSupabaseMigrationsSoft deletes

Security

JWT + bcryptTOTP / 2FARBACAudit logging

Quality

pytestExcel/PDF exportsWebSocket notifications

Platform

RenderCIGit / GitHub