Skip to content

feat(server): source-tagged logs and parameterized scheduled jobs#149

Merged
Sootopolis merged 1 commit into
mainfrom
wip
Jul 6, 2026
Merged

feat(server): source-tagged logs and parameterized scheduled jobs#149
Sootopolis merged 1 commit into
mainfrom
wip

Conversation

@Sootopolis

Copy link
Copy Markdown
Owner

What

Two improvements surfaced by running CcasServer in the foreground.

Log source attribution. Every app/job logged to one undifferentiated console stream. Reuses ZIO log annotations (the formatter already rendered them; nothing set them): ProgressDisplay.sourced sets a reserved src key that format renders as a bracketed prefix — lines now read [INFO 14:03:22] [Membership/london-cc] msg.

  • Jobs tagged [Kind/slug] at JobRunner.submit (single choke point; slug best-effort, #id fallback, kind-only for global jobs).
  • Global logs stay global: rate-limit warnings tag [rate-limit], scheduler poll logs [scheduler] — attributable even when running on a job's fiber.
  • No-annotation path is byte-identical, so CLI standalone apps are untouched.

Parameterized scheduled jobs. job_schedule.params was stored but the scheduler ignored it, forcing hardcoded defaults (e.g. a full ClubData refresh every tick). New ScheduleParams decodes per-kind option DTOs and threads them into the app calls.

  • Absent/blank params decode to the previous defaults exactly — existing schedules unchanged.
  • Decode is eager (before submit), so a malformed row is isolated by the existing poll guard without advancing last_run_at.
  • Recruitment caps moved to a shared JobCaps so the HTTP and scheduled paths bound identically.
  • Author via the existing flag: schedule add clubData --interval-hours 24 --params '{"minAgeHours":24}'. minAgeHours is opt-in (deriving from the interval would skip every club forever on a steady cadence).

Fixes

None (no linked issue).

Testing

  • sbt test — 1013 pass, 0 fail (pre-push hook + local).
  • New TestScheduleParams (decode defaults / populated / malformed / stats both-or-neither).
  • TestProgressBar +1 (src renders as prefix, other annotations stay trailing).
  • TestJobScheduler +2 (params reach submit; malformed row doesn't block other schedules).
  • Verified live in test output: [INFO ..] [MatchRef] hello from job.

🤖 Generated with Claude Code

Two gaps surfaced running CcasServer in the foreground.

Log attribution: every app/job logged to one undifferentiated console
stream. Reuse ZIO log annotations (the formatter already rendered them,
nothing set them): ProgressDisplay.sourced sets a reserved `src` key that
`format` renders as a bracketed prefix, so lines read `[INFO ..] [Kind/slug]
msg`. JobRunner tags each job at its single submit choke point (slug best-
effort, `#id` fallback); rate-limit warnings tag `[rate-limit]` and scheduler
poll logs `[scheduler]` so global logs stay attributable even on a job fiber.
No-annotation path is byte-identical, so CLI apps are untouched.

Scheduled params: job_schedule.params was stored but the scheduler ignored
it, forcing hardcoded defaults (e.g. a full ClubData refresh every tick).
New ScheduleParams decodes per-kind option DTOs and threads them into the
app calls; absent params decode to the previous defaults exactly. Decoding
is eager (before submit) so a malformed row is isolated by the existing poll
guard without advancing last_run_at. Recruitment caps move to a shared
JobCaps so the HTTP and scheduled paths bound identically. Author via the
existing flag: `schedule add clubData --params '{"minAgeHours":24}'`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Sootopolis Sootopolis merged commit 2494fce into main Jul 6, 2026
1 check passed
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