BEGIN; -- -- ACTION CREATE TABLE -- CREATE TABLE "assistant_budget" ( "id" bigserial PRIMARY KEY, "authUserId" uuid NOT NULL, "dailyCostMicros" bigint, "monthlyCostMicros" bigint, "dailyTokens" bigint, "monthlyTokens" bigint ); -- Indexes CREATE UNIQUE INDEX "assistant_budget_person_idx" ON "assistant_budget" USING btree ("authUserId"); -- -- DATA: each person's budget from their grants' limits, before those go -- (Halkyon Learn's ADR 0021, D58 and D59). Per unit (a grant's limits were -- in its assistant's cost, `costMicros`, or in `tokens`), the sum of the -- person's grants' limits of that unit; one grant of that unit without a -- limit makes the budget's limit none, as that grant had none; no grant of -- that unit, none. A person whose grants had no limit at all gets no budget, -- as before. Assistants with prices now count their tokens too, against a -- budget in tokens taken from the others: tighter, never looser. -- INSERT INTO "assistant_budget" ("authUserId", "dailyCostMicros", "monthlyCostMicros", "dailyTokens", "monthlyTokens") SELECT * FROM ( SELECT "authUserId", CASE WHEN bool_and("dailyLimit" IS NOT NULL) FILTER (WHERE "limitUnit" = 'costMicros') THEN sum("dailyLimit") FILTER (WHERE "limitUnit" = 'costMicros') END::bigint AS "dailyCostMicros", CASE WHEN bool_and("monthlyLimit" IS NOT NULL) FILTER (WHERE "limitUnit" = 'costMicros') THEN sum("monthlyLimit") FILTER (WHERE "limitUnit" = 'costMicros') END::bigint AS "monthlyCostMicros", CASE WHEN bool_and("dailyLimit" IS NOT NULL) FILTER (WHERE "limitUnit" = 'tokens') THEN sum("dailyLimit") FILTER (WHERE "limitUnit" = 'tokens') END::bigint AS "dailyTokens", CASE WHEN bool_and("monthlyLimit" IS NOT NULL) FILTER (WHERE "limitUnit" = 'tokens') THEN sum("monthlyLimit") FILTER (WHERE "limitUnit" = 'tokens') END::bigint AS "monthlyTokens" FROM "assistant_grant" GROUP BY "authUserId" ) AS "limits" WHERE num_nonnulls("dailyCostMicros", "monthlyCostMicros", "dailyTokens", "monthlyTokens") > 0; -- -- ACTION ALTER TABLE -- ALTER TABLE "assistant_grant" DROP COLUMN "limitUnit"; ALTER TABLE "assistant_grant" DROP COLUMN "dailyLimit"; ALTER TABLE "assistant_grant" DROP COLUMN "monthlyLimit"; -- -- MIGRATION VERSION FOR halkyon_todo -- INSERT INTO "serverpod_migrations" ("module", "version", "timestamp") VALUES ('halkyon_todo', '20261026140330157-assistant-budgets', now()) ON CONFLICT ("module") DO UPDATE SET "version" = '20261026140330157-assistant-budgets', "timestamp" = now(); -- -- MIGRATION VERSION FOR halkyon_base -- INSERT INTO "serverpod_migrations" ("module", "version", "timestamp") VALUES ('halkyon_base', '20261026140329453-assistant-budgets', now()) ON CONFLICT ("module") DO UPDATE SET "version" = '20261026140329453-assistant-budgets', "timestamp" = now(); -- -- MIGRATION VERSION FOR serverpod -- INSERT INTO "serverpod_migrations" ("module", "version", "timestamp") VALUES ('serverpod', '20260824182259319', now()) ON CONFLICT ("module") DO UPDATE SET "version" = '20260824182259319', "timestamp" = now(); -- -- MIGRATION VERSION FOR serverpod_auth_idp -- INSERT INTO "serverpod_migrations" ("module", "version", "timestamp") VALUES ('serverpod_auth_idp', '20260924105404509', now()) ON CONFLICT ("module") DO UPDATE SET "version" = '20260924105404509', "timestamp" = now(); -- -- MIGRATION VERSION FOR halkyon_oidc -- INSERT INTO "serverpod_migrations" ("module", "version", "timestamp") VALUES ('halkyon_oidc', '20261023180644988', now()) ON CONFLICT ("module") DO UPDATE SET "version" = '20261023180644988', "timestamp" = now(); -- -- MIGRATION VERSION FOR serverpod_auth_core -- INSERT INTO "serverpod_migrations" ("module", "version", "timestamp") VALUES ('serverpod_auth_core', '20260924105232991', now()) ON CONFLICT ("module") DO UPDATE SET "version" = '20260924105232991', "timestamp" = now(); COMMIT;