Launch blocker: implement billing enforcement and overdue server handling #14
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Launch blocker
Implement billing enforcement for overdue / non-paid customer servers.
Context
Controller/reconciler is now running in dry-run while we observe recommendations and noise. The next launch item is billing enforcement so ZLH can safely handle overdue accounts without requiring James to manually monitor everything.
Required policy
Do not destroy customer servers immediately for non-payment.
Required enforcement ladder:
Principles
Billing state model needed
Add/verify durable billing enforcement state per user/account and/or server:
Suggested durable fields, exact model TBD:
Stripe / billing event handling
Webhook handling should update durable state for events such as:
Expected behavior:
Enforcement worker / controller behavior
Controller/reconciler should observe billing state and enqueue safe enforcement actions.
Possible queue/action names:
Initial safe launch actions:
Dangerous actions not allowed automatically yet:
API gating requirements
API must enforce billing state consistently:
Portal requirements
Portal must show clear customer-facing state:
Do not show suspended servers as generic broken/offline servers.
Controller interaction
Controller must respect billing state:
Notifications
Need customer-facing email and internal Discord notifications.
Discord channels:
Customer email events:
Validation plan
Launch expectation
This is a launch blocker. The minimum acceptable launch behavior is warning + backup block + shutdown/suspension + retention. Destroy/delete automation can wait until after launch and must require explicit retention policy plus admin review.
Implementation update — billing enforcement pass
Billing enforcement has been implemented in
zpack-api.Created / changed
Billing schema added
Durable billing enforcement state now exists for:
Billing enforcement service
src/services/billingEnforcement.jsnow handles:Billing worker added
src/queues/billingEnforcement.jswas added with queue name:Script added:
Safe actions implemented:
Destructive actions are explicitly disabled.
Note: this creates a separate billing worker entrypoint. We should decide whether to keep it as a separate service or fold billing actions into the existing repair worker to avoid service sprawl.
Notifications
Added fail-soft customer notification wrapper:
Added generic
sendEmailexport in:Stripe webhook handling extended
Handled events now include:
Duplicate Stripe events are skipped through
StripeEventLog.API gates added
Billing gates were added for:
File read/list/download remains allowed while suspended/retained.
Controller behavior updated
Repair worker billing guard
Existing edge/DNS/Velocity repair jobs now skip if billing state is blocked.
Env defaults added
Validation completed
Not completed yet
Live/simulated Stripe flows still need validation against test users:
Portal was not changed yet. API now returns billing state/codes for Portal to render suspended/retained states clearly.
Validation update — billing enforcement simulated flow
Billing enforcement validation was run against a test user and disposable dev server.
Test subjects
Preflight
Migration was required on the deployed DB because the billing enforcement tables were not present.
npx prisma migrate deployapplied successfully.payment_failed simulation
State moved:
Stripe replay idempotency
Replayed
evt_test_payment_failed_001.Final warning / backup block
Timestamp advanced beyond 72 hours.
Backup mutation route validation was not fully applicable because the disposable server was a dev server; game backup route returned 404 for the dev VMID as expected.
Suspension
Timestamp advanced beyond 120 hours.
Worker recorded:
Data safety confirmed:
API gate validation
The running API process appears stale and was not serving the new billing-gated code.
Evidence while DB state was suspended:
Disposable server was re-stopped afterward through the billing worker.
Controller no-repair while suspended
Reason:
Needs disposable game server or safe controller lock window.
Payment restored
State restored:
Replay of
evt_test_invoice_paid_001passed: duplicate detected, event count stable, state remained active.Destructive action rejection
Enqueued forbidden action:
Result:
Failure against expectation:
Cleanup
Bugs / blockers
Completion status
Billing enforcement is not complete by the requested criteria yet because API gating and controller no-repair validation did not pass end-to-end in the deployed process.
Validation update — billing enforcement end-to-end pass
Billing enforcement validation has now completed across the main launch criteria.
Test subjects
API restart / redeploy
The stale API process was replaced and the current API is now running from updated code.
Preflight
payment_failed simulation
Billing state moved into overdue flow:
Stripe replay idempotency
Replay of
evt_test_payment_failed_001did not duplicate state changes, events, warnings, or queue actions.Final warning / backup block
Backup mutation gates are wired to block create/restore/delete/prune for customers. Full live route validation still needs a game backup route/test fixture with backups available.
Suspension
Data safety confirmed:
API gate validation while suspended
Observed:
Announcements
Authenticated
/api/announcementsnow includes a billing suspension announcement for affected users.Destructive action rejection
delete_suspended_serverwas rejected safely and now writes aBillingEnforcementEvent.Confirmed:
Controller no-repair while suspended
Using suspended test user and game server VMID
5211:Payment restored simulation
invoice.paidrestored state:Cleanup
Bugs fixed during validation
Remaining TODOs
Current completion status
Billing enforcement now passes the core launch validation criteria for:
Remaining launch work is primarily Portal customer-facing billing UI and any final backup/file route fixture validation.
Validation update — Portal billing announcement visible
Portal customer-facing billing messaging has been visually validated through the announcements system.
Current launch approach:
This means the Portal billing messaging requirement is satisfied for launch as long as announcements remain prominent and tied to billing state.
Remaining billing follow-ups:
Portal billing UI can remain a later enhancement unless announcements prove insufficient.
Billing worker is now installed and running under systemd as zpack-billing-worker.service. Launch service set now includes API, provisioning worker, repair worker, controller, and billing worker. Billing worker remains scoped to billing enforcement actions only: warnings, final warnings, backup block, suspension shutdown, retained marking, and restore access. Destructive actions remain rejected. Launch guardrail: do not add more worker or systemd services before launch unless there is a strong safety-boundary reason. Recommended final checks: verify systemctl status and recent journald logs for zpack-billing-worker.service, and add/verify queue staleness monitoring for billing_enforcement.