Files
member-console/internal/billing/queries/subscription_scheduled_changes.sql
T
cgalo5758 b0072d8971 Consolidate domain tables into core schema
Squash the pre-production migration history into fresh core, fedwiki,
and stripe baselines and reduce the canonical source list to those
three streams.

Update sqlc configs, generated queries, raw SQL, tests, and docs while
keeping provider tables schema-qualified.

BREAKING: existing local database volumes must be wiped because goose
version history restarts from the new baselines.
2026-07-05 20:10:23 -05:00

52 lines
2.0 KiB
SQL

-- name: CreateScheduledChange :one
INSERT INTO core.subscription_scheduled_changes
(subscription_id, change_type, target_price_id, target_quantity, effective_at, effective_trigger, credit_disposition)
VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING *;
-- name: GetScheduledChangeByID :one
SELECT * FROM core.subscription_scheduled_changes
WHERE scheduled_change_id = $1;
-- name: ListActiveScheduledChangesBySubscription :many
SELECT * FROM core.subscription_scheduled_changes
WHERE subscription_id = $1 AND status = 'scheduled'
ORDER BY effective_at ASC;
-- name: ListDueScheduledChanges :many
-- Sweeper backstop: due, not-yet-fired rows. Concurrency safety comes from the
-- per-row claim (MarkScheduledChangeApplied), not row locking, so a plain read
-- is sufficient.
SELECT * FROM core.subscription_scheduled_changes
WHERE status = 'scheduled' AND effective_at <= NOW()
ORDER BY effective_at ASC;
-- name: MarkScheduledChangeApplied :one
-- Idempotency guard / claim: the status transition scheduled->applied is the
-- claim. A second firer (webhook vs sweeper) gets sql.ErrNoRows and no-ops.
UPDATE core.subscription_scheduled_changes
SET status = 'applied'
WHERE scheduled_change_id = $1 AND status = 'scheduled'
RETURNING *;
-- name: ApplyScheduledChangesForSubscription :exec
-- Webhook-primary closeout: when a subscription actually ends (Stripe fires
-- customer.subscription.deleted at period end), mark its still-pending scheduled
-- changes applied so the intent ledger reflects what happened.
UPDATE core.subscription_scheduled_changes
SET status = 'applied'
WHERE subscription_id = $1 AND status = 'scheduled';
-- name: CancelScheduledChange :one
UPDATE core.subscription_scheduled_changes
SET status = 'canceled'
WHERE scheduled_change_id = $1 AND status = 'scheduled'
RETURNING *;
-- name: SupersedeActiveScheduledChanges :exec
-- A new scheduled change (or an immediate action) supersedes any still-pending
-- intent on the same subscription.
UPDATE core.subscription_scheduled_changes
SET status = 'superseded'
WHERE subscription_id = $1 AND status = 'scheduled';