chore: add jobs, backups, and migration history

Jobs:
- Add consentRetentionJob.ts for GDPR consent cleanup
- Add scheduler.ts for background job scheduling

Backups:
- Add database backup files for recovery

Migration backups:
- Archive old migration files for reference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2025-12-01 08:24:26 +00:00
parent eac43f9846
commit d18e58de40
27 changed files with 74929 additions and 0 deletions

File diff suppressed because it is too large Load diff

288
backups/data_cleaned.sql Normal file
View file

@ -0,0 +1,288 @@
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LC_CTYPE = (unset),
LC_NUMERIC = (unset),
LC_COLLATE = (unset),
LC_TIME = (unset),
LC_MESSAGES = (unset),
LC_MONETARY = (unset),
LC_ADDRESS = (unset),
LC_IDENTIFICATION = (unset),
LC_MEASUREMENT = (unset),
LC_PAPER = (unset),
LC_TELEPHONE = (unset),
LC_NAME = (unset),
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
--
-- PostgreSQL database dump
--
-- Dumped from database version 17.6 (Debian 17.6-0+deb13u1)
-- Dumped by pg_dump version 17.6 (Debian 17.6-0+deb13u1)
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
--
-- Data for Name: tenants; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.tenants (id, name, slug, updated_at, created_at) VALUES (1, 'porwoll.de', 'porwoll', '2025-11-26 20:33:47.509+00', '2025-11-26 20:33:47.508+00');
INSERT INTO public.tenants (id, name, slug, updated_at, created_at) VALUES (5, 'gunshin.de', 'gunshin', '2025-11-26 20:52:12.512+00', '2025-11-26 20:48:19.022+00');
INSERT INTO public.tenants (id, name, slug, updated_at, created_at) VALUES (4, 'complexcaresolutions.de', 'c2s', '2025-11-26 20:52:27.533+00', '2025-11-26 20:44:51.215+00');
INSERT INTO public.tenants (id, name, slug, updated_at, created_at) VALUES (6, 'zweitmein.ng', 'zweitmeinung', '2025-11-26 22:10:55.937+00', '2025-11-26 22:08:11.071+00');
--
-- Data for Name: categories; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.categories (id, tenant_id, name, slug, description, updated_at, created_at) VALUES (1, 1, 'Whistleblowing', 'whistleblowing', 'Artikel zum Thema Whistleblowing und Zytoskandal', '2025-11-27 10:01:53.601+00', '2025-11-27 10:01:53.601+00');
INSERT INTO public.categories (id, tenant_id, name, slug, description, updated_at, created_at) VALUES (2, 1, 'Unternehmer', 'unternehmer', 'Artikel über unternehmerische Aktivitäten', '2025-11-27 10:02:09.569+00', '2025-11-27 10:02:09.569+00');
--
-- Data for Name: cookie_configurations; Type: TABLE DATA; Schema: public; Owner: payload
--
--
-- Data for Name: cookie_configurations_enabled_categories; Type: TABLE DATA; Schema: public; Owner: payload
--
--
-- Data for Name: cookie_inventory; Type: TABLE DATA; Schema: public; Owner: payload
--
--
-- Data for Name: media; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (1, 'Favicon Porwoll', '2025-11-27 09:58:48.629+00', '2025-11-27 09:58:48.629+00', NULL, NULL, 'Favicon-270x270.jpg', 'image/jpeg', 12068, 270, 270, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (2, 'gunshin Holding UG Logo', '2025-11-27 10:20:21.25+00', '2025-11-27 10:20:21.25+00', NULL, NULL, 'gunshin-logo-1168x487-1.webp', 'image/webp', 29586, 1168, 487, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (3, 'Martin Porwoll - Portrait', '2025-11-27 10:20:55.311+00', '2025-11-27 10:20:55.311+00', NULL, NULL, 'martin-porwoll-frontal-1-1168x768-1.jpeg', 'image/jpeg', 40379, 714, 768, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (4, 'Martin Porwoll - Portrait', '2025-11-27 10:21:07.637+00', '2025-11-27 10:21:07.637+00', NULL, NULL, 'martin-porwoll-frontal-1-1168x768-1.webp', 'image/webp', 5650, 714, 768, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (5, 'Abstrakte Darstellung von Vision und Innovation', '2025-11-27 10:22:04.816+00', '2025-11-27 10:22:04.816+00', NULL, NULL, 'adobestock-432768272kopie-2576x2050-1-scaled.webp', 'image/webp', 95954, 2560, 2037, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (6, 'Team-Erfolg und Zusammenarbeit', '2025-11-27 10:24:47.406+00', '2025-11-27 10:24:47.406+00', NULL, NULL, 'Erfolg_und_Zusammenarbeit.webp', 'image/webp', 133848, 2560, 1706, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (7, 'porwoll.de Favicon', '2025-11-27 12:44:07.743+00', '2025-11-27 12:44:07.743+00', NULL, NULL, 'favicon.jpg', 'image/jpeg', 12068, 270, 270, 50, 50, 1);
--
-- Data for Name: navigation; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.navigation (id, updated_at, created_at) VALUES (1, '2025-11-27 12:46:01.591+00', '2025-11-27 12:46:01.591+00');
--
-- Data for Name: navigation_footer_menu; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.navigation_footer_menu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (1, 1, '69284809b6871dae2fda6e82', 'Impressum', 'page', 9, NULL);
INSERT INTO public.navigation_footer_menu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (2, 1, '69284809b6871dae2fda6e83', 'Datenschutzerklärung', 'page', 10, NULL);
--
-- Data for Name: navigation_main_menu; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.navigation_main_menu (_order, _parent_id, id, label, type, page_id, url, open_in_new_tab) VALUES (1, 1, '69284809b6871dae2fda6e7c', 'Whistleblowing', 'submenu', NULL, NULL, false);
INSERT INTO public.navigation_main_menu (_order, _parent_id, id, label, type, page_id, url, open_in_new_tab) VALUES (2, 1, '69284809b6871dae2fda6e7f', 'Unternehmer', 'submenu', NULL, NULL, false);
INSERT INTO public.navigation_main_menu (_order, _parent_id, id, label, type, page_id, url, open_in_new_tab) VALUES (3, 1, '69284809b6871dae2fda6e80', 'Mensch', 'page', 2, NULL, false);
INSERT INTO public.navigation_main_menu (_order, _parent_id, id, label, type, page_id, url, open_in_new_tab) VALUES (4, 1, '69284809b6871dae2fda6e81', 'Kontakt', 'page', 3, NULL, false);
--
-- Data for Name: navigation_main_menu_submenu; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.navigation_main_menu_submenu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (1, '69284809b6871dae2fda6e7c', '69284809b6871dae2fda6e7a', 'Zytoskandal', 'page', 5, NULL);
INSERT INTO public.navigation_main_menu_submenu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (2, '69284809b6871dae2fda6e7c', '69284809b6871dae2fda6e7b', 'Whistleblowing', 'page', 4, NULL);
INSERT INTO public.navigation_main_menu_submenu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (1, '69284809b6871dae2fda6e7f', '69284809b6871dae2fda6e7d', 'gunshin Holding UG', 'page', 6, NULL);
INSERT INTO public.navigation_main_menu_submenu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (2, '69284809b6871dae2fda6e7f', '69284809b6871dae2fda6e7e', 'complex care solutions GmbH', 'page', 7, NULL);
--
-- Data for Name: payload_migrations; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (1, '20251126_163428', 1, '2025-11-26 16:34:42.547+00', '2025-11-26 16:34:42.546+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (2, '20251126_200521', 2, '2025-11-26 20:05:36.195+00', '2025-11-26 20:05:36.194+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (3, '20251127_081206', 3, '2025-11-27 08:12:14.944+00', '2025-11-27 08:12:14.943+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (4, '20251127_085124', 4, '2025-11-27 08:51:33.23+00', '2025-11-27 08:51:33.229+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (6, '20251127_224713', 5, '2025-11-27 22:49:33.705+00', '2025-11-27 22:49:33.704+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (7, '20251128_142608', 6, '2025-11-28 14:28:27.621+00', '2025-11-28 14:28:27.62+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (5, 'dev', -1, '2025-11-28 14:36:30.472+00', '2025-11-27 12:44:07.275+00');
--
-- Data for Name: privacy_policy_settings; Type: TABLE DATA; Schema: public; Owner: payload
--
--
-- Data for Name: site_settings; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.site_settings (id, site_name, site_tagline, logo_id, favicon_id, contact_email, contact_phone, contact_address, footer_copyright_text, footer_show_social_links, seo_default_meta_title, seo_default_meta_description, seo_default_og_image_id, updated_at, created_at) VALUES (1, 'porwoll.de', 'Die Webseite von Martin Porwoll', NULL, 1, 'info@porwoll.de', '0800 80 44 100', 'Hans-Böckler-Str. 19
46236 Bottrop', 'Martin Porwoll', true, 'porwoll.de | Die Webseite von Martin Porwoll', 'Martin Porwoll - Whistleblower, Unternehmer, Mensch. Engagiert für Patientenwohl und Transparenz im Gesundheitswesen.', NULL, '2025-11-27 12:44:07.394+00', '2025-11-27 09:56:52.613+00');
--
-- Data for Name: social_links; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (1, 1, 'facebook', 'https://www.facebook.com/martinporwoll', true, '2025-11-27 09:59:41.9+00', '2025-11-27 09:59:41.9+00');
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (2, 1, 'instagram', 'https://www.instagram.com/martinporwoll', true, '2025-11-27 10:00:16.947+00', '2025-11-27 10:00:16.947+00');
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (3, 1, 'youtube', 'https://www.youtube.com/@martinporwoll', true, '2025-11-27 10:00:29.623+00', '2025-11-27 10:00:29.623+00');
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (4, 1, 'linkedin', 'https://www.linkedin.com/in/martinporwoll', true, '2025-11-27 10:00:41.713+00', '2025-11-27 10:00:41.713+00');
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (5, 1, 'x', 'https://x.com/martinporwoll', true, '2025-11-27 12:44:07.422+00', '2025-11-27 12:44:07.422+00');
--
-- Data for Name: tenants_domains; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (1, 1, '692763ff981e6105458e2df7', 'porwoll.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (2, 1, '69276406981e6105458e2df8', 'www.porwoll.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (1, 5, '6927676fd263874f0453e3e6', 'gunshin.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (2, 5, '69276776d263874f0453e3e7', 'www.gunshin.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (1, 4, '69276697de1f95ad5e22dfb1', 'complexcaresolutions.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (2, 4, '692766a1de1f95ad5e22dfb2', 'www.complexcaresolutions.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (1, 6, '69277ac36e43b25d0271266f', 'zweitmeinu.ng');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (2, 6, '69277ad26e43b25d02712670', 'www.zweitmeinu.ng');
--
-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.users (id, updated_at, created_at, email, reset_password_token, reset_password_expiration, salt, hash, login_attempts, lock_until) VALUES (1, '2025-11-26 16:40:22.979+00', '2025-11-26 16:40:22.978+00', 'martin.porwoll@complexcaresolutions.de', NULL, NULL, '44198dfdd90fadbff9a9e16caa36b43b051199ad213c7569ec15ec5ede60fbe4', '8acc6fb009b517a1427ff1e0f279dec5beabd349f18a61498244c9f74c2d240ebfb297abfa0296fa0c2962123c61eb47e0aaee3d1dc454f24c73c4e4b50a4f335e997e14848ee00f6c32a88d5e413dca1be5159dfad07b3b4f7579031ac814df274eda55fc037ffe659dee591f9f0c3a50a37e7eba69d6e20618094a46df3ac2b8c94701fab5834f5483f63af1390b7c54c6b6757edbc7e253e838f9c7e5e32415e7d38e5048f8b023894d027acfd1b8fddbc849ebf397336b029c00c11e69cc3dcba29888b083a25bdab24716a5132198ea97359e2c7054efa2f342814365e2dcbaf84c46a6bfc7e56557d16c38417f97ff14ea4e64037c5a5e4898aec64ea427f61a072ea34ed24ba863049a2b9918d330b0574c9294c269132e91841177c109c0bdc8e25d7d59d769af398c84b08e2c3c31c6cb3f8b108b7d70c94b62cf021f389dafc321e2167bb5553249fd64e3e980874fff9de9f6c2753090054edd515d1c39106fb7c27ceba255f37aab44f00ec1db22425d2fe84f1728358266b7ef19454bc021cf9f7c09b105debecc57c1c4b2a9e90fd4ced6320e2e9886252d5e00ef99ca158a79dd28b4edcb59c72b5d2475d91e5985be8d8277e541ba17a4524890c8544e75d1f30cbb5f4f87c2204b68862d9a98cad93f134c82b42d03bb9c5fb952c7d579fa2fe3c5a009bd7cbfc84f834ccf9b8e91e4afe7af4691d01e8b', 0, NULL);
--
-- Data for Name: users_sessions; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.users_sessions (_order, _parent_id, id, created_at, expires_at) VALUES (1, 1, '21fc0ad0-a771-4714-b5bb-3f341462d4b7', '2025-11-29 13:33:39.705+00', '2025-11-29 15:33:39.705+00');
--
-- Data for Name: users_tenants; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.users_tenants (_order, _parent_id, id, tenant_id) VALUES (1, 1, '1', 1);
INSERT INTO public.users_tenants (_order, _parent_id, id, tenant_id) VALUES (2, 1, '2', 4);
INSERT INTO public.users_tenants (_order, _parent_id, id, tenant_id) VALUES (3, 1, '3', 5);
INSERT INTO public.users_tenants (_order, _parent_id, id, tenant_id) VALUES (4, 1, '4', 6);
--
-- Name: categories_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.categories_id_seq', 2, true);
--
-- Name: cookie_configurations_enabled_categories_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.cookie_configurations_enabled_categories_id_seq', 1, false);
--
-- Name: cookie_configurations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.cookie_configurations_id_seq', 1, false);
--
-- Name: cookie_inventory_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.cookie_inventory_id_seq', 1, false);
--
-- Name: media_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.media_id_seq', 7, true);
--
-- Name: navigation_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.navigation_id_seq', 1, true);
--
-- Name: payload_migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.payload_migrations_id_seq', 7, true);
--
-- Name: privacy_policy_settings_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.privacy_policy_settings_id_seq', 1, false);
--
-- Name: site_settings_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.site_settings_id_seq', 1, true);
--
-- Name: social_links_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.social_links_id_seq', 5, true);
--
-- Name: tenants_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.tenants_id_seq', 6, true);
--
-- Name: users_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.users_id_seq', 1, true);
--
-- PostgreSQL database dump complete
--

View file

@ -0,0 +1,290 @@
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LC_CTYPE = (unset),
LC_NUMERIC = (unset),
LC_COLLATE = (unset),
LC_TIME = (unset),
LC_MESSAGES = (unset),
LC_MONETARY = (unset),
LC_ADDRESS = (unset),
LC_IDENTIFICATION = (unset),
LC_MEASUREMENT = (unset),
LC_PAPER = (unset),
LC_TELEPHONE = (unset),
LC_NAME = (unset),
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
--
-- PostgreSQL database dump
--
\restrict V03RmUkem2ZWgC8DLBrXZhXphPc93B8jja6lVqjTshfVYvh9EHYuLFUSNnmU7Ip
-- Dumped from database version 17.6 (Debian 17.6-0+deb13u1)
-- Dumped by pg_dump version 17.6 (Debian 17.6-0+deb13u1)
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
--
-- Data for Name: tenants; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.tenants (id, name, slug, updated_at, created_at) VALUES (1, 'porwoll.de', 'porwoll', '2025-11-26 20:33:47.509+00', '2025-11-26 20:33:47.508+00');
INSERT INTO public.tenants (id, name, slug, updated_at, created_at) VALUES (5, 'gunshin.de', 'gunshin', '2025-11-26 20:52:12.512+00', '2025-11-26 20:48:19.022+00');
INSERT INTO public.tenants (id, name, slug, updated_at, created_at) VALUES (4, 'complexcaresolutions.de', 'c2s', '2025-11-26 20:52:27.533+00', '2025-11-26 20:44:51.215+00');
INSERT INTO public.tenants (id, name, slug, updated_at, created_at) VALUES (6, 'zweitmein.ng', 'zweitmeinung', '2025-11-26 22:10:55.937+00', '2025-11-26 22:08:11.071+00');
--
-- Data for Name: categories; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.categories (id, tenant_id, name, slug, description, updated_at, created_at) VALUES (1, 1, 'Whistleblowing', 'whistleblowing', 'Artikel zum Thema Whistleblowing und Zytoskandal', '2025-11-27 10:01:53.601+00', '2025-11-27 10:01:53.601+00');
INSERT INTO public.categories (id, tenant_id, name, slug, description, updated_at, created_at) VALUES (2, 1, 'Unternehmer', 'unternehmer', 'Artikel über unternehmerische Aktivitäten', '2025-11-27 10:02:09.569+00', '2025-11-27 10:02:09.569+00');
--
-- Data for Name: cookie_configurations; Type: TABLE DATA; Schema: public; Owner: payload
--
--
-- Data for Name: cookie_configurations_enabled_categories; Type: TABLE DATA; Schema: public; Owner: payload
--
--
-- Data for Name: cookie_inventory; Type: TABLE DATA; Schema: public; Owner: payload
--
--
-- Data for Name: media; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (1, 'Favicon Porwoll', '2025-11-27 09:58:48.629+00', '2025-11-27 09:58:48.629+00', NULL, NULL, 'Favicon-270x270.jpg', 'image/jpeg', 12068, 270, 270, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (2, 'gunshin Holding UG Logo', '2025-11-27 10:20:21.25+00', '2025-11-27 10:20:21.25+00', NULL, NULL, 'gunshin-logo-1168x487-1.webp', 'image/webp', 29586, 1168, 487, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (3, 'Martin Porwoll - Portrait', '2025-11-27 10:20:55.311+00', '2025-11-27 10:20:55.311+00', NULL, NULL, 'martin-porwoll-frontal-1-1168x768-1.jpeg', 'image/jpeg', 40379, 714, 768, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (4, 'Martin Porwoll - Portrait', '2025-11-27 10:21:07.637+00', '2025-11-27 10:21:07.637+00', NULL, NULL, 'martin-porwoll-frontal-1-1168x768-1.webp', 'image/webp', 5650, 714, 768, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (5, 'Abstrakte Darstellung von Vision und Innovation', '2025-11-27 10:22:04.816+00', '2025-11-27 10:22:04.816+00', NULL, NULL, 'adobestock-432768272kopie-2576x2050-1-scaled.webp', 'image/webp', 95954, 2560, 2037, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (6, 'Team-Erfolg und Zusammenarbeit', '2025-11-27 10:24:47.406+00', '2025-11-27 10:24:47.406+00', NULL, NULL, 'Erfolg_und_Zusammenarbeit.webp', 'image/webp', 133848, 2560, 1706, 50, 50, 1);
INSERT INTO public.media (id, alt, updated_at, created_at, url, thumbnail_u_r_l, filename, mime_type, filesize, width, height, focal_x, focal_y, tenant_id) VALUES (7, 'porwoll.de Favicon', '2025-11-27 12:44:07.743+00', '2025-11-27 12:44:07.743+00', NULL, NULL, 'favicon.jpg', 'image/jpeg', 12068, 270, 270, 50, 50, 1);
--
-- Data for Name: navigation; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.navigation (id, updated_at, created_at) VALUES (1, '2025-11-27 12:46:01.591+00', '2025-11-27 12:46:01.591+00');
--
-- Data for Name: navigation_footer_menu; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.navigation_footer_menu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (1, 1, '69284809b6871dae2fda6e82', 'Impressum', 'page', 9, NULL);
INSERT INTO public.navigation_footer_menu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (2, 1, '69284809b6871dae2fda6e83', 'Datenschutzerklärung', 'page', 10, NULL);
--
-- Data for Name: navigation_main_menu; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.navigation_main_menu (_order, _parent_id, id, label, type, page_id, url, open_in_new_tab) VALUES (1, 1, '69284809b6871dae2fda6e7c', 'Whistleblowing', 'submenu', NULL, NULL, false);
INSERT INTO public.navigation_main_menu (_order, _parent_id, id, label, type, page_id, url, open_in_new_tab) VALUES (2, 1, '69284809b6871dae2fda6e7f', 'Unternehmer', 'submenu', NULL, NULL, false);
INSERT INTO public.navigation_main_menu (_order, _parent_id, id, label, type, page_id, url, open_in_new_tab) VALUES (3, 1, '69284809b6871dae2fda6e80', 'Mensch', 'page', 2, NULL, false);
INSERT INTO public.navigation_main_menu (_order, _parent_id, id, label, type, page_id, url, open_in_new_tab) VALUES (4, 1, '69284809b6871dae2fda6e81', 'Kontakt', 'page', 3, NULL, false);
--
-- Data for Name: navigation_main_menu_submenu; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.navigation_main_menu_submenu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (1, '69284809b6871dae2fda6e7c', '69284809b6871dae2fda6e7a', 'Zytoskandal', 'page', 5, NULL);
INSERT INTO public.navigation_main_menu_submenu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (2, '69284809b6871dae2fda6e7c', '69284809b6871dae2fda6e7b', 'Whistleblowing', 'page', 4, NULL);
INSERT INTO public.navigation_main_menu_submenu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (1, '69284809b6871dae2fda6e7f', '69284809b6871dae2fda6e7d', 'gunshin Holding UG', 'page', 6, NULL);
INSERT INTO public.navigation_main_menu_submenu (_order, _parent_id, id, label, link_type, page_id, url) VALUES (2, '69284809b6871dae2fda6e7f', '69284809b6871dae2fda6e7e', 'complex care solutions GmbH', 'page', 7, NULL);
--
-- Data for Name: payload_migrations; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (1, '20251126_163428', 1, '2025-11-26 16:34:42.547+00', '2025-11-26 16:34:42.546+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (2, '20251126_200521', 2, '2025-11-26 20:05:36.195+00', '2025-11-26 20:05:36.194+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (3, '20251127_081206', 3, '2025-11-27 08:12:14.944+00', '2025-11-27 08:12:14.943+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (4, '20251127_085124', 4, '2025-11-27 08:51:33.23+00', '2025-11-27 08:51:33.229+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (6, '20251127_224713', 5, '2025-11-27 22:49:33.705+00', '2025-11-27 22:49:33.704+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (7, '20251128_142608', 6, '2025-11-28 14:28:27.621+00', '2025-11-28 14:28:27.62+00');
INSERT INTO public.payload_migrations (id, name, batch, updated_at, created_at) VALUES (5, 'dev', -1, '2025-11-28 14:36:30.472+00', '2025-11-27 12:44:07.275+00');
--
-- Data for Name: privacy_policy_settings; Type: TABLE DATA; Schema: public; Owner: payload
--
--
-- Data for Name: site_settings; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.site_settings (id, site_name, site_tagline, logo_id, favicon_id, contact_email, contact_phone, contact_address, footer_copyright_text, footer_show_social_links, seo_default_meta_title, seo_default_meta_description, seo_default_og_image_id, updated_at, created_at) VALUES (1, 'porwoll.de', 'Die Webseite von Martin Porwoll', NULL, 1, 'info@porwoll.de', '0800 80 44 100', 'Hans-Böckler-Str. 19
46236 Bottrop', 'Martin Porwoll', true, 'porwoll.de | Die Webseite von Martin Porwoll', 'Martin Porwoll - Whistleblower, Unternehmer, Mensch. Engagiert für Patientenwohl und Transparenz im Gesundheitswesen.', NULL, '2025-11-27 12:44:07.394+00', '2025-11-27 09:56:52.613+00');
--
-- Data for Name: social_links; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (1, 1, 'facebook', 'https://www.facebook.com/martinporwoll', true, '2025-11-27 09:59:41.9+00', '2025-11-27 09:59:41.9+00');
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (2, 1, 'instagram', 'https://www.instagram.com/martinporwoll', true, '2025-11-27 10:00:16.947+00', '2025-11-27 10:00:16.947+00');
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (3, 1, 'youtube', 'https://www.youtube.com/@martinporwoll', true, '2025-11-27 10:00:29.623+00', '2025-11-27 10:00:29.623+00');
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (4, 1, 'linkedin', 'https://www.linkedin.com/in/martinporwoll', true, '2025-11-27 10:00:41.713+00', '2025-11-27 10:00:41.713+00');
INSERT INTO public.social_links (id, tenant_id, platform, url, is_active, updated_at, created_at) VALUES (5, 1, 'x', 'https://x.com/martinporwoll', true, '2025-11-27 12:44:07.422+00', '2025-11-27 12:44:07.422+00');
--
-- Data for Name: tenants_domains; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (1, 1, '692763ff981e6105458e2df7', 'porwoll.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (2, 1, '69276406981e6105458e2df8', 'www.porwoll.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (1, 5, '6927676fd263874f0453e3e6', 'gunshin.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (2, 5, '69276776d263874f0453e3e7', 'www.gunshin.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (1, 4, '69276697de1f95ad5e22dfb1', 'complexcaresolutions.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (2, 4, '692766a1de1f95ad5e22dfb2', 'www.complexcaresolutions.de');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (1, 6, '69277ac36e43b25d0271266f', 'zweitmeinu.ng');
INSERT INTO public.tenants_domains (_order, _parent_id, id, domain) VALUES (2, 6, '69277ad26e43b25d02712670', 'www.zweitmeinu.ng');
--
-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.users (id, updated_at, created_at, email, reset_password_token, reset_password_expiration, salt, hash, login_attempts, lock_until) VALUES (1, '2025-11-26 16:40:22.979+00', '2025-11-26 16:40:22.978+00', 'martin.porwoll@complexcaresolutions.de', NULL, NULL, '44198dfdd90fadbff9a9e16caa36b43b051199ad213c7569ec15ec5ede60fbe4', '8acc6fb009b517a1427ff1e0f279dec5beabd349f18a61498244c9f74c2d240ebfb297abfa0296fa0c2962123c61eb47e0aaee3d1dc454f24c73c4e4b50a4f335e997e14848ee00f6c32a88d5e413dca1be5159dfad07b3b4f7579031ac814df274eda55fc037ffe659dee591f9f0c3a50a37e7eba69d6e20618094a46df3ac2b8c94701fab5834f5483f63af1390b7c54c6b6757edbc7e253e838f9c7e5e32415e7d38e5048f8b023894d027acfd1b8fddbc849ebf397336b029c00c11e69cc3dcba29888b083a25bdab24716a5132198ea97359e2c7054efa2f342814365e2dcbaf84c46a6bfc7e56557d16c38417f97ff14ea4e64037c5a5e4898aec64ea427f61a072ea34ed24ba863049a2b9918d330b0574c9294c269132e91841177c109c0bdc8e25d7d59d769af398c84b08e2c3c31c6cb3f8b108b7d70c94b62cf021f389dafc321e2167bb5553249fd64e3e980874fff9de9f6c2753090054edd515d1c39106fb7c27ceba255f37aab44f00ec1db22425d2fe84f1728358266b7ef19454bc021cf9f7c09b105debecc57c1c4b2a9e90fd4ced6320e2e9886252d5e00ef99ca158a79dd28b4edcb59c72b5d2475d91e5985be8d8277e541ba17a4524890c8544e75d1f30cbb5f4f87c2204b68862d9a98cad93f134c82b42d03bb9c5fb952c7d579fa2fe3c5a009bd7cbfc84f834ccf9b8e91e4afe7af4691d01e8b', 0, NULL);
--
-- Data for Name: users_sessions; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.users_sessions (_order, _parent_id, id, created_at, expires_at) VALUES (1, 1, '21fc0ad0-a771-4714-b5bb-3f341462d4b7', '2025-11-29 13:33:39.705+00', '2025-11-29 15:33:39.705+00');
--
-- Data for Name: users_tenants; Type: TABLE DATA; Schema: public; Owner: payload
--
INSERT INTO public.users_tenants (_order, _parent_id, id, tenant_id) VALUES (1, 1, '1', 1);
INSERT INTO public.users_tenants (_order, _parent_id, id, tenant_id) VALUES (2, 1, '2', 4);
INSERT INTO public.users_tenants (_order, _parent_id, id, tenant_id) VALUES (3, 1, '3', 5);
INSERT INTO public.users_tenants (_order, _parent_id, id, tenant_id) VALUES (4, 1, '4', 6);
--
-- Name: categories_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.categories_id_seq', 2, true);
--
-- Name: cookie_configurations_enabled_categories_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.cookie_configurations_enabled_categories_id_seq', 1, false);
--
-- Name: cookie_configurations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.cookie_configurations_id_seq', 1, false);
--
-- Name: cookie_inventory_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.cookie_inventory_id_seq', 1, false);
--
-- Name: media_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.media_id_seq', 7, true);
--
-- Name: navigation_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.navigation_id_seq', 1, true);
--
-- Name: payload_migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.payload_migrations_id_seq', 7, true);
--
-- Name: privacy_policy_settings_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.privacy_policy_settings_id_seq', 1, false);
--
-- Name: site_settings_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.site_settings_id_seq', 1, true);
--
-- Name: social_links_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.social_links_id_seq', 5, true);
--
-- Name: tenants_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.tenants_id_seq', 6, true);
--
-- Name: users_id_seq; Type: SEQUENCE SET; Schema: public; Owner: payload
--
SELECT pg_catalog.setval('public.users_id_seq', 1, true);
--
-- PostgreSQL database dump complete
--
\unrestrict V03RmUkem2ZWgC8DLBrXZhXphPc93B8jja6lVqjTshfVYvh9EHYuLFUSNnmU7Ip

View file

@ -0,0 +1,55 @@
import type { Payload, CollectionSlug } from 'payload'
const CONSENT_LOGS_COLLECTION = 'consent-logs' as CollectionSlug
/**
* Consent Retention Job
*
* Löscht abgelaufene ConsentLogs gemäß DSGVO Art. 5 Abs. 1e (Speicherbegrenzung).
* Sollte täglich via Cron ausgeführt werden.
*/
export const runConsentRetentionJob = async (payload: Payload): Promise<void> => {
const now = new Date().toISOString()
try {
// Finde abgelaufene Einträge
const expired = await payload.find({
collection: CONSENT_LOGS_COLLECTION,
where: {
expiresAt: {
less_than: now,
},
},
limit: 1000, // Batch-Größe
})
if (expired.docs.length === 0) {
console.log('[ConsentRetention] Keine abgelaufenen Einträge gefunden.')
return
}
console.log(
`[ConsentRetention] ${expired.docs.length} abgelaufene Einträge gefunden. Lösche...`,
)
// Lösche jeden Eintrag einzeln (WORM-Bypass via direktem DB-Zugriff)
// Da delete: () => false gesetzt ist, müssen wir den DB-Adapter direkt nutzen
for (const doc of expired.docs) {
await payload.db.deleteOne({
collection: CONSENT_LOGS_COLLECTION,
where: { id: { equals: doc.id } },
})
}
console.log(`[ConsentRetention] ${expired.docs.length} Einträge gelöscht.`)
// Falls mehr als 1000 Einträge: Rekursiv weitermachen
if (expired.docs.length === 1000) {
console.log('[ConsentRetention] Weitere Einträge vorhanden, führe nächsten Batch aus...')
await runConsentRetentionJob(payload)
}
} catch (error) {
console.error('[ConsentRetention] Fehler:', error)
throw error
}
}

26
src/jobs/scheduler.ts Normal file
View file

@ -0,0 +1,26 @@
import cron from 'node-cron'
import type { Payload } from 'payload'
import { runConsentRetentionJob } from './consentRetentionJob'
/**
* Initialisiert alle Scheduled Jobs
*/
export const initScheduledJobs = (payload: Payload): void => {
// Consent Retention: Täglich um 03:00 Uhr
cron.schedule(
'0 3 * * *',
async () => {
console.log('[Scheduler] Starte Consent Retention Job...')
try {
await runConsentRetentionJob(payload)
} catch (error) {
console.error('[Scheduler] Consent Retention Job fehlgeschlagen:', error)
}
},
{
timezone: 'Europe/Berlin',
},
)
console.log('[Scheduler] Scheduled Jobs initialisiert.')
}

View file

@ -0,0 +1,963 @@
{
"version": "7",
"dialect": "postgresql",
"tables": {
"public.users_sessions": {
"name": "users_sessions",
"schema": "",
"columns": {
"_order": {
"name": "_order",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"_parent_id": {
"name": "_parent_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"id": {
"name": "id",
"type": "varchar",
"primaryKey": true,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"users_sessions_order_idx": {
"name": "users_sessions_order_idx",
"columns": [
{
"expression": "_order",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"users_sessions_parent_id_idx": {
"name": "users_sessions_parent_id_idx",
"columns": [
{
"expression": "_parent_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"users_sessions_parent_id_fk": {
"name": "users_sessions_parent_id_fk",
"tableFrom": "users_sessions",
"tableTo": "users",
"columnsFrom": [
"_parent_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.users": {
"name": "users",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"email": {
"name": "email",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"reset_password_token": {
"name": "reset_password_token",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"reset_password_expiration": {
"name": "reset_password_expiration",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": false
},
"salt": {
"name": "salt",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"hash": {
"name": "hash",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"login_attempts": {
"name": "login_attempts",
"type": "numeric",
"primaryKey": false,
"notNull": false,
"default": 0
},
"lock_until": {
"name": "lock_until",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"users_updated_at_idx": {
"name": "users_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"users_created_at_idx": {
"name": "users_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"users_email_idx": {
"name": "users_email_idx",
"columns": [
{
"expression": "email",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.media": {
"name": "media",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"alt": {
"name": "alt",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"url": {
"name": "url",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"thumbnail_u_r_l": {
"name": "thumbnail_u_r_l",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"filename": {
"name": "filename",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"mime_type": {
"name": "mime_type",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"filesize": {
"name": "filesize",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"width": {
"name": "width",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"height": {
"name": "height",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"focal_x": {
"name": "focal_x",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"focal_y": {
"name": "focal_y",
"type": "numeric",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"media_updated_at_idx": {
"name": "media_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"media_created_at_idx": {
"name": "media_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"media_filename_idx": {
"name": "media_filename_idx",
"columns": [
{
"expression": "filename",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_kv": {
"name": "payload_kv",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"key": {
"name": "key",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"data": {
"name": "data",
"type": "jsonb",
"primaryKey": false,
"notNull": true
}
},
"indexes": {
"payload_kv_key_idx": {
"name": "payload_kv_key_idx",
"columns": [
{
"expression": "key",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_locked_documents": {
"name": "payload_locked_documents",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"global_slug": {
"name": "global_slug",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"payload_locked_documents_global_slug_idx": {
"name": "payload_locked_documents_global_slug_idx",
"columns": [
{
"expression": "global_slug",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_updated_at_idx": {
"name": "payload_locked_documents_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_created_at_idx": {
"name": "payload_locked_documents_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_locked_documents_rels": {
"name": "payload_locked_documents_rels",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"order": {
"name": "order",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"parent_id": {
"name": "parent_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"path": {
"name": "path",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"users_id": {
"name": "users_id",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"media_id": {
"name": "media_id",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"payload_locked_documents_rels_order_idx": {
"name": "payload_locked_documents_rels_order_idx",
"columns": [
{
"expression": "order",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_rels_parent_idx": {
"name": "payload_locked_documents_rels_parent_idx",
"columns": [
{
"expression": "parent_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_rels_path_idx": {
"name": "payload_locked_documents_rels_path_idx",
"columns": [
{
"expression": "path",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_rels_users_id_idx": {
"name": "payload_locked_documents_rels_users_id_idx",
"columns": [
{
"expression": "users_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_locked_documents_rels_media_id_idx": {
"name": "payload_locked_documents_rels_media_id_idx",
"columns": [
{
"expression": "media_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"payload_locked_documents_rels_parent_fk": {
"name": "payload_locked_documents_rels_parent_fk",
"tableFrom": "payload_locked_documents_rels",
"tableTo": "payload_locked_documents",
"columnsFrom": [
"parent_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"payload_locked_documents_rels_users_fk": {
"name": "payload_locked_documents_rels_users_fk",
"tableFrom": "payload_locked_documents_rels",
"tableTo": "users",
"columnsFrom": [
"users_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"payload_locked_documents_rels_media_fk": {
"name": "payload_locked_documents_rels_media_fk",
"tableFrom": "payload_locked_documents_rels",
"tableTo": "media",
"columnsFrom": [
"media_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_preferences": {
"name": "payload_preferences",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"key": {
"name": "key",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"value": {
"name": "value",
"type": "jsonb",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"payload_preferences_key_idx": {
"name": "payload_preferences_key_idx",
"columns": [
{
"expression": "key",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_updated_at_idx": {
"name": "payload_preferences_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_created_at_idx": {
"name": "payload_preferences_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_preferences_rels": {
"name": "payload_preferences_rels",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"order": {
"name": "order",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"parent_id": {
"name": "parent_id",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"path": {
"name": "path",
"type": "varchar",
"primaryKey": false,
"notNull": true
},
"users_id": {
"name": "users_id",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"payload_preferences_rels_order_idx": {
"name": "payload_preferences_rels_order_idx",
"columns": [
{
"expression": "order",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_rels_parent_idx": {
"name": "payload_preferences_rels_parent_idx",
"columns": [
{
"expression": "parent_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_rels_path_idx": {
"name": "payload_preferences_rels_path_idx",
"columns": [
{
"expression": "path",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_preferences_rels_users_id_idx": {
"name": "payload_preferences_rels_users_id_idx",
"columns": [
{
"expression": "users_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"payload_preferences_rels_parent_fk": {
"name": "payload_preferences_rels_parent_fk",
"tableFrom": "payload_preferences_rels",
"tableTo": "payload_preferences",
"columnsFrom": [
"parent_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"payload_preferences_rels_users_fk": {
"name": "payload_preferences_rels_users_fk",
"tableFrom": "payload_preferences_rels",
"tableTo": "users",
"columnsFrom": [
"users_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.payload_migrations": {
"name": "payload_migrations",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "varchar",
"primaryKey": false,
"notNull": false
},
"batch": {
"name": "batch",
"type": "numeric",
"primaryKey": false,
"notNull": false
},
"updated_at": {
"name": "updated_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"created_at": {
"name": "created_at",
"type": "timestamp(3) with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"payload_migrations_updated_at_idx": {
"name": "payload_migrations_updated_at_idx",
"columns": [
{
"expression": "updated_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"payload_migrations_created_at_idx": {
"name": "payload_migrations_created_at_idx",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"id": "8f5aa12b-08f6-4857-a473-f525e7f7ee01",
"prevId": "00000000-0000-0000-0000-000000000000"
}

View file

@ -0,0 +1,133 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
CREATE TABLE "users_sessions" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"created_at" timestamp(3) with time zone,
"expires_at" timestamp(3) with time zone NOT NULL
);
CREATE TABLE "users" (
"id" serial PRIMARY KEY NOT NULL,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"email" varchar NOT NULL,
"reset_password_token" varchar,
"reset_password_expiration" timestamp(3) with time zone,
"salt" varchar,
"hash" varchar,
"login_attempts" numeric DEFAULT 0,
"lock_until" timestamp(3) with time zone
);
CREATE TABLE "media" (
"id" serial PRIMARY KEY NOT NULL,
"alt" varchar NOT NULL,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"url" varchar,
"thumbnail_u_r_l" varchar,
"filename" varchar,
"mime_type" varchar,
"filesize" numeric,
"width" numeric,
"height" numeric,
"focal_x" numeric,
"focal_y" numeric
);
CREATE TABLE "payload_kv" (
"id" serial PRIMARY KEY NOT NULL,
"key" varchar NOT NULL,
"data" jsonb NOT NULL
);
CREATE TABLE "payload_locked_documents" (
"id" serial PRIMARY KEY NOT NULL,
"global_slug" varchar,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "payload_locked_documents_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"users_id" integer,
"media_id" integer
);
CREATE TABLE "payload_preferences" (
"id" serial PRIMARY KEY NOT NULL,
"key" varchar,
"value" jsonb,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "payload_preferences_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"users_id" integer
);
CREATE TABLE "payload_migrations" (
"id" serial PRIMARY KEY NOT NULL,
"name" varchar,
"batch" numeric,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
ALTER TABLE "users_sessions" ADD CONSTRAINT "users_sessions_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."payload_locked_documents"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_users_fk" FOREIGN KEY ("users_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_media_fk" FOREIGN KEY ("media_id") REFERENCES "public"."media"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_preferences_rels" ADD CONSTRAINT "payload_preferences_rels_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."payload_preferences"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_preferences_rels" ADD CONSTRAINT "payload_preferences_rels_users_fk" FOREIGN KEY ("users_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "users_sessions_order_idx" ON "users_sessions" USING btree ("_order");
CREATE INDEX "users_sessions_parent_id_idx" ON "users_sessions" USING btree ("_parent_id");
CREATE INDEX "users_updated_at_idx" ON "users" USING btree ("updated_at");
CREATE INDEX "users_created_at_idx" ON "users" USING btree ("created_at");
CREATE UNIQUE INDEX "users_email_idx" ON "users" USING btree ("email");
CREATE INDEX "media_updated_at_idx" ON "media" USING btree ("updated_at");
CREATE INDEX "media_created_at_idx" ON "media" USING btree ("created_at");
CREATE UNIQUE INDEX "media_filename_idx" ON "media" USING btree ("filename");
CREATE UNIQUE INDEX "payload_kv_key_idx" ON "payload_kv" USING btree ("key");
CREATE INDEX "payload_locked_documents_global_slug_idx" ON "payload_locked_documents" USING btree ("global_slug");
CREATE INDEX "payload_locked_documents_updated_at_idx" ON "payload_locked_documents" USING btree ("updated_at");
CREATE INDEX "payload_locked_documents_created_at_idx" ON "payload_locked_documents" USING btree ("created_at");
CREATE INDEX "payload_locked_documents_rels_order_idx" ON "payload_locked_documents_rels" USING btree ("order");
CREATE INDEX "payload_locked_documents_rels_parent_idx" ON "payload_locked_documents_rels" USING btree ("parent_id");
CREATE INDEX "payload_locked_documents_rels_path_idx" ON "payload_locked_documents_rels" USING btree ("path");
CREATE INDEX "payload_locked_documents_rels_users_id_idx" ON "payload_locked_documents_rels" USING btree ("users_id");
CREATE INDEX "payload_locked_documents_rels_media_id_idx" ON "payload_locked_documents_rels" USING btree ("media_id");
CREATE INDEX "payload_preferences_key_idx" ON "payload_preferences" USING btree ("key");
CREATE INDEX "payload_preferences_updated_at_idx" ON "payload_preferences" USING btree ("updated_at");
CREATE INDEX "payload_preferences_created_at_idx" ON "payload_preferences" USING btree ("created_at");
CREATE INDEX "payload_preferences_rels_order_idx" ON "payload_preferences_rels" USING btree ("order");
CREATE INDEX "payload_preferences_rels_parent_idx" ON "payload_preferences_rels" USING btree ("parent_id");
CREATE INDEX "payload_preferences_rels_path_idx" ON "payload_preferences_rels" USING btree ("path");
CREATE INDEX "payload_preferences_rels_users_id_idx" ON "payload_preferences_rels" USING btree ("users_id");
CREATE INDEX "payload_migrations_updated_at_idx" ON "payload_migrations" USING btree ("updated_at");
CREATE INDEX "payload_migrations_created_at_idx" ON "payload_migrations" USING btree ("created_at");`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
DROP TABLE "users_sessions" CASCADE;
DROP TABLE "users" CASCADE;
DROP TABLE "media" CASCADE;
DROP TABLE "payload_kv" CASCADE;
DROP TABLE "payload_locked_documents" CASCADE;
DROP TABLE "payload_locked_documents_rels" CASCADE;
DROP TABLE "payload_preferences" CASCADE;
DROP TABLE "payload_preferences_rels" CASCADE;
DROP TABLE "payload_migrations" CASCADE;`)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,62 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
CREATE TABLE "users_tenants" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"tenant_id" integer NOT NULL
);
CREATE TABLE "tenants_domains" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"domain" varchar NOT NULL
);
CREATE TABLE "tenants" (
"id" serial PRIMARY KEY NOT NULL,
"name" varchar NOT NULL,
"slug" varchar NOT NULL,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
ALTER TABLE "media" ADD COLUMN "tenant_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "tenants_id" integer;
ALTER TABLE "users_tenants" ADD CONSTRAINT "users_tenants_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "users_tenants" ADD CONSTRAINT "users_tenants_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "tenants_domains" ADD CONSTRAINT "tenants_domains_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "users_tenants_order_idx" ON "users_tenants" USING btree ("_order");
CREATE INDEX "users_tenants_parent_id_idx" ON "users_tenants" USING btree ("_parent_id");
CREATE INDEX "users_tenants_tenant_idx" ON "users_tenants" USING btree ("tenant_id");
CREATE INDEX "tenants_domains_order_idx" ON "tenants_domains" USING btree ("_order");
CREATE INDEX "tenants_domains_parent_id_idx" ON "tenants_domains" USING btree ("_parent_id");
CREATE UNIQUE INDEX "tenants_slug_idx" ON "tenants" USING btree ("slug");
CREATE INDEX "tenants_updated_at_idx" ON "tenants" USING btree ("updated_at");
CREATE INDEX "tenants_created_at_idx" ON "tenants" USING btree ("created_at");
ALTER TABLE "media" ADD CONSTRAINT "media_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_tenants_fk" FOREIGN KEY ("tenants_id") REFERENCES "public"."tenants"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "media_tenant_idx" ON "media" USING btree ("tenant_id");
CREATE INDEX "payload_locked_documents_rels_tenants_id_idx" ON "payload_locked_documents_rels" USING btree ("tenants_id");`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
ALTER TABLE "users_tenants" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "tenants_domains" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "tenants" DISABLE ROW LEVEL SECURITY;
DROP TABLE "users_tenants" CASCADE;
DROP TABLE "tenants_domains" CASCADE;
DROP TABLE "tenants" CASCADE;
ALTER TABLE "media" DROP CONSTRAINT "media_tenant_id_tenants_id_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_tenants_fk";
DROP INDEX "media_tenant_idx";
DROP INDEX "payload_locked_documents_rels_tenants_id_idx";
ALTER TABLE "media" DROP COLUMN "tenant_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "tenants_id";`)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,466 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
CREATE TYPE "public"."enum_pages_status" AS ENUM('draft', 'published');
CREATE TYPE "public"."enum_posts_status" AS ENUM('draft', 'published');
CREATE TYPE "public"."enum_social_links_platform" AS ENUM('facebook', 'x', 'instagram', 'youtube', 'linkedin', 'xing');
CREATE TYPE "public"."enum_forms_confirmation_type" AS ENUM('message', 'redirect');
CREATE TYPE "public"."enum_redirects_to_type" AS ENUM('reference', 'custom');
CREATE TYPE "public"."enum_navigation_main_menu_submenu_link_type" AS ENUM('page', 'custom');
CREATE TYPE "public"."enum_navigation_main_menu_type" AS ENUM('page', 'custom', 'submenu');
CREATE TYPE "public"."enum_navigation_footer_menu_link_type" AS ENUM('page', 'custom');
CREATE TABLE "pages" (
"id" serial PRIMARY KEY NOT NULL,
"tenant_id" integer,
"title" varchar NOT NULL,
"slug" varchar NOT NULL,
"hero_image_id" integer,
"hero_headline" varchar,
"hero_subline" varchar,
"content" jsonb,
"seo_meta_title" varchar,
"seo_meta_description" varchar,
"seo_og_image_id" integer,
"status" "enum_pages_status" DEFAULT 'draft',
"published_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
);
CREATE TABLE "posts" (
"id" serial PRIMARY KEY NOT NULL,
"tenant_id" integer,
"title" varchar NOT NULL,
"slug" varchar NOT NULL,
"excerpt" varchar,
"content" jsonb,
"featured_image_id" integer,
"category_id" integer,
"author_id" integer,
"published_at" timestamp(3) with time zone,
"status" "enum_posts_status" DEFAULT 'draft',
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "categories" (
"id" serial PRIMARY KEY NOT NULL,
"tenant_id" integer,
"name" varchar NOT NULL,
"slug" varchar NOT NULL,
"description" varchar,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "social_links" (
"id" serial PRIMARY KEY NOT NULL,
"tenant_id" integer,
"platform" "enum_social_links_platform" NOT NULL,
"url" varchar NOT NULL,
"is_active" boolean DEFAULT true,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "forms_blocks_checkbox" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"name" varchar NOT NULL,
"label" varchar,
"width" numeric,
"required" boolean,
"default_value" boolean,
"block_name" varchar
);
CREATE TABLE "forms_blocks_email" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"name" varchar NOT NULL,
"label" varchar,
"width" numeric,
"required" boolean,
"block_name" varchar
);
CREATE TABLE "forms_blocks_message" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"message" jsonb,
"block_name" varchar
);
CREATE TABLE "forms_blocks_number" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"name" varchar NOT NULL,
"label" varchar,
"width" numeric,
"default_value" numeric,
"required" boolean,
"block_name" varchar
);
CREATE TABLE "forms_blocks_select_options" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"label" varchar NOT NULL,
"value" varchar NOT NULL
);
CREATE TABLE "forms_blocks_select" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"name" varchar NOT NULL,
"label" varchar,
"width" numeric,
"default_value" varchar,
"placeholder" varchar,
"required" boolean,
"block_name" varchar
);
CREATE TABLE "forms_blocks_text" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"name" varchar NOT NULL,
"label" varchar,
"width" numeric,
"default_value" varchar,
"required" boolean,
"block_name" varchar
);
CREATE TABLE "forms_blocks_textarea" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"name" varchar NOT NULL,
"label" varchar,
"width" numeric,
"default_value" varchar,
"required" boolean,
"block_name" varchar
);
CREATE TABLE "forms_emails" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"email_to" varchar,
"cc" varchar,
"bcc" varchar,
"reply_to" varchar,
"email_from" varchar,
"subject" varchar DEFAULT 'You''ve received a new message.' NOT NULL,
"message" jsonb
);
CREATE TABLE "forms" (
"id" serial PRIMARY KEY NOT NULL,
"title" varchar NOT NULL,
"submit_button_label" varchar,
"confirmation_type" "enum_forms_confirmation_type" DEFAULT 'message',
"confirmation_message" jsonb,
"redirect_url" varchar,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "form_submissions_submission_data" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"field" varchar NOT NULL,
"value" varchar NOT NULL
);
CREATE TABLE "form_submissions" (
"id" serial PRIMARY KEY NOT NULL,
"form_id" integer NOT NULL,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "redirects" (
"id" serial PRIMARY KEY NOT NULL,
"from" varchar NOT NULL,
"to_type" "enum_redirects_to_type" DEFAULT 'reference',
"to_url" varchar,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "site_settings" (
"id" serial PRIMARY KEY NOT NULL,
"site_name" varchar DEFAULT 'porwoll.de',
"site_tagline" varchar,
"logo_id" integer,
"favicon_id" integer,
"contact_email" varchar,
"contact_phone" varchar,
"contact_address" varchar,
"footer_copyright_text" varchar,
"footer_show_social_links" boolean DEFAULT true,
"seo_default_meta_title" varchar,
"seo_default_meta_description" varchar,
"seo_default_og_image_id" integer,
"updated_at" timestamp(3) with time zone,
"created_at" timestamp(3) with time zone
);
CREATE TABLE "navigation_main_menu_submenu" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"label" varchar,
"link_type" "enum_navigation_main_menu_submenu_link_type" DEFAULT 'page',
"page_id" integer,
"url" varchar
);
CREATE TABLE "navigation_main_menu" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"label" varchar NOT NULL,
"type" "enum_navigation_main_menu_type" DEFAULT 'page',
"page_id" integer,
"url" varchar,
"open_in_new_tab" boolean DEFAULT false
);
CREATE TABLE "navigation_footer_menu" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"label" varchar NOT NULL,
"link_type" "enum_navigation_footer_menu_link_type" DEFAULT 'page',
"page_id" integer,
"url" varchar
);
CREATE TABLE "navigation" (
"id" serial PRIMARY KEY NOT NULL,
"updated_at" timestamp(3) with time zone,
"created_at" timestamp(3) with time zone
);
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "pages_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "posts_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "categories_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "social_links_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "forms_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "form_submissions_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "redirects_id" integer;
ALTER TABLE "pages" ADD CONSTRAINT "pages_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "pages" ADD CONSTRAINT "pages_hero_image_id_media_id_fk" FOREIGN KEY ("hero_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "pages" ADD CONSTRAINT "pages_seo_og_image_id_media_id_fk" FOREIGN KEY ("seo_og_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "posts" ADD CONSTRAINT "posts_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "posts" ADD CONSTRAINT "posts_featured_image_id_media_id_fk" FOREIGN KEY ("featured_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "posts" ADD CONSTRAINT "posts_category_id_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "posts" ADD CONSTRAINT "posts_author_id_users_id_fk" FOREIGN KEY ("author_id") REFERENCES "public"."users"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "categories" ADD CONSTRAINT "categories_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "social_links" ADD CONSTRAINT "social_links_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "forms_blocks_checkbox" ADD CONSTRAINT "forms_blocks_checkbox_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."forms"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "forms_blocks_email" ADD CONSTRAINT "forms_blocks_email_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."forms"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "forms_blocks_message" ADD CONSTRAINT "forms_blocks_message_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."forms"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "forms_blocks_number" ADD CONSTRAINT "forms_blocks_number_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."forms"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "forms_blocks_select_options" ADD CONSTRAINT "forms_blocks_select_options_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."forms_blocks_select"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "forms_blocks_select" ADD CONSTRAINT "forms_blocks_select_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."forms"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "forms_blocks_text" ADD CONSTRAINT "forms_blocks_text_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."forms"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "forms_blocks_textarea" ADD CONSTRAINT "forms_blocks_textarea_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."forms"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "forms_emails" ADD CONSTRAINT "forms_emails_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."forms"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "form_submissions_submission_data" ADD CONSTRAINT "form_submissions_submission_data_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."form_submissions"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "form_submissions" ADD CONSTRAINT "form_submissions_form_id_forms_id_fk" FOREIGN KEY ("form_id") REFERENCES "public"."forms"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "site_settings" ADD CONSTRAINT "site_settings_logo_id_media_id_fk" FOREIGN KEY ("logo_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "site_settings" ADD CONSTRAINT "site_settings_favicon_id_media_id_fk" FOREIGN KEY ("favicon_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "site_settings" ADD CONSTRAINT "site_settings_seo_default_og_image_id_media_id_fk" FOREIGN KEY ("seo_default_og_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "navigation_main_menu_submenu" ADD CONSTRAINT "navigation_main_menu_submenu_page_id_pages_id_fk" FOREIGN KEY ("page_id") REFERENCES "public"."pages"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "navigation_main_menu_submenu" ADD CONSTRAINT "navigation_main_menu_submenu_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."navigation_main_menu"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "navigation_main_menu" ADD CONSTRAINT "navigation_main_menu_page_id_pages_id_fk" FOREIGN KEY ("page_id") REFERENCES "public"."pages"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "navigation_main_menu" ADD CONSTRAINT "navigation_main_menu_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."navigation"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "navigation_footer_menu" ADD CONSTRAINT "navigation_footer_menu_page_id_pages_id_fk" FOREIGN KEY ("page_id") REFERENCES "public"."pages"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "navigation_footer_menu" ADD CONSTRAINT "navigation_footer_menu_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."navigation"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "pages_tenant_idx" ON "pages" USING btree ("tenant_id");
CREATE UNIQUE INDEX "pages_slug_idx" ON "pages" USING btree ("slug");
CREATE INDEX "pages_hero_hero_image_idx" ON "pages" USING btree ("hero_image_id");
CREATE INDEX "pages_seo_seo_og_image_idx" ON "pages" USING btree ("seo_og_image_id");
CREATE INDEX "pages_updated_at_idx" ON "pages" USING btree ("updated_at");
CREATE INDEX "pages_created_at_idx" ON "pages" USING btree ("created_at");
CREATE INDEX "posts_tenant_idx" ON "posts" USING btree ("tenant_id");
CREATE UNIQUE INDEX "posts_slug_idx" ON "posts" USING btree ("slug");
CREATE INDEX "posts_featured_image_idx" ON "posts" USING btree ("featured_image_id");
CREATE INDEX "posts_category_idx" ON "posts" USING btree ("category_id");
CREATE INDEX "posts_author_idx" ON "posts" USING btree ("author_id");
CREATE INDEX "posts_updated_at_idx" ON "posts" USING btree ("updated_at");
CREATE INDEX "posts_created_at_idx" ON "posts" USING btree ("created_at");
CREATE INDEX "categories_tenant_idx" ON "categories" USING btree ("tenant_id");
CREATE UNIQUE INDEX "categories_slug_idx" ON "categories" USING btree ("slug");
CREATE INDEX "categories_updated_at_idx" ON "categories" USING btree ("updated_at");
CREATE INDEX "categories_created_at_idx" ON "categories" USING btree ("created_at");
CREATE INDEX "social_links_tenant_idx" ON "social_links" USING btree ("tenant_id");
CREATE INDEX "social_links_updated_at_idx" ON "social_links" USING btree ("updated_at");
CREATE INDEX "social_links_created_at_idx" ON "social_links" USING btree ("created_at");
CREATE INDEX "forms_blocks_checkbox_order_idx" ON "forms_blocks_checkbox" USING btree ("_order");
CREATE INDEX "forms_blocks_checkbox_parent_id_idx" ON "forms_blocks_checkbox" USING btree ("_parent_id");
CREATE INDEX "forms_blocks_checkbox_path_idx" ON "forms_blocks_checkbox" USING btree ("_path");
CREATE INDEX "forms_blocks_email_order_idx" ON "forms_blocks_email" USING btree ("_order");
CREATE INDEX "forms_blocks_email_parent_id_idx" ON "forms_blocks_email" USING btree ("_parent_id");
CREATE INDEX "forms_blocks_email_path_idx" ON "forms_blocks_email" USING btree ("_path");
CREATE INDEX "forms_blocks_message_order_idx" ON "forms_blocks_message" USING btree ("_order");
CREATE INDEX "forms_blocks_message_parent_id_idx" ON "forms_blocks_message" USING btree ("_parent_id");
CREATE INDEX "forms_blocks_message_path_idx" ON "forms_blocks_message" USING btree ("_path");
CREATE INDEX "forms_blocks_number_order_idx" ON "forms_blocks_number" USING btree ("_order");
CREATE INDEX "forms_blocks_number_parent_id_idx" ON "forms_blocks_number" USING btree ("_parent_id");
CREATE INDEX "forms_blocks_number_path_idx" ON "forms_blocks_number" USING btree ("_path");
CREATE INDEX "forms_blocks_select_options_order_idx" ON "forms_blocks_select_options" USING btree ("_order");
CREATE INDEX "forms_blocks_select_options_parent_id_idx" ON "forms_blocks_select_options" USING btree ("_parent_id");
CREATE INDEX "forms_blocks_select_order_idx" ON "forms_blocks_select" USING btree ("_order");
CREATE INDEX "forms_blocks_select_parent_id_idx" ON "forms_blocks_select" USING btree ("_parent_id");
CREATE INDEX "forms_blocks_select_path_idx" ON "forms_blocks_select" USING btree ("_path");
CREATE INDEX "forms_blocks_text_order_idx" ON "forms_blocks_text" USING btree ("_order");
CREATE INDEX "forms_blocks_text_parent_id_idx" ON "forms_blocks_text" USING btree ("_parent_id");
CREATE INDEX "forms_blocks_text_path_idx" ON "forms_blocks_text" USING btree ("_path");
CREATE INDEX "forms_blocks_textarea_order_idx" ON "forms_blocks_textarea" USING btree ("_order");
CREATE INDEX "forms_blocks_textarea_parent_id_idx" ON "forms_blocks_textarea" USING btree ("_parent_id");
CREATE INDEX "forms_blocks_textarea_path_idx" ON "forms_blocks_textarea" USING btree ("_path");
CREATE INDEX "forms_emails_order_idx" ON "forms_emails" USING btree ("_order");
CREATE INDEX "forms_emails_parent_id_idx" ON "forms_emails" USING btree ("_parent_id");
CREATE INDEX "forms_updated_at_idx" ON "forms" USING btree ("updated_at");
CREATE INDEX "forms_created_at_idx" ON "forms" USING btree ("created_at");
CREATE INDEX "form_submissions_submission_data_order_idx" ON "form_submissions_submission_data" USING btree ("_order");
CREATE INDEX "form_submissions_submission_data_parent_id_idx" ON "form_submissions_submission_data" USING btree ("_parent_id");
CREATE INDEX "form_submissions_form_idx" ON "form_submissions" USING btree ("form_id");
CREATE INDEX "form_submissions_updated_at_idx" ON "form_submissions" USING btree ("updated_at");
CREATE INDEX "form_submissions_created_at_idx" ON "form_submissions" USING btree ("created_at");
CREATE UNIQUE INDEX "redirects_from_idx" ON "redirects" USING btree ("from");
CREATE INDEX "redirects_updated_at_idx" ON "redirects" USING btree ("updated_at");
CREATE INDEX "redirects_created_at_idx" ON "redirects" USING btree ("created_at");
CREATE INDEX "site_settings_logo_idx" ON "site_settings" USING btree ("logo_id");
CREATE INDEX "site_settings_favicon_idx" ON "site_settings" USING btree ("favicon_id");
CREATE INDEX "site_settings_seo_seo_default_og_image_idx" ON "site_settings" USING btree ("seo_default_og_image_id");
CREATE INDEX "navigation_main_menu_submenu_order_idx" ON "navigation_main_menu_submenu" USING btree ("_order");
CREATE INDEX "navigation_main_menu_submenu_parent_id_idx" ON "navigation_main_menu_submenu" USING btree ("_parent_id");
CREATE INDEX "navigation_main_menu_submenu_page_idx" ON "navigation_main_menu_submenu" USING btree ("page_id");
CREATE INDEX "navigation_main_menu_order_idx" ON "navigation_main_menu" USING btree ("_order");
CREATE INDEX "navigation_main_menu_parent_id_idx" ON "navigation_main_menu" USING btree ("_parent_id");
CREATE INDEX "navigation_main_menu_page_idx" ON "navigation_main_menu" USING btree ("page_id");
CREATE INDEX "navigation_footer_menu_order_idx" ON "navigation_footer_menu" USING btree ("_order");
CREATE INDEX "navigation_footer_menu_parent_id_idx" ON "navigation_footer_menu" USING btree ("_parent_id");
CREATE INDEX "navigation_footer_menu_page_idx" ON "navigation_footer_menu" USING btree ("page_id");
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_pages_fk" FOREIGN KEY ("pages_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_posts_fk" FOREIGN KEY ("posts_id") REFERENCES "public"."posts"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_categories_fk" FOREIGN KEY ("categories_id") REFERENCES "public"."categories"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_social_links_fk" FOREIGN KEY ("social_links_id") REFERENCES "public"."social_links"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_forms_fk" FOREIGN KEY ("forms_id") REFERENCES "public"."forms"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_form_submissions_fk" FOREIGN KEY ("form_submissions_id") REFERENCES "public"."form_submissions"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_redirects_fk" FOREIGN KEY ("redirects_id") REFERENCES "public"."redirects"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "payload_locked_documents_rels_pages_id_idx" ON "payload_locked_documents_rels" USING btree ("pages_id");
CREATE INDEX "payload_locked_documents_rels_posts_id_idx" ON "payload_locked_documents_rels" USING btree ("posts_id");
CREATE INDEX "payload_locked_documents_rels_categories_id_idx" ON "payload_locked_documents_rels" USING btree ("categories_id");
CREATE INDEX "payload_locked_documents_rels_social_links_id_idx" ON "payload_locked_documents_rels" USING btree ("social_links_id");
CREATE INDEX "payload_locked_documents_rels_forms_id_idx" ON "payload_locked_documents_rels" USING btree ("forms_id");
CREATE INDEX "payload_locked_documents_rels_form_submissions_id_idx" ON "payload_locked_documents_rels" USING btree ("form_submissions_id");
CREATE INDEX "payload_locked_documents_rels_redirects_id_idx" ON "payload_locked_documents_rels" USING btree ("redirects_id");`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
ALTER TABLE "pages" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "posts" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "categories" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "social_links" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms_blocks_checkbox" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms_blocks_email" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms_blocks_message" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms_blocks_number" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms_blocks_select_options" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms_blocks_select" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms_blocks_text" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms_blocks_textarea" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms_emails" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "forms" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "form_submissions_submission_data" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "form_submissions" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "redirects" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "site_settings" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "navigation_main_menu_submenu" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "navigation_main_menu" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "navigation_footer_menu" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "navigation" DISABLE ROW LEVEL SECURITY;
DROP TABLE "pages" CASCADE;
DROP TABLE "posts" CASCADE;
DROP TABLE "categories" CASCADE;
DROP TABLE "social_links" CASCADE;
DROP TABLE "forms_blocks_checkbox" CASCADE;
DROP TABLE "forms_blocks_email" CASCADE;
DROP TABLE "forms_blocks_message" CASCADE;
DROP TABLE "forms_blocks_number" CASCADE;
DROP TABLE "forms_blocks_select_options" CASCADE;
DROP TABLE "forms_blocks_select" CASCADE;
DROP TABLE "forms_blocks_text" CASCADE;
DROP TABLE "forms_blocks_textarea" CASCADE;
DROP TABLE "forms_emails" CASCADE;
DROP TABLE "forms" CASCADE;
DROP TABLE "form_submissions_submission_data" CASCADE;
DROP TABLE "form_submissions" CASCADE;
DROP TABLE "redirects" CASCADE;
DROP TABLE "site_settings" CASCADE;
DROP TABLE "navigation_main_menu_submenu" CASCADE;
DROP TABLE "navigation_main_menu" CASCADE;
DROP TABLE "navigation_footer_menu" CASCADE;
DROP TABLE "navigation" CASCADE;
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_pages_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_posts_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_categories_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_social_links_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_forms_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_form_submissions_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_redirects_fk";
DROP INDEX "payload_locked_documents_rels_pages_id_idx";
DROP INDEX "payload_locked_documents_rels_posts_id_idx";
DROP INDEX "payload_locked_documents_rels_categories_id_idx";
DROP INDEX "payload_locked_documents_rels_social_links_id_idx";
DROP INDEX "payload_locked_documents_rels_forms_id_idx";
DROP INDEX "payload_locked_documents_rels_form_submissions_id_idx";
DROP INDEX "payload_locked_documents_rels_redirects_id_idx";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "pages_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "posts_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "categories_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "social_links_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "forms_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "form_submissions_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "redirects_id";
DROP TYPE "public"."enum_pages_status";
DROP TYPE "public"."enum_posts_status";
DROP TYPE "public"."enum_social_links_platform";
DROP TYPE "public"."enum_forms_confirmation_type";
DROP TYPE "public"."enum_redirects_to_type";
DROP TYPE "public"."enum_navigation_main_menu_submenu_link_type";
DROP TYPE "public"."enum_navigation_main_menu_type";
DROP TYPE "public"."enum_navigation_footer_menu_link_type";`)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,253 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
CREATE TYPE "public"."enum_pages_blocks_hero_block_alignment" AS ENUM('left', 'center', 'right');
CREATE TYPE "public"."enum_pages_blocks_hero_block_cta_style" AS ENUM('primary', 'secondary', 'outline');
CREATE TYPE "public"."enum_pages_blocks_text_block_width" AS ENUM('narrow', 'medium', 'full');
CREATE TYPE "public"."enum_pages_blocks_image_text_block_image_position" AS ENUM('left', 'right');
CREATE TYPE "public"."enum_pages_blocks_card_grid_block_columns" AS ENUM('2', '3', '4');
CREATE TYPE "public"."enum_pages_blocks_quote_block_style" AS ENUM('simple', 'highlighted', 'with-image');
CREATE TYPE "public"."enum_pages_blocks_cta_block_buttons_style" AS ENUM('primary', 'secondary', 'outline');
CREATE TYPE "public"."enum_pages_blocks_cta_block_background_color" AS ENUM('dark', 'light', 'accent');
CREATE TYPE "public"."enum_pages_blocks_divider_block_style" AS ENUM('line', 'space', 'dots');
CREATE TYPE "public"."enum_pages_blocks_divider_block_spacing" AS ENUM('small', 'medium', 'large');
CREATE TYPE "public"."enum_pages_blocks_video_block_aspect_ratio" AS ENUM('16:9', '4:3', '1:1');
CREATE TABLE "pages_blocks_hero_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"background_image_id" integer,
"headline" varchar NOT NULL,
"subline" varchar,
"alignment" "enum_pages_blocks_hero_block_alignment" DEFAULT 'center',
"overlay" boolean DEFAULT true,
"cta_text" varchar,
"cta_link" varchar,
"cta_style" "enum_pages_blocks_hero_block_cta_style" DEFAULT 'primary',
"block_name" varchar
);
CREATE TABLE "pages_blocks_text_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"content" jsonb NOT NULL,
"width" "enum_pages_blocks_text_block_width" DEFAULT 'medium',
"block_name" varchar
);
CREATE TABLE "pages_blocks_image_text_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"image_id" integer NOT NULL,
"image_position" "enum_pages_blocks_image_text_block_image_position" DEFAULT 'left',
"headline" varchar,
"content" jsonb,
"cta_text" varchar,
"cta_link" varchar,
"block_name" varchar
);
CREATE TABLE "pages_blocks_card_grid_block_cards" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"image_id" integer,
"title" varchar NOT NULL,
"description" varchar,
"link" varchar,
"link_text" varchar DEFAULT 'mehr'
);
CREATE TABLE "pages_blocks_card_grid_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"headline" varchar,
"columns" "enum_pages_blocks_card_grid_block_columns" DEFAULT '3',
"block_name" varchar
);
CREATE TABLE "pages_blocks_quote_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"quote" varchar NOT NULL,
"author" varchar,
"role" varchar,
"image_id" integer,
"style" "enum_pages_blocks_quote_block_style" DEFAULT 'simple',
"block_name" varchar
);
CREATE TABLE "pages_blocks_cta_block_buttons" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"text" varchar NOT NULL,
"link" varchar NOT NULL,
"style" "enum_pages_blocks_cta_block_buttons_style" DEFAULT 'primary'
);
CREATE TABLE "pages_blocks_cta_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"headline" varchar NOT NULL,
"description" varchar,
"background_color" "enum_pages_blocks_cta_block_background_color" DEFAULT 'dark',
"block_name" varchar
);
CREATE TABLE "pages_blocks_contact_form_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"headline" varchar DEFAULT 'Kontakt',
"description" varchar,
"recipient_email" varchar DEFAULT 'info@porwoll.de',
"show_phone" boolean DEFAULT true,
"show_address" boolean DEFAULT true,
"show_socials" boolean DEFAULT true,
"block_name" varchar
);
CREATE TABLE "pages_blocks_timeline_block_events" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"year" varchar NOT NULL,
"title" varchar NOT NULL,
"description" varchar,
"image_id" integer
);
CREATE TABLE "pages_blocks_timeline_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"headline" varchar,
"block_name" varchar
);
CREATE TABLE "pages_blocks_divider_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"style" "enum_pages_blocks_divider_block_style" DEFAULT 'space',
"spacing" "enum_pages_blocks_divider_block_spacing" DEFAULT 'medium',
"block_name" varchar
);
CREATE TABLE "pages_blocks_video_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"video_url" varchar NOT NULL,
"caption" varchar,
"aspect_ratio" "enum_pages_blocks_video_block_aspect_ratio" DEFAULT '16:9',
"block_name" varchar
);
ALTER TABLE "pages_blocks_hero_block" ADD CONSTRAINT "pages_blocks_hero_block_background_image_id_media_id_fk" FOREIGN KEY ("background_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "pages_blocks_hero_block" ADD CONSTRAINT "pages_blocks_hero_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_text_block" ADD CONSTRAINT "pages_blocks_text_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_image_text_block" ADD CONSTRAINT "pages_blocks_image_text_block_image_id_media_id_fk" FOREIGN KEY ("image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "pages_blocks_image_text_block" ADD CONSTRAINT "pages_blocks_image_text_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_card_grid_block_cards" ADD CONSTRAINT "pages_blocks_card_grid_block_cards_image_id_media_id_fk" FOREIGN KEY ("image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "pages_blocks_card_grid_block_cards" ADD CONSTRAINT "pages_blocks_card_grid_block_cards_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_card_grid_block"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_card_grid_block" ADD CONSTRAINT "pages_blocks_card_grid_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_quote_block" ADD CONSTRAINT "pages_blocks_quote_block_image_id_media_id_fk" FOREIGN KEY ("image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "pages_blocks_quote_block" ADD CONSTRAINT "pages_blocks_quote_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_cta_block_buttons" ADD CONSTRAINT "pages_blocks_cta_block_buttons_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_cta_block"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_cta_block" ADD CONSTRAINT "pages_blocks_cta_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_contact_form_block" ADD CONSTRAINT "pages_blocks_contact_form_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_timeline_block_events" ADD CONSTRAINT "pages_blocks_timeline_block_events_image_id_media_id_fk" FOREIGN KEY ("image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "pages_blocks_timeline_block_events" ADD CONSTRAINT "pages_blocks_timeline_block_events_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_timeline_block"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_timeline_block" ADD CONSTRAINT "pages_blocks_timeline_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_divider_block" ADD CONSTRAINT "pages_blocks_divider_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_video_block" ADD CONSTRAINT "pages_blocks_video_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "pages_blocks_hero_block_order_idx" ON "pages_blocks_hero_block" USING btree ("_order");
CREATE INDEX "pages_blocks_hero_block_parent_id_idx" ON "pages_blocks_hero_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_hero_block_path_idx" ON "pages_blocks_hero_block" USING btree ("_path");
CREATE INDEX "pages_blocks_hero_block_background_image_idx" ON "pages_blocks_hero_block" USING btree ("background_image_id");
CREATE INDEX "pages_blocks_text_block_order_idx" ON "pages_blocks_text_block" USING btree ("_order");
CREATE INDEX "pages_blocks_text_block_parent_id_idx" ON "pages_blocks_text_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_text_block_path_idx" ON "pages_blocks_text_block" USING btree ("_path");
CREATE INDEX "pages_blocks_image_text_block_order_idx" ON "pages_blocks_image_text_block" USING btree ("_order");
CREATE INDEX "pages_blocks_image_text_block_parent_id_idx" ON "pages_blocks_image_text_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_image_text_block_path_idx" ON "pages_blocks_image_text_block" USING btree ("_path");
CREATE INDEX "pages_blocks_image_text_block_image_idx" ON "pages_blocks_image_text_block" USING btree ("image_id");
CREATE INDEX "pages_blocks_card_grid_block_cards_order_idx" ON "pages_blocks_card_grid_block_cards" USING btree ("_order");
CREATE INDEX "pages_blocks_card_grid_block_cards_parent_id_idx" ON "pages_blocks_card_grid_block_cards" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_card_grid_block_cards_image_idx" ON "pages_blocks_card_grid_block_cards" USING btree ("image_id");
CREATE INDEX "pages_blocks_card_grid_block_order_idx" ON "pages_blocks_card_grid_block" USING btree ("_order");
CREATE INDEX "pages_blocks_card_grid_block_parent_id_idx" ON "pages_blocks_card_grid_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_card_grid_block_path_idx" ON "pages_blocks_card_grid_block" USING btree ("_path");
CREATE INDEX "pages_blocks_quote_block_order_idx" ON "pages_blocks_quote_block" USING btree ("_order");
CREATE INDEX "pages_blocks_quote_block_parent_id_idx" ON "pages_blocks_quote_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_quote_block_path_idx" ON "pages_blocks_quote_block" USING btree ("_path");
CREATE INDEX "pages_blocks_quote_block_image_idx" ON "pages_blocks_quote_block" USING btree ("image_id");
CREATE INDEX "pages_blocks_cta_block_buttons_order_idx" ON "pages_blocks_cta_block_buttons" USING btree ("_order");
CREATE INDEX "pages_blocks_cta_block_buttons_parent_id_idx" ON "pages_blocks_cta_block_buttons" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_cta_block_order_idx" ON "pages_blocks_cta_block" USING btree ("_order");
CREATE INDEX "pages_blocks_cta_block_parent_id_idx" ON "pages_blocks_cta_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_cta_block_path_idx" ON "pages_blocks_cta_block" USING btree ("_path");
CREATE INDEX "pages_blocks_contact_form_block_order_idx" ON "pages_blocks_contact_form_block" USING btree ("_order");
CREATE INDEX "pages_blocks_contact_form_block_parent_id_idx" ON "pages_blocks_contact_form_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_contact_form_block_path_idx" ON "pages_blocks_contact_form_block" USING btree ("_path");
CREATE INDEX "pages_blocks_timeline_block_events_order_idx" ON "pages_blocks_timeline_block_events" USING btree ("_order");
CREATE INDEX "pages_blocks_timeline_block_events_parent_id_idx" ON "pages_blocks_timeline_block_events" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_timeline_block_events_image_idx" ON "pages_blocks_timeline_block_events" USING btree ("image_id");
CREATE INDEX "pages_blocks_timeline_block_order_idx" ON "pages_blocks_timeline_block" USING btree ("_order");
CREATE INDEX "pages_blocks_timeline_block_parent_id_idx" ON "pages_blocks_timeline_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_timeline_block_path_idx" ON "pages_blocks_timeline_block" USING btree ("_path");
CREATE INDEX "pages_blocks_divider_block_order_idx" ON "pages_blocks_divider_block" USING btree ("_order");
CREATE INDEX "pages_blocks_divider_block_parent_id_idx" ON "pages_blocks_divider_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_divider_block_path_idx" ON "pages_blocks_divider_block" USING btree ("_path");
CREATE INDEX "pages_blocks_video_block_order_idx" ON "pages_blocks_video_block" USING btree ("_order");
CREATE INDEX "pages_blocks_video_block_parent_id_idx" ON "pages_blocks_video_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_video_block_path_idx" ON "pages_blocks_video_block" USING btree ("_path");
ALTER TABLE "pages" DROP COLUMN "content";`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
DROP TABLE "pages_blocks_hero_block" CASCADE;
DROP TABLE "pages_blocks_text_block" CASCADE;
DROP TABLE "pages_blocks_image_text_block" CASCADE;
DROP TABLE "pages_blocks_card_grid_block_cards" CASCADE;
DROP TABLE "pages_blocks_card_grid_block" CASCADE;
DROP TABLE "pages_blocks_quote_block" CASCADE;
DROP TABLE "pages_blocks_cta_block_buttons" CASCADE;
DROP TABLE "pages_blocks_cta_block" CASCADE;
DROP TABLE "pages_blocks_contact_form_block" CASCADE;
DROP TABLE "pages_blocks_timeline_block_events" CASCADE;
DROP TABLE "pages_blocks_timeline_block" CASCADE;
DROP TABLE "pages_blocks_divider_block" CASCADE;
DROP TABLE "pages_blocks_video_block" CASCADE;
ALTER TABLE "pages" ADD COLUMN "content" jsonb;
DROP TYPE "public"."enum_pages_blocks_hero_block_alignment";
DROP TYPE "public"."enum_pages_blocks_hero_block_cta_style";
DROP TYPE "public"."enum_pages_blocks_text_block_width";
DROP TYPE "public"."enum_pages_blocks_image_text_block_image_position";
DROP TYPE "public"."enum_pages_blocks_card_grid_block_columns";
DROP TYPE "public"."enum_pages_blocks_quote_block_style";
DROP TYPE "public"."enum_pages_blocks_cta_block_buttons_style";
DROP TYPE "public"."enum_pages_blocks_cta_block_background_color";
DROP TYPE "public"."enum_pages_blocks_divider_block_style";
DROP TYPE "public"."enum_pages_blocks_divider_block_spacing";
DROP TYPE "public"."enum_pages_blocks_video_block_aspect_ratio";`)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,122 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
CREATE TYPE "public"."enum_cookie_configurations_enabled_categories" AS ENUM('necessary', 'functional', 'analytics', 'marketing');
CREATE TYPE "public"."enum_cookie_configurations_styling_position" AS ENUM('bottom', 'top', 'middle');
CREATE TYPE "public"."enum_cookie_configurations_styling_theme" AS ENUM('dark', 'light', 'auto');
CREATE TYPE "public"."enum_cookie_inventory_category" AS ENUM('necessary', 'functional', 'analytics', 'marketing');
CREATE TABLE "cookie_configurations_enabled_categories" (
"order" integer NOT NULL,
"parent_id" integer NOT NULL,
"value" "enum_cookie_configurations_enabled_categories",
"id" serial PRIMARY KEY NOT NULL
);
CREATE TABLE "cookie_configurations" (
"id" serial PRIMARY KEY NOT NULL,
"tenant_id" integer NOT NULL,
"title" varchar DEFAULT 'Cookie-Einstellungen' NOT NULL,
"revision" numeric DEFAULT 1 NOT NULL,
"translations_de_banner_title" varchar DEFAULT 'Wir respektieren Ihre Privatsphäre',
"translations_de_banner_description" varchar DEFAULT 'Diese Website verwendet Cookies, um Ihnen die bestmögliche Erfahrung zu bieten. Sie können Ihre Einstellungen jederzeit anpassen.',
"translations_de_accept_all_button" varchar DEFAULT 'Alle akzeptieren',
"translations_de_accept_necessary_button" varchar DEFAULT 'Nur notwendige',
"translations_de_settings_button" varchar DEFAULT 'Einstellungen',
"translations_de_save_button" varchar DEFAULT 'Auswahl speichern',
"translations_de_privacy_policy_url" varchar DEFAULT '/datenschutz',
"translations_de_category_labels_necessary_title" varchar DEFAULT 'Notwendig',
"translations_de_category_labels_necessary_description" varchar DEFAULT 'Diese Cookies sind für die Grundfunktionen der Website erforderlich.',
"translations_de_category_labels_functional_title" varchar DEFAULT 'Funktional',
"translations_de_category_labels_functional_description" varchar DEFAULT 'Diese Cookies ermöglichen erweiterte Funktionen und Personalisierung.',
"translations_de_category_labels_analytics_title" varchar DEFAULT 'Statistik',
"translations_de_category_labels_analytics_description" varchar DEFAULT 'Diese Cookies helfen uns zu verstehen, wie Besucher mit der Website interagieren.',
"translations_de_category_labels_marketing_title" varchar DEFAULT 'Marketing',
"translations_de_category_labels_marketing_description" varchar DEFAULT 'Diese Cookies werden verwendet, um Werbung relevanter für Sie zu gestalten.',
"styling_position" "enum_cookie_configurations_styling_position" DEFAULT 'bottom',
"styling_theme" "enum_cookie_configurations_styling_theme" DEFAULT 'dark',
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "cookie_inventory" (
"id" serial PRIMARY KEY NOT NULL,
"tenant_id" integer NOT NULL,
"name" varchar NOT NULL,
"provider" varchar NOT NULL,
"category" "enum_cookie_inventory_category" NOT NULL,
"duration" varchar NOT NULL,
"description" varchar NOT NULL,
"is_active" boolean DEFAULT true,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE TABLE "consent_logs" (
"id" serial PRIMARY KEY NOT NULL,
"consent_id" varchar NOT NULL,
"client_ref" varchar,
"tenant_id" integer NOT NULL,
"categories" jsonb NOT NULL,
"revision" numeric NOT NULL,
"user_agent" varchar,
"anonymized_ip" varchar,
"expires_at" timestamp(3) with time zone NOT NULL,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "cookie_configurations_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "cookie_inventory_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "consent_logs_id" integer;
ALTER TABLE "cookie_configurations_enabled_categories" ADD CONSTRAINT "cookie_configurations_enabled_categories_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."cookie_configurations"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "cookie_configurations" ADD CONSTRAINT "cookie_configurations_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "cookie_inventory" ADD CONSTRAINT "cookie_inventory_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "consent_logs" ADD CONSTRAINT "consent_logs_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
CREATE INDEX "cookie_configurations_enabled_categories_order_idx" ON "cookie_configurations_enabled_categories" USING btree ("order");
CREATE INDEX "cookie_configurations_enabled_categories_parent_idx" ON "cookie_configurations_enabled_categories" USING btree ("parent_id");
CREATE UNIQUE INDEX "cookie_configurations_tenant_idx" ON "cookie_configurations" USING btree ("tenant_id");
CREATE INDEX "cookie_configurations_updated_at_idx" ON "cookie_configurations" USING btree ("updated_at");
CREATE INDEX "cookie_configurations_created_at_idx" ON "cookie_configurations" USING btree ("created_at");
CREATE INDEX "cookie_inventory_tenant_idx" ON "cookie_inventory" USING btree ("tenant_id");
CREATE INDEX "cookie_inventory_updated_at_idx" ON "cookie_inventory" USING btree ("updated_at");
CREATE INDEX "cookie_inventory_created_at_idx" ON "cookie_inventory" USING btree ("created_at");
CREATE UNIQUE INDEX "consent_logs_consent_id_idx" ON "consent_logs" USING btree ("consent_id");
CREATE INDEX "consent_logs_tenant_idx" ON "consent_logs" USING btree ("tenant_id");
CREATE INDEX "consent_logs_updated_at_idx" ON "consent_logs" USING btree ("updated_at");
CREATE INDEX "consent_logs_created_at_idx" ON "consent_logs" USING btree ("created_at");
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_cookie_configurations_fk" FOREIGN KEY ("cookie_configurations_id") REFERENCES "public"."cookie_configurations"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_cookie_inventory_fk" FOREIGN KEY ("cookie_inventory_id") REFERENCES "public"."cookie_inventory"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_consent_logs_fk" FOREIGN KEY ("consent_logs_id") REFERENCES "public"."consent_logs"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "payload_locked_documents_rels_cookie_configurations_id_idx" ON "payload_locked_documents_rels" USING btree ("cookie_configurations_id");
CREATE INDEX "payload_locked_documents_rels_cookie_inventory_id_idx" ON "payload_locked_documents_rels" USING btree ("cookie_inventory_id");
CREATE INDEX "payload_locked_documents_rels_consent_logs_id_idx" ON "payload_locked_documents_rels" USING btree ("consent_logs_id");`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
ALTER TABLE "cookie_configurations_enabled_categories" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "cookie_configurations" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "cookie_inventory" DISABLE ROW LEVEL SECURITY;
ALTER TABLE "consent_logs" DISABLE ROW LEVEL SECURITY;
DROP TABLE "cookie_configurations_enabled_categories" CASCADE;
DROP TABLE "cookie_configurations" CASCADE;
DROP TABLE "cookie_inventory" CASCADE;
DROP TABLE "consent_logs" CASCADE;
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_cookie_configurations_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_cookie_inventory_fk";
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_consent_logs_fk";
DROP INDEX "payload_locked_documents_rels_cookie_configurations_id_idx";
DROP INDEX "payload_locked_documents_rels_cookie_inventory_id_idx";
DROP INDEX "payload_locked_documents_rels_consent_logs_id_idx";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "cookie_configurations_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "cookie_inventory_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "consent_logs_id";
DROP TYPE "public"."enum_cookie_configurations_enabled_categories";
DROP TYPE "public"."enum_cookie_configurations_styling_position";
DROP TYPE "public"."enum_cookie_configurations_styling_theme";
DROP TYPE "public"."enum_cookie_inventory_category";`)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,61 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
CREATE TYPE "public"."enum_privacy_policy_settings_provider" AS ENUM('alfright', 'internal');
CREATE TYPE "public"."enum_privacy_policy_settings_alfright_language" AS ENUM('de-de', 'de-at', 'de-ch', 'en-gb', 'en-us');
CREATE TABLE "privacy_policy_settings" (
"id" serial PRIMARY KEY NOT NULL,
"tenant_id" integer NOT NULL,
"title" varchar DEFAULT 'Datenschutzerklärung' NOT NULL,
"provider" "enum_privacy_policy_settings_provider" DEFAULT 'alfright' NOT NULL,
"alfright_tenant_id" varchar DEFAULT 'alfright_schutzteam',
"alfright_api_key" varchar,
"alfright_language" "enum_privacy_policy_settings_alfright_language" DEFAULT 'de-de',
"alfright_iframe_height" numeric DEFAULT 4000,
"styling_header_color" varchar DEFAULT '#ca8a04',
"styling_header_font" varchar DEFAULT 'Inter, sans-serif',
"styling_header_size" varchar DEFAULT '24px',
"styling_subheader_size" varchar DEFAULT '18px',
"styling_font_color" varchar DEFAULT '#f3f4f6',
"styling_text_font" varchar DEFAULT 'Inter, sans-serif',
"styling_text_size" varchar DEFAULT '16px',
"styling_link_color" varchar DEFAULT '#ca8a04',
"styling_background_color" varchar DEFAULT '#111827',
"show_cookie_table" boolean DEFAULT true,
"cookie_table_title" varchar DEFAULT 'Übersicht der verwendeten Cookies',
"cookie_table_description" varchar DEFAULT 'Ergänzend zur Datenschutzerklärung finden Sie hier eine detaillierte Übersicht aller auf dieser Website eingesetzten Cookies. Sie können Ihre Cookie-Einstellungen jederzeit über den Link "Cookie-Einstellungen" im Footer anpassen.',
"seo_meta_title" varchar DEFAULT 'Datenschutzerklärung',
"seo_meta_description" varchar DEFAULT 'Informationen zum Datenschutz und zur Verarbeitung Ihrer personenbezogenen Daten.',
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
ALTER TABLE "cookie_configurations" ALTER COLUMN "translations_de_banner_description" SET DEFAULT 'Diese Website verwendet Cookies, um Ihnen die bestmögliche Erfahrung zu bieten.';
ALTER TABLE "cookie_configurations" ALTER COLUMN "translations_de_category_labels_functional_description" SET DEFAULT 'Diese Cookies ermöglichen erweiterte Funktionen.';
ALTER TABLE "cookie_configurations" ALTER COLUMN "translations_de_category_labels_analytics_description" SET DEFAULT 'Diese Cookies helfen uns zu verstehen, wie Besucher die Website nutzen.';
ALTER TABLE "cookie_configurations" ALTER COLUMN "translations_de_category_labels_marketing_description" SET DEFAULT 'Diese Cookies werden für Werbezwecke verwendet.';
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "privacy_policy_settings_id" integer;
ALTER TABLE "privacy_policy_settings" ADD CONSTRAINT "privacy_policy_settings_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
CREATE UNIQUE INDEX "privacy_policy_settings_tenant_idx" ON "privacy_policy_settings" USING btree ("tenant_id");
CREATE INDEX "privacy_policy_settings_updated_at_idx" ON "privacy_policy_settings" USING btree ("updated_at");
CREATE INDEX "privacy_policy_settings_created_at_idx" ON "privacy_policy_settings" USING btree ("created_at");
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_privacy_policy_settings_fk" FOREIGN KEY ("privacy_policy_settings_id") REFERENCES "public"."privacy_policy_settings"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "payload_locked_documents_rels_privacy_policy_settings_id_idx" ON "payload_locked_documents_rels" USING btree ("privacy_policy_settings_id");`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
ALTER TABLE "privacy_policy_settings" DISABLE ROW LEVEL SECURITY;
DROP TABLE "privacy_policy_settings" CASCADE;
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_privacy_policy_settings_fk";
DROP INDEX "payload_locked_documents_rels_privacy_policy_settings_id_idx";
ALTER TABLE "cookie_configurations" ALTER COLUMN "translations_de_banner_description" SET DEFAULT 'Diese Website verwendet Cookies, um Ihnen die bestmögliche Erfahrung zu bieten. Sie können Ihre Einstellungen jederzeit anpassen.';
ALTER TABLE "cookie_configurations" ALTER COLUMN "translations_de_category_labels_functional_description" SET DEFAULT 'Diese Cookies ermöglichen erweiterte Funktionen und Personalisierung.';
ALTER TABLE "cookie_configurations" ALTER COLUMN "translations_de_category_labels_analytics_description" SET DEFAULT 'Diese Cookies helfen uns zu verstehen, wie Besucher mit der Website interagieren.';
ALTER TABLE "cookie_configurations" ALTER COLUMN "translations_de_category_labels_marketing_description" SET DEFAULT 'Diese Cookies werden verwendet, um Werbung relevanter für Sie zu gestalten.';
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "privacy_policy_settings_id";
DROP TYPE "public"."enum_privacy_policy_settings_provider";
DROP TYPE "public"."enum_privacy_policy_settings_alfright_language";`)
}

View file

@ -0,0 +1,170 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
-- ENUMs für neue Collections
CREATE TYPE "public"."enum_posts_type" AS ENUM('blog', 'news', 'press', 'announcement');
CREATE TYPE "public"."enum_newsletter_subscribers_status" AS ENUM('pending', 'confirmed', 'unsubscribed', 'bounced');
-- Testimonials Collection
CREATE TABLE IF NOT EXISTS "testimonials" (
"id" serial PRIMARY KEY NOT NULL,
"tenant_id" integer,
"quote" varchar NOT NULL,
"author" varchar NOT NULL,
"role" varchar,
"company" varchar,
"image_id" integer,
"rating" numeric,
"source" varchar,
"source_url" varchar,
"date" timestamp(3) with time zone,
"is_active" boolean DEFAULT true,
"order" integer DEFAULT 0,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE INDEX IF NOT EXISTS "testimonials_tenant_idx" ON "testimonials" USING btree ("tenant_id");
CREATE INDEX IF NOT EXISTS "testimonials_created_at_idx" ON "testimonials" USING btree ("created_at");
CREATE INDEX IF NOT EXISTS "testimonials_updated_at_idx" ON "testimonials" USING btree ("updated_at");
ALTER TABLE "testimonials" ADD CONSTRAINT "testimonials_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "testimonials" ADD CONSTRAINT "testimonials_image_id_media_id_fk" FOREIGN KEY ("image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
-- Newsletter Subscribers Collection
CREATE TABLE IF NOT EXISTS "newsletter_subscribers" (
"id" serial PRIMARY KEY NOT NULL,
"tenant_id" integer,
"email" varchar NOT NULL,
"first_name" varchar,
"last_name" varchar,
"status" "enum_newsletter_subscribers_status" DEFAULT 'pending',
"source" varchar,
"subscribed_at" timestamp(3) with time zone,
"confirmed_at" timestamp(3) with time zone,
"unsubscribed_at" timestamp(3) with time zone,
"confirmation_token" varchar,
"ip_address" varchar,
"user_agent" varchar,
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
);
CREATE INDEX IF NOT EXISTS "newsletter_subscribers_tenant_idx" ON "newsletter_subscribers" USING btree ("tenant_id");
CREATE INDEX IF NOT EXISTS "newsletter_subscribers_email_idx" ON "newsletter_subscribers" USING btree ("email");
CREATE INDEX IF NOT EXISTS "newsletter_subscribers_created_at_idx" ON "newsletter_subscribers" USING btree ("created_at");
ALTER TABLE "newsletter_subscribers" ADD CONSTRAINT "newsletter_subscribers_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
-- Newsletter Subscribers Interests (hasMany select)
CREATE TABLE IF NOT EXISTS "newsletter_subscribers_interests" (
"order" integer NOT NULL,
"parent_id" integer NOT NULL,
"value" varchar,
"id" serial PRIMARY KEY NOT NULL
);
CREATE INDEX IF NOT EXISTS "newsletter_subscribers_interests_order_idx" ON "newsletter_subscribers_interests" USING btree ("order");
CREATE INDEX IF NOT EXISTS "newsletter_subscribers_interests_parent_idx" ON "newsletter_subscribers_interests" USING btree ("parent_id");
ALTER TABLE "newsletter_subscribers_interests" ADD CONSTRAINT "newsletter_subscribers_interests_parent_id_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."newsletter_subscribers"("id") ON DELETE cascade ON UPDATE no action;
-- Pages Rels (für Block-Relationships)
CREATE TABLE IF NOT EXISTS "pages_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"categories_id" integer,
"testimonials_id" integer
);
CREATE INDEX IF NOT EXISTS "pages_rels_order_idx" ON "pages_rels" USING btree ("order");
CREATE INDEX IF NOT EXISTS "pages_rels_parent_idx" ON "pages_rels" USING btree ("parent_id");
CREATE INDEX IF NOT EXISTS "pages_rels_path_idx" ON "pages_rels" USING btree ("path");
ALTER TABLE "pages_rels" ADD CONSTRAINT "pages_rels_parent_id_pages_id_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_rels" ADD CONSTRAINT "pages_rels_categories_id_categories_id_fk" FOREIGN KEY ("categories_id") REFERENCES "public"."categories"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_rels" ADD CONSTRAINT "pages_rels_testimonials_id_testimonials_id_fk" FOREIGN KEY ("testimonials_id") REFERENCES "public"."testimonials"("id") ON DELETE cascade ON UPDATE no action;
-- Posts Rels (für Category Relationships)
CREATE TABLE IF NOT EXISTS "posts_rels" (
"id" serial PRIMARY KEY NOT NULL,
"order" integer,
"parent_id" integer NOT NULL,
"path" varchar NOT NULL,
"categories_id" integer
);
CREATE INDEX IF NOT EXISTS "posts_rels_order_idx" ON "posts_rels" USING btree ("order");
CREATE INDEX IF NOT EXISTS "posts_rels_parent_idx" ON "posts_rels" USING btree ("parent_id");
CREATE INDEX IF NOT EXISTS "posts_rels_path_idx" ON "posts_rels" USING btree ("path");
ALTER TABLE "posts_rels" ADD CONSTRAINT "posts_rels_parent_id_posts_id_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."posts"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "posts_rels" ADD CONSTRAINT "posts_rels_categories_id_categories_id_fk" FOREIGN KEY ("categories_id") REFERENCES "public"."categories"("id") ON DELETE cascade ON UPDATE no action;
-- Füge type-Feld zu posts hinzu (falls nicht vorhanden)
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'posts' AND column_name = 'type') THEN
ALTER TABLE "posts" ADD COLUMN "type" "enum_posts_type" DEFAULT 'blog';
END IF;
END $$;
-- Füge isFeatured-Feld zu posts hinzu (falls nicht vorhanden)
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'posts' AND column_name = 'is_featured') THEN
ALTER TABLE "posts" ADD COLUMN "is_featured" boolean DEFAULT false;
END IF;
END $$;
-- Füge excerpt-Feld zu posts hinzu (falls nicht vorhanden)
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'posts' AND column_name = 'excerpt') THEN
ALTER TABLE "posts" ADD COLUMN "excerpt" varchar;
END IF;
END $$;
-- Payload Locked Documents Rels erweitern
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'payload_locked_documents_rels' AND column_name = 'testimonials_id') THEN
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "testimonials_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_testimonials_fk" FOREIGN KEY ("testimonials_id") REFERENCES "public"."testimonials"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "payload_locked_documents_rels_testimonials_id_idx" ON "payload_locked_documents_rels" USING btree ("testimonials_id");
END IF;
END $$;
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'payload_locked_documents_rels' AND column_name = 'newsletter_subscribers_id') THEN
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "newsletter_subscribers_id" integer;
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_newsletter_subscribers_fk" FOREIGN KEY ("newsletter_subscribers_id") REFERENCES "public"."newsletter_subscribers"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "payload_locked_documents_rels_newsletter_subscribers_id_idx" ON "payload_locked_documents_rels" USING btree ("newsletter_subscribers_id");
END IF;
END $$;
`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
DROP TABLE IF EXISTS "pages_rels" CASCADE;
DROP TABLE IF EXISTS "posts_rels" CASCADE;
DROP TABLE IF EXISTS "newsletter_subscribers_interests" CASCADE;
DROP TABLE IF EXISTS "newsletter_subscribers" CASCADE;
DROP TABLE IF EXISTS "testimonials" CASCADE;
ALTER TABLE "posts" DROP COLUMN IF EXISTS "type";
ALTER TABLE "posts" DROP COLUMN IF EXISTS "is_featured";
ALTER TABLE "posts" DROP COLUMN IF EXISTS "excerpt";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN IF EXISTS "testimonials_id";
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN IF EXISTS "newsletter_subscribers_id";
DROP TYPE IF EXISTS "enum_posts_type";
DROP TYPE IF EXISTS "enum_newsletter_subscribers_status";
`)
}

View file

@ -0,0 +1,177 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
-- Neue Felder für Media Collection
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "caption" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "credit" varchar;
-- Image Size Spalten für optimierte Bildvarianten
-- WebP Varianten
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_thumbnail_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_thumbnail_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_thumbnail_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_thumbnail_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_thumbnail_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_thumbnail_filename" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_small_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_small_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_small_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_small_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_small_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_small_filename" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_filename" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_filename" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_filename" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_2k_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_2k_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_2k_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_2k_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_2k_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_2k_filename" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_og_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_og_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_og_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_og_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_og_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_og_filename" varchar;
-- AVIF Varianten
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_avif_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_avif_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_avif_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_avif_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_avif_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_medium_avif_filename" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_avif_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_avif_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_avif_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_avif_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_avif_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_large_avif_filename" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_avif_url" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_avif_width" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_avif_height" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_avif_mime_type" varchar;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_avif_filesize" numeric;
ALTER TABLE "media" ADD COLUMN IF NOT EXISTS "sizes_xlarge_avif_filename" varchar;
-- Tags Tabelle (hasMany text)
CREATE TABLE IF NOT EXISTS "media_tags" (
"order" integer NOT NULL,
"parent_id" integer NOT NULL,
"value" varchar,
"id" serial PRIMARY KEY NOT NULL
);
CREATE INDEX IF NOT EXISTS "media_tags_order_idx" ON "media_tags" USING btree ("order");
CREATE INDEX IF NOT EXISTS "media_tags_parent_idx" ON "media_tags" USING btree ("parent_id");
ALTER TABLE "media_tags" DROP CONSTRAINT IF EXISTS "media_tags_parent_id_fk";
ALTER TABLE "media_tags" ADD CONSTRAINT "media_tags_parent_id_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."media"("id") ON DELETE cascade ON UPDATE no action;
`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
ALTER TABLE "media" DROP COLUMN IF EXISTS "caption";
ALTER TABLE "media" DROP COLUMN IF EXISTS "credit";
-- WebP Sizes
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_thumbnail_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_thumbnail_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_thumbnail_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_thumbnail_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_thumbnail_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_thumbnail_filename";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_small_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_small_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_small_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_small_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_small_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_small_filename";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_filename";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_filename";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_filename";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_2k_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_2k_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_2k_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_2k_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_2k_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_2k_filename";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_og_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_og_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_og_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_og_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_og_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_og_filename";
-- AVIF Sizes
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_avif_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_avif_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_avif_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_avif_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_avif_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_medium_avif_filename";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_avif_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_avif_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_avif_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_avif_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_avif_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_large_avif_filename";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_avif_url";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_avif_width";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_avif_height";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_avif_mime_type";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_avif_filesize";
ALTER TABLE "media" DROP COLUMN IF EXISTS "sizes_xlarge_avif_filename";
DROP TABLE IF EXISTS "media_tags" CASCADE;
`)
}

View file

@ -0,0 +1,269 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
-- Posts List Block Table
CREATE TABLE IF NOT EXISTS "pages_blocks_posts_list_block" (
"id" serial PRIMARY KEY NOT NULL,
"_parent_id" integer NOT NULL,
"_order" integer NOT NULL,
"_path" varchar NOT NULL,
"title" varchar,
"subtitle" varchar,
"post_type" varchar DEFAULT 'blog',
"layout" varchar DEFAULT 'grid',
"columns" varchar DEFAULT '3',
"limit" integer DEFAULT 6,
"show_featured_only" boolean DEFAULT false,
"show_excerpt" boolean DEFAULT true,
"show_date" boolean DEFAULT true,
"show_author" boolean DEFAULT false,
"show_category" boolean DEFAULT true,
"show_pagination" boolean DEFAULT false,
"show_read_more" boolean DEFAULT true,
"read_more_label" varchar DEFAULT 'Alle Beiträge anzeigen',
"read_more_link" varchar DEFAULT '/blog',
"background_color" varchar DEFAULT 'white',
"block_name" varchar
);
CREATE INDEX IF NOT EXISTS "pages_blocks_posts_list_block_parent_idx" ON "pages_blocks_posts_list_block" USING btree ("_parent_id");
CREATE INDEX IF NOT EXISTS "pages_blocks_posts_list_block_order_idx" ON "pages_blocks_posts_list_block" USING btree ("_order");
CREATE INDEX IF NOT EXISTS "pages_blocks_posts_list_block_path_idx" ON "pages_blocks_posts_list_block" USING btree ("_path");
ALTER TABLE "pages_blocks_posts_list_block" DROP CONSTRAINT IF EXISTS "pages_blocks_posts_list_block_parent_id_fk";
ALTER TABLE "pages_blocks_posts_list_block" ADD CONSTRAINT "pages_blocks_posts_list_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
-- Testimonials Block Table
CREATE TABLE IF NOT EXISTS "pages_blocks_testimonials_block" (
"id" serial PRIMARY KEY NOT NULL,
"_parent_id" integer NOT NULL,
"_order" integer NOT NULL,
"_path" varchar NOT NULL,
"title" varchar DEFAULT 'Das sagen unsere Kunden',
"subtitle" varchar,
"layout" varchar DEFAULT 'slider',
"columns" varchar DEFAULT '3',
"display_mode" varchar DEFAULT 'all',
"limit" integer DEFAULT 6,
"show_rating" boolean DEFAULT true,
"show_image" boolean DEFAULT true,
"show_company" boolean DEFAULT true,
"show_source" boolean DEFAULT false,
"autoplay" boolean DEFAULT true,
"autoplay_speed" integer DEFAULT 5000,
"background_color" varchar DEFAULT 'light',
"block_name" varchar
);
CREATE INDEX IF NOT EXISTS "pages_blocks_testimonials_block_parent_idx" ON "pages_blocks_testimonials_block" USING btree ("_parent_id");
CREATE INDEX IF NOT EXISTS "pages_blocks_testimonials_block_order_idx" ON "pages_blocks_testimonials_block" USING btree ("_order");
CREATE INDEX IF NOT EXISTS "pages_blocks_testimonials_block_path_idx" ON "pages_blocks_testimonials_block" USING btree ("_path");
ALTER TABLE "pages_blocks_testimonials_block" DROP CONSTRAINT IF EXISTS "pages_blocks_testimonials_block_parent_id_fk";
ALTER TABLE "pages_blocks_testimonials_block" ADD CONSTRAINT "pages_blocks_testimonials_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
-- Newsletter Block Table
CREATE TABLE IF NOT EXISTS "pages_blocks_newsletter_block" (
"id" serial PRIMARY KEY NOT NULL,
"_parent_id" integer NOT NULL,
"_order" integer NOT NULL,
"_path" varchar NOT NULL,
"title" varchar DEFAULT 'Newsletter abonnieren',
"subtitle" varchar,
"layout" varchar DEFAULT 'inline',
"image_id" integer,
"image_position" varchar DEFAULT 'left',
"collect_name" boolean DEFAULT false,
"show_interests" boolean DEFAULT false,
"button_text" varchar DEFAULT 'Anmelden',
"placeholder_email" varchar DEFAULT 'Ihre E-Mail-Adresse',
"success_message" varchar,
"error_message" varchar,
"privacy_text" varchar,
"privacy_link" varchar DEFAULT '/datenschutz',
"source" varchar DEFAULT 'website',
"background_color" varchar DEFAULT 'accent',
"block_name" varchar
);
CREATE INDEX IF NOT EXISTS "pages_blocks_newsletter_block_parent_idx" ON "pages_blocks_newsletter_block" USING btree ("_parent_id");
CREATE INDEX IF NOT EXISTS "pages_blocks_newsletter_block_order_idx" ON "pages_blocks_newsletter_block" USING btree ("_order");
CREATE INDEX IF NOT EXISTS "pages_blocks_newsletter_block_path_idx" ON "pages_blocks_newsletter_block" USING btree ("_path");
ALTER TABLE "pages_blocks_newsletter_block" DROP CONSTRAINT IF EXISTS "pages_blocks_newsletter_block_parent_id_fk";
ALTER TABLE "pages_blocks_newsletter_block" ADD CONSTRAINT "pages_blocks_newsletter_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_newsletter_block" DROP CONSTRAINT IF EXISTS "pages_blocks_newsletter_block_image_id_fk";
ALTER TABLE "pages_blocks_newsletter_block" ADD CONSTRAINT "pages_blocks_newsletter_block_image_id_fk" FOREIGN KEY ("image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
-- Newsletter Block Available Interests (hasMany select)
CREATE TABLE IF NOT EXISTS "pages_blocks_newsletter_block_available_interests" (
"id" serial PRIMARY KEY NOT NULL,
"parent_id" integer NOT NULL,
"order" integer NOT NULL,
"value" varchar
);
CREATE INDEX IF NOT EXISTS "pages_blocks_newsletter_block_available_interests_parent_idx" ON "pages_blocks_newsletter_block_available_interests" USING btree ("parent_id");
CREATE INDEX IF NOT EXISTS "pages_blocks_newsletter_block_available_interests_order_idx" ON "pages_blocks_newsletter_block_available_interests" USING btree ("order");
ALTER TABLE "pages_blocks_newsletter_block_available_interests" DROP CONSTRAINT IF EXISTS "pages_blocks_newsletter_block_available_interests_parent_id_fk";
ALTER TABLE "pages_blocks_newsletter_block_available_interests" ADD CONSTRAINT "pages_blocks_newsletter_block_available_interests_parent_id_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."pages_blocks_newsletter_block"("id") ON DELETE cascade ON UPDATE no action;
-- Process Steps Block Table
CREATE TABLE IF NOT EXISTS "pages_blocks_process_steps_block" (
"id" serial PRIMARY KEY NOT NULL,
"_parent_id" integer NOT NULL,
"_order" integer NOT NULL,
"_path" varchar NOT NULL,
"title" varchar DEFAULT 'So funktioniert es',
"subtitle" varchar,
"layout" varchar DEFAULT 'horizontal',
"show_numbers" boolean DEFAULT true,
"show_icons" boolean DEFAULT true,
"cta_show" boolean DEFAULT false,
"cta_label" varchar DEFAULT 'Jetzt starten',
"cta_href" varchar,
"cta_variant" varchar DEFAULT 'default',
"background_color" varchar DEFAULT 'white',
"block_name" varchar
);
CREATE INDEX IF NOT EXISTS "pages_blocks_process_steps_block_parent_idx" ON "pages_blocks_process_steps_block" USING btree ("_parent_id");
CREATE INDEX IF NOT EXISTS "pages_blocks_process_steps_block_order_idx" ON "pages_blocks_process_steps_block" USING btree ("_order");
CREATE INDEX IF NOT EXISTS "pages_blocks_process_steps_block_path_idx" ON "pages_blocks_process_steps_block" USING btree ("_path");
ALTER TABLE "pages_blocks_process_steps_block" DROP CONSTRAINT IF EXISTS "pages_blocks_process_steps_block_parent_id_fk";
ALTER TABLE "pages_blocks_process_steps_block" ADD CONSTRAINT "pages_blocks_process_steps_block_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
-- Process Steps Block Steps (array)
CREATE TABLE IF NOT EXISTS "pages_blocks_process_steps_block_steps" (
"id" serial PRIMARY KEY NOT NULL,
"_parent_id" integer NOT NULL,
"_order" integer NOT NULL,
"title" varchar NOT NULL,
"description" varchar,
"icon" varchar,
"image_id" integer
);
CREATE INDEX IF NOT EXISTS "pages_blocks_process_steps_block_steps_parent_idx" ON "pages_blocks_process_steps_block_steps" USING btree ("_parent_id");
CREATE INDEX IF NOT EXISTS "pages_blocks_process_steps_block_steps_order_idx" ON "pages_blocks_process_steps_block_steps" USING btree ("_order");
ALTER TABLE "pages_blocks_process_steps_block_steps" DROP CONSTRAINT IF EXISTS "pages_blocks_process_steps_block_steps_parent_id_fk";
ALTER TABLE "pages_blocks_process_steps_block_steps" ADD CONSTRAINT "pages_blocks_process_steps_block_steps_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_process_steps_block"("id") ON DELETE cascade ON UPDATE no action;
ALTER TABLE "pages_blocks_process_steps_block_steps" DROP CONSTRAINT IF EXISTS "pages_blocks_process_steps_block_steps_image_id_fk";
ALTER TABLE "pages_blocks_process_steps_block_steps" ADD CONSTRAINT "pages_blocks_process_steps_block_steps_image_id_fk" FOREIGN KEY ("image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
-- SEO Settings Global
CREATE TABLE IF NOT EXISTS "seo_settings" (
"id" serial PRIMARY KEY NOT NULL,
"meta_defaults_title_suffix" varchar DEFAULT '| Website',
"meta_defaults_default_description" varchar,
"meta_defaults_default_og_image_id" integer,
"organization_name" varchar,
"organization_legal_name" varchar,
"organization_description" varchar,
"organization_logo_id" integer,
"organization_founding_date" timestamp(3) with time zone,
"contact_email" varchar,
"contact_phone" varchar,
"contact_fax" varchar,
"address_street" varchar,
"address_postal_code" varchar,
"address_city" varchar,
"address_region" varchar,
"address_country" varchar DEFAULT 'Deutschland',
"address_country_code" varchar DEFAULT 'DE',
"geo_latitude" numeric,
"geo_longitude" numeric,
"local_business_enabled" boolean DEFAULT false,
"local_business_type" varchar,
"local_business_price_range" varchar,
"robots_allow_indexing" boolean DEFAULT true,
"verification_google" varchar,
"verification_bing" varchar,
"verification_yandex" varchar,
"updated_at" timestamp(3) with time zone,
"created_at" timestamp(3) with time zone
);
ALTER TABLE "seo_settings" DROP CONSTRAINT IF EXISTS "seo_settings_meta_defaults_default_og_image_id_fk";
ALTER TABLE "seo_settings" ADD CONSTRAINT "seo_settings_meta_defaults_default_og_image_id_fk" FOREIGN KEY ("meta_defaults_default_og_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "seo_settings" DROP CONSTRAINT IF EXISTS "seo_settings_organization_logo_id_fk";
ALTER TABLE "seo_settings" ADD CONSTRAINT "seo_settings_organization_logo_id_fk" FOREIGN KEY ("organization_logo_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
-- SEO Settings Keywords (hasMany text)
CREATE TABLE IF NOT EXISTS "seo_settings_meta_defaults_keywords" (
"id" serial PRIMARY KEY NOT NULL,
"_parent_id" integer NOT NULL,
"order" integer NOT NULL,
"value" varchar
);
CREATE INDEX IF NOT EXISTS "seo_settings_meta_defaults_keywords_parent_idx" ON "seo_settings_meta_defaults_keywords" USING btree ("_parent_id");
CREATE INDEX IF NOT EXISTS "seo_settings_meta_defaults_keywords_order_idx" ON "seo_settings_meta_defaults_keywords" USING btree ("order");
ALTER TABLE "seo_settings_meta_defaults_keywords" DROP CONSTRAINT IF EXISTS "seo_settings_meta_defaults_keywords_parent_id_fk";
ALTER TABLE "seo_settings_meta_defaults_keywords" ADD CONSTRAINT "seo_settings_meta_defaults_keywords_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."seo_settings"("id") ON DELETE cascade ON UPDATE no action;
-- SEO Settings Social Profiles (array)
CREATE TABLE IF NOT EXISTS "seo_settings_social_profiles" (
"id" serial PRIMARY KEY NOT NULL,
"_parent_id" integer NOT NULL,
"_order" integer NOT NULL,
"platform" varchar,
"url" varchar
);
CREATE INDEX IF NOT EXISTS "seo_settings_social_profiles_parent_idx" ON "seo_settings_social_profiles" USING btree ("_parent_id");
CREATE INDEX IF NOT EXISTS "seo_settings_social_profiles_order_idx" ON "seo_settings_social_profiles" USING btree ("_order");
ALTER TABLE "seo_settings_social_profiles" DROP CONSTRAINT IF EXISTS "seo_settings_social_profiles_parent_id_fk";
ALTER TABLE "seo_settings_social_profiles" ADD CONSTRAINT "seo_settings_social_profiles_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."seo_settings"("id") ON DELETE cascade ON UPDATE no action;
-- SEO Settings Opening Hours (array)
CREATE TABLE IF NOT EXISTS "seo_settings_local_business_opening_hours" (
"id" serial PRIMARY KEY NOT NULL,
"_parent_id" integer NOT NULL,
"_order" integer NOT NULL,
"specification" varchar
);
CREATE INDEX IF NOT EXISTS "seo_settings_local_business_opening_hours_parent_idx" ON "seo_settings_local_business_opening_hours" USING btree ("_parent_id");
CREATE INDEX IF NOT EXISTS "seo_settings_local_business_opening_hours_order_idx" ON "seo_settings_local_business_opening_hours" USING btree ("_order");
ALTER TABLE "seo_settings_local_business_opening_hours" DROP CONSTRAINT IF EXISTS "seo_settings_local_business_opening_hours_parent_id_fk";
ALTER TABLE "seo_settings_local_business_opening_hours" ADD CONSTRAINT "seo_settings_local_business_opening_hours_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."seo_settings"("id") ON DELETE cascade ON UPDATE no action;
-- SEO Settings Additional Disallow Paths (hasMany text)
CREATE TABLE IF NOT EXISTS "seo_settings_robots_additional_disallow" (
"id" serial PRIMARY KEY NOT NULL,
"_parent_id" integer NOT NULL,
"order" integer NOT NULL,
"value" varchar
);
CREATE INDEX IF NOT EXISTS "seo_settings_robots_additional_disallow_parent_idx" ON "seo_settings_robots_additional_disallow" USING btree ("_parent_id");
CREATE INDEX IF NOT EXISTS "seo_settings_robots_additional_disallow_order_idx" ON "seo_settings_robots_additional_disallow" USING btree ("order");
ALTER TABLE "seo_settings_robots_additional_disallow" DROP CONSTRAINT IF EXISTS "seo_settings_robots_additional_disallow_parent_id_fk";
ALTER TABLE "seo_settings_robots_additional_disallow" ADD CONSTRAINT "seo_settings_robots_additional_disallow_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."seo_settings"("id") ON DELETE cascade ON UPDATE no action;
`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
DROP TABLE IF EXISTS "pages_blocks_posts_list_block" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_testimonials_block" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_newsletter_block_available_interests" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_newsletter_block" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_process_steps_block_steps" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_process_steps_block" CASCADE;
DROP TABLE IF EXISTS "seo_settings_meta_defaults_keywords" CASCADE;
DROP TABLE IF EXISTS "seo_settings_social_profiles" CASCADE;
DROP TABLE IF EXISTS "seo_settings_local_business_opening_hours" CASCADE;
DROP TABLE IF EXISTS "seo_settings_robots_additional_disallow" CASCADE;
DROP TABLE IF EXISTS "seo_settings" CASCADE;
`)
}

View file

@ -0,0 +1,50 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
/**
* Migration zur Behebung der Schema-Divergenz zwischen Code und Datenbank
*
* Hauptänderungen:
* - media_tags media_texts umbenennen (Payload 3.x Konvention)
* - Spaltenstruktur anpassen (path-Feld hinzufügen)
*/
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
await db.execute(sql`
-- Umbenennen von media_tags zu media_texts
ALTER TABLE IF EXISTS "media_tags" RENAME TO "media_texts";
-- Spalte 'path' hinzufügen falls nicht vorhanden (Payload 3.x benötigt diese)
ALTER TABLE "media_texts" ADD COLUMN IF NOT EXISTS "path" varchar NOT NULL DEFAULT 'tags';
-- Indices umbenennen
ALTER INDEX IF EXISTS "media_tags_order_idx" RENAME TO "media_texts_order_idx";
ALTER INDEX IF EXISTS "media_tags_parent_idx" RENAME TO "media_texts_parent_idx";
-- Constraint umbenennen
ALTER TABLE "media_texts" DROP CONSTRAINT IF EXISTS "media_tags_parent_id_fk";
ALTER TABLE "media_texts" ADD CONSTRAINT "media_texts_parent_id_fk"
FOREIGN KEY ("parent_id") REFERENCES "public"."media"("id") ON DELETE cascade ON UPDATE no action;
-- Path Index hinzufügen
CREATE INDEX IF NOT EXISTS "media_texts_path_idx" ON "media_texts" USING btree ("path");
`)
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
await db.execute(sql`
-- Zurück umbenennen
ALTER TABLE IF EXISTS "media_texts" RENAME TO "media_tags";
-- Spalte entfernen
ALTER TABLE "media_tags" DROP COLUMN IF EXISTS "path";
-- Indices zurück umbenennen
ALTER INDEX IF EXISTS "media_texts_order_idx" RENAME TO "media_tags_order_idx";
ALTER INDEX IF EXISTS "media_texts_parent_idx" RENAME TO "media_tags_parent_idx";
DROP INDEX IF EXISTS "media_texts_path_idx";
-- Constraint zurück
ALTER TABLE "media_tags" DROP CONSTRAINT IF EXISTS "media_texts_parent_id_fk";
ALTER TABLE "media_tags" ADD CONSTRAINT "media_tags_parent_id_fk"
FOREIGN KEY ("parent_id") REFERENCES "public"."media"("id") ON DELETE cascade ON UPDATE no action;
`)
}

View file

@ -0,0 +1,105 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
/**
* Migration: Add Full-Text Search Index for Posts
*
* This migration adds:
* 1. A function to extract text from Lexical JSONB content
* 2. A generated column (search_text) that concatenates searchable fields
* 3. GIN indexes for both German and English full-text search
*
* The FTS can be activated by setting USE_FTS=true environment variable.
* Without this flag, the search API uses ILIKE which works without these indexes.
*/
export async function up({ db }: MigrateUpArgs): Promise<void> {
// 1. Create function to extract text from Lexical JSONB content
await db.execute(sql`
CREATE OR REPLACE FUNCTION extract_lexical_text(content jsonb)
RETURNS text
LANGUAGE sql
IMMUTABLE
PARALLEL SAFE
AS $$
SELECT COALESCE(
string_agg(node_text, ' '),
''
)
FROM (
SELECT jsonb_path_query(
content,
'strict $.root.**.text'
)::text AS node_text
) extracted
WHERE node_text IS NOT NULL
AND node_text != 'null'
$$;
`)
// 2. Add generated column for full searchable text
// This combines title, excerpt, and extracted content text
await db.execute(sql`
ALTER TABLE posts
ADD COLUMN IF NOT EXISTS search_text text
GENERATED ALWAYS AS (
COALESCE(title, '') || ' ' ||
COALESCE(excerpt, '') || ' ' ||
COALESCE(extract_lexical_text(content), '')
) STORED;
`)
// 3. Create GIN index for German full-text search
await db.execute(sql`
CREATE INDEX IF NOT EXISTS posts_search_german_idx
ON posts
USING GIN (to_tsvector('pg_catalog.german', search_text));
`)
// 4. Create GIN index for English full-text search
await db.execute(sql`
CREATE INDEX IF NOT EXISTS posts_search_english_idx
ON posts
USING GIN (to_tsvector('pg_catalog.english', search_text));
`)
// 5. Create btree index on title for faster ILIKE prefix searches
// This is a fallback for when FTS is not used
await db.execute(sql`
CREATE INDEX IF NOT EXISTS posts_title_lower_idx
ON posts (LOWER(title) varchar_pattern_ops);
`)
// Note: For even better ILIKE performance, pg_trgm extension can be enabled manually:
// CREATE EXTENSION IF NOT EXISTS pg_trgm;
// CREATE INDEX posts_title_trgm_idx ON posts USING GIN (title gin_trgm_ops);
}
export async function down({ db }: MigrateDownArgs): Promise<void> {
// Remove indexes
await db.execute(sql`
DROP INDEX IF EXISTS posts_title_lower_idx;
`)
await db.execute(sql`
DROP INDEX IF EXISTS posts_title_trgm_idx;
`)
await db.execute(sql`
DROP INDEX IF EXISTS posts_search_english_idx;
`)
await db.execute(sql`
DROP INDEX IF EXISTS posts_search_german_idx;
`)
// Remove generated column
await db.execute(sql`
ALTER TABLE posts
DROP COLUMN IF EXISTS search_text;
`)
// Remove function
await db.execute(sql`
DROP FUNCTION IF EXISTS extract_lexical_text(jsonb);
`)
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
// Migration code
}
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
// Migration code
}

View file

@ -0,0 +1,75 @@
import * as migration_20251126_163428 from './20251126_163428';
import * as migration_20251126_200521 from './20251126_200521';
import * as migration_20251127_081206 from './20251127_081206';
import * as migration_20251127_085124 from './20251127_085124';
import * as migration_20251127_224713 from './20251127_224713';
import * as migration_20251128_142608 from './20251128_142608';
import * as migration_20251130_135459 from './20251130_135459';
import * as migration_20251130_143000_media_optimization from './20251130_143000_media_optimization';
import * as migration_20251130_150000_blocks_tables from './20251130_150000_blocks_tables';
import * as migration_20251130_160000_fix_schema_divergence from './20251130_160000_fix_schema_divergence';
import * as migration_20251130_170000_add_search_index from './20251130_170000_add_search_index';
import * as migration_20251130_213429_add_localization from './20251130_213429_add_localization';
export const migrations = [
{
up: migration_20251126_163428.up,
down: migration_20251126_163428.down,
name: '20251126_163428',
},
{
up: migration_20251126_200521.up,
down: migration_20251126_200521.down,
name: '20251126_200521',
},
{
up: migration_20251127_081206.up,
down: migration_20251127_081206.down,
name: '20251127_081206',
},
{
up: migration_20251127_085124.up,
down: migration_20251127_085124.down,
name: '20251127_085124',
},
{
up: migration_20251127_224713.up,
down: migration_20251127_224713.down,
name: '20251127_224713',
},
{
up: migration_20251128_142608.up,
down: migration_20251128_142608.down,
name: '20251128_142608',
},
{
up: migration_20251130_135459.up,
down: migration_20251130_135459.down,
name: '20251130_135459',
},
{
up: migration_20251130_143000_media_optimization.up,
down: migration_20251130_143000_media_optimization.down,
name: '20251130_143000_media_optimization',
},
{
up: migration_20251130_150000_blocks_tables.up,
down: migration_20251130_150000_blocks_tables.down,
name: '20251130_150000_blocks_tables',
},
{
up: migration_20251130_160000_fix_schema_divergence.up,
down: migration_20251130_160000_fix_schema_divergence.down,
name: '20251130_160000_fix_schema_divergence',
},
{
up: migration_20251130_170000_add_search_index.up,
down: migration_20251130_170000_add_search_index.down,
name: '20251130_170000_add_search_index',
},
{
up: migration_20251130_213429_add_localization.up,
down: migration_20251130_213429_add_localization.down,
name: '20251130_213429_add_localization'
},
];