Introduce timetracker/config.py with a single config() helper that resolves
settings from a fixed priority chain: NAME__FILE (opt-in secret) -> env var
-> .env -> settings.ini -> in-code default. Supports type casting
(bool/list/int/Path), file-based secrets with .strip(), and required_in_prod
validation.
Migrate settings.py off the previous ad-hoc idioms:
- DEBUG via config() (PROD kept as deprecated alias)
- SECRET_KEY required in prod, supports SECRET_KEY__FILE
- APP_URL derives ALLOWED_HOSTS and CSRF_TRUSTED_ORIGINS (kept separate,
each independently overridable); ALLOWED_HOSTS is now configurable
- TZ and DATA_DIR via config()
Fix DATA_DIR inconsistency: entrypoint.sh now reads DATA_DIR (was hardcoded)
so the bash bootstrap and Django agree on the database directory.
Document the container/entrypoint-only flags (PUID/PGID/
CREATE_DEFAULT_SUPERUSER/STAGING/LOAD_SAMPLE_DATA) as bash concerns.
Update deployment configs to set APP_URL (and DEBUG), add docs/configuration.md,
settings.ini.example, regrouped .env.example, CLAUDE.md, and tests.
https://claude.ai/code/session_01FFn8BiGrQpEJarC8xGse8s
Bite-sized TDD plan for the design spec: TS toolchain scaffold, htpy-style
Element sugar, custom-element registry + codegen, then the three exemplar
conversions (GameStatusSelector, SessionDeviceSelector, played-row) retiring
their inline Alpine/@@TOKEN@@ f-strings, plus CI/Docker/docs wiring.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brainstormed design for replacing the trusted HTML/JS f-strings (Alpine
selectors, @@TOKEN@@ played-row) with three composing layers:
- htpy-style sugar on the existing Element (kwargs attrs + [] children),
additive, keeps Media/collect_media — no build step.
- Custom Elements (light DOM, TypeScript) for behavior, with the native
connectedCallback lifecycle replacing the onSwap shim.
- A typed contract: one Python Props type per component, codegen'd into a TS
interface + attribute reader, so server↔client drift fails `tsc`.
Toolchain: tsc per-module (no bundler, preserves per-component Media),
build-only/gitignored output, wired into make + Docker. Exemplars:
GameStatusSelector, SessionDeviceSelector, played-row. Alpine retired for
those three; existing .js migrated later.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>