-- ============================================================================= -- Politische Amtsvorteile (falukant_predefine.political_office_benefit) -- ============================================================================= -- -- Fehler „SQL Error [08003]: This connection has been closed“ -- ----------------------------------------------------------- -- Das ist meist KEIN Inhaltfehler dieses Skripts, sondern: -- 1) Eine VORHERIGE Anweisung in derselben Session ist fehlgeschlagen → die -- Transaktion ist abgebrochen; der Client meldet dann oft nur noch 08003. -- → Neue Verbindung öffnen, ggf. ROLLBACK; dann erneut ausführen. -- 2) Fehler 23502: political_office_id NOT NULL, aber INSERT nutzt nur office_type_id -- (beide Spalten nach Sync) → dieses Skript gleicht das Schema zuerst an. -- 3) Spalte office_type_id fehlt komplett → Migration 20260401120000 ausführen. -- 4) PgBouncer (Pool) im Transaction-Modus: lange Skripte mit vielen -- Statements trennen die Verbindung → einzelne Blöcke nacheinander -- ausführen oder Datei falukant_political_office_benefits_steps.sql nutzen. -- 5) Netzwerk / Server-Neustart / Idle-Timeout. -- -- Empfehlung: Im Terminal mit psql und ON_ERROR_STOP (bricht beim ersten Fehler -- sauber ab und zeigt die echte Meldung): -- psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f backend/sql/falukant_political_office_benefits.sql -- -- JSON value daily_salary: -- • dailyAmount: fester Tagesbetrag (überschreibt alles) -- • rank: optional feste Stufe in JSON (überschreibt DB-Stufe) -- • Standard: salaryStart × salaryGrowth^(Stufe−1); Stufe = hierarchy_level (s. Migration political-office-hierarchy-level) -- • Optional: salaryStart, salaryGrowth pro Amt; ENV POLITICAL_DAILY_SALARY_START / POLITICAL_DAILY_SALARY_GROWTH -- • Legacy linear: salaryFormula = 'linear' und base, perRank -- JSON value tax_exemption: -- • regions: Text-Array (z. B. "city") oder "*" für alle Ebenen -- ============================================================================= DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'falukant_predefine' AND table_name = 'political_office_benefit' ) THEN RAISE EXCEPTION 'Tabelle falukant_predefine.political_office_benefit fehlt.'; END IF; -- Legacy: nur political_office_id (speichert fälschlich die office_type_id) IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'falukant_predefine' AND table_name = 'political_office_benefit' AND column_name = 'political_office_id' ) AND NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'falukant_predefine' AND table_name = 'political_office_benefit' AND column_name = 'office_type_id' ) THEN ALTER TABLE falukant_predefine.political_office_benefit RENAME COLUMN political_office_id TO office_type_id; END IF; -- Doppel-Spalten nach Sequelize: office_type_id wird befüllt, political_office_id bleibt NULL → 23502 IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'falukant_predefine' AND table_name = 'political_office_benefit' AND column_name = 'political_office_id' ) AND EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'falukant_predefine' AND table_name = 'political_office_benefit' AND column_name = 'office_type_id' ) THEN UPDATE falukant_predefine.political_office_benefit SET office_type_id = COALESCE(office_type_id, political_office_id); ALTER TABLE falukant_predefine.political_office_benefit DROP COLUMN political_office_id; END IF; IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_schema = 'falukant_predefine' AND table_name = 'political_office_benefit' AND column_name = 'office_type_id' ) THEN RAISE EXCEPTION 'Spalte office_type_id fehlt. Migration 20260401120000-politics-benefits-and-daily-salary.cjs ausführen.'; END IF; END $$; -- Benefit-Typen (falls noch nicht aus App-Init vorhanden) INSERT INTO falukant_type.political_office_benefit_type (tr) SELECT 'tax_exemption' WHERE NOT EXISTS ( SELECT 1 FROM falukant_type.political_office_benefit_type t WHERE t.tr = 'tax_exemption' ); INSERT INTO falukant_type.political_office_benefit_type (tr) SELECT 'daily_salary' WHERE NOT EXISTS ( SELECT 1 FROM falukant_type.political_office_benefit_type t WHERE t.tr = 'daily_salary' ); -- Steuerbefreiungen (wie POLITICAL_TAX_EXEMPTIONS im Backend) INSERT INTO falukant_predefine.political_office_benefit (office_type_id, benefit_type_id, value) SELECT ot.id, bt.id, '{"regions":["city"]}'::jsonb FROM falukant_type.political_office_type ot JOIN falukant_type.political_office_benefit_type bt ON bt.tr = 'tax_exemption' WHERE ot.name = 'council' AND NOT EXISTS ( SELECT 1 FROM falukant_predefine.political_office_benefit x WHERE x.office_type_id = ot.id AND x.benefit_type_id = bt.id ); INSERT INTO falukant_predefine.political_office_benefit (office_type_id, benefit_type_id, value) SELECT ot.id, bt.id, '{"regions":["city","county"]}'::jsonb FROM falukant_type.political_office_type ot JOIN falukant_type.political_office_benefit_type bt ON bt.tr = 'tax_exemption' WHERE ot.name = 'taxman' AND NOT EXISTS ( SELECT 1 FROM falukant_predefine.political_office_benefit x WHERE x.office_type_id = ot.id AND x.benefit_type_id = bt.id ); INSERT INTO falukant_predefine.political_office_benefit (office_type_id, benefit_type_id, value) SELECT ot.id, bt.id, '{"regions":["city","county","shire"]}'::jsonb FROM falukant_type.political_office_type ot JOIN falukant_type.political_office_benefit_type bt ON bt.tr = 'tax_exemption' WHERE ot.name = 'treasurer' AND NOT EXISTS ( SELECT 1 FROM falukant_predefine.political_office_benefit x WHERE x.office_type_id = ot.id AND x.benefit_type_id = bt.id ); INSERT INTO falukant_predefine.political_office_benefit (office_type_id, benefit_type_id, value) SELECT ot.id, bt.id, '{"regions":["city","county","shire","markgrave","duchy"]}'::jsonb FROM falukant_type.political_office_type ot JOIN falukant_type.political_office_benefit_type bt ON bt.tr = 'tax_exemption' WHERE ot.name = 'super-state-administrator' AND NOT EXISTS ( SELECT 1 FROM falukant_predefine.political_office_benefit x WHERE x.office_type_id = ot.id AND x.benefit_type_id = bt.id ); INSERT INTO falukant_predefine.political_office_benefit (office_type_id, benefit_type_id, value) SELECT ot.id, bt.id, '{"regions":["*"]}'::jsonb FROM falukant_type.political_office_type ot JOIN falukant_type.political_office_benefit_type bt ON bt.tr = 'tax_exemption' WHERE ot.name = 'chancellor' AND NOT EXISTS ( SELECT 1 FROM falukant_predefine.political_office_benefit x WHERE x.office_type_id = ot.id AND x.benefit_type_id = bt.id ); -- Tageslohn: Betrag aus App-Formel (exponentiell nach hierarchy_level); value leer = Defaults INSERT INTO falukant_predefine.political_office_benefit (office_type_id, benefit_type_id, value) SELECT ot.id, bt.id, '{}'::jsonb FROM falukant_type.political_office_type ot JOIN falukant_type.political_office_benefit_type bt ON bt.tr = 'daily_salary' WHERE ot.name IN ( 'assessor', 'councillor', 'council', 'beadle', 'town-clerk', 'mayor', 'master-builder', 'village-major', 'judge', 'bailif', 'taxman', 'sheriff', 'consultant', 'treasurer', 'hangman', 'territorial-council', 'territorial-council-speaker', 'ruler-consultant', 'state-administrator', 'super-state-administrator', 'governor', 'ministry-helper', 'minister', 'chancellor' ) AND NOT EXISTS ( SELECT 1 FROM falukant_predefine.political_office_benefit x WHERE x.office_type_id = ot.id AND x.benefit_type_id = bt.id );