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
Address issue #20 and the CI divergence between Gitea and GitHub.
Issue #20 (staging seeded from a prod snapshot):
- Read SECRET_KEY from the environment with the insecure dev key as
fallback, so each deployment can have its own key.
- Add a `scrub_staging` management command that clears django_session and
the django-q schedule/queue/results, removing copied prod sessions and
the inherited convert_prices() schedule.
- Run the scrub from entrypoint.sh when STAGING=true, and wire STAGING plus
a per-branch SECRET_KEY into the Gitea staging deploy.
CI parity (both systems kept, independent):
- Add the Node/pnpm/TypeScript build steps to the Gitea build workflow to
match the GitHub test job.
- Add a GitHub staging workflow that deploys per-branch ephemeral instances
to Fly.io (*.fly.dev) with a fresh database seeded from sample fixtures
and its own SECRET_KEY, never production data. Tears the app down on
branch delete and comments the URL on the open PR via github-script.
- Add fly.staging.toml and a LOAD_SAMPLE_DATA entrypoint hook for the
fresh-database public staging.
https://claude.ai/code/session_01KYjUcNjLfZ8Hq1GAC8J4oZ