1aad002a3e
When ops staff reset a tenant's current-plan usage, the existing 'refunded' terminal status conflated user-initiated refunds with ops-driven resets, and tenants still saw the old balance in the top-nav chip until the quota-summary cache TTL expired. - Introduce a dedicated 'reset' status for quota_reservations, separate from 'refunded'. Both the initial and an incremental migration widen the CHECK constraint to allow it; the down migration folds 'reset' rows back into 'refunded' before tightening the constraint. - resetQuotaReservations / resetAIPointReservations now write 'reset' without touching refunded_amount, and stop cascading into ai_point_usage_logs (carried no audit value for ops resets). - AdminUserService gains an optional cache dependency and calls invalidateQuotaSummaryCache(tenant_id) immediately after a successful reset so the tenant's top-nav chip refreshes on the next request without waiting on TTL. - Wire the existing appCache into AdminUserService at boot. - Drop the now-unused ai_point_usage_logs field from the reset response and from the ops-web AdminUsersView type. - Add a unit test covering the cache-key invalidation contract. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
18 lines
804 B
SQL
18 lines
804 B
SQL
CREATE TABLE quota_reservations (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_id BIGINT NOT NULL REFERENCES tenants(id),
|
|
quota_type VARCHAR(50) NOT NULL,
|
|
resource_type VARCHAR(50) NOT NULL,
|
|
resource_id BIGINT NOT NULL,
|
|
reserved_amount INT NOT NULL,
|
|
consumed_amount INT NOT NULL DEFAULT 0,
|
|
refunded_amount INT NOT NULL DEFAULT 0,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
|
expire_at TIMESTAMPTZ NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT chk_quota_reservation_status
|
|
CHECK (status IN ('pending', 'confirmed', 'refunded', 'reset'))
|
|
);
|
|
CREATE INDEX idx_quota_reservation_tenant_status ON quota_reservations(tenant_id, status);
|