mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 20:54:11 +00:00
feat: add Portfolio and PortfolioCategories collections
Add collections for photography portfolio website: - PortfolioCategories: categories with name, slug, cover image, order - Portfolios: galleries with images, project details, SEO fields - Both collections are tenant-scoped and localized (DE/EN) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
f1f3273fa7
commit
cef310c1f6
6 changed files with 14723 additions and 1 deletions
78
src/collections/PortfolioCategories.ts
Normal file
78
src/collections/PortfolioCategories.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
import type { CollectionConfig } from 'payload'
|
||||||
|
import { authenticatedOnly, tenantScopedPublicRead } from '../lib/tenantAccess'
|
||||||
|
|
||||||
|
export const PortfolioCategories: CollectionConfig = {
|
||||||
|
slug: 'portfolio-categories',
|
||||||
|
admin: {
|
||||||
|
useAsTitle: 'name',
|
||||||
|
group: 'Portfolio',
|
||||||
|
description: 'Kategorien für Portfolio-Galerien (z.B. Hochzeit, Portrait, Landschaft)',
|
||||||
|
defaultColumns: ['name', 'slug', 'order'],
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
read: tenantScopedPublicRead,
|
||||||
|
create: authenticatedOnly,
|
||||||
|
update: authenticatedOnly,
|
||||||
|
delete: authenticatedOnly,
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'name',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
localized: true,
|
||||||
|
label: 'Kategoriename',
|
||||||
|
admin: {
|
||||||
|
description: 'z.B. "Hochzeitsfotografie", "Portraits", "Landschaften"',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'slug',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
unique: false, // Uniqueness per tenant/locale
|
||||||
|
label: 'URL-Slug',
|
||||||
|
admin: {
|
||||||
|
description: 'URL-freundlicher Name (z.B. "hochzeit", "portrait")',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'textarea',
|
||||||
|
localized: true,
|
||||||
|
label: 'Beschreibung',
|
||||||
|
admin: {
|
||||||
|
description: 'Kurzbeschreibung der Kategorie für SEO und Übersichten',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'coverImage',
|
||||||
|
type: 'upload',
|
||||||
|
relationTo: 'media',
|
||||||
|
label: 'Cover-Bild',
|
||||||
|
admin: {
|
||||||
|
description: 'Repräsentatives Bild für die Kategorieübersicht',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'order',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 0,
|
||||||
|
label: 'Reihenfolge',
|
||||||
|
admin: {
|
||||||
|
position: 'sidebar',
|
||||||
|
description: 'Niedrigere Zahlen erscheinen zuerst',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'isActive',
|
||||||
|
type: 'checkbox',
|
||||||
|
defaultValue: true,
|
||||||
|
label: 'Aktiv',
|
||||||
|
admin: {
|
||||||
|
position: 'sidebar',
|
||||||
|
description: 'Inaktive Kategorien werden nicht angezeigt',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
264
src/collections/Portfolios.ts
Normal file
264
src/collections/Portfolios.ts
Normal file
|
|
@ -0,0 +1,264 @@
|
||||||
|
import type { CollectionConfig } from 'payload'
|
||||||
|
import { authenticatedOnly, tenantScopedPublicRead } from '../lib/tenantAccess'
|
||||||
|
|
||||||
|
export const Portfolios: CollectionConfig = {
|
||||||
|
slug: 'portfolios',
|
||||||
|
admin: {
|
||||||
|
useAsTitle: 'title',
|
||||||
|
group: 'Portfolio',
|
||||||
|
description: 'Portfolio-Galerien mit Fotografien',
|
||||||
|
defaultColumns: ['title', 'category', 'isFeatured', 'status', 'publishedAt'],
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
read: tenantScopedPublicRead,
|
||||||
|
create: authenticatedOnly,
|
||||||
|
update: authenticatedOnly,
|
||||||
|
delete: authenticatedOnly,
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
// === HAUPTINFORMATIONEN ===
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
localized: true,
|
||||||
|
label: 'Titel',
|
||||||
|
admin: {
|
||||||
|
description: 'Name der Galerie / des Projekts',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'slug',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
unique: false, // Uniqueness per tenant/locale
|
||||||
|
label: 'URL-Slug',
|
||||||
|
admin: {
|
||||||
|
description: 'URL-freundlicher Name (z.B. "hochzeit-maria-thomas")',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'description',
|
||||||
|
type: 'richText',
|
||||||
|
localized: true,
|
||||||
|
label: 'Beschreibung',
|
||||||
|
admin: {
|
||||||
|
description: 'Ausführliche Beschreibung des Projekts/Shootings',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'excerpt',
|
||||||
|
type: 'textarea',
|
||||||
|
localized: true,
|
||||||
|
maxLength: 300,
|
||||||
|
label: 'Kurzfassung',
|
||||||
|
admin: {
|
||||||
|
description: 'Kurze Beschreibung für Übersichten und SEO (max. 300 Zeichen)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// === KATEGORISIERUNG ===
|
||||||
|
{
|
||||||
|
name: 'category',
|
||||||
|
type: 'relationship',
|
||||||
|
relationTo: 'portfolio-categories',
|
||||||
|
required: true,
|
||||||
|
label: 'Kategorie',
|
||||||
|
admin: {
|
||||||
|
description: 'Hauptkategorie dieser Galerie',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tags',
|
||||||
|
type: 'text',
|
||||||
|
hasMany: true,
|
||||||
|
label: 'Tags',
|
||||||
|
admin: {
|
||||||
|
description: 'Zusätzliche Schlagwörter für Filterung (z.B. "outdoor", "studio", "schwarz-weiß")',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// === BILDER ===
|
||||||
|
{
|
||||||
|
name: 'coverImage',
|
||||||
|
type: 'upload',
|
||||||
|
relationTo: 'media',
|
||||||
|
required: true,
|
||||||
|
label: 'Cover-Bild',
|
||||||
|
admin: {
|
||||||
|
description: 'Hauptbild für Übersichten und Vorschauen',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'images',
|
||||||
|
type: 'array',
|
||||||
|
required: true,
|
||||||
|
minRows: 1,
|
||||||
|
label: 'Galerie-Bilder',
|
||||||
|
admin: {
|
||||||
|
description: 'Alle Bilder dieser Galerie',
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'image',
|
||||||
|
type: 'upload',
|
||||||
|
relationTo: 'media',
|
||||||
|
required: true,
|
||||||
|
label: 'Bild',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'caption',
|
||||||
|
type: 'text',
|
||||||
|
localized: true,
|
||||||
|
label: 'Bildunterschrift',
|
||||||
|
admin: {
|
||||||
|
description: 'Optionale Beschreibung für dieses Bild',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'isHighlight',
|
||||||
|
type: 'checkbox',
|
||||||
|
defaultValue: false,
|
||||||
|
label: 'Highlight',
|
||||||
|
admin: {
|
||||||
|
description: 'Als Highlight-Bild markieren',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// === PROJEKT-DETAILS ===
|
||||||
|
{
|
||||||
|
name: 'projectDetails',
|
||||||
|
type: 'group',
|
||||||
|
label: 'Projekt-Details',
|
||||||
|
admin: {
|
||||||
|
description: 'Zusätzliche Informationen zum Shooting',
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'client',
|
||||||
|
type: 'text',
|
||||||
|
label: 'Kunde/Auftraggeber',
|
||||||
|
admin: {
|
||||||
|
description: 'Name des Kunden (optional, für Referenzen)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'location',
|
||||||
|
type: 'text',
|
||||||
|
localized: true,
|
||||||
|
label: 'Ort',
|
||||||
|
admin: {
|
||||||
|
description: 'Wo wurde das Shooting durchgeführt?',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'shootingDate',
|
||||||
|
type: 'date',
|
||||||
|
label: 'Shooting-Datum',
|
||||||
|
admin: {
|
||||||
|
date: {
|
||||||
|
pickerAppearance: 'dayOnly',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'equipment',
|
||||||
|
type: 'text',
|
||||||
|
hasMany: true,
|
||||||
|
label: 'Verwendete Ausrüstung',
|
||||||
|
admin: {
|
||||||
|
description: 'Kamera, Objektive etc. (optional)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// === STATUS & VERÖFFENTLICHUNG ===
|
||||||
|
{
|
||||||
|
name: 'status',
|
||||||
|
type: 'select',
|
||||||
|
defaultValue: 'draft',
|
||||||
|
required: true,
|
||||||
|
options: [
|
||||||
|
{ label: 'Entwurf', value: 'draft' },
|
||||||
|
{ label: 'Veröffentlicht', value: 'published' },
|
||||||
|
{ label: 'Archiviert', value: 'archived' },
|
||||||
|
],
|
||||||
|
admin: {
|
||||||
|
position: 'sidebar',
|
||||||
|
description: 'Veröffentlichungsstatus',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'isFeatured',
|
||||||
|
type: 'checkbox',
|
||||||
|
defaultValue: false,
|
||||||
|
label: 'Hervorgehoben',
|
||||||
|
admin: {
|
||||||
|
position: 'sidebar',
|
||||||
|
description: 'Auf der Startseite anzeigen',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'publishedAt',
|
||||||
|
type: 'date',
|
||||||
|
label: 'Veröffentlichungsdatum',
|
||||||
|
admin: {
|
||||||
|
position: 'sidebar',
|
||||||
|
date: {
|
||||||
|
pickerAppearance: 'dayAndTime',
|
||||||
|
},
|
||||||
|
description: 'Wann soll die Galerie veröffentlicht werden?',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'order',
|
||||||
|
type: 'number',
|
||||||
|
defaultValue: 0,
|
||||||
|
label: 'Reihenfolge',
|
||||||
|
admin: {
|
||||||
|
position: 'sidebar',
|
||||||
|
description: 'Für manuelle Sortierung (niedrigere Zahlen zuerst)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// === SEO ===
|
||||||
|
{
|
||||||
|
name: 'seo',
|
||||||
|
type: 'group',
|
||||||
|
label: 'SEO',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'metaTitle',
|
||||||
|
type: 'text',
|
||||||
|
label: 'Meta-Titel',
|
||||||
|
localized: true,
|
||||||
|
admin: {
|
||||||
|
description: 'Überschreibt den Standardtitel für Suchmaschinen',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'metaDescription',
|
||||||
|
type: 'textarea',
|
||||||
|
label: 'Meta-Beschreibung',
|
||||||
|
maxLength: 160,
|
||||||
|
localized: true,
|
||||||
|
admin: {
|
||||||
|
description: 'Beschreibung für Suchmaschinen (max. 160 Zeichen)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ogImage',
|
||||||
|
type: 'upload',
|
||||||
|
relationTo: 'media',
|
||||||
|
label: 'Social Media Bild',
|
||||||
|
admin: {
|
||||||
|
description: 'Bild für Social Media Shares (verwendet Cover-Bild wenn leer)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
14225
src/migrations/20251206_071552_portfolio_collections.json
Normal file
14225
src/migrations/20251206_071552_portfolio_collections.json
Normal file
File diff suppressed because it is too large
Load diff
139
src/migrations/20251206_071552_portfolio_collections.ts
Normal file
139
src/migrations/20251206_071552_portfolio_collections.ts
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
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_portfolios_status" AS ENUM('draft', 'published', 'archived');
|
||||||
|
CREATE TABLE "portfolio_categories" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"tenant_id" integer,
|
||||||
|
"slug" varchar NOT NULL,
|
||||||
|
"cover_image_id" integer,
|
||||||
|
"order" numeric DEFAULT 0,
|
||||||
|
"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 "portfolio_categories_locales" (
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"description" varchar,
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"_locale" "_locales" NOT NULL,
|
||||||
|
"_parent_id" integer NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "portfolios_images" (
|
||||||
|
"_order" integer NOT NULL,
|
||||||
|
"_parent_id" integer NOT NULL,
|
||||||
|
"id" varchar PRIMARY KEY NOT NULL,
|
||||||
|
"image_id" integer NOT NULL,
|
||||||
|
"is_highlight" boolean DEFAULT false
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "portfolios_images_locales" (
|
||||||
|
"caption" varchar,
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"_locale" "_locales" NOT NULL,
|
||||||
|
"_parent_id" varchar NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "portfolios" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"tenant_id" integer,
|
||||||
|
"slug" varchar NOT NULL,
|
||||||
|
"category_id" integer NOT NULL,
|
||||||
|
"cover_image_id" integer NOT NULL,
|
||||||
|
"project_details_client" varchar,
|
||||||
|
"project_details_shooting_date" timestamp(3) with time zone,
|
||||||
|
"status" "enum_portfolios_status" DEFAULT 'draft' NOT NULL,
|
||||||
|
"is_featured" boolean DEFAULT false,
|
||||||
|
"published_at" timestamp(3) with time zone,
|
||||||
|
"order" numeric DEFAULT 0,
|
||||||
|
"seo_og_image_id" integer,
|
||||||
|
"updated_at" timestamp(3) with time zone DEFAULT now() NOT NULL,
|
||||||
|
"created_at" timestamp(3) with time zone DEFAULT now() NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "portfolios_locales" (
|
||||||
|
"title" varchar NOT NULL,
|
||||||
|
"description" jsonb,
|
||||||
|
"excerpt" varchar,
|
||||||
|
"project_details_location" varchar,
|
||||||
|
"seo_meta_title" varchar,
|
||||||
|
"seo_meta_description" varchar,
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"_locale" "_locales" NOT NULL,
|
||||||
|
"_parent_id" integer NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "portfolios_texts" (
|
||||||
|
"id" serial PRIMARY KEY NOT NULL,
|
||||||
|
"order" integer NOT NULL,
|
||||||
|
"parent_id" integer NOT NULL,
|
||||||
|
"path" varchar NOT NULL,
|
||||||
|
"text" varchar
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "portfolio_categories_id" integer;
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD COLUMN "portfolios_id" integer;
|
||||||
|
ALTER TABLE "portfolio_categories" ADD CONSTRAINT "portfolio_categories_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolio_categories" ADD CONSTRAINT "portfolio_categories_cover_image_id_media_id_fk" FOREIGN KEY ("cover_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolio_categories_locales" ADD CONSTRAINT "portfolio_categories_locales_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."portfolio_categories"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolios_images" ADD CONSTRAINT "portfolios_images_image_id_media_id_fk" FOREIGN KEY ("image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolios_images" ADD CONSTRAINT "portfolios_images_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."portfolios"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolios_images_locales" ADD CONSTRAINT "portfolios_images_locales_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."portfolios_images"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolios" ADD CONSTRAINT "portfolios_tenant_id_tenants_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenants"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolios" ADD CONSTRAINT "portfolios_category_id_portfolio_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."portfolio_categories"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolios" ADD CONSTRAINT "portfolios_cover_image_id_media_id_fk" FOREIGN KEY ("cover_image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolios" ADD CONSTRAINT "portfolios_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 "portfolios_locales" ADD CONSTRAINT "portfolios_locales_parent_id_fk" FOREIGN KEY ("_parent_id") REFERENCES "public"."portfolios"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "portfolios_texts" ADD CONSTRAINT "portfolios_texts_parent_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."portfolios"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
CREATE INDEX "portfolio_categories_tenant_idx" ON "portfolio_categories" USING btree ("tenant_id");
|
||||||
|
CREATE INDEX "portfolio_categories_cover_image_idx" ON "portfolio_categories" USING btree ("cover_image_id");
|
||||||
|
CREATE INDEX "portfolio_categories_updated_at_idx" ON "portfolio_categories" USING btree ("updated_at");
|
||||||
|
CREATE INDEX "portfolio_categories_created_at_idx" ON "portfolio_categories" USING btree ("created_at");
|
||||||
|
CREATE UNIQUE INDEX "portfolio_categories_locales_locale_parent_id_unique" ON "portfolio_categories_locales" USING btree ("_locale","_parent_id");
|
||||||
|
CREATE INDEX "portfolios_images_order_idx" ON "portfolios_images" USING btree ("_order");
|
||||||
|
CREATE INDEX "portfolios_images_parent_id_idx" ON "portfolios_images" USING btree ("_parent_id");
|
||||||
|
CREATE INDEX "portfolios_images_image_idx" ON "portfolios_images" USING btree ("image_id");
|
||||||
|
CREATE UNIQUE INDEX "portfolios_images_locales_locale_parent_id_unique" ON "portfolios_images_locales" USING btree ("_locale","_parent_id");
|
||||||
|
CREATE INDEX "portfolios_tenant_idx" ON "portfolios" USING btree ("tenant_id");
|
||||||
|
CREATE INDEX "portfolios_category_idx" ON "portfolios" USING btree ("category_id");
|
||||||
|
CREATE INDEX "portfolios_cover_image_idx" ON "portfolios" USING btree ("cover_image_id");
|
||||||
|
CREATE INDEX "portfolios_seo_seo_og_image_idx" ON "portfolios" USING btree ("seo_og_image_id");
|
||||||
|
CREATE INDEX "portfolios_updated_at_idx" ON "portfolios" USING btree ("updated_at");
|
||||||
|
CREATE INDEX "portfolios_created_at_idx" ON "portfolios" USING btree ("created_at");
|
||||||
|
CREATE UNIQUE INDEX "portfolios_locales_locale_parent_id_unique" ON "portfolios_locales" USING btree ("_locale","_parent_id");
|
||||||
|
CREATE INDEX "portfolios_texts_order_parent" ON "portfolios_texts" USING btree ("order","parent_id");
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_portfolio_categories_fk" FOREIGN KEY ("portfolio_categories_id") REFERENCES "public"."portfolio_categories"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" ADD CONSTRAINT "payload_locked_documents_rels_portfolios_fk" FOREIGN KEY ("portfolios_id") REFERENCES "public"."portfolios"("id") ON DELETE cascade ON UPDATE no action;
|
||||||
|
CREATE INDEX "payload_locked_documents_rels_portfolio_categories_id_idx" ON "payload_locked_documents_rels" USING btree ("portfolio_categories_id");
|
||||||
|
CREATE INDEX "payload_locked_documents_rels_portfolios_id_idx" ON "payload_locked_documents_rels" USING btree ("portfolios_id");`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||||
|
await db.execute(sql`
|
||||||
|
ALTER TABLE "portfolio_categories" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "portfolio_categories_locales" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "portfolios_images" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "portfolios_images_locales" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "portfolios" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "portfolios_locales" DISABLE ROW LEVEL SECURITY;
|
||||||
|
ALTER TABLE "portfolios_texts" DISABLE ROW LEVEL SECURITY;
|
||||||
|
DROP TABLE "portfolio_categories" CASCADE;
|
||||||
|
DROP TABLE "portfolio_categories_locales" CASCADE;
|
||||||
|
DROP TABLE "portfolios_images" CASCADE;
|
||||||
|
DROP TABLE "portfolios_images_locales" CASCADE;
|
||||||
|
DROP TABLE "portfolios" CASCADE;
|
||||||
|
DROP TABLE "portfolios_locales" CASCADE;
|
||||||
|
DROP TABLE "portfolios_texts" CASCADE;
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_portfolio_categories_fk";
|
||||||
|
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP CONSTRAINT "payload_locked_documents_rels_portfolios_fk";
|
||||||
|
|
||||||
|
DROP INDEX "payload_locked_documents_rels_portfolio_categories_id_idx";
|
||||||
|
DROP INDEX "payload_locked_documents_rels_portfolios_id_idx";
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "portfolio_categories_id";
|
||||||
|
ALTER TABLE "payload_locked_documents_rels" DROP COLUMN "portfolios_id";
|
||||||
|
DROP TYPE "public"."enum_portfolios_status";`)
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import * as migration_20251130_213501_initial_with_localization from './20251130_213501_initial_with_localization';
|
import * as migration_20251130_213501_initial_with_localization from './20251130_213501_initial_with_localization';
|
||||||
import * as migration_20251202_081830_add_is_super_admin_to_users from './20251202_081830_add_is_super_admin_to_users';
|
import * as migration_20251202_081830_add_is_super_admin_to_users from './20251202_081830_add_is_super_admin_to_users';
|
||||||
|
import * as migration_20251206_071552_portfolio_collections from './20251206_071552_portfolio_collections';
|
||||||
|
|
||||||
export const migrations = [
|
export const migrations = [
|
||||||
{
|
{
|
||||||
|
|
@ -10,6 +11,11 @@ export const migrations = [
|
||||||
{
|
{
|
||||||
up: migration_20251202_081830_add_is_super_admin_to_users.up,
|
up: migration_20251202_081830_add_is_super_admin_to_users.up,
|
||||||
down: migration_20251202_081830_add_is_super_admin_to_users.down,
|
down: migration_20251202_081830_add_is_super_admin_to_users.down,
|
||||||
name: '20251202_081830_add_is_super_admin_to_users'
|
name: '20251202_081830_add_is_super_admin_to_users',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
up: migration_20251206_071552_portfolio_collections.up,
|
||||||
|
down: migration_20251206_071552_portfolio_collections.down,
|
||||||
|
name: '20251206_071552_portfolio_collections'
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,10 @@ import { SocialLinks } from './collections/SocialLinks'
|
||||||
import { Testimonials } from './collections/Testimonials'
|
import { Testimonials } from './collections/Testimonials'
|
||||||
import { NewsletterSubscribers } from './collections/NewsletterSubscribers'
|
import { NewsletterSubscribers } from './collections/NewsletterSubscribers'
|
||||||
|
|
||||||
|
// Portfolio Collections
|
||||||
|
import { PortfolioCategories } from './collections/PortfolioCategories'
|
||||||
|
import { Portfolios } from './collections/Portfolios'
|
||||||
|
|
||||||
// Consent Management Collections
|
// Consent Management Collections
|
||||||
import { CookieConfigurations } from './collections/CookieConfigurations'
|
import { CookieConfigurations } from './collections/CookieConfigurations'
|
||||||
import { CookieInventory } from './collections/CookieInventory'
|
import { CookieInventory } from './collections/CookieInventory'
|
||||||
|
|
@ -93,6 +97,9 @@ export default buildConfig({
|
||||||
SocialLinks,
|
SocialLinks,
|
||||||
Testimonials,
|
Testimonials,
|
||||||
NewsletterSubscribers,
|
NewsletterSubscribers,
|
||||||
|
// Portfolio
|
||||||
|
PortfolioCategories,
|
||||||
|
Portfolios,
|
||||||
// Consent Management
|
// Consent Management
|
||||||
CookieConfigurations,
|
CookieConfigurations,
|
||||||
CookieInventory,
|
CookieInventory,
|
||||||
|
|
@ -128,6 +135,9 @@ export default buildConfig({
|
||||||
...({
|
...({
|
||||||
testimonials: {},
|
testimonials: {},
|
||||||
'newsletter-subscribers': {},
|
'newsletter-subscribers': {},
|
||||||
|
// Portfolio Collections
|
||||||
|
'portfolio-categories': {},
|
||||||
|
portfolios: {},
|
||||||
// Consent Management Collections - customTenantField: true weil sie bereits ein tenant-Feld haben
|
// Consent Management Collections - customTenantField: true weil sie bereits ein tenant-Feld haben
|
||||||
'cookie-configurations': { customTenantField: true },
|
'cookie-configurations': { customTenantField: true },
|
||||||
'cookie-inventory': { customTenantField: true },
|
'cookie-inventory': { customTenantField: true },
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue