release / govulncheck (push) Successful in 17s
release / web (push) Successful in 1m33s
release / go (push) Successful in 1m49s
release / integration (push) Successful in 5m42s
release / android (push) Successful in 5m59s
release / Build signed APK (releases and dev) (push) Successful in 6m9s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 16s
release / Verify release artifacts (tag releases only) (push) Skipped
Applies rule 32's migration exception: each header still says what the schema was, what changes and what it prevents, but task, milestone, decision and rule ids are replaced by the practice they stood for, the operator quotes by the decision, single-install counts are dropped, and pointers to a deleted package and an external design doc are gone. golang-migrate keeps no checksum, so editing applied migrations' comments is safe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
2.3 KiB
SQL
61 lines
2.3 KiB
SQL
-- Core library schema: artists, albums, tracks and users. Likes, sessions,
|
|
-- scrobbling and similarity get tables of their own in later migrations.
|
|
|
|
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
|
|
|
CREATE TABLE artists (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name text NOT NULL,
|
|
sort_name text NOT NULL,
|
|
mbid text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
CREATE UNIQUE INDEX artists_mbid_unique ON artists (mbid) WHERE mbid IS NOT NULL;
|
|
CREATE INDEX artists_sort_name ON artists (sort_name);
|
|
|
|
CREATE TABLE albums (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
title text NOT NULL,
|
|
sort_title text NOT NULL,
|
|
artist_id uuid NOT NULL REFERENCES artists (id) ON DELETE CASCADE,
|
|
release_date date,
|
|
mbid text,
|
|
cover_art_path text,
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
CREATE UNIQUE INDEX albums_mbid_unique ON albums (mbid) WHERE mbid IS NOT NULL;
|
|
CREATE INDEX albums_artist ON albums (artist_id);
|
|
CREATE INDEX albums_sort_title ON albums (sort_title);
|
|
|
|
CREATE TABLE tracks (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
title text NOT NULL,
|
|
album_id uuid NOT NULL REFERENCES albums (id) ON DELETE CASCADE,
|
|
artist_id uuid NOT NULL REFERENCES artists (id) ON DELETE CASCADE,
|
|
track_number integer,
|
|
disc_number integer,
|
|
duration_ms integer NOT NULL,
|
|
file_path text NOT NULL UNIQUE,
|
|
file_size bigint NOT NULL,
|
|
file_format text NOT NULL,
|
|
bitrate integer,
|
|
mbid text,
|
|
genre text,
|
|
added_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
CREATE UNIQUE INDEX tracks_mbid_unique ON tracks (mbid) WHERE mbid IS NOT NULL;
|
|
CREATE INDEX tracks_album ON tracks (album_id, disc_number, track_number);
|
|
CREATE INDEX tracks_artist ON tracks (artist_id);
|
|
|
|
CREATE TABLE users (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
username text NOT NULL UNIQUE,
|
|
password_hash text NOT NULL,
|
|
api_token text NOT NULL UNIQUE,
|
|
is_admin boolean NOT NULL DEFAULT false,
|
|
created_at timestamptz NOT NULL DEFAULT now()
|
|
);
|