The Go server now runs sync -> infer -> flush-cache by itself at the times in SYNC_SCHEDULE (comma-separated HH:MM, default 04:00, "off" disables), read in SYNC_TZ (default Europe/Prague). Nothing runs at startup; an invalid value stops the server with an error. - internal/scheduler: time-of-day parsing, Next, and the run loop - banksync.Runner: one lock shared by /sync-bank and the scheduler so runs never overlap, plus the status of the last run - footer shows the last sync since start and the next scheduled run - binary embeds time/tzdata because the Alpine image has no zone data Deliberately not implemented in the legacy Python app, which is being phased out; recorded in CLAUDE.md under "Deliberately Go-only features". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8.9 KiB
8.9 KiB
Pre-feature cleanup — task list
Findings from a full repo audit on 2026-10-08, written up as tasks to clear before new feature work starts. Companion to the Go rewrite tracker, 2026-05-03-2349-go-backend-rewrite-progress.md.
State at audit time
- Two full implementations live side by side: Flask (
app.py,scripts/,templates/) and Go (go/). Recent changes were made in both. - Update 2026-10-08: the Python code was moved to
legacy/after this audit. Python paths below are relative tolegacy/(build/Dockerfileis nowlegacy/build/Dockerfile). - Python tests pass (32 tests). Go unit tests and the parity suite pass. Go lint could not run (see T7).
- The gitops workflow bumps the cluster deployment to the
-goimage, so Go appears to be what is deployed. This was not verified against the cluster. CLAUDE.mdand all docs outsidedocs/plans/describe a Python-only project. The rewrite tracker stops at M6; M7 and M8 are untouched.
How to use
- Tick a checkbox when the task's PR or commit lands and append the SHA.
- Tasks in "Fix first" are small and independent of each other and of the cutover decision. Do them in any order.
- T5 is a decision. Several cleanup tasks become unnecessary once it is made; they are marked "moot if Python is retired".
Fix first
- T1 Remove the secret leak in
.gitea/workflows/kubernetes-deploy.yaml. Workflow deleted on 2026-10-08. Still open for the owner: rotate the credentials and remove the now-unused repo secrets (see below).- It runs on every push to every branch and deploys nothing.
- It echoes the raw Vault login response, the Kanidm token response and the OIDC token response body to the log, and dumps the environment twice.
- It uses
--insecure-skip-tls-verify=true. - Delete or disable the workflow. Rotate the Vault AppRole secret and the Kanidm API token if anyone else can read the CI logs.
- After deletion the repo secrets
VAULT_ROLE_ID,VAULT_SECRET_IDandK8S_CA_CERTare unused and can be removed. Old job logs still contain the leaked tokens until they are deleted or expire.
- T2 Confirm the fee rates for 2026-09 onward. Done 2026-10-08:
adult default 600, 2026-07/08 at 0, 2026-09 to 2026-12 at 600. Junior
rates were not changed.
ADULT_FEE_MONTHLY_RATEends at 2026-08 inscripts/attendance.pyandgo/internal/domain/fees/fees.go.- September and October 2026 are billed at the defaults: 700 CZK adults, 500 CZK juniors.
- If those are not the intended rates, add the months in both files.
- T3 Done 2026-10-08, extended: both dashboards now sync the
current year plus November–December of the previous one. Original task:
remove the hardcoded 2026 window from Python
/sync-bank(app.py, thesync_to_sheetscall with2026-01-01/2026-12-31).- It stops picking up transactions on 2027-01-01. Go already uses the current year.
- Same applies to the
sync-2026Makefile target. - Moot if Python is retired before then.
- T4 Remove member names from tracked files (PII rule in
CLAUDE.md).CHANGELOG.mdline 29 names a member in a fix description.tests/test_match_payments.py,tests/test_reconcile_exceptions.pyandgo/internal/domain/reconcile/reconcile_test.gouse names that may be real. Check them and replace with obviously fictional ones.- Three files in
docs/plans/contain the same names:2026-05-05-1717-payment-person-name-canonicalization.md,2026-05-06-1626-infer-payments-junior-roster.md,2026-05-11-2353-fill-first-multi-month-allocation.md. - The parity fixtures under
go/tests/fixtures/are scrubbed and need no change. - Decide whether the names also need removing from git history.
Decide before new features
- T5 Decide how to finish the Python → Go cutover (M7 and M8 in the
rewrite tracker).
- Recommended: declare Go primary now, freeze Python, run one month-end comparison of the balance report on both sides, then delete Python.
- Until this is done, every feature has to be written twice.
- Confirm first that the cluster really runs the
-goimage.
- T6 Add a test job to CI.
.gitea/workflows/build.yamlonly builds images on tag push. Nothing runs tests.- Run
go test -race ./..., the parity suite (-tags=parity) andgolangci-linton pull requests. - Stop building the Python image on every tag once Python is retired.
- T7 Fix
make go-lint.go/.golangci.ymlis in the v1 config format. golangci-lint 2.12 refuses to load it ("unsupported version of the configuration").- Migrate the config to v2 and pin the linter version used in CI.
- T8 Protect the side-effectful routes.
- Neither app has any authentication.
GET /sync-bankwrites to the payments sheet, so a link prefetcher or crawler can trigger a sync. Change it to POST with a confirmation page, as/flush-cachealready does.- Confirm that the ingress enforces access control, or add it in the app.
- The Go server uses
http.ListenAndServewith no read, write or idle timeouts (go/internal/web/server.go). Use anhttp.Serverwith timeouts.
- T9 Move fee rates and merged months out of code.
- Today a rate change needs a code change in two languages and a release.
- Candidate: a tab in the payments sheet, read the same way as
exceptions. - This also removes the cause of T2.
Cleanup
- T10 Rewrite
CLAUDE.mdfor the current state: Go commands, architecture and key modules, and which backend is primary. Done with the move of Python tolegacy/. - T11 Collapse the documentation into one set.
docs/by-claude-opus/,docs/by-gemini/and the top-level docs overlap, date from February–March 2026 and predate the Go rewrite.- Update
docs/_sidebar.mdanddocs/README.mdto match.
- T12 Update the rewrite tracker.
- M6.7 is unchecked although the changelog records it as done.
- M7.1 and M8.4 refer to a
docker-compose.ymlthat does not exist.
- T13 Remove leftovers:
.agent/rules.md(Antigravity config) andprompts/. - T14 Prune merged branches: 42 local and 44 remote branches are
fully merged into
main. - T15 Clean up
.claude/settings.json.- It is tracked and contains absolute paths under one user's home directory and one-off commands.
- Keep only shared, generic permissions there; move the rest to
.claude/settings.local.json, which is already ignored.
- T16 Align versions.
pyproject.tomlsays0.10; git tags are at0.39.build/Dockerfilepip-installs unpinned packages and ignoresuv.lock.go.modandgo/build/Dockerfileare on Go 1.26; the local toolchain is 1.27.- Dependencies on both sides are a few months behind.
- The Python items are moot if Python is retired.
- T17 Stop the Python tests from calling live Google APIs.
warmup_cache()runs at import ofapp.py, somake testmakes real Drive and Sheets read calls and needs the credentials file.- Moot if Python is retired.
- T18 Set the time zone in the Go container. Partly addressed
2026-10-08: the binary now embeds the zone database and the scheduled sync
uses
SYNC_TZ; the "current month" logic below is still open.- The image has no time zone configured, so
time.Now()is UTC and the "current month" flips one to two hours late at month boundaries. - The Python image sets
Europe/Prague.
- The image has no time zone configured, so
- T19 Decide where
fujarna/lives.fujarna/project.mdis untracked. It is a brief for a separate tournament website and shares almost nothing with this codebase.- Options: its own repository, or a clearly separate Go module here.
- T20 Add tests for the untested Go packages:
cmd/fuj,internal/io/sheets,internal/io/drive,internal/config(about 590 lines in total).
Found during validation of the legacy/ move
Plan: 2026-10-08-1103-api-parity-vs-months-to-show.md.
- T21 Go rendered numeric VS cells in exponent form
(
2.609767878e+09). Sheet text cells now go throughsheets.CellString. - T22 Python
/api/adultsand/api/juniorsdid not returnmonths_to_show. Backported;make parityreports 3/3 routes matching. - T23 Write VS to the payments sheet as text. Both sync
implementations use
USER_ENTERED, so Sheets stored VS as a number and dropped leading zeros. New rows now carry a text marker; existing rows are left as they are and are read correctly either way.
Features added since the audit
- 2026-10-08 — Scheduled bank sync in the Go server, deliberately Go-only. Plan: 2026-10-08-1216-scheduled-bank-sync.md. It also added a lock so two syncs cannot overlap (relevant to T8).
Notes & decisions
(Add entries as you go. Format: YYYY-MM-DD — short note.)