The central internal system for the Broward County Transit (BCT) uniform program. Orders from bulk-scanned documents, on-site operator entry and the existing customer portal merge into one validated queue, and data stays in sync with the portal, the extraction service, accounting and the company's file store.
Project media coming soon
Screenshots and demo videos for this case study will appear here.
BCT employees receive their uniform entitlement as vouchers, and orders arrive through several channels. Paper order forms and vouchers are scanned in bulk, operators take walk-in orders on site, and employees order through an OpenCart-based customer portal. BCT Order Management is the central system behind all of them. It checks every order against real employee, voucher and product data, runs it through a single processing queue, and carries it through accounting, fulfilment and the final handover at the transit garages.
Each channel produced data of different quality: OCR'd handwriting, operator input and portal checkouts. All of it still had to meet the same rules. Every order needed a confirmed employee, had to consume exactly one valid voucher and could never be duplicated. The customer portal also stays live alongside the new system, so the two must share employee and order data continuously without either becoming a single point of failure.
I built a React 19 and TypeScript operations UI on a FastAPI, SQLAlchemy and PostgreSQL API, with an arq worker on Redis for extraction and scheduled sync jobs. Each intake channel has its own staging area and review screen, but only one Order Acceptance Service can create a canonical order. The frontend client is generated from the API's OpenAPI schema, so a contract change breaks the build instead of production. I delivered the system in phases, writing a design spec before each feature.
Operators work from one queue regardless of where an order came from. Each order carries its source documents, a fixed record of its intake channel and a full audit trail. That trail runs from upload through dispatch batch, accounting delivery and partial or full handover to invoicing.
Dense, keyboard-friendly workspaces for upload triage, review, manual entry, the order queue, dispatch, fulfilment and returns, all calling a typed client generated from the API schema.
Domain services for vouchers, employee matching, order acceptance, dispatch batching, shipments, delivery runs, returns and stock, with role-based permissions and audit history.
Runs a document-extraction job for each page, plus cron jobs for portal employee sync and order import with resumable cursors.
Combined PDFs are split into single pages, and each page is classified as an order form, a voucher or unknown before being extracted into structured JSON.
A server-to-server API I added to the legacy store, with scoped and hashed credentials, an IP allowlist, keyset-paginated reads and an idempotent order-create endpoint.
Released dispatch batches are sent to the accounting integration with an idempotency key, and order documents are stored in the company's centralized file system.
Document extraction, manual entry and the portal inbox each keep their own drafts and review screens. Only the Order Acceptance Service creates canonical orders. In one transaction it consumes exactly one voucher, snapshots the employee, voucher and order values, and records the intake source, which can never change afterwards. Unreviewed data never reaches the order table, and validation cannot drift between channels.
An operator uploads one combined scan. The system splits it into one document per page, sends each page to the extraction service on its own, and pairs order forms with vouchers by the extracted voucher number rather than by filename. A failed or unrecognised page never blocks the rest of the batch. The raw extraction output is stored unchanged, operator corrections are stored separately, and the scan appears beside the editable values.
Instead of adding a checkout hook to the legacy store, the API polls the portal on a schedule with a keyset cursor on modification time and order ID. Imports are idempotent and only store-approved orders come through. Orders placed while this system was down are picked up on the next run. Orders this system created on the portal carry an external reference, so they are never imported back, and a retried push cannot create a duplicate.
Integration tokens are random 32-byte values stored only as SHA-256 hashes, with separate read and write scopes. The recurring sync job's token therefore cannot create orders. Tokens travel in the Authorization header rather than the query string, so they stay out of access logs. Responses use explicitly whitelisted columns and never SELECT *.
Orders can be prepared partly, by line and by quantity, and carried to a garage in a delivery run. Each shipment is then recorded as fully, partly or not handed over, with reasons for missing or swapped items. Anything not handed over returns to the same order's balance. An order counts as delivered only when every quantity has been handed over, and it can be invoiced only once it is delivered and its purchase order is recorded.