Skip to content

Catch up scheduled jobs, fix the monthly payment and send codes with more errors - #30

Merged
bpstack merged 10 commits into
mainfrom
claude/compassionate-planck-gh6aof
Oct 14, 2026
Merged

bpstack merged 10 commits into
mainfrom
claude/compassionate-planck-gh6aof

Conversation

@bpstack

@bpstack bpstack commented Oct 14, 2026

Copy link
Copy Markdown
Owner

Changes

  • Cron catch-up (ADR-046): Render's free plan sleeps the backend, and a week of logs showed no scheduled job ever ran. Every start now runs the jobs whose period is due and not done; cron_job_runs keeps each period to one run, shared by preview and production.
  • Monthly batch payment: it signed with system-cron, which did not exist, so it never paid an invoice. Adds the inactive user and pays in one transaction with the history rows. Migration 20261014_cron_catch_up.sql is already applied on local and Aiven.
  • Error codes: auth, user and middleware errors now carry a code, so the frontend shows them in the page language; the duplicate-user 409 no longer leaks the raw MySQL message.
  • Groups: the history only logs the fields that really changed on update.
  • Parking: SpotType matches the spot_type ENUM.
  • TODO list, INDEX.md and module docs updated.

Checked

  • pnpm verify in backend and frontend; backend tests without a database, as CI runs them.
  • Local: catch-up on start, no repeat on restart, retry after a failed run, manual and automatic batch payment, Backoffice paid tab.
  • Preview (Aiven): the four jobs ran on the first start; ELEC-0001 paid by system-cron; AUTH_USER_NOT_FOUND and FORBIDDEN codes; editing a group amount adds one history row.

- SESSION: main now matches the branch (PR #29, merge 47f77b9), the
  OpenCode review is in main since PR #28, and the next steps start at
  the post-publication TODO list
- TODO: update the last merge into main, which still said PR #4
- Move 25 items that will not be fixed now to the known-issues section
  of the git-ignored archive TODO, with their text and priority, and
  leave a pointer to it in TODO.md
- Drop the money audit trail and the Node check from SESSION's next
  steps, since both moved out
- Record the decision as ADR-045

The owner accepts these issues for now; TODO.md should only list what
is going to be worked on, while the archive keeps them under watch.
- Pass the keys of the validated body as changedFields: the controller
  compared the whole row, so created_at, updated_at and updated_by were
  always logged.
- Compare normalised values in logGroupUpdated: a DATE column arrives as a
  Date and the body as 'YYYY-MM-DD', null and undefined are the same, and a
  DECIMAL arrives as a string. Editing only the amount left 7 history rows.
- Add regression tests for each case.
- Use the six values of parking_spots.spot_type: the old type listed
  values the DB never stores, so it protected nothing.
- Replace the mismatch warning in the parking doc with the sync rule.
- Drop the item from the TODO list.
- Replace the fixed Spanish texts in auth-controllers.ts and
  user-controllers.ts with ERROR_CODES, so the frontend shows them in the
  page language.
- Stop returning the raw MySQL message on a duplicate user: it now answers
  AUTH_USER_ALREADY_EXISTS.
- Add AUTH_USER_ALREADY_EXISTS, AUTH_INVALID_ROLE,
  AUTH_NEW_PASSWORD_SAME_AS_CURRENT and AUTH_RESET_PASSWORD_ERROR, with
  their es/en texts and a test.
- List the existing user codes in TRANSLATED: their texts were already
  there but never used.
- Drop auth from the untranslated errors item in the TODO list.
- Answer with ERROR_CODES in authenticateToken, roleCheck,
  demoRestriction, rateLimiter, imageUpload and checklistParams, so the
  frontend shows these errors in the page language.
- Collapse the role-specific 403 texts of roleCheck into FORBIDDEN: the UI
  already hides what a role cannot use, so the detail is rarely seen.
- Keep demo: true on the demo block: apiClient uses it for its notice.
- Drop the message option of the rate limiters that set their own handler:
  express-rate-limit only reads it in the default handler.
- Add the 17 new codes with their es/en texts and adapt the tests that
  checked the old texts.
- Drop middlewares from the untranslated errors item in the TODO list.
- Run on every start the jobs whose period is due and not done
  (notifications, checklist reset and purge, batch payment): Render's free
  plan sleeps the backend, and a week of logs showed no job ever ran.
- Record the last period of each job in cron_job_runs and claim it with a
  locking UPDATE, so the start-up catch-up and node-cron never run a period
  twice; a failed or abandoned run is retried on the next start.
- Keep the batch payment due for the previous month's period until day 10,
  so a month the backend slept through is still paid.
- Add the inactive system-cron user: the payment signed with it and failed
  on the users foreign key, so it never paid an invoice.
- Pay the batch in one transaction, locking the selected invoices, so no
  invoice ends up paid without its history.
- Record the decision as ADR-046 and the migration in INDEX.md (Aiven
  pending), and merge the two cron items of the TODO list.
@vercel

vercel Bot commented Oct 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
four-points Ready Ready Preview Oct 14, 2026 4:51pm UTC

@bpstack
bpstack merged commit 9b33943 into main Oct 14, 2026
6 checks passed

This branch was successfully deployed

1 active deployment
Preview — de07038e Deployed Oct 14, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant