Software Engineering
Operational Ticket Intelligence
A support-operations platform for reconciling tickets, reviewing routing suggestions, and understanding workload.
- Setting
- Internal support operations · CU Boulder IBS
- Status
- Active development · read-only integration
Overview
The problem
Support staff need a consistent view of changing tickets, historical workload, and routing suggestions. Stale records or unreviewed predictions must not trigger external changes.
My contribution
At CU Boulder IBS, I build the FastAPI, PostgreSQL, and React workflows that connect source reconciliation, analytics, model evidence, and staff review. Training and evaluation remain separate from serving.
Interactive example · synthetic data
Follow a ticket through review
No tickets are fetched or updated; the suggested group is illustrative.
Step 1 of 4
Reconcile
Start with a consistent source record so the application can distinguish intake from later changes.
- Example record
- DEMO-104
- Request
- Set up a replacement laptop
- Source state
- Open · imported for review
Step 2 of 4
Suggest
A routing suggestion is evidence for the operator. It does not grant permission to update the source system.
- Illustrative destination
- Endpoint support
- Evidence type
- Model suggestion · not a verified label
- External update
- Not authorized
Step 3 of 4
Review
The operator can accept a suggestion. That review decision remains distinct from permission to send an external update.
- Operator decision
- Awaiting review
- Runtime policy
- Read-only
Example accepted for review. External delivery remains blocked by the read-only policy; no external update was sent.
Step 4 of 4
Apply controls
Even an accepted label must pass runtime and lifecycle controls before any external change is possible.
- Approval alone
- Insufficient for delivery
- Hosted policy described here
- Read-only · automatic delivery disabled · daily write cap 0
- Result in this example
- External update blocked
Measured and implemented
Results, with their scope.
- 10,803 tickets
- Local reconciled corpus on August 27, 2026; 96.7% carried support-group IDs.
- 82.63% accuracy
- Sealed-test result for an unreleased BERT candidate; macro-F1 0.7563. Not a production result.
- 61% smaller payload
- Raw analytics visualization payload after replacing Plotly; 66% smaller with gzip.
Architecture
How the parts work together
Select a step for the decision behind it.
Source reconciliation
Support-ticket changes enter one consistent intake and update path.
Design details for Source reconciliation
Polling remains the correctness path. Optional authenticated notifications fetch canonical source state before using the same upsert workflow.
Durable application state
PostgreSQL preserves lifecycle-aware state for analytics, review, and reconciliation.
Design details for Durable application state
Durable watermarks, overlapping recovery, per-record transaction boundaries, and failure-aware checkpoint advancement keep partial ingestion from looking complete.
Advisory ML boundary
Predictions appear as evidence for review rather than automatic decisions.
Design details for Advisory ML boundary
Prediction provenance is retained. A prediction alone cannot authorize an external update; accepted labels or explicitly approved rules create approval records.
Bounded delivery
External changes remain constrained by approval, lifecycle, and runtime controls.
Design details for Bounded delivery
Read-only and disabled modes, destination checks, caps, dry runs, retry and backoff, and a final lifecycle check bound the write path.
Operator surface
React views connect monitoring, labeling, and operational patterns for day-to-day decisions.
Design details for Operator surface
Lifecycle-aware analytics distinguish intake from reportable volume. Replacing Plotly with Recharts and accessible chart tables reduced the visualization payload from about 1.07 MB to 415 KB raw and from 361 KB to 123 KB gzip.
Model and data preparation
The validated data rebuild produced 10,399 canonical tickets, including 10,038 labeled tickets, plus 35,001 conversations and 1,525 attachment-metadata rows. Exact IDs, foreign keys, and migrations were verified after retaining historical-only records and reconciling newly exported IDs.
An unreleased BERT candidate trained on 6,137 tickets reached 82.63% accuracy and 0.7563 macro-F1 on a sealed test set. That was 3.11 accuracy points and 5.36 macro-F1 points above the prior XGBoost model, but the candidate remained an evaluation artifact rather than a production claim.
August 2026 data snapshot
On August 27, 2026, the local PostgreSQL database after read-only Freshdesk reconciliation contained 10,803 ticket records spanning October 4, 2022 through August 27, 2026. Of those records, 10,442—or 96.7%—carried a nonblank support-group ID. Those values spanned 14 observed IDs: 13 mapped to the current runtime group configuration, while one legacy unmapped ID appeared on three records.
Snapshot cohorts and training eligibility
After lifecycle exclusions, 10,649 records were reportable and 10,285 resolved through the current group mapping. The current training policy further narrowed the corpus to 6,487 records across seven eligible destination classes using lifecycle, provenance, text-quality, group-policy, and minimum-support gates.
During the preceding 30 days, 524 tickets were created and 610 records carried source update timestamps. The cohorts are not additive: all 524 newly created tickets fall inside the 610-record update cohort, alongside 86 older tickets. These figures establish a current, changing source corpus; they do not by themselves establish staff adoption of the application.
Reliability and control
- Source reconciliation uses durable progress markers and failure-aware advancement so a partial ingest is not reported as complete.
- Ticket lifecycle state distinguishes source intake from reportable operational volume, including records that were deleted, merged, or marked as spam.
- Production-target readiness fails closed when required database, migration, or model contracts do not pass.
- Predictions retain provenance. External changes require an accepted label or an explicitly approved automation rule; a prediction alone is not authorization.
- Human/source-assigned and automation-derived routing records retain distinct provenance. Unreviewed automation remains excluded from model training unless a complete human override is recorded.
- Delivery behavior supports read-only and disabled modes, dry runs, bounded retries, and a final lifecycle check before any approved update.
- The checked-in hosted policy keeps the integration read-only, disables automatic delivery, and sets the daily external-write cap to zero.
Operational evidence
A Recharts dashboard exposes busiest weekdays and peak hours as independent measures. Lifecycle-aware filtering keeps deleted, merged, and spam records from silently inflating reportable operational volume. Replacing Plotly reduced the analytics visualization payload by 61% raw and 66% gzip while adding accessible chart-table fallbacks.
Across the first 248 successful authenticated requests logged inside the running Compose app container on August 27, 2026, the stored analytics-snapshot endpoint measured 24.2 ms p50 and 45.8 ms p95 server-side latency. This was a warm local read of a persisted snapshot—not analytics recomputation, browser or network latency, concurrent load, or a production service-level objective.
These are dated local measurements, not claims of production latency, staff adoption, or staffing impact.
Technologies
FastAPI · PostgreSQL · React · TypeScript · SQLAlchemy · Recharts · scikit-learn · Docker
Get in touch
Discuss this project.
Questions about Operational Ticket Intelligence, the tradeoffs, or my contribution?