DATA DESK
A database investigation platform for QA engineers. Stop writing the same SQL every day. Search an ID, follow the data, prove the bug.
- Python
- Streamlit
- MySQL
- Gemini API
- Playwright
- PyTest
- Docker
- Caddy / Nginx
- ROLE
- Solo: product, build, tests, docs, deploy
- TIMELINE
- Sep 2026 → ongoing
- STATUS
- Open source, self-hosted
The problem
QA work means proving things about data, and proving things about data meant writing the same exploratory SQL over and over: finding which table holds a record, chasing foreign keys by hand, screenshotting results into Jira. Every investigation started from zero.
What I built
NO-SQL TABLE FINDER
Type a table name, a topic or a column and it finds the right table through aliases and schema search. The feature that started the whole thing.
START AN INVESTIGATION
Paste any identifier and it searches the whole database for it, then drafts an investigation plan.
RECORD EXPLORER
Linked tables, a relationship graph and a timeline for a single record, built by following the foreign keys.
API vs DATABASE VALIDATION
Compare an API response against the database and against expected values, with response rules. This is the part no SQL client does.
BUG EVIDENCE GENERATOR
Turns a finished investigation into a masked Jira or Markdown bug report from a template, with SQL, API and expected-vs-actual included.
CHECK LIBRARY + QA DASHBOARD
Reusable data-quality checks with severity, tags and owners; runs recorded over time with change detection, trends and TXT/CSV/XLSX exports.
SQL WORKBENCH
Named parameters, query library and history, an EXPLAIN analyzer and plain-English 'in short' summaries of what a query does.
AI ASSIST (GEMINI)
Table suggestions, natural-language-to-SQL, explain and fix. Only table and column NAMES are ever sent to the model, never a single row of data.
The part I'm proudest of
It physically cannot write to your database.
Read-only isn't a policy here, it's two independent layers: a statement guard that rejects anything that isn't a read, including comment-smuggled SQL, LOAD_FILE and locking reads, and a MySQL SET SESSION TRANSACTION READ ONLY backstop underneath it. If the guard were ever bypassed, the database itself refuses the write. I verified it at the engine level: error 1792.
Built like a product, not a script
Accounts with admin approval, a one-time setup code for the first admin, role-based masking of emails and phones, secret columns hidden by name, and login lockout after 5 failed attempts.
384 passing tests plus real-Chrome Playwright end-to-end suites: 20/20, 15/15 and 32/32 green.
Hardened for the open web: privacy policy and terms, cookie notice, XSRF on, CORS off, and Caddy/Nginx configs with HTTPS redirect, HSTS and security headers.
A real docs folder (user guide, configuration reference, architecture, security, scheduler and development notes) so someone else can actually run it.
Engineering decisions
GENERIC BY DESIGN
The core knows nothing about my employer's schema. Every company-specific check, chart and note lives in a git-ignored local/ folder, which is why it could be published at all.
CONNECTION POOLING
The same query went from 0.87s to 0.08s. Charts and heavy panels build only when you ask for them, because in Streamlit a collapsed panel still runs its code on every rerun.
SCHEDULED CHECKS WITHOUT A SERVER
A headless runner you point cron at, so data-quality checks keep running whether anyone has the app open or not.
The result
- automated tests
- 384
- tools in one app
- 8
- writes to your database
- 0
- faster queries after pooling
- 10x
Built for my own QA work, then made generic enough that anyone with a MySQL database can point it at theirs.
No public demo, because it connects to a database, so you self-host it. Setup is two commands, in SETUP.md.
INTERNAL PORTAL & REPORTING AUTOMATION
OPTI-RECOURSE