Register a built-in noop job kind and store only failure codes
CI / ci (push) Successful in 1m27s
CI / ci (pull_request) Successful in 1m27s

The server now registers the framework's built-in noop kind through
registerJobKinds before the runner starts, so production can run a job; a
noop job succeeds with {"ok":true}. Each feature's kinds are registered in
the same function.

Handlers report failure only with a *jobs.Failure code their kind declared
at registration. The runner stores and returns only that code, or
internal_error, interrupted or unknown_kind, and logs only the job id, kind,
code and a fixed reason: handler error text is never stored, returned or
logged. Results implement jobs.Public, whose PublicJSON names exactly the
data that is stored and returned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 15:12:30 -04:00
co-authored by Claude Opus 5.5
parent f37f240b26
commit f160c9f3a9
6 changed files with 389 additions and 80 deletions
+30 -2
View File
@@ -67,8 +67,7 @@ func run(cfg config.Config, logger *slog.Logger) error {
return err
}
settings := household.NewSettingsService(db)
// Job handlers are registered on the runner here, before Start.
runner, err := jobs.NewRunner(db, logger, jobWorkers)
runner, _, err := newJobRunner(db, logger)
if err != nil {
return err
}
@@ -186,6 +185,35 @@ func seedDefaults(ctx context.Context, db *store.Store, defaultTZ string) error
return household.SeedNotificationPrefs(ctx, db)
}
// jobKinds enqueues every job kind the server runs.
type jobKinds struct {
builtins *jobs.Builtins
}
// newJobRunner returns the job runner with every job kind registered, ready
// to Start.
func newJobRunner(db *store.Store, logger *slog.Logger) (*jobs.Runner, *jobKinds, error) {
runner, err := jobs.NewRunner(db, logger, jobWorkers)
if err != nil {
return nil, nil, err
}
kinds, err := registerJobKinds(runner)
if err != nil {
return nil, nil, err
}
return runner, kinds, nil
}
// registerJobKinds registers every job kind's handler on runner. Each
// feature's job kinds are registered here.
func registerJobKinds(runner *jobs.Runner) (*jobKinds, error) {
builtins, err := jobs.RegisterBuiltins(runner)
if err != nil {
return nil, err
}
return &jobKinds{builtins: builtins}, nil
}
// logListening logs the startup line. Only the public URL's origin is logged
// so no credential-bearing URL component can reach the log.
func logListening(logger *slog.Logger, cfg config.Config) {