CREATE TABLE "user" (
    id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    email VARCHAR(255) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    username VARCHAR(255) NOT NULL UNIQUE,
    locked BOOLEAN NOT NULL,
    expired BOOLEAN NOT NULL,
    enabled BOOLEAN NOT NULL,
    credentials_expired BOOLEAN NOT NULL
);

CREATE TABLE user_granted_authority (
    id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    user_id INT NOT NULL,
    authority VARCHAR(255),
    FOREIGN KEY (user_id) REFERENCES "user"
);

CREATE TABLE refresh_token (
    token UUID PRIMARY KEY,
    issued TIMESTAMPTZ(6) NOT NULL,
    expiration TIMESTAMPTZ(6) NOT NULL,
    owner_id INT NOT NULL,
    deleted BOOLEAN NOT NULL,
    revoked BOOLEAN NOT NULL,
    FOREIGN KEY (owner_id) REFERENCES "user"
);

CREATE TABLE image (
    id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    created TIMESTAMPTZ(6) NOT NULL,
    modified TIMESTAMPTZ(6),

    owner_id INT NOT NULL,
    is_public BOOLEAN NOT NULL,

    object_name VARCHAR(255) NOT NULL,
    user_filename VARCHAR(255) NOT NULL,
    mime_type VARCHAR(255) NOT NULL,
    alt VARCHAR(255),
    caption VARCHAR(255),

    height INTEGER,
    width INTEGER,

    FOREIGN KEY (owner_id) REFERENCES "user"
);

CREATE TABLE image_viewer (
    image_id INT NOT NULL,
    viewer_id INT NOT NULL,
    PRIMARY KEY (image_id, viewer_id),
    FOREIGN KEY (image_id) REFERENCES image,
    FOREIGN KEY (viewer_id) REFERENCES "user"
);

CREATE TABLE recipe (
    id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    created TIMESTAMPTZ(6) NOT NULL,
    modified TIMESTAMPTZ(6),

    owner_id INT NOT NULL,
    slug VARCHAR(255) NOT NULL,
    is_public BOOLEAN NOT NULL,

    title VARCHAR(255) NOT NULL,
    raw_text TEXT NOT NULL,
    cached_rendered_text TEXT,
    main_image_id INT,

    preparation_time INT,
    cooking_time INT,
    total_time INT,

    FOREIGN KEY (owner_id) REFERENCES "user",
    FOREIGN KEY (main_image_id) REFERENCES image
);

CREATE INDEX recipe_username_slug ON recipe (owner_id, slug);

CREATE TABLE recipe_viewer (
    recipe_id INT NOT NULL,
    viewer_id INT NOT NULL,
    PRIMARY KEY (recipe_id, viewer_id),
    FOREIGN KEY (recipe_id) REFERENCES recipe,
    FOREIGN KEY (viewer_id) REFERENCES "user"
);

CREATE TABLE recipe_comment (
    id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
    created TIMESTAMPTZ(6) NOT NULL,
    modified TIMESTAMPTZ(6),
    owner_id INT NOT NULL,
    recipe_id INT NOT NULL,
    raw_text TEXT NOT NULL,
    cached_rendered_text TEXT,
    FOREIGN KEY (owner_id) REFERENCES "user",
    FOREIGN KEY (recipe_id) REFERENCES recipe
);

CREATE TABLE recipe_star (
    timestamp TIMESTAMPTZ(6) NOT NULL,
    recipe_id INT NOT NULL,
    owner_id INT NOT NULL,
    PRIMARY KEY (recipe_id, owner_id),
    FOREIGN KEY (recipe_id) references recipe,
    FOREIGN KEY (owner_id) references "user"
);