feat: initialize k-tv-frontend with Next.js and Tailwind CSS

- Added package.json with dependencies and scripts for development, build, and linting.
- Created postcss.config.mjs for Tailwind CSS integration.
- Added SVG assets for UI components including file, globe, next, vercel, and window icons.
- Configured TypeScript with tsconfig.json for strict type checking and module resolution.
This commit is contained in:
2026-03-11 19:13:21 +01:00
commit 01108aa23e
130 changed files with 29949 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
-- Create users table
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY NOT NULL,
subject TEXT NOT NULL,
email TEXT NOT NULL,
password_hash TEXT,
created_at TEXT NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_subject ON users(subject);
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email ON users(email);

View File

@@ -0,0 +1,59 @@
-- Channels: user-defined broadcast channels with their schedule template
CREATE TABLE IF NOT EXISTS channels (
id TEXT PRIMARY KEY NOT NULL,
owner_id TEXT NOT NULL,
name TEXT NOT NULL,
description TEXT,
timezone TEXT NOT NULL DEFAULT 'UTC',
-- JSON-encoded ScheduleConfig (the shareable/exportable template)
schedule_config TEXT NOT NULL DEFAULT '{"blocks":[]}',
-- JSON-encoded RecyclePolicy
recycle_policy TEXT NOT NULL DEFAULT '{"cooldown_days":30,"cooldown_generations":null,"min_available_ratio":0.2}',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_channels_owner ON channels(owner_id);
-- Generated 48-hour schedules (resolved from a channel's template)
CREATE TABLE IF NOT EXISTS generated_schedules (
id TEXT PRIMARY KEY NOT NULL,
channel_id TEXT NOT NULL,
valid_from TEXT NOT NULL,
valid_until TEXT NOT NULL,
generation INTEGER NOT NULL,
FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE CASCADE
);
-- Composite index supports both "find active at time T" and "find latest"
CREATE INDEX IF NOT EXISTS idx_schedules_channel_valid
ON generated_schedules(channel_id, valid_from DESC);
-- Individual scheduled slots within a generated schedule.
-- The MediaItem snapshot is stored as JSON so the EPG survives library changes.
CREATE TABLE IF NOT EXISTS scheduled_slots (
id TEXT PRIMARY KEY NOT NULL,
schedule_id TEXT NOT NULL,
start_at TEXT NOT NULL,
end_at TEXT NOT NULL,
-- JSON-encoded MediaItem (metadata snapshot at generation time)
item TEXT NOT NULL,
source_block_id TEXT NOT NULL,
FOREIGN KEY (schedule_id) REFERENCES generated_schedules(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_slots_schedule_start
ON scheduled_slots(schedule_id, start_at);
-- Playback history for the recycle policy engine
CREATE TABLE IF NOT EXISTS playback_records (
id TEXT PRIMARY KEY NOT NULL,
channel_id TEXT NOT NULL,
item_id TEXT NOT NULL,
played_at TEXT NOT NULL,
generation INTEGER NOT NULL,
FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_playback_channel_date
ON playback_records(channel_id, played_at DESC);