← Back to Work

Air Duct Cleaning Service

Confidential

2025

FastAPIReactExpoPostgreSQLCeleryRedisAWSTerraformGitHub Actions

Executive Summary

This system is a service management platform built for an air duct cleaning and insulation company. It provides a single platform for administrators, managers, and field employees to manage scheduling, vehicle fleets, resources, request workflows (tools, clothing, time-off), and financial transactions (expenses, spiffs). The system consists of a REST API backend, a web portal for administrators and managers, and a mobile app for field employees. Together they deliver self-service for employees, location-level oversight for managers, and organization-wide configuration and audit for administrators.


Problem Statement and Goals

Problem Statement

  • Fragmented visibility: Field operations lacked a centralized view of schedules, vehicle assignments, and resource availability.
  • Disconnected processes: Requests for tools, clothing, and time-off were handled through ad-hoc channels (email, spreadsheets, verbal requests), leading to delays and lost visibility.
  • Manual coordination: Managers spent significant time coordinating approvals, tracking expenses and spiffs, and communicating with dispersed field employees.
  • Audit gaps: Financial transactions and approvals lacked a consistent audit trail for compliance and reconciliation.

Goals

  • Reduced request turnaround: Request workflows move from submission to approval/completion with clear status visibility.
  • Single source of truth: Schedules, assignments, and resource data centralized and consistent across the organization.
  • Audit trail: All approvals and financial transactions logged for compliance and reconciliation.
  • Field employee adoption: Employees use the mobile app for day-to-day self-service instead of relying on managers or office staff.

System Architecture

Application Architecture

ApplicationPathTechnologyTarget Users
APIapps/apiFastAPI, Python 3.12, PostgreSQL, Redis, Celery, AWS S3Backend service
Web Portalapps/webReact, ViteAdministrators, Managers
Mobile Appapps/mobileExpo, React NativeField Employees

All clients consume the same REST API and use JWT authentication. WebSocket is used for real-time in-app notifications.

System Design

Deployment Architecture

ComponentTechnologyHostingDescription
APIFastAPI, UvicornAWS App RunnerREST API, WebSocket; HTTPS, auto-scaling
CeleryPythonAWS ECS FargateBackground workers (email, SMS, exports)
Web PortalReact, ViteAWS AmplifyAdmin and manager UI; CDN, SSL
Mobile AppExpo, React NativeApp Store, Google Play (EAS)Field employee self-service
DatabasePostgreSQLAWS RDSPrimary data store
Cache / brokerRedisElastiCacheCelery broker, cache
File storageAWS S3Uploads, exports, backups
SecretsAWS Secrets ManagerDB credentials, JWT, API keys

Network Architecture

Network Architecture

Supporting Components

ComponentPurpose
Lambda (restore-db)Restores PostgreSQL from a plain SQL dump in S3 into RDS (e.g. staging, prod)
TwilioSMS (OTP, notifications)
AWS SESTransactional email
Firebase Cloud MessagingPush notifications (Android)
APNsPush notifications (iOS)
SentryError tracking and performance

System Design

API Design

  • Base path: /api/v1
  • Authentication: JWT Bearer (Authorization: Bearer <token>). Login: POST /api/v1/auth/login.
  • WebSocket: WS /api/v1/ws/notifications/{user_id}?token=<jwt> for real-time notifications.

API modules:

PrefixModule
/authAuthentication
/usersUsers
/locationsLocations
/tenantsTenants
/audit-logsAudit logs
/vehiclesVehicles
/resourcesResources
/typesReference types (catalogs)
/toolsTools
/clothingClothing
/tool-requestsTool requests
/clothing-requestsClothing requests
/expensesExpenses
/spiffsSpiffs
/notificationsNotifications
/device-tokensDevice tokens (push)
/referralsReferrals (partner companies)
/emergency-contactsEmergency contacts
/repair-requestsRepair requests
/suggestionsSuggestions
/mediaMedia upload/download
/preferencesUser preferences
/scheduleVehicle schedules
/specializationsSpecializations
/time-off-requestsTime-off (PTO) requests

Pattern: REST resources with controller and service layers; Celery for asynchronous work (email, SMS, export generation).

Authentication and Authorization

  • Auth methods: Email/password and phone OTP (employees).
  • Tokens: JWT (access and refresh); validated on each request.
  • Authorization: Role-based access control (Admin, Manager, Employee). Data scoped by tenant and location; users are assigned to locations.

Data Flow (High Level)

  • Request/response: Web and Mobile send HTTPS requests to the API; the API reads and writes PostgreSQL. Redis is used as the Celery message broker and for cache.
  • Real-time: In-app notifications are delivered over WebSocket. Mobile push uses FCM (Android) and APNs (iOS); device tokens are registered via /device-tokens.
  • Files and exports: Uploads go to S3 via the API. Export generation and delivery (e.g. email) are handled by Celery tasks.

Key Backend Components

ComponentDescription
FastAPI appMain HTTP and WebSocket server; mounts all routers at /api/v1
Celery appSame codebase as API; entrypoint celery -A src.celery_app worker (ECS uses --pool=solo)
AlembicDatabase migrations in apps/api/alembic/versions/
EntitiesSQLAlchemy models (users, locations, vehicles, schedule, expenses, spiffs, tools, clothing, requests, notifications, etc.)

Domain and Feature Summary

AreaDescription
User and organization managementUsers, tenants, locations, roles (Admin, Manager, Employee)
SchedulingDaily scheduling, vehicle assignments, service management
Vehicle fleetVehicles, maintenance, repairs, odometer tracking
Request workflowsTool requests, clothing requests, PTO (time-off) requests
Financial trackingExpenses, spiffs, approval flows
Resources and suggestionsResource library, suggestions, referrals
NotificationsIn-app (WebSocket), push (mobile), email (SES), SMS (Twilio)

Out of scope: Payroll or accounting system integration; automated inventory management or procurement; native iOS/Android codebases (Expo managed workflow in scope).


Development and Operations

Monorepo and Local Development

  • Workspace: pnpm monorepo with Turbo. Apps: apps/api, apps/web, apps/mobile. Shared: packages/api-client, packages/shared-types.
  • API (local): Make targets from repo root: make db-up (Postgres, Redis), make migrate, make create-admin, make dev (API + Celery).

CI

GitHub Actions:

WorkflowScopeJobs
ci-apiAPI codeLint (ruff, black), test (pytest), optional migration checks
ci-webWeb, packagesTest (Vitest), lint
ci-mobileMobile, packagesTest (Jest), lint, typecheck
ci-e2e-webWeb, API, packagesE2E (Playwright), web integration tests

CD

  • deploy-staging: Triggered on push to main. Single pipeline: Terraform (staging) then deploy API (App Runner), Celery (ECS), web (Amplify), mobile (EAS).
  • deploy-production: Triggered on tag v* (e.g. v1.2.3). Same pipeline for production.
  • Secrets: Runtime secrets (Postgres URL, JWT, Twilio, Expo token, etc.) in AWS Secrets Manager; Terraform and workflows consume as needed.

Summary

This system is a production-grade, multi-tenant field-service platform: one backend (FastAPI + Celery), one web app for admins/managers, and one mobile app for employees, with shared types and API client, full request and financial workflows, and a clear path from local dev to staged and production deploys on AWS via Terraform and GitHub Actions.