Skip to content

Commit 247ef49

Browse files
docs(jobs): fix stale money-path + quota comments (terminate endpoint live, Team not unlimited) (#97)
Three agent-misleading comment inaccuracies in two job files. Comment-only — zero behavior change; `go build ./internal/jobs/` + `go vet` clean. payment_grace_terminator.go: - Header said terminate "(b) downgrade tier to ANONYMOUS" — the api endpoint downgrades to FREE (api internal_terminate.go:207, "anonymous would be wrong"); a terminated team keeps its team_id so free is the correct floor. - The TODO claimed the api side "is referenced by this dispatcher but NOT yet implemented in the api repo — that side ships in a separate PR." It IS implemented and live: api router.go:893 → internal_terminate.go::Terminate (pause-resources + downgrade-to-free + mark-grace-terminated + audit-emit). An agent reading the TODO would wrongly conclude dunning-termination is a no-op. Rewritten to describe the live state. quota_wall_nudge.go: - Skip-rationale said "team tier is unlimited on every axis." False post the strict-≥80%-margin redesign (2026-06-05) which retired all -1 limits — Team now carries finite high-capacity caps. Skipping Team is still correct (it's the top self-serve tier; the wall nudge is an UPGRADE banner with nothing above to upsell), so this is a stale-reason fix, not a behavior change. Verified the one local integration-test failure (TestIntegration_BillingReconciler_SkipsTestCohort) reproduces IDENTICALLY on clean origin/master without this diff — it is a pre-existing local-test-DB seed flake unrelated to these comment edits (the authoritative gate is CI's seeded postgres service). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent eb427f4 commit 247ef49

2 files changed

Lines changed: 20 additions & 10 deletions

File tree

internal/jobs/payment_grace_terminator.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ package jobs
44
// payment_grace_periods table looking for teams whose grace expired
55
// (expires_at < now()) and calls the api repo's
66
// POST /internal/teams/:id/terminate endpoint to (a) pause all resources,
7-
// (b) downgrade tier to anonymous, (c) mark the dunning row terminated.
7+
// (b) downgrade tier to FREE — NOT anonymous; a terminated team keeps its
8+
// team_id, so "free" (claimed-but-unpaid) is the correct floor (see
9+
// api internal_terminate.go), (c) mark the dunning row terminated.
810
//
911
// Cadence: every 1h (per the brief). The 1h floor is fine because the
1012
// grace clock is 7 days; a customer who recovers in the final hour
@@ -27,14 +29,18 @@ package jobs
2729
// without action — better than booting the worker with no secret and
2830
// later writing audit_log rows for non-terminations.
2931
//
30-
// TODO(ops): WORKER_INTERNAL_JWT_SECRET is a new env var. Operator must
32+
// OPS: WORKER_INTERNAL_JWT_SECRET is a shared env var. Operator must
3133
// (1) generate a 32-byte random value, (2) write it into the worker's
3234
// secrets, (3) write the same value into the api's secrets under
33-
// WORKER_INTERNAL_JWT_SECRET so the api can verify the bearer token,
34-
// (4) the api must expose POST /internal/teams/:id/terminate that
35-
// accepts the bearer + does pause/downgrade/mark-terminated. The
36-
// endpoint is referenced by this dispatcher but NOT yet implemented in
37-
// the api repo — that side ships in a separate PR.
35+
// WORKER_INTERNAL_JWT_SECRET so the api can verify the bearer token.
36+
// The api side IS shipped: POST /internal/teams/:id/terminate is
37+
// registered (api router.go → internal_terminate.go::Terminate) and
38+
// does the pause-resources + downgrade-to-free + mark-grace-terminated
39+
// + audit-emit work. This dispatcher only fires the call and mirrors the
40+
// lifecycle event into audit_log for the email forwarder. (Historical
41+
// note: when this file was first written the api endpoint was a separate
42+
// follow-up PR — that PR has since merged, so the prior "NOT yet
43+
// implemented" TODO is removed to avoid misleading an agent reading it.)
3844

3945
import (
4046
"bytes"

internal/jobs/quota_wall_nudge.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ package jobs
1313
// inside the last 24h, regardless of axis. This keeps the dashboard banner
1414
// stable (it won't flicker between axes once it's earned a slot).
1515
//
16-
// Tier gating: teams on the "team" tier are skipped entirely — team tier
17-
// is unlimited on every axis, so a wall nudge is incoherent. Teams on
18-
// tier "free" (claimed-but-unpaid) and "anonymous" (unclaimed) are also
16+
// Tier gating: teams on the "team" tier are skipped entirely — Team is the
17+
// top self-serve tier, so an "upgrade for headroom" nudge has no target
18+
// to point at. (The wall nudge is an UPGRADE banner; post the
19+
// strict-≥80%-margin redesign of 2026-06-05 Team is no longer "unlimited"
20+
// — it carries finite high-capacity limits — but there is still nothing
21+
// above it to upsell, so skipping it remains correct.) Teams on tier
22+
// "free" (claimed-but-unpaid) and "anonymous" (unclaimed) are also
1923
// skipped: they are pre-conversion and the conversion CTA is the claim
2024
// banner, not an upgrade banner.
2125
//

0 commit comments

Comments
 (0)