NEXORA β Known issues & technical debt
This file lists inconsistencies / risks that were identified but deliberately not fixed yet, to keep a trace and not lose them. High priority = to handle soon.
π΄ High β SQL built by interpolation
Several tools execute Postgres by building SQL through string concatenation (no ORM / no parameterized queries):
scripts/import_march.pyβpsql()/psql_query()(ensure_classes_subjects,ensure_students,ensure_sessions,ensure_parent_linksβ¦)processing/pipelines/reports.pyβ_write_to_db()(only escapes apostrophes of the content)ai/pipeline/db.pyβquery()/execute()/set_status()/get_reference_photos()
Today all values are internal constants (demo: S001..S031, CLASSESβ¦) or escaped, so no exploit path. But it is fragile:
- Table / column names are interpolated (no
%s). - Values go through single quotes (escaped for LLM content only).
Suggested fix: migrate these three modules to psycopg or postgres (the
driver already used on the web side) with real parameterized queries
(%s / $1), or expose a small shared SQL client.
π Medium β Other points to watch
-
Lake purge on every import.
import_march.run_pipeline()and the standalone mode deletebronze/silver/goldbefore re-running. Correct for the single-batch demo, but incompatible with incremental multi-lesson accumulation. Eventually: ingest without purge + hook the worker so new lessons are appended. -
processing/.venvcorrupted on this machine. It belongs torootwith a symlink to a nonexistent python βuv runinprocessing/fails locally (Permission denied). The code has a βcurrent interpreterβ fallback (ai/pipeline/runner.py::_run_polarsandscripts/import_march.py), so it works if the calling interpreter haspolars. Definitive fix:sudo rm -rf processing/.venvthenuv syncinprocessing/(the venv must exist foruv runin Docker). -
Two demo data paths.
scripts/import_march.py(importer) is the source of truth;web/scripts/seed_fake_data.tsis a shortcut that delegates to it.ai/pipeline/steps/classify.pykeeps a legacy PROFILES: the βrandomβ logic stays deliberately simplistic until a real behavior model exists. -
ORIGIN/BETTER_AUTH_SECREThardcoded indocker-compose.ymlβ dev values; inject them properly in prod (same as the.env). -
web/.envcontainsGITHUB_CLIENT_ID/SECRETnever used (no GitHub plugin inauth.ts) => dead variables to remove or wire up. -
Root
.env.examplevsweb/.env.examplediverge (two sources of truth).web/.env.exampleis the most complete. -
No versioned Drizzle migrations:
drizzle-kit pushis used (fine for dev, but no reproducible migrations for prod). -
Scoring tables duplicated in
ai/pipeline/steps/score.py(inline_InlineEnginefallback in case the canonical engineprocessing/pipelines/scoring.pyfails to import). The canonical engine must stay the reference; the fallback is only a safety net. -
Photos and storage paths:
photo.filenamestores the URL returned bystorage.put(with/). Verify LocalStorage vs S3 consistency for photoDELETE. -
merge_segmentsremoved fromimport_march.py(the old 2-min chunk splitting imposed a magic 123.147 s offset). The new format is direct multi-lesson, so it is no longer needed.