-- +goose Up CREATE EXTENSION IF NOT EXISTS pgcrypto; CREATE TABLE item ( id BIGSERIAL PRIMARY KEY, pub_id UUID NOT NULL DEFAULT gen_random_uuid(), source_url TEXT NOT NULL, title TEXT NOT NULL DEFAULT '', description TEXT NOT NULL DEFAULT '', site_name TEXT NOT NULL DEFAULT '', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), deleted_at TIMESTAMPTZ, UNIQUE (pub_id) ); CREATE INDEX idx_item_created_at ON item(created_at DESC); CREATE INDEX idx_item_deleted_at ON item(deleted_at); CREATE TABLE image ( id BIGSERIAL PRIMARY KEY, item_id BIGINT NOT NULL REFERENCES item(id) ON DELETE CASCADE, original_url TEXT NOT NULL DEFAULT '', content_type TEXT NOT NULL DEFAULT '', bytes BYTEA NOT NULL, width INT NOT NULL DEFAULT 0, height INT NOT NULL DEFAULT 0, is_thumb BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_image_item ON image(item_id); CREATE INDEX idx_image_thumb ON image(item_id, is_thumb); CREATE TABLE tag ( id BIGSERIAL PRIMARY KEY, name TEXT NOT NULL UNIQUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE item_tag ( item_id BIGINT NOT NULL REFERENCES item(id) ON DELETE CASCADE, tag_id BIGINT NOT NULL REFERENCES tag(id) ON DELETE CASCADE, PRIMARY KEY (item_id, tag_id) ); CREATE INDEX idx_item_tag_item ON item_tag(item_id); CREATE INDEX idx_item_tag_tag ON item_tag(tag_id); CREATE TABLE auth ( id BIGSERIAL PRIMARY KEY, password_hash BYTEA NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE session ( id BIGSERIAL PRIMARY KEY, token TEXT NOT NULL UNIQUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), expires_at TIMESTAMPTZ NOT NULL ); CREATE INDEX idx_session_token ON session(token); CREATE INDEX idx_session_expires_at ON session(expires_at); -- +goose Down DROP TABLE IF EXISTS session; DROP TABLE IF EXISTS auth; DROP TABLE IF EXISTS item_tag; DROP TABLE IF EXISTS tag; DROP TABLE IF EXISTS image; DROP TABLE IF EXISTS item; DROP EXTENSION IF EXISTS pgcrypto;