A small tool for better decisions
Data, ready for
the next step.
Validate a CSV. Isolate exceptions. Explore the operational picture.
One transparent workflow, from source rows to useful signals.
01 / Protect the input
A clear result for every row.
Start with the fictional sample, or check a CSV of your own. Only accepted rows enter the operations view.
Check a dataset
Choose a UTF-8 CSV. It stays on this device and is cleared when you leave or reload.
Up to 1 MB · 2,000 data rows · 40 columns
View the expected schema
Use these nine headers. Dates are YYYY-MM-DD; effort is a non-negative whole number of minutes.
id, title, status, priority, channel, opened_at, due_at, resolved_at, effort_minutes- Status
- Open, In progress, Resolved
- Priority
- Low, Medium, High, Urgent
- Channel
- Email, Portal, Phone, Chat
Resolved tickets require a resolution date; other tickets leave it blank. The snapshot date is 26 October 2026. Future opened or resolved dates are rejected.
Loading fictional sample
Original, deterministic fictional data.
Exports quote every cell and prefix formula-like text for spreadsheet safety. CSV remains data; review it before importing elsewhere.
Exception review
Every held record includes its source line and reason.
No exceptions found
Every source record passed the rules for this schema and snapshot.
| Source | Record ID | Title / context | Reason for review |
|---|
What this check does — and its limits
The parser handles quoted commas, escaped quotes, multiline fields, UTF-8 BOM and CRLF/LF line endings. Headers are trimmed and case-normalised. Unexpected extra columns are disclosed and excluded from accepted exports.
All instances of a duplicate ID are held; no record is silently chosen as correct. Blank lines are ignored and counted. A failed file does not replace the previous successful run. This is a schema check, not proof of business accuracy or an immutable audit trail.
02 / Understand the queue
Turn a clean dataset into a decision.
Filter accepted tickets, inspect the backlog and follow a signal to the underlying records.
No tickets in this view
Try a wider date range, a different channel or a shorter search.
Unresolved tickets
Backlog ageing
Age = snapshot date − opened date. Select a bar to inspect that group.
All matching tickets
Status mix
Counts describe this fictional dataset. They are not personal performance results.
Ticket register
Select any row to inspect the record.
| Ticket / title | Status | Priority | Channel | Opened | Due | Age |
|---|
Metric definitions & reporting boundaries
Filters use the ticket’s opened date, including both endpoints. Backlog means Open or In progress. Overdue means unresolved with a due date before 26 October 2026; a ticket due on the snapshot date is not overdue. Ageing includes unresolved tickets only.
Summary cards and charts share the main filters. Selecting a card, status or age group narrows the register and its export; the summary remains a view of the base filters. Effort is input data, not elapsed time or a measured saving. No SLA, productivity or personal-impact claim is made.
Why I built this
Useful automation needs
visible checks.
This original demonstration connects two parts of business systems work: making inputs dependable, then making the result understandable.
It uses a bounded schema, explicit exception handling, reconciliation and traceable calculations. The demo is built with HTML, CSS and vanilla JavaScript; its data and outcomes are fictional.
Back to selected work