-- 001_initial.sql -- Basis-Schema: Tenants, Screens, Medien, Playlists create extension if not exists pgcrypto; create table if not exists tenants ( id text primary key default gen_random_uuid()::text, slug text not null unique, name text not null, created_at timestamptz not null default now() ); create table if not exists screens ( id text primary key default gen_random_uuid()::text, tenant_id text not null references tenants(id) on delete cascade, slug text not null unique, name text not null, orientation text not null default 'landscape', created_at timestamptz not null default now() ); create table if not exists media_assets ( id text primary key default gen_random_uuid()::text, tenant_id text not null references tenants(id) on delete cascade, title text not null, type text not null, -- image | video | pdf | web storage_path text null, -- set for uploads original_url text null, -- set for web/remote mime_type text null, size_bytes bigint null, enabled boolean not null default true, created_at timestamptz not null default now() ); create table if not exists playlists ( id text primary key default gen_random_uuid()::text, tenant_id text not null references tenants(id) on delete cascade, screen_id text not null references screens(id) on delete cascade, name text not null, is_active boolean not null default true, default_duration_seconds integer not null default 20, created_at timestamptz not null default now(), updated_at timestamptz not null default now(), unique (screen_id) -- one active playlist per screen (simplified) ); create table if not exists playlist_items ( id text primary key default gen_random_uuid()::text, playlist_id text not null references playlists(id) on delete cascade, media_asset_id text null references media_assets(id) on delete set null, order_index integer not null default 0, type text not null, -- image | video | pdf | web src text not null, -- URL or served path title text null, duration_seconds integer not null default 20, valid_from timestamptz null, valid_until timestamptz null, enabled boolean not null default true, created_at timestamptz not null default now() ); create index if not exists idx_screens_tenant_id on screens(tenant_id); create index if not exists idx_media_assets_tenant_id on media_assets(tenant_id); create index if not exists idx_playlists_screen_id on playlists(screen_id); create index if not exists idx_playlist_items_order on playlist_items(playlist_id, order_index); -- Schema-Versions-Tabelle create table if not exists schema_migrations ( version integer primary key, applied_at timestamptz not null default now() ); -- Seed: Standard-Tenant und erster Screen (idempotent) insert into tenants (id, slug, name) values ('tenant-morz', 'morz', 'MORZ Schule') on conflict (slug) do nothing;