QDG Knowledge Base Read-only viewer QWebHub
bugs

Known Issues & Limitations

Version 3 · Restored the 'Not built: upcoming races' item that was accidentally dropped in the previous edit; still confirmed accurate (queries.py:1047 hard-codes upcoming_races to [])

Runner Form — Known Issues & Limitations

Open: hard-coded login credentials

Status: Open — dev-only, must fix before production. Symptoms: Login accepts a single hard-coded username/password checked directly in views.py, not Django's user system. Cause: Custom session auth was written for local development speed; @custom_login_required only checks request.session['is_authenticated']. Workaround: Acceptable for local/dev use only. Resolution: Replace with proper Django user accounts or OAuth before any production or shared deployment.

Open: DB credentials stored in plain text

Status: Open. Symptoms: MySQL connection details, including the database password, live directly in config/settings.py in plain text. Cause: No .env/environment-variable layer was set up. Workaround: None — treat the repository as sensitive. Resolution: Move DB credentials to environment variables before production.

Open: single-process cache

Status: Open — functional, but won't scale. Symptoms: Django's default in-memory cache is per-process; cached form/search/date data is not shared across multiple IIS/wFastCGI workers. Cause: No shared cache backend configured. Workaround: Fine for a single-worker deployment. Resolution: Switch CACHES['default'] to Redis for multi-worker deployment.

Open: documentation says qdg, code connects to qdb

Status: Open — documentation defect, not a code bug. Symptoms: CLAUDE.md and PLAN.md both name the database qdg. config/settings.py sets DATABASES['default']['NAME'] = 'qdb' — confirmed by reading the file directly. Cause: Unclear — possibly a rename that wasn't propagated to the docs, or the docs were written from an earlier/different environment. Resolution: Update CLAUDE.md/PLAN.md to say qdb, or confirm there's a second qdg database somewhere that these docs actually mean. Until resolved, trust settings.py. See [[database-schema]].

Open: Django 5.2.8 (docs/docx) vs Django 6.0.6 (CLAUDE.md)

Status: Open — unverified which is actually installed. Symptoms: Runner_Form_Project_Documentation.docx and PLAN.md record Django 5.2.8; CLAUDE.md records 6.0.6. Resolution: Check the active venv (python -m django --version) and correct whichever doc is wrong.

Note: two templates exist with no route (meeting_list.html, meeting_detail.html)

Status: Dead or in-progress code, not confirmed which. Symptoms: runner_form/templates/runner_form/meeting_list.html and meeting_detail.html exist, and queries.py has a matching get_meeting_details() function with its own cache key (runner_form:meeting_details:{date}), but no view or URL in urls.py renders them. Resolution: Confirm with whoever added them whether this is unfinished work-in-progress or safe to remove.

Note: FEATURES.md / Runner_Form_Features.docx are partly stale

Status: Documentation defect. Symptoms: Both describe the "Form Guide" page and horse age/description in the header as not-yet-built. Both are implemented today (/form/guide/, views.form_guide, and horse.description rendered in detailed-form.html). Resolution: Re-check remaining FEATURES.md items (extended career stats breakdown by distance/track/class) against the current templates before treating that file as an accurate backlog.

Limitation: trial data fields always null

Status: Data limitation, not a code bug. Symptoms: trial_race.class_level, sot, and time_winner_sec render as — on every row. Cause: These columns are NULL for all rows in the current DB. Resolution: Will resolve automatically once the source data is populated; no template/query change needed.

Limitation: pre-2021 sectional data (confirmed root cause)

Status: Data limitation, not a code bug — root cause confirmed by direct investigation. Symptoms: run.vp_1200/800/600/400/200 sectional-position columns are NULL for races before 2021; the UI shows dashes. Investigation: A full-table count against run (43,952,078 total rows) found that for the 2015–2020 date range (11,473,723 rows — all of WINX's 43-race career, runner_id 989258) every vp_* column returns exactly 0. The same query against 2020–2025 shows ~639,000+ rows with data per column, confirming the data-ingestion pipeline never back-filled sectional data before roughly 2021. Workaround: Code falls back to run.pos_1200, run.pos_800, run.pos_turn, run.pos_settling for older races, and correctly renders — when those are also NULL. Resolution: Requires the data provider to back-fill historical sectional data into qdb; no application code changes are needed once that happens.

Limitation: gear_change parsing is string-based

Status: Fragile by design, not currently broken. Symptoms: gear_change parsing in queries.py relies on human-readable strings (blinkers, winkers, tongue tie, etc.) mapped via GEAR_MAPPING. Risk: If the live schema starts storing coded values instead of these strings, GEAR_MAPPING needs updating. Verify with:

SELECT DISTINCT gear_change FROM run WHERE gear_change IS NOT NULL ORDER BY gear_change;

Not built: upcoming races

Status: Planned, not implemented. Symptoms: get_runner_form_data() hard-codes 'upcoming_races': [] (queries.py:1047) even though the DB has upcoming race data.

Updated by Claude on Aug. 12, 2026, 9:44 a.m. · Task: create project documentation (restore dropped item)