chore(migrations): track schema snapshots and require explicit apply
This commit is contained in:
parent
83f203d736
commit
b22a1836e4
30 changed files with 250316 additions and 23 deletions
|
|
@ -185,7 +185,7 @@ gameTick → POST `/api/game-tick/notify` (guarded by `x-game-tick-secret` heade
|
||||||
- **Server actions**: `src/app/(frontend)/logistics/banking/actions.ts`. `createBankAccount` (regular users may only create their own personal account; treasury/faction require a manager), `ensureMyAccount`, `depositFunds`/`withdrawFunds`/`transferFunds`. Permission model: personal accounts are owner- or manager-only; **treasury/faction accounts are manager-only**. Manager = admin/developer or logistics-qualified (`hasLogisticsQualification`). Emits `finance:deposit` / `finance:withdraw` / `finance:transfer` / `bank:account-create` events.
|
- **Server actions**: `src/app/(frontend)/logistics/banking/actions.ts`. `createBankAccount` (regular users may only create their own personal account; treasury/faction require a manager), `ensureMyAccount`, `depositFunds`/`withdrawFunds`/`transferFunds`. Permission model: personal accounts are owner- or manager-only; **treasury/faction accounts are manager-only**. Manager = admin/developer or logistics-qualified (`hasLogisticsQualification`). Emits `finance:deposit` / `finance:withdraw` / `finance:transfer` / `bank:account-create` events.
|
||||||
- **UI**: `src/app/(frontend)/logistics/banking/` (overview + `[id]` detail), components in `src/components/frontend/banking/` (`BankingOverview`, `AccountCard`, `AccountDetail`, `CreateAccountDialog`, `BankTransactionDialog`, `LedgerTable`, `MyWalletCard`). Sidebar entry "Banking" under Logistics.
|
- **UI**: `src/app/(frontend)/logistics/banking/` (overview + `[id]` detail), components in `src/components/frontend/banking/` (`BankingOverview`, `AccountCard`, `AccountDetail`, `CreateAccountDialog`, `BankTransactionDialog`, `LedgerTable`, `MyWalletCard`). Sidebar entry "Banking" under Logistics.
|
||||||
- **Event targets**: `bank-accounts`, `bank-transactions`, `ledger-entries` added to `GameEventLogs` `TARGET_COLLECTIONS` and `emit.ts` `targetCollection` union. Finance event types in `eventTypes.ts`.
|
- **Event targets**: `bank-accounts`, `bank-transactions`, `ledger-entries` added to `GameEventLogs` `TARGET_COLLECTIONS` and `emit.ts` `targetCollection` union. Finance event types in `eventTypes.ts`.
|
||||||
- **Gotchas**: Payload's create TS overloads reject `undefined` on relationship/required fields — pass `null` for empty relationships and a concrete value (`""` for `transactionNumber`) or TS falls through to the draft-variant and errors `Property 'draft' is missing`. No migration has been added for these collections yet (project relies on dev `push: true`).
|
- **Gotchas**: Payload's create TS overloads reject `undefined` on relationship/required fields — pass `null` for empty relationships and a concrete value (`""` for `transactionNumber`) or TS falls through to the draft-variant and errors `Property 'draft' is missing`. No migration has been added for these collections yet (dev uses `push: false`; run `bun run payload migrate` after schema changes).
|
||||||
|
|
||||||
## Trading Marketplace
|
## Trading Marketplace
|
||||||
|
|
||||||
|
|
@ -213,7 +213,7 @@ gameTick → POST `/api/game-tick/notify` (guarded by `x-game-tick-secret` heade
|
||||||
- **NPC attribution**: auto entries belong to a `game-npcs` NPC instead of a user. `src/lib/market/npcs.ts` — `resolveVendorNpc(payload, assetId)` prefers an in-game vendor NPC that `vendor.sells` the asset, falls back to any enabled vendor NPC selling it, otherwise `createGeneratedNpc` (random name/occupation, `isGenerated: true`, `isInGame: false`, set up as a vendor for that asset). `applyNpcPriceModifier(base, npc)` applies `vendor.priceModifier`. GMs create real NPCs in the admin panel and tick `isInGame` on generated placeholders to promote them.
|
- **NPC attribution**: auto entries belong to a `game-npcs` NPC instead of a user. `src/lib/market/npcs.ts` — `resolveVendorNpc(payload, assetId)` prefers an in-game vendor NPC that `vendor.sells` the asset, falls back to any enabled vendor NPC selling it, otherwise `createGeneratedNpc` (random name/occupation, `isGenerated: true`, `isInGame: false`, set up as a vendor for that asset). `applyNpcPriceModifier(base, npc)` applies `vendor.priceModifier`. GMs create real NPCs in the admin panel and tick `isInGame` on generated placeholders to promote them.
|
||||||
- **UI**: `src/app/(frontend)/logistics/market/` page + `src/components/frontend/market/` (`MarketView` with search/rarity/type filters, `ListingCard` with Buy/Offer/Cancel, `CreateListingDialog`, `NegotiationPanel`, `MakeOfferDialog`, `NpcChat`, `Countdown`). Sidebar entry "Market" under Logistics. Uses `formatAmount` from `src/lib/banking/format` for prices. Auto entries show the NPC name + occupation in the "from" line (`npcLabel`), falling back to "Market vendor" for legacy entries with no NPC.
|
- **UI**: `src/app/(frontend)/logistics/market/` page + `src/components/frontend/market/` (`MarketView` with search/rarity/type filters, `ListingCard` with Buy/Offer/Cancel, `CreateListingDialog`, `NegotiationPanel`, `MakeOfferDialog`, `NpcChat`, `Countdown`). Sidebar entry "Market" under Logistics. Uses `formatAmount` from `src/lib/banking/format` for prices. Auto entries show the NPC name + occupation in the "from" line (`npcLabel`), falling back to "Market vendor" for legacy entries with no NPC.
|
||||||
- **Event targets**: `market-listings` + `market-negotiations` added to `GameEventLogs` `TARGET_COLLECTIONS` and `emit.ts` `targetCollection` union. Market event types in `eventTypes.ts`.
|
- **Event targets**: `market-listings` + `market-negotiations` added to `GameEventLogs` `TARGET_COLLECTIONS` and `emit.ts` `targetCollection` union. Market event types in `eventTypes.ts`.
|
||||||
- **Gotchas**: The `market-tick` bin must be run regularly (external cron) for expiry + vendor stock to update. `buyListing` credits the locker before clearing the payment — if the buyer's locker is full, the payment already moved and the purchase throws; consider escrow/refund handling in a later pass. When a seller accepts a buyer's offer, `buyListing` runs as the **buyer** (from `negotiation.buyer`), never the accepting actor. No migration added yet (dev relies on `push: true`; the `quantity` column on `market-negotiations` was added directly to the dev DB via `ALTER TABLE` because `bun run db push` fails with `must be owner of table spatial_ref_sys`).
|
- **Gotchas**: The `market-tick` bin must be run regularly (external cron) for expiry + vendor stock to update. `buyListing` credits the locker before clearing the payment — if the buyer's locker is full, the payment already moved and the purchase throws; consider escrow/refund handling in a later pass. When a seller accepts a buyer's offer, `buyListing` runs as the **buyer** (from `negotiation.buyer`), never the accepting actor. No migration added yet (dev uses `push: false`; run `bun run payload migrate` after schema changes). `bun run db push` fails with `must be owner of table spatial_ref_sys` — use Payload's migration runner instead.
|
||||||
|
|
||||||
## Notifications
|
## Notifications
|
||||||
|
|
||||||
|
|
@ -268,7 +268,7 @@ Username-based login (no email login). Users log in via Payload admin with `user
|
||||||
|
|
||||||
PostgreSQL via `@payloadcms/db-postgres`. Schema defined in `src/payload-generated-schema.ts`. Migrations in `src/migrations/` (timestamp-named .ts + .json pairs, registered in `migrations/index.ts`). Drizzle config reads `DATABASE_URI` from env.
|
PostgreSQL via `@payloadcms/db-postgres`. Schema defined in `src/payload-generated-schema.ts`. Migrations in `src/migrations/` (timestamp-named .ts + .json pairs, registered in `migrations/index.ts`). Drizzle config reads `DATABASE_URI` from env.
|
||||||
|
|
||||||
In development, `postgresAdapter` uses `push: true` to auto-sync schema.
|
In development, `postgresAdapter` uses `push: false` — run `bun run payload migrate` after schema changes to apply them locally.
|
||||||
|
|
||||||
## Code style
|
## Code style
|
||||||
|
|
||||||
|
|
@ -302,7 +302,7 @@ shadcn/ui components live in `src/components/ui/`. Use `bunx shadcn@latest add <
|
||||||
- Playwright tests auto-start the dev server — make sure port 3000 is free before running e2e.
|
- Playwright tests auto-start the dev server — make sure port 3000 is free before running e2e.
|
||||||
- Payload admin layout and importMap are auto-generated — do not edit by hand.
|
- Payload admin layout and importMap are auto-generated — do not edit by hand.
|
||||||
- `.npmrc` sets `legacy-peer-deps=true` for dependency resolution compatibility.
|
- `.npmrc` sets `legacy-peer-deps=true` for dependency resolution compatibility.
|
||||||
- `bun run db push` fails with `must be owner of table spatial_ref_sys` (a PostGIS table owned by the DB superuser) — drizzle-kit push does a full-schema diff and trips on it. Workaround: apply the needed `ALTER TABLE` directly (via node + `pg` reading `DATABASE_URI` from `.env`) or start the dev server, whose Payload `push: true` path may skip the offending table.
|
- `bun run db push` fails with `must be owner of table spatial_ref_sys` (a PostGIS table owned by the DB superuser) — drizzle-kit push does a full-schema diff and trips on it. Workaround: apply the needed `ALTER TABLE` directly (via node + `pg` reading `DATABASE_URI` from `.env`) or use Payload's migration runner (`bun run payload migrate`).
|
||||||
|
|
||||||
## Server Actions convention
|
## Server Actions convention
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ docker exec <container-name> node node_modules/payload/bin.js migrate
|
||||||
|
|
||||||
Coolify Scheduled Tasks support ad-hoc runs of the same command — fire it manually, watch the logs, then commit. **Never** run drizzle-kit (`bun run db migrate`) in prod; `bun run db push` fails on this DB because of the PostGIS `spatial_ref_sys` ownership issue (see `AGENTS.md` Gotchas). Use Payload's migration runner exclusively.
|
Coolify Scheduled Tasks support ad-hoc runs of the same command — fire it manually, watch the logs, then commit. **Never** run drizzle-kit (`bun run db migrate`) in prod; `bun run db push` fails on this DB because of the PostGIS `spatial_ref_sys` ownership issue (see `AGENTS.md` Gotchas). Use Payload's migration runner exclusively.
|
||||||
|
|
||||||
For dev (where `push: true` in `payload.config.ts`), starting the dev server auto-applies schema changes — that's intentional and fine for dev databases.
|
For dev (where `push: false` in `payload.config.ts`), run `bun run payload migrate` after schema changes to apply them locally.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
8535
src/migrations/20251206_065831.json
Normal file
8535
src/migrations/20251206_065831.json
Normal file
File diff suppressed because it is too large
Load diff
8535
src/migrations/20251212_183607.json
Normal file
8535
src/migrations/20251212_183607.json
Normal file
File diff suppressed because it is too large
Load diff
8863
src/migrations/20251219_061127.json
Normal file
8863
src/migrations/20251219_061127.json
Normal file
File diff suppressed because it is too large
Load diff
8995
src/migrations/20251222_200320.json
Normal file
8995
src/migrations/20251222_200320.json
Normal file
File diff suppressed because it is too large
Load diff
9106
src/migrations/20251223_055859.json
Normal file
9106
src/migrations/20251223_055859.json
Normal file
File diff suppressed because it is too large
Load diff
9237
src/migrations/20260109_065519.json
Normal file
9237
src/migrations/20260109_065519.json
Normal file
File diff suppressed because it is too large
Load diff
15515
src/migrations/20260816_213455.json
Normal file
15515
src/migrations/20260816_213455.json
Normal file
File diff suppressed because it is too large
Load diff
15515
src/migrations/20260816_220000.json
Normal file
15515
src/migrations/20260816_220000.json
Normal file
File diff suppressed because it is too large
Load diff
15671
src/migrations/20260817_053752.json
Normal file
15671
src/migrations/20260817_053752.json
Normal file
File diff suppressed because it is too large
Load diff
15972
src/migrations/20260818_024510.json
Normal file
15972
src/migrations/20260818_024510.json
Normal file
File diff suppressed because it is too large
Load diff
18648
src/migrations/20260825_184347.json
Normal file
18648
src/migrations/20260825_184347.json
Normal file
File diff suppressed because it is too large
Load diff
175
src/migrations/20260825_220000.ts
Normal file
175
src/migrations/20260825_220000.ts
Normal file
|
|
@ -0,0 +1,175 @@
|
||||||
|
import { MigrateUpArgs, MigrateDownArgs, sql } from "@payloadcms/db-postgres";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds targeting, path matching, and enabled fields to the shims global.
|
||||||
|
* This is a diff migration — production already has the base shims_shims table
|
||||||
|
* with (name, summary, content, type). This adds the new columns, enum types,
|
||||||
|
* and junction tables without recreating anything that already exists.
|
||||||
|
*/
|
||||||
|
export async function up({ db }: MigrateUpArgs): Promise<void> {
|
||||||
|
// --- New enum types ---
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TYPE "public"."enum_shims_shims_targeting_audience"
|
||||||
|
AS ENUM('all', 'percentage', 'users', 'roles');
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TYPE "public"."enum_shims_shims_targeting_roles"
|
||||||
|
AS ENUM('guest', 'user', 'trusted', 'admin', 'developer');
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TYPE "public"."enum_shims_shims_paths_match_type"
|
||||||
|
AS ENUM('all', 'include', 'exclude');
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`);
|
||||||
|
|
||||||
|
// --- New columns on shims_shims ---
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "shims_shims"
|
||||||
|
ADD COLUMN IF NOT EXISTS "enabled" boolean DEFAULT false NOT NULL;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "shims_shims"
|
||||||
|
ADD COLUMN IF NOT EXISTS "targeting_audience"
|
||||||
|
"enum_shims_shims_targeting_audience" DEFAULT 'all' NOT NULL;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "shims_shims"
|
||||||
|
ADD COLUMN IF NOT EXISTS "targeting_percentage" numeric;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "shims_shims"
|
||||||
|
ADD COLUMN IF NOT EXISTS "paths_match_type"
|
||||||
|
"enum_shims_shims_paths_match_type" DEFAULT 'all' NOT NULL;
|
||||||
|
`);
|
||||||
|
|
||||||
|
// --- Junction table: shims_shims_targeting_roles (hasMany select) ---
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE TABLE IF NOT EXISTS "shims_shims_targeting_roles" (
|
||||||
|
"order" integer NOT NULL,
|
||||||
|
"parent_id" varchar NOT NULL,
|
||||||
|
"value" "enum_shims_shims_targeting_roles",
|
||||||
|
"id" serial PRIMARY KEY NOT NULL
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "shims_shims_targeting_roles"
|
||||||
|
ADD CONSTRAINT "shims_shims_targeting_roles_parent_id_fk"
|
||||||
|
FOREIGN KEY ("parent_id") REFERENCES "public"."shims_shims"("id")
|
||||||
|
ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_shims_targeting_roles_order_idx"
|
||||||
|
ON "shims_shims_targeting_roles" USING btree ("order");
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_shims_targeting_roles_parent_id_idx"
|
||||||
|
ON "shims_shims_targeting_roles" USING btree ("parent_id");
|
||||||
|
`);
|
||||||
|
|
||||||
|
// --- Junction table: shims_shims_targeting_users (hasMany relationship) ---
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE TABLE IF NOT EXISTS "shims_shims_targeting_users" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" varchar NOT NULL,
|
||||||
|
"id" varchar PRIMARY KEY NOT NULL,
|
||||||
|
"value" integer NOT NULL
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "shims_shims_targeting_users"
|
||||||
|
ADD CONSTRAINT "shims_shims_targeting_users_parent_id_fk"
|
||||||
|
FOREIGN KEY ("_parent_id") REFERENCES "public"."shims_shims"("id")
|
||||||
|
ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "shims_shims_targeting_users"
|
||||||
|
ADD CONSTRAINT "shims_shims_targeting_users_value_fk"
|
||||||
|
FOREIGN KEY ("value") REFERENCES "public"."users"("id")
|
||||||
|
ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_shims_targeting_users_order_idx"
|
||||||
|
ON "shims_shims_targeting_users" USING btree ("_order");
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_shims_targeting_users_parent_id_idx"
|
||||||
|
ON "shims_shims_targeting_users" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_shims_targeting_users_value_idx"
|
||||||
|
ON "shims_shims_targeting_users" USING btree ("value");
|
||||||
|
`);
|
||||||
|
|
||||||
|
// --- Junction table: shims_shims_paths_paths (hasMany text) ---
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE TABLE IF NOT EXISTS "shims_shims_paths_paths" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" varchar NOT NULL,
|
||||||
|
"id" varchar PRIMARY KEY NOT NULL,
|
||||||
|
"value" varchar
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "shims_shims_paths_paths"
|
||||||
|
ADD CONSTRAINT "shims_shims_paths_paths_parent_id_fk"
|
||||||
|
FOREIGN KEY ("_parent_id") REFERENCES "public"."shims_shims"("id")
|
||||||
|
ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_shims_paths_paths_order_idx"
|
||||||
|
ON "shims_shims_paths_paths" USING btree ("_order");
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_shims_paths_paths_parent_id_idx"
|
||||||
|
ON "shims_shims_paths_paths" USING btree ("_parent_id");
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down({ db }: MigrateDownArgs): Promise<void> {
|
||||||
|
// Drop junction tables (cascade removes FK rows)
|
||||||
|
await db.execute(sql`DROP TABLE IF EXISTS "shims_shims_paths_paths";`);
|
||||||
|
await db.execute(sql`DROP TABLE IF EXISTS "shims_shims_targeting_users";`);
|
||||||
|
await db.execute(sql`DROP TABLE IF EXISTS "shims_shims_targeting_roles";`);
|
||||||
|
|
||||||
|
// Drop columns
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "shims_shims" DROP COLUMN IF EXISTS "enabled";
|
||||||
|
ALTER TABLE "shims_shims" DROP COLUMN IF EXISTS "targeting_audience";
|
||||||
|
ALTER TABLE "shims_shims" DROP COLUMN IF EXISTS "targeting_percentage";
|
||||||
|
ALTER TABLE "shims_shims" DROP COLUMN IF EXISTS "paths_match_type";
|
||||||
|
`);
|
||||||
|
|
||||||
|
// Drop enum types
|
||||||
|
await db.execute(sql`DROP TYPE IF EXISTS "public"."enum_shims_shims_paths_match_type";`);
|
||||||
|
await db.execute(sql`DROP TYPE IF EXISTS "public"."enum_shims_shims_targeting_roles";`);
|
||||||
|
await db.execute(sql`DROP TYPE IF EXISTS "public"."enum_shims_shims_targeting_audience";`);
|
||||||
|
}
|
||||||
19001
src/migrations/20260826_043422.json
Normal file
19001
src/migrations/20260826_043422.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { MigrateDownArgs, MigrateUpArgs, sql } from "@payloadcms/db-postgres";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repairs auxiliary tables required by Payload's current Shims global schema.
|
||||||
|
*
|
||||||
|
* The original Shims migrations created the global and its array/targeting
|
||||||
|
* tables, but the later relationship/text fields also require these two
|
||||||
|
* Payload-managed tables. Existing databases need this additive repair.
|
||||||
|
*/
|
||||||
|
export async function up({ db }: MigrateUpArgs): Promise<void> {
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE TABLE IF NOT EXISTS "shims_texts" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"order" integer NOT NULL,
|
||||||
|
"parent_id" integer NOT NULL,
|
||||||
|
"path" varchar NOT NULL,
|
||||||
|
"text" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "shims_rels" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"order" integer,
|
||||||
|
"parent_id" integer NOT NULL,
|
||||||
|
"path" varchar NOT NULL,
|
||||||
|
"users_id" integer
|
||||||
|
);
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "shims_texts"
|
||||||
|
ADD CONSTRAINT "shims_texts_parent_fk"
|
||||||
|
FOREIGN KEY ("parent_id") REFERENCES "public"."shims"("id")
|
||||||
|
ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "shims_rels"
|
||||||
|
ADD CONSTRAINT "shims_rels_parent_fk"
|
||||||
|
FOREIGN KEY ("parent_id") REFERENCES "public"."shims"("id")
|
||||||
|
ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "shims_rels"
|
||||||
|
ADD CONSTRAINT "shims_rels_users_fk"
|
||||||
|
FOREIGN KEY ("users_id") REFERENCES "public"."users"("id")
|
||||||
|
ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`);
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_texts_order_parent"
|
||||||
|
ON "shims_texts" USING btree ("order", "parent_id");
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_rels_order_idx"
|
||||||
|
ON "shims_rels" USING btree ("order");
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_rels_parent_idx"
|
||||||
|
ON "shims_rels" USING btree ("parent_id");
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_rels_path_idx"
|
||||||
|
ON "shims_rels" USING btree ("path");
|
||||||
|
CREATE INDEX IF NOT EXISTS "shims_rels_users_id_idx"
|
||||||
|
ON "shims_rels" USING btree ("users_id");
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down({ db }: MigrateDownArgs): Promise<void> {
|
||||||
|
await db.execute(sql`
|
||||||
|
DROP TABLE IF EXISTS "shims_rels";
|
||||||
|
DROP TABLE IF EXISTS "shims_texts";
|
||||||
|
`);
|
||||||
|
}
|
||||||
16667
src/migrations/_archived/20260820_004157.json
Normal file
16667
src/migrations/_archived/20260820_004157.json
Normal file
File diff suppressed because it is too large
Load diff
276
src/migrations/_archived/20260820_004157.ts
Normal file
276
src/migrations/_archived/20260820_004157.ts
Normal file
|
|
@ -0,0 +1,276 @@
|
||||||
|
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
|
||||||
|
|
||||||
|
// Idempotent migration: safe to run on databases where push: true already applied
|
||||||
|
// the schema (dev), and on fresh production databases that need these objects.
|
||||||
|
// Each DDL block is wrapped in exception handlers to skip already-existing objects.
|
||||||
|
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||||
|
// --- Enums ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TYPE "public"."enum_users_preferences_display_lead_or_actual" AS ENUM('lead', 'actual');
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TYPE "public"."enum_roles_permissions" AS ENUM('system:admin-access', 'users:create', 'users:read', 'users:update', 'users:delete', 'users:unlock', 'users:assign-roles', 'ranks:create', 'ranks:read', 'ranks:update', 'ranks:delete', 'profiles:create', 'profiles:read', 'profiles:update', 'profiles:delete', 'awards:create', 'awards:read', 'awards:update', 'awards:delete', 'qualifications:create', 'qualifications:read', 'qualifications:update', 'qualifications:delete', 'assignments:create', 'assignments:read', 'assignments:update', 'assignments:delete', 'experience:create', 'experience:read', 'experience:update', 'experience:delete', 'user-notifications:create', 'user-notifications:read', 'user-notifications:update', 'user-notifications:delete', 'missions:create', 'missions:read', 'missions:update', 'missions:delete', 'missions:read-sensitive', 'mission-attendances:create', 'mission-attendances:read', 'mission-attendances:update', 'mission-attendances:delete', 'campaigns:create', 'campaigns:read', 'campaigns:update', 'campaigns:delete', 'factions:create', 'factions:read', 'factions:update', 'factions:delete', 'technologies:create', 'technologies:read', 'technologies:update', 'technologies:delete', 'assets:create', 'assets:read', 'assets:update', 'assets:delete', 'resources:create', 'resources:read', 'resources:update', 'resources:delete', 'vehicles:create', 'vehicles:read', 'vehicles:update', 'vehicles:delete', 'structures:create', 'structures:read', 'structures:update', 'structures:delete', 'shipments:create', 'shipments:read', 'shipments:update', 'shipments:delete', 'bank-accounts:create', 'bank-accounts:read', 'bank-accounts:update', 'bank-accounts:delete', 'bank-transactions:create', 'bank-transactions:read', 'bank-transactions:update', 'bank-transactions:delete', 'ledger-entries:create', 'ledger-entries:read', 'ledger-entries:update', 'ledger-entries:delete', 'locker-storages:create', 'locker-storages:read', 'locker-storages:update', 'locker-storages:delete', 'loadouts:create', 'loadouts:read', 'loadouts:update', 'loadouts:delete', 'market-listings:create', 'market-listings:read', 'market-listings:update', 'market-listings:delete', 'market-negotiations:create', 'market-negotiations:read', 'market-negotiations:update', 'market-negotiations:delete', 'tickets:create', 'tickets:read', 'tickets:update', 'tickets:delete', 'game-structures:create', 'game-structures:read', 'game-structures:update', 'game-structures:delete', 'game-vehicles:create', 'game-vehicles:read', 'game-vehicles:update', 'game-vehicles:delete', 'game-npcs:create', 'game-npcs:read', 'game-npcs:update', 'game-npcs:delete', 'game-hard-resources:create', 'game-hard-resources:read', 'game-hard-resources:update', 'game-hard-resources:delete', 'game-event-logs:create', 'game-event-logs:read', 'game-event-logs:update', 'game-event-logs:delete', 'maps:create', 'maps:read', 'maps:update', 'maps:delete', 'narrative-events:create', 'narrative-events:read', 'narrative-events:update', 'narrative-events:delete', 'mission-files:create', 'mission-files:read', 'mission-files:update', 'mission-files:delete', 'mod-lists:create', 'mod-lists:read', 'mod-lists:update', 'mod-lists:delete', 'game-rules:read', 'game-rules:update', 'shims:read', 'shims:update', 'logistics:manage', 'intelligence:manage', 'profiles:intel_excerpt:update', 'banking:manage', 'tickets:staff', 'discord:staff', 'discord:announce');
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Tables ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TABLE "users_rels" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"order" integer,
|
||||||
|
"parent_id" integer NOT NULL,
|
||||||
|
"path" varchar NOT NULL,
|
||||||
|
"roles_id" integer
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TABLE "roles_permissions" (
|
||||||
|
"order" integer NOT NULL,
|
||||||
|
"parent_id" integer NOT NULL,
|
||||||
|
"value" "enum_roles_permissions",
|
||||||
|
"id" serial PRIMARY KEY NOT NULL
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TABLE "roles" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"slug" varchar NOT NULL,
|
||||||
|
"description" varchar,
|
||||||
|
"is_system" boolean DEFAULT false,
|
||||||
|
"is_superuser" boolean DEFAULT false,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TABLE "roles_rels" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"order" integer,
|
||||||
|
"parent_id" integer NOT NULL,
|
||||||
|
"path" varchar NOT NULL,
|
||||||
|
"roles_id" integer
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Columns (ADD COLUMN with DEFAULT for NOT NULL columns to handle existing rows) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "users" ADD COLUMN "preferences_display_lead_or_actual" "enum_users_preferences_display_lead_or_actual" DEFAULT 'lead';
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "users" ADD COLUMN "preferences_display_show_version_overlay" boolean DEFAULT true;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "profiles" ADD COLUMN "dossier_enlistment_date" timestamp(3) with time zone DEFAULT now() NOT NULL;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "roles_id" integer;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Foreign keys ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "users_rels" ADD CONSTRAINT "users_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "users_rels" ADD CONSTRAINT "users_rels_roles_fk" FOREIGN KEY ("roles_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "roles_permissions" ADD CONSTRAINT "roles_permissions_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "roles_rels" ADD CONSTRAINT "roles_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "roles_rels" ADD CONSTRAINT "roles_rels_roles_fk" FOREIGN KEY ("roles_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Indexes (catch duplicate_table OR duplicate_object — PostgreSQL uses 42P07 for indexes) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "users_rels_order_idx" ON "users_rels" USING btree ("order");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "users_rels_parent_idx" ON "users_rels" USING btree ("parent_id");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "users_rels_path_idx" ON "users_rels" USING btree ("path");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "users_rels_roles_id_idx" ON "users_rels" USING btree ("roles_id");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "roles_permissions_order_idx" ON "roles_permissions" USING btree ("order");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "roles_permissions_parent_idx" ON "roles_permissions" USING btree ("parent_id");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE UNIQUE INDEX "roles_name_idx" ON "roles" USING btree ("name");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE UNIQUE INDEX "roles_slug_idx" ON "roles" USING btree ("slug");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "roles_updated_at_idx" ON "roles" USING btree ("updated_at");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "roles_created_at_idx" ON "roles" USING btree ("created_at");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "roles_rels_order_idx" ON "roles_rels" USING btree ("order");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "roles_rels_parent_idx" ON "roles_rels" USING btree ("parent_id");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "roles_rels_path_idx" ON "roles_rels" USING btree ("path");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "roles_rels_roles_id_idx" ON "roles_rels" USING btree ("roles_id");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_roles_fk" FOREIGN KEY ("roles_id") REFERENCES "public"."roles"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "payload_locked_documents_rels_roles_id_idx" ON "payload_locked_documents_rels" USING btree ("roles_id");
|
||||||
|
EXCEPTION WHEN duplicate_object OR duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "users_rels" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "roles_permissions" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "roles" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "roles_rels" DISABLE ROW LEVEL SECURITY;
|
||||||
|
DROP TABLE "users_rels" CASCADE;
|
||||||
|
DROP TABLE "roles_permissions" CASCADE;
|
||||||
|
DROP TABLE "roles" CASCADE;
|
||||||
|
DROP TABLE "roles_rels" CASCADE;
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_roles_fk";
|
||||||
|
|
||||||
|
DROP INDEX "payload_locked_documents_rels_roles_id_idx";
|
||||||
|
ALTER TABLE "users" DROP COLUMN "preferences_display_lead_or_actual";
|
||||||
|
ALTER TABLE "users" DROP COLUMN "preferences_display_show_version_overlay";
|
||||||
|
ALTER TABLE "profiles" DROP COLUMN "dossier_enlistment_date";
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "roles_id";
|
||||||
|
DROP TYPE "public"."enum_users_preferences_display_lead_or_actual";
|
||||||
|
DROP TYPE "public"."enum_roles_permissions";
|
||||||
|
`)
|
||||||
|
}
|
||||||
17726
src/migrations/_archived/20260821_043007.json
Normal file
17726
src/migrations/_archived/20260821_043007.json
Normal file
File diff suppressed because it is too large
Load diff
18648
src/migrations/_archived/20260825_184347.json
Normal file
18648
src/migrations/_archived/20260825_184347.json
Normal file
File diff suppressed because it is too large
Load diff
510
src/migrations/_archived/20260825_184347.ts
Normal file
510
src/migrations/_archived/20260825_184347.ts
Normal file
|
|
@ -0,0 +1,510 @@
|
||||||
|
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
|
||||||
|
|
||||||
|
// Idempotent migration: safe to run on databases where push: true already applied
|
||||||
|
// the schema (dev), and on production databases where prior migrations already ran.
|
||||||
|
// Each DDL block is wrapped in exception handlers to skip already-existing objects.
|
||||||
|
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||||
|
// --- Enums ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TYPE "public"."enum_game_servers_status" AS ENUM('online', 'offline');
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TYPE "public"."enum_arma_commands_status" AS ENUM('queued', 'delivered', 'succeeded', 'failed');
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TYPE "public"."enum_roles_permissions" ADD VALUE 'campaigns:manage' BEFORE 'factions:create';
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Tables ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TABLE "profiles_progression_awards" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" integer NOT NULL,
|
||||||
|
"id" varchar PRIMARY KEY NOT NULL,
|
||||||
|
"award_id" integer NOT NULL,
|
||||||
|
"awarded_by_id" integer,
|
||||||
|
"awarded_at" timestamp(3) with time zone NOT NULL,
|
||||||
|
"award_reason" varchar
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TABLE "game_servers" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"server_id" varchar NOT NULL,
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"status" "enum_game_servers_status" DEFAULT 'offline' NOT NULL,
|
||||||
|
"last_seen_at" timestamp(3) with time zone,
|
||||||
|
"metadata" jsonb,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TABLE "arma_sync_events" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"event_id" varchar NOT NULL,
|
||||||
|
"server_id" integer NOT NULL,
|
||||||
|
"type" varchar NOT NULL,
|
||||||
|
"occurred_at" timestamp(3) with time zone NOT NULL,
|
||||||
|
"payload" jsonb NOT NULL,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TABLE "arma_commands" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"command_id" varchar NOT NULL,
|
||||||
|
"server_id" integer NOT NULL,
|
||||||
|
"type" varchar NOT NULL,
|
||||||
|
"payload" jsonb NOT NULL,
|
||||||
|
"status" "enum_arma_commands_status" DEFAULT 'queued' NOT NULL,
|
||||||
|
"result" jsonb,
|
||||||
|
"error" varchar,
|
||||||
|
"delivered_at" timestamp(3) with time zone,
|
||||||
|
"completed_at" timestamp(3) with time zone,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE TABLE "payload_mcp_api_keys" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"user_id" integer NOT NULL,
|
||||||
|
"label" varchar,
|
||||||
|
"description" varchar,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"enable_a_p_i_key" boolean,
|
||||||
|
"api_key" varchar,
|
||||||
|
"api_key_index" varchar
|
||||||
|
);
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Drop existing constraint/index/column (may already be dropped by prior migrations) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "profiles_rels" DROP CONSTRAINT IF EXISTS "profiles_rels_awards_fk";
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DROP INDEX IF EXISTS "profiles_rels_awards_id_idx";
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Columns ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "users" ADD COLUMN "preferences_display_xp_display_mini" boolean DEFAULT false;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "missions_mission_objectives" ADD COLUMN "redacted" boolean DEFAULT false;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "missions" ADD COLUMN "discord_attendance_sent_at" timestamp(3) with time zone;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "campaigns" ADD COLUMN "owner_id" integer;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "game_servers_id" integer;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "arma_sync_events_id" integer;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "arma_commands_id" integer;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "payload_mcp_api_keys_id" integer;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_preferences_rels" ADD COLUMN "payload_mcp_api_keys_id" integer;
|
||||||
|
EXCEPTION WHEN duplicate_column THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Foreign keys (profiles_progression_awards) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "profiles_progression_awards" ADD CONSTRAINT "profiles_progression_awards_award_id_awards_id_fk" FOREIGN KEY ("award_id") REFERENCES "public"."awards"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "profiles_progression_awards" ADD CONSTRAINT "profiles_progression_awards_awarded_by_id_profiles_id_fk" FOREIGN KEY ("awarded_by_id") REFERENCES "public"."profiles"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "profiles_progression_awards" ADD CONSTRAINT "profiles_progression_awards_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."profiles"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Foreign keys (arma tables) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "arma_sync_events" ADD CONSTRAINT "arma_sync_events_server_id_game_servers_id_fk" FOREIGN KEY ("server_id") REFERENCES "public"."game_servers"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "arma_commands" ADD CONSTRAINT "arma_commands_server_id_game_servers_id_fk" FOREIGN KEY ("server_id") REFERENCES "public"."game_servers"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_mcp_api_keys" ADD CONSTRAINT "payload_mcp_api_keys_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Indexes (profiles_progression_awards) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "profiles_progression_awards_order_idx" ON "profiles_progression_awards" USING btree ("_order");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "profiles_progression_awards_parent_id_idx" ON "profiles_progression_awards" USING btree ("_parent_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "profiles_progression_awards_award_idx" ON "profiles_progression_awards" USING btree ("award_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "profiles_progression_awards_awarded_by_idx" ON "profiles_progression_awards" USING btree ("awarded_by_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Indexes (game_servers) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE UNIQUE INDEX "game_servers_server_id_idx" ON "game_servers" USING btree ("server_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "game_servers_updated_at_idx" ON "game_servers" USING btree ("updated_at");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "game_servers_created_at_idx" ON "game_servers" USING btree ("created_at");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Indexes (arma_sync_events) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE UNIQUE INDEX "arma_sync_events_event_id_idx" ON "arma_sync_events" USING btree ("event_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "arma_sync_events_server_idx" ON "arma_sync_events" USING btree ("server_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "arma_sync_events_type_idx" ON "arma_sync_events" USING btree ("type");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "arma_sync_events_updated_at_idx" ON "arma_sync_events" USING btree ("updated_at");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "arma_sync_events_created_at_idx" ON "arma_sync_events" USING btree ("created_at");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Indexes (arma_commands) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE UNIQUE INDEX "arma_commands_command_id_idx" ON "arma_commands" USING btree ("command_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "arma_commands_server_idx" ON "arma_commands" USING btree ("server_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "arma_commands_updated_at_idx" ON "arma_commands" USING btree ("updated_at");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "arma_commands_created_at_idx" ON "arma_commands" USING btree ("created_at");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Indexes (payload_mcp_api_keys) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "payload_mcp_api_keys_user_idx" ON "payload_mcp_api_keys" USING btree ("user_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "payload_mcp_api_keys_updated_at_idx" ON "payload_mcp_api_keys" USING btree ("updated_at");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "payload_mcp_api_keys_created_at_idx" ON "payload_mcp_api_keys" USING btree ("created_at");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Foreign keys (campaigns) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "campaigns" ADD CONSTRAINT "campaigns_owner_id_users_id_fk" FOREIGN KEY ("owner_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Foreign keys (payload locked/preferences rels) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_game_servers_fk" FOREIGN KEY ("game_servers_id") REFERENCES "public"."game_servers"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_arma_sync_events_fk" FOREIGN KEY ("arma_sync_events_id") REFERENCES "public"."arma_sync_events"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_arma_commands_fk" FOREIGN KEY ("arma_commands_id") REFERENCES "public"."arma_commands"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_payload_mcp_api_keys_fk" FOREIGN KEY ("payload_mcp_api_keys_id") REFERENCES "public"."payload_mcp_api_keys"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
ALTER TABLE "payload_preferences_rels" ADD CONSTRAINT "payload_preferences_rels_payload_mcp_api_keys_fk" FOREIGN KEY ("payload_mcp_api_keys_id") REFERENCES "public"."payload_mcp_api_keys"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
EXCEPTION WHEN duplicate_object THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Remaining indexes ---
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "campaigns_owner_idx" ON "campaigns" USING btree ("owner_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "payload_locked_documents_rels_game_servers_id_idx" ON "payload_locked_documents_rels" USING btree ("game_servers_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "payload_locked_documents_rels_arma_sync_events_id_idx" ON "payload_locked_documents_rels" USING btree ("arma_sync_events_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "payload_locked_documents_rels_arma_commands_id_idx" ON "payload_locked_documents_rels" USING btree ("arma_commands_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "payload_locked_documents_rels_payload_mcp_api_keys_id_idx" ON "payload_locked_documents_rels" USING btree ("payload_mcp_api_keys_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
await db.execute(sql`
|
||||||
|
DO $$ BEGIN
|
||||||
|
CREATE INDEX "payload_preferences_rels_payload_mcp_api_keys_id_idx" ON "payload_preferences_rels" USING btree ("payload_mcp_api_keys_id");
|
||||||
|
EXCEPTION WHEN duplicate_table THEN null;
|
||||||
|
END $$;
|
||||||
|
`)
|
||||||
|
|
||||||
|
// --- Drop old column (may already be dropped by prior migrations) ---
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "profiles_rels" DROP COLUMN IF EXISTS "awards_id";
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "profiles_progression_awards" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "game_servers" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "arma_sync_events" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "arma_commands" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "payload_mcp_api_keys" DISABLE ROW LEVEL SECURITY;
|
||||||
|
DROP TABLE "profiles_progression_awards" CASCADE;
|
||||||
|
DROP TABLE "game_servers" CASCADE;
|
||||||
|
DROP TABLE "arma_sync_events" CASCADE;
|
||||||
|
DROP TABLE "arma_commands" CASCADE;
|
||||||
|
DROP TABLE "payload_mcp_api_keys" CASCADE;
|
||||||
|
ALTER TABLE "campaigns" DROP CONSTRAINT "campaigns_owner_id_users_id_fk";
|
||||||
|
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_game_servers_fk";
|
||||||
|
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_arma_sync_events_fk";
|
||||||
|
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_arma_commands_fk";
|
||||||
|
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_payload_mcp_api_keys_fk";
|
||||||
|
|
||||||
|
ALTER TABLE "payload_preferences_rels" DROP CONSTRAINT "payload_preferences_rels_payload_mcp_api_keys_fk";
|
||||||
|
|
||||||
|
ALTER TABLE "roles_permissions" ALTER COLUMN "value" SET DATA TYPE text;
|
||||||
|
DROP TYPE "public"."enum_roles_permissions";
|
||||||
|
CREATE TYPE "public"."enum_roles_permissions" AS ENUM('system:admin-access', 'users:create', 'users:read', 'users:update', 'users:delete', 'users:unlock', 'users:assign-roles', 'ranks:create', 'ranks:read', 'ranks:update', 'ranks:delete', 'profiles:create', 'profiles:read', 'profiles:update', 'profiles:delete', 'awards:create', 'awards:read', 'awards:update', 'awards:delete', 'qualifications:create', 'qualifications:read', 'qualifications:update', 'qualifications:delete', 'assignments:create', 'assignments:read', 'assignments:update', 'assignments:delete', 'experience:create', 'experience:read', 'experience:update', 'experience:delete', 'user-notifications:create', 'user-notifications:read', 'user-notifications:update', 'user-notifications:delete', 'missions:create', 'missions:read', 'missions:update', 'missions:delete', 'missions:read-sensitive', 'mission-attendances:create', 'mission-attendances:read', 'mission-attendances:update', 'mission-attendances:delete', 'campaigns:create', 'campaigns:read', 'campaigns:update', 'campaigns:delete', 'factions:create', 'factions:read', 'factions:update', 'factions:delete', 'technologies:create', 'technologies:read', 'technologies:update', 'technologies:delete', 'assets:create', 'assets:read', 'assets:update', 'assets:delete', 'resources:create', 'resources:read', 'resources:update', 'resources:delete', 'vehicles:create', 'vehicles:read', 'vehicles:update', 'vehicles:delete', 'structures:create', 'structures:read', 'structures:update', 'structures:delete', 'shipments:create', 'shipments:read', 'shipments:update', 'shipments:delete', 'bank-accounts:create', 'bank-accounts:read', 'bank-accounts:update', 'bank-accounts:delete', 'bank-transactions:create', 'bank-transactions:read', 'bank-transactions:update', 'bank-transactions:delete', 'ledger-entries:create', 'ledger-entries:read', 'ledger-entries:update', 'ledger-entries:delete', 'locker-storages:create', 'locker-storages:read', 'locker-storages:update', 'locker-storages:delete', 'game-structures:create', 'game-structures:read', 'game-structures:update', 'game-structures:delete', 'game-hard-resources:create', 'game-hard-resources:read', 'game-hard-resources:update', 'game-hard-resources:delete', 'game-event-logs:create', 'game-event-logs:read', 'game-event-logs:update', 'game-event-logs:delete', 'game-vehicles:create', 'game-vehicles:read', 'game-vehicles:update', 'game-vehicles:delete', 'game-npcs:create', 'game-npcs:read', 'game-npcs:update', 'game-npcs:delete', 'mission-files:create', 'mission-files:read', 'mission-files:update', 'mission-files:delete', 'mod-lists:create', 'mod-lists:read', 'mod-lists:update', 'mod-lists:delete', 'maps:create', 'maps:read', 'maps:update', 'maps:delete', 'narrative-events:create', 'narrative-events:read', 'narrative-events:update', 'narrative-events:delete', 'market-listings:create', 'market-listings:read', 'market-listings:update', 'market-listings:delete', 'market-negotiations:create', 'market-negotiations:read', 'market-negotiations:update', 'market-negotiations:delete', 'game-rules:create', 'game-rules:read', 'game-rules:update', 'game-rules:delete');
|
||||||
|
ALTER TABLE "roles_permissions" ALTER COLUMN "value" SET DATA TYPE "public"."enum_roles_permissions" USING "value"::"public"."enum_roles_permissions";
|
||||||
|
DROP INDEX "campaigns_owner_idx";
|
||||||
|
DROP INDEX "payload_locked_documents_rels_game_servers_id_idx";
|
||||||
|
DROP INDEX "payload_locked_documents_rels_arma_sync_events_id_idx";
|
||||||
|
DROP INDEX "payload_locked_documents_rels_arma_commands_id_idx";
|
||||||
|
DROP INDEX "payload_locked_documents_rels_payload_mcp_api_keys_id_idx";
|
||||||
|
DROP INDEX "payload_preferences_rels_payload_mcp_api_keys_id_idx";
|
||||||
|
ALTER TABLE "profiles_rels" ADD COLUMN "awards_id" integer;
|
||||||
|
ALTER TABLE "profiles_rels" ADD CONSTRAINT "profiles_rels_awards_fk" FOREIGN KEY ("awards_id") REFERENCES "public"."awards"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
CREATE INDEX "profiles_rels_awards_id_idx" ON "profiles_rels" USING btree ("awards_id");
|
||||||
|
ALTER TABLE "users" DROP COLUMN "preferences_display_xp_display_mini";
|
||||||
|
ALTER TABLE "missions_mission_objectives" DROP COLUMN "redacted";
|
||||||
|
ALTER TABLE "missions" DROP COLUMN "discord_attendance_sent_at";
|
||||||
|
ALTER TABLE "campaigns" DROP COLUMN "owner_id";
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "game_servers_id";
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "arma_sync_events_id";
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "arma_commands_id";
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "payload_mcp_api_keys_id";
|
||||||
|
ALTER TABLE "payload_preferences_rels" DROP COLUMN "payload_mcp_api_keys_id";
|
||||||
|
DROP TYPE "public"."enum_game_servers_status";
|
||||||
|
DROP TYPE "public"."enum_arma_commands_status";`)
|
||||||
|
}
|
||||||
19001
src/migrations/_staged/20260825_201135.json
Normal file
19001
src/migrations/_staged/20260825_201135.json
Normal file
File diff suppressed because it is too large
Load diff
2314
src/migrations/_staged/20260825_201135.ts
Normal file
2314
src/migrations/_staged/20260825_201135.ts
Normal file
File diff suppressed because it is too large
Load diff
19001
src/migrations/_staged/20260825_201536.json
Normal file
19001
src/migrations/_staged/20260825_201536.json
Normal file
File diff suppressed because it is too large
Load diff
2314
src/migrations/_staged/20260825_201536.ts
Normal file
2314
src/migrations/_staged/20260825_201536.ts
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,28 +1,21 @@
|
||||||
import * as migration_20260818_024510 from './_archived/20260818_024510';
|
import * as migration_20260820_004157 from "./20260820_004157";
|
||||||
import * as migration_20260820_004157 from './20260820_004157';
|
import * as migration_20260825_220000 from "./20260825_220000";
|
||||||
import * as migration_20260821_043007 from './20260821_043007';
|
import * as migration_20260826_050000_repair_shims_auxiliary_tables from "./20260826_050000_repair_shims_auxiliary_tables";
|
||||||
import * as migration_20260821_060000 from './20260821_060000';
|
|
||||||
import * as migration_20260821_120000 from './20260821_120000';
|
|
||||||
|
|
||||||
export const migrations = [
|
export const migrations = [
|
||||||
{
|
{
|
||||||
up: migration_20260820_004157.up,
|
up: migration_20260820_004157.up,
|
||||||
down: migration_20260820_004157.down,
|
down: migration_20260820_004157.down,
|
||||||
name: '20260820_004157',
|
name: "20260820_004157",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
up: migration_20260821_043007.up,
|
up: migration_20260825_220000.up,
|
||||||
down: migration_20260821_043007.down,
|
down: migration_20260825_220000.down,
|
||||||
name: '20260821_043007'
|
name: "20260825_220000",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
up: migration_20260821_060000.up,
|
up: migration_20260826_050000_repair_shims_auxiliary_tables.up,
|
||||||
down: migration_20260821_060000.down,
|
down: migration_20260826_050000_repair_shims_auxiliary_tables.down,
|
||||||
name: '20260821_060000'
|
name: "20260826_050000_repair_shims_auxiliary_tables",
|
||||||
},
|
|
||||||
{
|
|
||||||
up: migration_20260821_120000.up,
|
|
||||||
down: migration_20260821_120000.down,
|
|
||||||
name: '20260821_120000'
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,8 @@ export default buildConfig({
|
||||||
pool: {
|
pool: {
|
||||||
connectionString: process.env.DATABASE_URI || "",
|
connectionString: process.env.DATABASE_URI || "",
|
||||||
},
|
},
|
||||||
push: process.env.NODE_ENV === "development",
|
// push: process.env.NODE_ENV === "development",
|
||||||
|
push: false,
|
||||||
prodMigrations: migrations,
|
prodMigrations: migrations,
|
||||||
}),
|
}),
|
||||||
sharp,
|
sharp,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue