feat(health): live daily spend from audit log + limits/breaker surfacing (#83) - #240
feat(health): live daily spend from audit log + limits/breaker surfacing (#83)#240blippip69 wants to merge 1 commit into
Conversation
|
| function spendAmount(entry: AuditEntry): number | null { | ||
| const action = entry.action as unknown as string | ||
| if (action !== "spend" && action !== "verified_spend") return null | ||
| const amount = (entry.metadata as { amountXlm?: unknown } | undefined)?.amountXlm | ||
| return typeof amount === "number" && Number.isFinite(amount) ? amount : null | ||
| } |
There was a problem hiding this comment.
⚠️ Bug: Daily/weekly spend always 0 — no producer emits spend entries
spendAmount only counts audit entries whose action is spend or verified_spend, but the AuditAction union (lib/passport/audit.ts:3-11) does not include those values and no code anywhere calls appendAuditEntry with them (grep finds references only in this route and its test, which force action: "spend" as never). Consequently dailySpentXlm and weeklySpentXlm will always be 0 against real data — the tests pass only because they bypass the type system. Add spend/verified_spend to AuditAction and ensure the spend flow actually writes those audit entries (with metadata.amountXlm), otherwise the endpoint reports fabricated zeros.
Was this helpful? React with 👍 / 👎
| const config = passport.config as { | ||
| spendLimits?: { dailyMaxXlm?: number; weeklyMaxXlm?: number | null } | null | ||
| circuitBreaker?: { | ||
| consecutiveFailures?: number | ||
| maxConsecutiveFailures?: number | ||
| tripped?: boolean | ||
| } | null | ||
| } | ||
| const spendLimits = | ||
| config.spendLimits && typeof config.spendLimits.dailyMaxXlm === "number" | ||
| ? { | ||
| dailyMaxXlm: config.spendLimits.dailyMaxXlm, | ||
| weeklyMaxXlm: config.spendLimits.weeklyMaxXlm ?? null, | ||
| } | ||
| : null |
There was a problem hiding this comment.
⚠️ Bug: spendLimits/circuitBreakerStatus can never populate in production
The route casts passport.config to a shape with optional spendLimits/circuitBreaker, but PassportConfig is defined as only { allowTransfer: boolean } (lib/passport/passport.ts:6), so these fields are never present on real records and spendingLimits/circuitBreakerStatus will always be null. The test only exercises this by casting injected config as Partial<PassportRecord>, bypassing the type. Extend PassportConfig to declare spendLimits/circuitBreaker so the values can actually be stored and surfaced.
Was this helpful? React with 👍 / 👎
Code Review
|
| Auto-apply | Compact |
|
|
Important
Your trial ends in 7 days — upgrade now to keep code review, CI analysis, auto-apply, custom automations, and more.
Was this helpful? React with 👍 / 👎 | Gitar



feat(health): passport health endpoint with live spend + optional limits (#83)
EN
Completes the health route so every field from the issue schema is real data:
dailySpentXlmnow derives from the audit log — entries with actionspend/verified_spendcarryingmetadata.amountXlm, current UTC day;weeklySpentXlmcovers the trailing seven days (bonus field).spendLimitsandcircuitBreakerStatussurface the passport's configuredvalues when present in
config; null otherwise (optional features, no fakezeros).
fullLifeExpiryHoursRemainingcontract; status logic and404-for-unknown-agent unchanged.
Tests: 3 new (
health-spend.test.ts) covering UTC-day boundary math, weeklywindow, non-spend entries being ignored, and config surfacing. Existing 8
health tests untouched and green.
ES
El endpoint de health ahora devuelve datos reales en todos los campos del
esquema: gasto diario/semanal derivado del audit log (UTC), limites de gasto y
estado del circuit breaker cuando esten configurados. Tests nuevos para las
fronteras del dia y la semana; suite completa en verde (149 tests).