dorfteich/apps/api/prisma/migrations/20260705185146_quotas/migration.sql
Claude Fable 5 64928f0ac0
All checks were successful
CD / Build and push images (push) Successful in 1m46s
CI / Lint, typecheck, test (push) Successful in 1m17s
CI / Auth e2e pack (push) Successful in 1m39s
CI / Build container images (push) Has been skipped
CD / Deploy to Test (push) Successful in 8s
CD / Smoke tests against Test (push) Successful in 1m6s
CD / Promote to Int (push) Successful in 10s
Quota foundation: overrides, resolution, race-safe consumption (#22)
- quota_overrides + pond_usage models (BigInt values, unique per
  subject+key); migration 20260705185146_quotas
- instance-default quota keys in the settings registry (editors 5,
  readers 50, additional ponds 0, storage 1 GiB, max file 25 MiB)
- QuotaService: getEffective with pond → user → instance resolution
  (zero counts as a value, not a gap); assertCanCreateSharedPond and
  checkAndConsume serialize via pg_advisory_xact_lock inside the guarded
  write's transaction; release never drops below zero
- pond creation enforces additional_ponds (personal ponds don't count);
  quota errors carry code quota_exceeded + {quotaKey, limit}, localized
- seed grants fixtures an additional_ponds override (default is 0)
- table-driven resolution tests, parallel-consumption test, e2e for the
  pond-creation limit

Closes #22

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UpQz6ypHJsLfMf4S6fyQEB
2026-07-05 20:55:59 +02:00

32 lines
1.0 KiB
SQL

-- CreateEnum
CREATE TYPE "QuotaSubjectType" AS ENUM ('USER', 'POND');
-- CreateTable
CREATE TABLE "quota_overrides" (
"id" TEXT NOT NULL,
"subject_type" "QuotaSubjectType" NOT NULL,
"subject_id" TEXT NOT NULL,
"quota_key" TEXT NOT NULL,
"value" BIGINT NOT NULL,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "quota_overrides_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "pond_usage" (
"pond_id" TEXT NOT NULL,
"storage_bytes_used" BIGINT NOT NULL DEFAULT 0,
"editor_count" INTEGER NOT NULL DEFAULT 0,
"reader_count" INTEGER NOT NULL DEFAULT 0,
"updated_at" TIMESTAMP(3) NOT NULL,
CONSTRAINT "pond_usage_pkey" PRIMARY KEY ("pond_id")
);
-- CreateIndex
CREATE UNIQUE INDEX "quota_overrides_subject_type_subject_id_quota_key_key" ON "quota_overrides"("subject_type", "subject_id", "quota_key");
-- AddForeignKey
ALTER TABLE "pond_usage" ADD CONSTRAINT "pond_usage_pond_id_fkey" FOREIGN KEY ("pond_id") REFERENCES "ponds"("id") ON DELETE CASCADE ON UPDATE CASCADE;