-- Posts are public quotes pulled from the knowledgebase. Each carries the -- selected text verbatim as its caption (immutable after create) plus a link -- back to the source URL the user was reading. Optional images are stored in -- the `post_images` table, one row per image, ordered by `position`. -- -- Posts are always public — visibility is a per-user concern (the user's -- /u/ feed), not a per-post one. Private saves should use bookmarks. CREATE TABLE IF NOT EXISTS posts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, caption TEXT NOT NULL, source_url TEXT NOT NULL, source_title VARCHAR(200), created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS posts_user_created_idx ON posts (user_id, created_at DESC); CREATE TABLE IF NOT EXISTS post_images ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), post_id UUID NOT NULL REFERENCES posts(id) ON DELETE CASCADE, url TEXT NOT NULL, position INT NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT now() ); CREATE INDEX IF NOT EXISTS post_images_post_idx ON post_images (post_id, position);