From be2d0588902b357af610d6478309d37b920f2595 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Thu, 12 Feb 2026 17:43:57 -0500 Subject: [PATCH 01/17] Move legacy sql class into the shared workspace --- .../middleware/legacy/commandqueue.mirror.ts | 2 +- shared/database/package.json | 3 +- shared/database/src/client.ts | 4 +++ shared/database/src/index.ts | 1 + .../database/src}/legacy/sql.mirror.ts | 30 +++++++++++++++---- 5 files changed, 33 insertions(+), 7 deletions(-) rename {apps/backend/middleware => shared/database/src}/legacy/sql.mirror.ts (76%) diff --git a/apps/backend/middleware/legacy/commandqueue.mirror.ts b/apps/backend/middleware/legacy/commandqueue.mirror.ts index f11cbf4..db218cb 100644 --- a/apps/backend/middleware/legacy/commandqueue.mirror.ts +++ b/apps/backend/middleware/legacy/commandqueue.mirror.ts @@ -3,7 +3,7 @@ import { EventData, MirrorEvents, serverEventsMgr } from '../../utils/serverEven import { promises } from 'fs'; import { EventEmitter } from 'node:events'; import path from 'path'; -import { MirrorSQL } from './sql.mirror'; +import { MirrorSQL } from '@wxyc/database'; import { cryptoRandomId, expBackoffMs } from './utilities.mirror'; const CommandQueueEvents = { diff --git a/shared/database/package.json b/shared/database/package.json index b5b2da7..bc81b4d 100644 --- a/shared/database/package.json +++ b/shared/database/package.json @@ -20,7 +20,8 @@ }, "dependencies": { "drizzle-orm": "^0.41.0", - "postgres": "^3.4.4" + "postgres": "^3.4.4", + "node-ssh": "^13.2.1" }, "devDependencies": { "tsup": "^8.5.0", diff --git a/shared/database/src/client.ts b/shared/database/src/client.ts index 4ff4b94..240043f 100644 --- a/shared/database/src/client.ts +++ b/shared/database/src/client.ts @@ -19,3 +19,7 @@ const queryClient = postgres({ }); export const db = drizzle(queryClient, { schema }); + +export function closeDatabaseConnection(): Promise { + return queryClient.end().then(() => console.log('Database connection closed.')); +} diff --git a/shared/database/src/index.ts b/shared/database/src/index.ts index ecc55c8..7250844 100644 --- a/shared/database/src/index.ts +++ b/shared/database/src/index.ts @@ -1,3 +1,4 @@ export * from './client.js'; export * from './schema.js'; export * from './types/index.js'; +export * from './legacy/sql.mirror.js'; diff --git a/apps/backend/middleware/legacy/sql.mirror.ts b/shared/database/src/legacy/sql.mirror.ts similarity index 76% rename from apps/backend/middleware/legacy/sql.mirror.ts rename to shared/database/src/legacy/sql.mirror.ts index 95c91c9..08f3f47 100644 --- a/apps/backend/middleware/legacy/sql.mirror.ts +++ b/shared/database/src/legacy/sql.mirror.ts @@ -3,6 +3,7 @@ import { Config, NodeSSH } from 'node-ssh'; export class MirrorSQL { private static _instance: MirrorSQL | null = null; private static _ssh: NodeSSH | null = null; + private static _disposeTimer: NodeJS.Timeout | null = null; static instance() { if (!this._instance) this._instance = new MirrorSQL(); @@ -24,19 +25,37 @@ export class MirrorSQL { await this._ssh.connect(sshConfig); } - setTimeout( + if (this._disposeTimer) { + clearTimeout(this._disposeTimer); + } + + this._disposeTimer = setTimeout( () => { - if (this._ssh && this._ssh.isConnected()) { - this._ssh.dispose(); - this._ssh = null; - } + MirrorSQL.instance().close(); }, 5 * 60 * 1000 ); // auto-dispose after 5 minutes of inactivity + this._disposeTimer.unref(); return this._ssh; } + close() { + if (MirrorSQL._disposeTimer) { + clearTimeout(MirrorSQL._disposeTimer); + MirrorSQL._disposeTimer = null; + } + + if (MirrorSQL._ssh) { + if (MirrorSQL._ssh.isConnected()) { + MirrorSQL._ssh.dispose(); + } + MirrorSQL._ssh = null; + } + + console.log('[MirrorSQL] Database connection closed.'); + } + private static shSingleQuote = (s: string) => s.replace(/'/g, `'\\''`); private static getRemotePwd = () => process.env.REMOTE_DB_PASSWORD ?? ''; @@ -46,6 +65,7 @@ export class MirrorSQL { mysql -u ${process.env.REMOTE_DB_USER ?? ''} \\ -h ${process.env.REMOTE_DB_HOST ?? ''} \\ -D ${process.env.REMOTE_DB_NAME ?? ''} \\ + -P ${process.env.REMOTE_DB_PORT ?? '3306'} \\ --protocol=TCP \\ --connect-timeout=10 \\ --skip-ssl \\ From bd1e9062075ae0894c73d827515f5934351c66ce Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Thu, 12 Feb 2026 17:47:12 -0500 Subject: [PATCH 02/17] implement etl job --- jobs/library-etl/job.ts | 440 ++++++++++++++++++++++++++++++++ jobs/library-etl/package.json | 26 ++ jobs/library-etl/tsconfig.json | 12 + jobs/library-etl/tsup.config.ts | 24 ++ 4 files changed, 502 insertions(+) create mode 100644 jobs/library-etl/job.ts create mode 100644 jobs/library-etl/package.json create mode 100644 jobs/library-etl/tsconfig.json create mode 100644 jobs/library-etl/tsup.config.ts diff --git a/jobs/library-etl/job.ts b/jobs/library-etl/job.ts new file mode 100644 index 0000000..40055ec --- /dev/null +++ b/jobs/library-etl/job.ts @@ -0,0 +1,440 @@ +import { and, eq } from 'drizzle-orm'; +import { isNull } from 'drizzle-orm'; +import { + MirrorSQL, + db, + artists, + format, + genre_artist_crossreference, + genres, + library, + cronjob_runs, + closeDatabaseConnection, +} from '@wxyc/database'; + +const legacyDB = MirrorSQL.instance(); +const JOB_NAME = 'library-etl'; + +type LegacyReleaseRow = { + release_id: number; + release_title: string; + release_last_modified: number | null; + release_time_created: number | null; + release_call_numbers: number | null; + release_call_letters: string | null; + release_alternate_artist_name: string | null; + artist_name: string; + artist_alpha_name: string | null; + artist_call_letters: string | null; + artist_call_numbers: number | null; + genre_ref_name: string | null; + format_ref_name: string | null; +}; + +const VARIOUS_ARTISTS_NAME = 'Various Artists'; +const VARIOUS_ARTISTS_CODE_LETTERS = 'V/A'; +const VARIOUS_ARTISTS_CODE_NUMBER = 0; + +const parseTabRow = (line: string, columnCount: number) => { + const columns = line.split('\t'); + if (columns.length !== columnCount) { + return null; + } + return columns; +}; + +const toNullableString = (value?: string) => { + if (value == null || value.trim().length === 0) return null; + return value.trim(); +}; + +const toNullableNumber = (value?: string) => { + if (value == null || value.trim().length === 0) return null; + const parsed = Number(value); + return Number.isFinite(parsed) ? parsed : null; +}; + +const isDbOnlyGenre = (genreRef?: string | null) => { + return genreRef != null && genreRef.trim().toLowerCase() === 'db_only'; +}; + +const normalizeArtistName = (name: string) => { + const trimmed = name.trim(); + if (/^various\s+artists\s*-\s*/i.test(trimmed)) { + return { name: VARIOUS_ARTISTS_NAME, isVarious: true }; + } + return { name: trimmed, isVarious: false }; +}; + +const normalizeCodeLetters = (code: string | null) => { + if (!code) return null; + const trimmed = code.trim(); + if (trimmed.length === 0) return null; + return trimmed.slice(0, 2).toUpperCase(); +}; + +const parseFormatAndDiscs = (formatText: string) => { + const normalized = formatText.toLowerCase().trim(); + + const matchCd = normalized.match(/^cd(?:\s*x\s*(\d+))?(?:\s*box)?$/); + if (matchCd) { + const discQuantity = matchCd[1] ? Number(matchCd[1]) : 1; + return { formatName: 'cd', discQuantity }; + } + + const matchCdr = normalized.match(/^cdr$/); + if (matchCdr) { + return { formatName: 'cdr', discQuantity: 1 }; + } + + if (!normalized.startsWith('vinyl')) { + return null; + } + + const xMatch = normalized.match(/\bx\s*(\d+)\b/); + const discQuantity = xMatch && Number.isFinite(Number(xMatch[1])) ? Number(xMatch[1]) : 1; + + let formatName = 'vinyl'; + if (normalized.includes('7"')) { + formatName = 'vinyl 7"'; + } else if (normalized.includes('10"')) { + formatName = 'vinyl 10"'; + } else if (normalized.includes('12"') || normalized.includes('lp')) { + formatName = 'vinyl 12"'; + } + + return { formatName, discQuantity }; +}; + +const toDateOrUndefined = (value: number | null) => { + if (value == null) return undefined; + const date = new Date(value); + if (Number.isNaN(date.getTime())) return undefined; + return date; +}; + +const toDateOnlyString = (value: number | null) => { + const date = toDateOrUndefined(value); + if (!date) return undefined; + return date.toISOString().slice(0, 10); +}; + +type DbTransaction = Parameters[0]>[0]; +type DbClient = typeof db | DbTransaction; + +const getLastRunTimestamp = async (jobName: string): Promise => { + const response = await db + .select({ lastRun: cronjob_runs.last_run }) + .from(cronjob_runs) + .where(eq(cronjob_runs.job_name, jobName)) + .limit(1); + + const lastRun = response[0]?.lastRun ?? null; + return lastRun ? lastRun.getTime() : null; +}; + +const updateLastRun = async (dbClient: DbClient, jobName: string, lastRun: Date) => { + await dbClient + .insert(cronjob_runs) + .values({ job_name: jobName, last_run: lastRun }) + .onConflictDoUpdate({ + target: cronjob_runs.job_name, + set: { last_run: lastRun }, + }); +}; + +const fetchLegacyReleases = async (lastRunMs: number | null) => { + const lastRunFilter = lastRunMs == null ? '' : `WHERE lr.TIME_LAST_MODIFIED > ${lastRunMs}`; + const sqlQuery = ` + SELECT + lr.ID, + REPLACE(REPLACE(IFNULL(lr.TITLE, ''), '\\t', ' '), '\\n', ' '), + lr.TIME_LAST_MODIFIED, + lr.TIME_CREATED, + lr.CALL_NUMBERS AS release_call_numbers, + lr.CALL_LETTERS AS release_call_letters, + REPLACE(REPLACE(IFNULL(lr.ALTERNATE_ARTIST_NAME, ''), '\\t', ' '), '\\n', ' '), + REPLACE(REPLACE(IFNULL(lc.PRESENTATION_NAME, ''), '\\t', ' '), '\\n', ' '), + REPLACE(REPLACE(IFNULL(lc.ALPHABETICAL_NAME, ''), '\\t', ' '), '\\n', ' '), + lc.CALL_LETTERS AS artist_call_letters, + lc.CALL_NUMBERS AS artist_call_numbers, + g.REFERENCE_NAME, + f.REFERENCE_NAME + FROM LIBRARY_RELEASE lr + JOIN LIBRARY_CODE lc ON lr.LIBRARY_CODE_ID = lc.ID + JOIN GENRE g ON lc.GENRE_ID = g.ID + JOIN FORMAT f ON lr.FORMAT_ID = f.ID + ${lastRunFilter} + ORDER BY lr.TIME_LAST_MODIFIED ASC; + `; + + const raw = await legacyDB.send(sqlQuery); + const rows = raw.trim().length === 0 ? [] : raw.trim().split('\n'); + const columnCount = 13; + const parsed: LegacyReleaseRow[] = []; + + for (const line of rows) { + const columns = parseTabRow(line, columnCount); + if (!columns) { + console.warn('[library-etl] Skipping malformed legacy row:', line); + continue; + } + + parsed.push({ + release_id: Number(columns[0]), + release_title: columns[1], + release_last_modified: toNullableNumber(columns[2]), + release_time_created: toNullableNumber(columns[3]), + release_call_numbers: toNullableNumber(columns[4]), + release_call_letters: toNullableString(columns[5]), + release_alternate_artist_name: toNullableString(columns[6]), + artist_name: columns[7], + artist_alpha_name: toNullableString(columns[8]), + artist_call_letters: toNullableString(columns[9]), + artist_call_numbers: toNullableNumber(columns[10]), + genre_ref_name: toNullableString(columns[11]), + format_ref_name: toNullableString(columns[12]), + }); + } + + return parsed; +}; + +const ensureArtist = async ( + dbClient: DbClient, + artistName: string, + isVarious: boolean, + genreId: number, + codeLetters: string | null, + codeArtistNumber: number | null, + artistCache: Map, + addDate?: string, + lastModified?: Date +) => { + const normalizedLetters = codeLetters ?? '??'; + const normalizedNumber = codeArtistNumber ?? 0; + const artistKey = `${artistName.toLowerCase()}|${normalizedLetters}|${normalizedNumber}`; + const cached = artistCache.get(artistKey); + if (cached) return cached; + + const baseConditions = [ + eq(artists.artist_name, artistName), + eq(artists.code_letters, normalizedLetters), + eq(artists.code_artist_number, normalizedNumber), + ]; + + const query = dbClient + .select({ id: artists.id }) + .from(artists) + .where(isVarious ? and(...baseConditions) : and(...baseConditions, eq(artists.genre_id, genreId))) + .limit(1); + + const existing = await query; + if (existing.length) { + artistCache.set(artistKey, existing[0].id); + return existing[0].id; + } + + const inserted = await dbClient + .insert(artists) + .values({ + artist_name: artistName, + genre_id: genreId, + code_letters: normalizedLetters, + code_artist_number: normalizedNumber, + add_date: addDate, + last_modified: lastModified, + }) + .returning(); + + const id = inserted[0]?.id; + if (!id) { + throw new Error(`[library-etl] Failed to insert artist ${artistName}.`); + } + artistCache.set(artistKey, id); + return id; +}; + +const ensureGenreArtistCrossref = async ( + dbClient: DbClient, + artistId: number, + genreId: number, + artistGenreCode: number +) => { + const existing = await dbClient + .select({ artist_id: genre_artist_crossreference.artist_id }) + .from(genre_artist_crossreference) + .where(and(eq(genre_artist_crossreference.artist_id, artistId), eq(genre_artist_crossreference.genre_id, genreId))) + .limit(1); + + if (existing.length) return; + + await dbClient.insert(genre_artist_crossreference).values({ + artist_id: artistId, + genre_id: genreId, + artist_genre_code: artistGenreCode, + }); +}; + +const albumExists = async ( + dbClient: DbClient, + artistId: number, + genreId: number, + albumTitle: string, + codeNumber: number | null, + codeVolumeLetters: string | null +) => { + const response = await dbClient + .select({ id: library.id }) + .from(library) + .where( + and( + eq(library.artist_id, artistId), + eq(library.genre_id, genreId), + eq(library.album_title, albumTitle), + eq(library.code_number, codeNumber ?? 0), + codeVolumeLetters ? eq(library.code_volume_letters, codeVolumeLetters) : isNull(library.code_volume_letters) + ) + ) + .limit(1); + + return response.length > 0; +}; + +const run = async () => { + try { + const runStartedAt = new Date(); + const lastRunMs = await getLastRunTimestamp(JOB_NAME); + const legacyReleases = await fetchLegacyReleases(lastRunMs); + + if (legacyReleases.length === 0) { + console.log('[library-etl] No new legacy releases found.'); + await updateLastRun(db, JOB_NAME, runStartedAt); + return; + } + + let insertedCount = 0; + let skippedCount = 0; + + await db.transaction(async (tx) => { + const genreRows = await tx.select().from(genres); + const genreMap = new Map(genreRows.map((genre) => [genre.genre_name.toLowerCase(), genre.id])); + + const formatRows = await tx.select().from(format); + const formatMap = new Map(formatRows.map((row) => [row.format_name.toLowerCase(), row.id])); + + const artistCache = new Map(); + + for (const release of legacyReleases) { + if (isDbOnlyGenre(release.genre_ref_name)) { + skippedCount += 1; + continue; + } + + const genreName = release.genre_ref_name ?? ''; + const genreId = genreMap.get(genreName.toLowerCase()); + if (!genreId) { + console.warn(`[library-etl] Missing genre "${genreName}" for release ${release.release_id}.`); + skippedCount += 1; + continue; + } + + const formatText = release.format_ref_name ?? ''; + const formatParsed = parseFormatAndDiscs(formatText); + if (!formatParsed) { + console.warn(`[library-etl] Unsupported format "${formatText}" for release ${release.release_id}.`); + skippedCount += 1; + continue; + } + + const formatId = formatMap.get(formatParsed.formatName.toLowerCase()) ?? null; + if (!formatId) { + console.warn(`[library-etl] Missing format "${formatParsed.formatName}" for release ${release.release_id}.`); + skippedCount += 1; + continue; + } + + const artistInfo = normalizeArtistName(release.artist_name); + if (artistInfo.name.length === 0) { + skippedCount += 1; + continue; + } + const codeLetters = artistInfo.isVarious + ? VARIOUS_ARTISTS_CODE_LETTERS + : normalizeCodeLetters(release.artist_call_letters); + const codeArtistNumber = artistInfo.isVarious + ? VARIOUS_ARTISTS_CODE_NUMBER + : (release.artist_call_numbers ?? 0); + + const artistId = await ensureArtist( + tx, + artistInfo.name, + artistInfo.isVarious, + genreId, + codeLetters, + codeArtistNumber, + artistCache, + toDateOnlyString(release.release_time_created), + toDateOrUndefined(release.release_last_modified) + ); + + await ensureGenreArtistCrossref( + tx, + artistId, + genreId, + artistInfo.isVarious ? VARIOUS_ARTISTS_CODE_NUMBER : (release.artist_call_numbers ?? 0) + ); + + const albumTitle = release.release_title.trim(); + if (albumTitle.length === 0) { + skippedCount += 1; + continue; + } + + const codeVolumeLetters = + release.release_call_letters != null && release.release_call_letters.trim().length > 0 + ? release.release_call_letters.trim() + : null; + const alreadyExists = await albumExists( + tx, + artistId, + genreId, + albumTitle, + release.release_call_numbers, + codeVolumeLetters + ); + if (alreadyExists) { + skippedCount += 1; + continue; + } + + await tx.insert(library).values({ + artist_id: artistId, + genre_id: genreId, + format_id: formatId, + alternate_artist_name: release.release_alternate_artist_name, + album_title: albumTitle, + code_number: release.release_call_numbers ?? 0, + code_volume_letters: codeVolumeLetters, + disc_quantity: formatParsed.discQuantity, + add_date: toDateOrUndefined(release.release_time_created), + last_modified: toDateOrUndefined(release.release_last_modified), + }); + + insertedCount += 1; + } + + await updateLastRun(tx, JOB_NAME, runStartedAt); + }); + + console.log(`[library-etl] Completed. Inserted ${insertedCount}, skipped ${skippedCount}.`); + } finally { + await closeDatabaseConnection(); + legacyDB.close(); + } +}; + +run().catch((error) => { + console.error('[library-etl] Failed:', error); + process.exitCode = 1; +}); diff --git a/jobs/library-etl/package.json b/jobs/library-etl/package.json new file mode 100644 index 0000000..3787506 --- /dev/null +++ b/jobs/library-etl/package.json @@ -0,0 +1,26 @@ +{ + "name": "@wxyc/library-etl", + "cron-schedule": "*/30 * * * *", + "version": "1.0.0", + "description": "WXYC Authentication Service using Better Auth", + "type": "module", + "main": "./dist/job.js", + "scripts": { + "start": "node dist/job.js", + "build": "tsup --minify", + "clean": "rm -rf dist", + "docker:build": "docker build -t wxyc_library_etl:ci -f ../../Dockerfile.library-etl ../../", + "dev": "tsup --watch" + }, + "author": "Adrian Bruno", + "license": "MIT", + "dependencies": { + "@wxyc/database": "^1.0.0" + }, + "peerDependencies": { + "drizzle-orm": "^0.41.0" + }, + "devDependencies": { + "typescript": "^5.6.2" + } +} diff --git a/jobs/library-etl/tsconfig.json b/jobs/library-etl/tsconfig.json new file mode 100644 index 0000000..d5ee8b7 --- /dev/null +++ b/jobs/library-etl/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": ["../../tsconfig.base.json"], + "references": [{ "path": "../../shared/database" }], + "include": ["."], + "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler", + "paths": { + "@/*": ["./*"] + } + } +} diff --git a/jobs/library-etl/tsup.config.ts b/jobs/library-etl/tsup.config.ts new file mode 100644 index 0000000..6f1d2ba --- /dev/null +++ b/jobs/library-etl/tsup.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from 'tsup'; +import { resolve, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +// Get the directory where this config file is located +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +export default defineConfig((options) => ({ + entry: ['job.ts'], + format: ['cjs'], + outDir: 'dist', + clean: true, + onSuccess: options.watch ? 'node ./dist/job.js' : undefined, + minify: !options.watch, + + esbuildOptions(options) { + // Resolve @/ alias to the directory where this config file is located + // This matches TypeScript's behavior (relative to tsconfig.json location) + options.alias = { + '@': resolve(__dirname), + }; + }, +})); From bca243303212211157803c7c70b4a4a82ded5327 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Thu, 12 Feb 2026 17:48:47 -0500 Subject: [PATCH 03/17] update github workflow to handle cronjobs --- .github/workflows/deploy-base.yml | 75 ++++++++++++++++++++++++++++--- package.json | 3 +- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/.github/workflows/deploy-base.yml b/.github/workflows/deploy-base.yml index 9cf5d3b..cb2faee 100644 --- a/.github/workflows/deploy-base.yml +++ b/.github/workflows/deploy-base.yml @@ -26,8 +26,8 @@ jobs: run: | TARGET_INPUT="${{ inputs.target }}" - if [ ! -d "apps/$TARGET_INPUT" ]; then - echo "Error: The target directory 'apps/$TARGET_INPUT' does not exist." >&2 + if [ ! -d "apps/$TARGET_INPUT" ] && [ ! -d "jobs/$TARGET_INPUT" ]; then + echo "Error: The target directory 'apps/$TARGET_INPUT' or 'jobs/$TARGET_INPUT' does not exist." >&2 exit 1 fi echo "target input '$TARGET_INPUT' is valid." @@ -75,7 +75,7 @@ jobs: TARGETS="${{ inputs.target }}" else echo "Detecting targets from git diff..." - TARGETS=$(git diff --name-only HEAD~1..HEAD | grep '^apps' | cut -d '/' -f 2 | sort -u) + TARGETS=$(git diff --name-only HEAD~1..HEAD | awk -F/ '/^(apps|jobs)\//{print $2}' | sort -u) fi if [ -z "$TARGETS" ] ; then @@ -309,11 +309,24 @@ jobs: id: deploy_vars run: | TARGET_APP=${{ matrix.target }} - PUBLISH_PORT=$(yq .publishPort apps/$TARGET_APP/package.json) + if [ -f "jobs/$TARGET_APP/package.json" ]; then + TARGET_TYPE="job" + CRON_SCHEDULE=$(yq '.["cron-schedule"]' jobs/$TARGET_APP/package.json) + if [ -z "$CRON_SCHEDULE" ] || [ "$CRON_SCHEDULE" = "null" ]; then + echo "Missing cron-schedule in jobs/$TARGET_APP/package.json" >&2 + exit 1 + fi + echo "cron_schedule=$CRON_SCHEDULE" >> $GITHUB_OUTPUT + else + TARGET_TYPE="app" + PUBLISH_PORT=$(yq .publishPort apps/$TARGET_APP/package.json) + echo "publish_port=$PUBLISH_PORT" >> $GITHUB_OUTPUT + fi - echo "publish_port=$PUBLISH_PORT" >> $GITHUB_OUTPUT + echo "target_type=$TARGET_TYPE" >> $GITHUB_OUTPUT - name: Deploy Service + if: steps.deploy_vars.outputs.target_type == 'app' uses: ./.github/actions/deploy-service with: target_app: ${{ matrix.target }} @@ -327,7 +340,39 @@ jobs: aws_region: ${{ secrets.AWS_REGION }} aws_ecr_uri: ${{ secrets.AWS_ECR_URI }} + - name: Deploy Cron Job + if: steps.deploy_vars.outputs.target_type == 'job' + uses: appleboy/ssh-action@v1 + with: + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USER }} + key: ${{ secrets.EC2_SSH_KEY }} + script: | + set -e + export AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }} + export AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} + + TARGET_APP=${{ matrix.target }} + DEPLOY_TAG=${{ steps.determine_version.outputs.deploy_version }} + CRON_SCHEDULE='${{ steps.deploy_vars.outputs.cron_schedule }}' + AWS_ECR_URI=${{ secrets.AWS_ECR_URI }} + AWS_REGION=${{ secrets.AWS_REGION }} + + CRON_ID="wxyc_${TARGET_APP}" + echo "Logging into AWS ECR..." + aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ECR_URI + + echo "Pulling Docker image for deploy..." + docker pull $AWS_ECR_URI/$TARGET_APP:$DEPLOY_TAG + + CRON_CMD="docker rm -f ${TARGET_APP}-cron >/dev/null 2>&1 || true; docker run --rm --name ${TARGET_APP}-cron --env-file .env $AWS_ECR_URI/$TARGET_APP:$DEPLOY_TAG" + + (crontab -l 2>/dev/null | grep -v "$CRON_ID"; echo "$CRON_SCHEDULE $CRON_CMD # $CRON_ID") | crontab - + + echo "Cron schedule updated." + - name: Confirm server is up + if: steps.deploy_vars.outputs.target_type == 'app' uses: appleboy/ssh-action@v1 with: host: ${{ secrets.EC2_HOST }} @@ -344,3 +389,23 @@ jobs: echo "Server is not running. Deployment failed." >&2 exit 1 fi + + - name: Confirm cron is updated + if: steps.deploy_vars.outputs.target_type == 'job' + uses: appleboy/ssh-action@v1 + with: + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USER }} + key: ${{ secrets.EC2_SSH_KEY }} + script: | + set -e + TARGET_APP=${{ matrix.target }} + CRON_ID="wxyc_${TARGET_APP}" + + echo "Verifying crontab entry..." + if crontab -l 2>/dev/null | grep -F "$CRON_ID" > /dev/null; then + echo "Cronjob entry verified." + else + echo "Cronjob not updated properly. Deployment failed" >&2 + exit 1 + fi diff --git a/package.json b/package.json index 687e3c3..3836812 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "lint:env": "node scripts/lint-env.js", "format": "prettier --write .", "format:check": "prettier --check .", - "build": "npm run build --workspace=@wxyc/database --workspace=shared/** --workspace=apps/**", + "build": "npm run build --workspace=@wxyc/database --workspace=shared/** --workspace=apps/** --workspace=jobs/**", "dev": "dotenvx run -f .env -- concurrently \"npm:dev:auth\" \"npm:dev:backend\"", "dev:backend": "npm run dev --workspace=@wxyc/backend", "dev:auth": "npm run dev --workspace=@wxyc/auth-service", @@ -44,6 +44,7 @@ "license": "MIT", "workspaces": [ "apps/*", + "jobs/*", "shared/*" ], "devDependencies": { From 511b1fa35083f37ef25df91faef7513de146e9d1 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Thu, 12 Feb 2026 17:49:41 -0500 Subject: [PATCH 04/17] Add cronjob runs tracking table --- .../src/migrations/0026_cron_job_tracking.sql | 36 + .../src/migrations/meta/0026_snapshot.json | 2689 +++++++++++++++++ .../src/migrations/meta/_journal.json | 9 +- shared/database/src/schema.ts | 12 +- 4 files changed, 2743 insertions(+), 3 deletions(-) create mode 100644 shared/database/src/migrations/0026_cron_job_tracking.sql create mode 100644 shared/database/src/migrations/meta/0026_snapshot.json diff --git a/shared/database/src/migrations/0026_cron_job_tracking.sql b/shared/database/src/migrations/0026_cron_job_tracking.sql new file mode 100644 index 0000000..1338abe --- /dev/null +++ b/shared/database/src/migrations/0026_cron_job_tracking.sql @@ -0,0 +1,36 @@ +CREATE TABLE "wxyc_schema"."cronjob_runs" ( + "job_name" varchar(64) PRIMARY KEY NOT NULL, + "last_run" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint + +--> Drop view in order to alter the artists table +DROP VIEW IF EXISTS "wxyc_schema"."library_artist_view"; +--> statement-breakpoint + +ALTER TABLE "wxyc_schema"."artists" ALTER COLUMN "code_letters" SET DATA TYPE varchar(4); +--> statement-breakpoint + +ALTER TABLE "wxyc_schema"."library" ADD COLUMN "code_volume_letters" varchar(4); +--> statement-breakpoint + +--> Recreate view with the altered column in the artists table +CREATE VIEW "wxyc_schema"."library_artist_view" AS +SELECT "library"."id", + "artists"."code_letters", + "artists"."code_artist_number", + "library"."code_number", + "artists"."artist_name", + "library"."album_title", + "library"."label", + "format"."format_name", + "genres"."genre_name", + "rotation"."play_freq", + "library"."add_date" +FROM "wxyc_schema"."library" + INNER JOIN "wxyc_schema"."artists" ON "artists"."id" = "library"."artist_id" + INNER JOIN "wxyc_schema"."genres" ON "genres"."id" = "library"."genre_id" + INNER JOIN "wxyc_schema"."format" ON "format"."id" = "library"."format_id" + LEFT JOIN "wxyc_schema"."rotation" + ON "rotation"."album_id" = "library"."id" AND ("rotation"."kill_date" > CURRENT_DATE OR "rotation"."kill_date" IS NULL); +--> statement-breakpoint \ No newline at end of file diff --git a/shared/database/src/migrations/meta/0026_snapshot.json b/shared/database/src/migrations/meta/0026_snapshot.json new file mode 100644 index 0000000..f4d45ed --- /dev/null +++ b/shared/database/src/migrations/meta/0026_snapshot.json @@ -0,0 +1,2689 @@ +{ + "id": "1bcc0430-ce5d-4cd6-bcc3-9a5bb8823f61", + "prevId": "335ff99b-a9d0-49ec-a275-2bf4e9b2edf7", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_account_provider_account_key": { + "name": "auth_account_provider_account_key", + "columns": [ + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.album_metadata": { + "name": "album_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "discogs_release_id": { + "name": "discogs_release_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "discogs_url": { + "name": "discogs_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "release_year": { + "name": "release_year", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "artwork_url": { + "name": "artwork_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "spotify_url": { + "name": "spotify_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "apple_music_url": { + "name": "apple_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "youtube_music_url": { + "name": "youtube_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "bandcamp_url": { + "name": "bandcamp_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "soundcloud_url": { + "name": "soundcloud_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "is_rotation": { + "name": "is_rotation", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "album_metadata_album_id_idx": { + "name": "album_metadata_album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_cache_key_idx": { + "name": "album_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_last_accessed_idx": { + "name": "album_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "album_metadata_album_id_library_id_fk": { + "name": "album_metadata_album_id_library_id_fk", + "tableFrom": "album_metadata", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "album_metadata_album_id_unique": { + "name": "album_metadata_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + }, + "album_metadata_cache_key_unique": { + "name": "album_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.anonymous_devices": { + "name": "anonymous_devices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "device_id": { + "name": "device_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "blocked": { + "name": "blocked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "blocked_at": { + "name": "blocked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "anonymous_devices_device_id_key": { + "name": "anonymous_devices_device_id_key", + "columns": [ + { + "expression": "device_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "anonymous_devices_device_id_unique": { + "name": "anonymous_devices_device_id_unique", + "nullsNotDistinct": false, + "columns": [ + "device_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_library_crossreference": { + "name": "artist_library_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "library_id": { + "name": "library_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "library_id_artist_id": { + "name": "library_id_artist_id", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "library_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_library_crossreference_artist_id_artists_id_fk": { + "name": "artist_library_crossreference_artist_id_artists_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "artist_library_crossreference_library_id_library_id_fk": { + "name": "artist_library_crossreference_library_id_library_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_metadata": { + "name": "artist_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "discogs_artist_id": { + "name": "discogs_artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "wikipedia_url": { + "name": "wikipedia_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_metadata_artist_id_idx": { + "name": "artist_metadata_artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_cache_key_idx": { + "name": "artist_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_last_accessed_idx": { + "name": "artist_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_metadata_artist_id_artists_id_fk": { + "name": "artist_metadata_artist_id_artists_id_fk", + "tableFrom": "artist_metadata", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "artist_metadata_artist_id_unique": { + "name": "artist_metadata_artist_id_unique", + "nullsNotDistinct": false, + "columns": [ + "artist_id" + ] + }, + "artist_metadata_cache_key_unique": { + "name": "artist_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artists": { + "name": "artists", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true + }, + "code_artist_number": { + "name": "code_artist_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_name_trgm_idx": { + "name": "artist_name_trgm_idx", + "columns": [ + { + "expression": "\"artist_name\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "code_letters_idx": { + "name": "code_letters_idx", + "columns": [ + { + "expression": "code_letters", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artists_genre_id_genres_id_fk": { + "name": "artists_genre_id_genres_id_fk", + "tableFrom": "artists", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.bins": { + "name": "bins", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "bins_dj_id_auth_user_id_fk": { + "name": "bins_dj_id_auth_user_id_fk", + "tableFrom": "bins", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bins_album_id_library_id_fk": { + "name": "bins_album_id_library_id_fk", + "tableFrom": "bins", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.cronjob_runs": { + "name": "cronjob_runs", + "schema": "wxyc_schema", + "columns": { + "job_name": { + "name": "job_name", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "last_run": { + "name": "last_run", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.dj_stats": { + "name": "dj_stats", + "schema": "wxyc_schema", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "shows_covered": { + "name": "shows_covered", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "dj_stats_user_id_auth_user_id_fk": { + "name": "dj_stats_user_id_auth_user_id_fk", + "tableFrom": "dj_stats", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.flowsheet": { + "name": "flowsheet", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rotation_id": { + "name": "rotation_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "entry_type": { + "name": "entry_type", + "type": "flowsheet_entry_type", + "typeSchema": "wxyc_schema", + "primaryKey": false, + "notNull": true, + "default": "'track'" + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "record_label": { + "name": "record_label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "play_order": { + "name": "play_order", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "request_flag": { + "name": "request_flag", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "message": { + "name": "message", + "type": "varchar(250)", + "primaryKey": false, + "notNull": false + }, + "add_time": { + "name": "add_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "flowsheet_show_id_shows_id_fk": { + "name": "flowsheet_show_id_shows_id_fk", + "tableFrom": "flowsheet", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_album_id_library_id_fk": { + "name": "flowsheet_album_id_library_id_fk", + "tableFrom": "flowsheet", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_rotation_id_rotation_id_fk": { + "name": "flowsheet_rotation_id_rotation_id_fk", + "tableFrom": "flowsheet", + "tableTo": "rotation", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "rotation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.format": { + "name": "format", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genre_artist_crossreference": { + "name": "genre_artist_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "artist_genre_key": { + "name": "artist_genre_key", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "genre_artist_crossreference_artist_id_artists_id_fk": { + "name": "genre_artist_crossreference_artist_id_artists_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "genre_artist_crossreference_genre_id_genres_id_fk": { + "name": "genre_artist_crossreference_genre_id_genres_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genres": { + "name": "genres", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_invitation": { + "name": "auth_invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "inviter_id": { + "name": "inviter_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_invitation_email_idx": { + "name": "auth_invitation_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_invitation_organization_id_auth_organization_id_fk": { + "name": "auth_invitation_organization_id_auth_organization_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_invitation_inviter_id_auth_user_id_fk": { + "name": "auth_invitation_inviter_id_auth_user_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_jwks": { + "name": "auth_jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.library": { + "name": "library", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "format_id": { + "name": "format_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "alternate_artist_name": { + "name": "alternate_artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "code_volume_letters": { + "name": "code_volume_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": false + }, + "disc_quantity": { + "name": "disc_quantity", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "title_trgm_idx": { + "name": "title_trgm_idx", + "columns": [ + { + "expression": "\"album_title\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "genre_id_idx": { + "name": "genre_id_idx", + "columns": [ + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "format_id_idx": { + "name": "format_id_idx", + "columns": [ + { + "expression": "format_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_id_idx": { + "name": "artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "library_artist_id_artists_id_fk": { + "name": "library_artist_id_artists_id_fk", + "tableFrom": "library", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_genre_id_genres_id_fk": { + "name": "library_genre_id_genres_id_fk", + "tableFrom": "library", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_format_id_format_id_fk": { + "name": "library_format_id_format_id_fk", + "tableFrom": "library", + "tableTo": "format", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "format_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_member": { + "name": "auth_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_member_org_user_key": { + "name": "auth_member_org_user_key", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_member_organization_id_auth_organization_id_fk": { + "name": "auth_member_organization_id_auth_organization_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_member_user_id_auth_user_id_fk": { + "name": "auth_member_user_id_auth_user_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_organization": { + "name": "auth_organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_organization_slug_key": { + "name": "auth_organization_slug_key", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.reviews": { + "name": "reviews", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "review": { + "name": "review", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "author": { + "name": "author", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "reviews_album_id_library_id_fk": { + "name": "reviews_album_id_library_id_fk", + "tableFrom": "reviews", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reviews_album_id_unique": { + "name": "reviews_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.rotation": { + "name": "rotation", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "play_freq": { + "name": "play_freq", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "album_id_idx": { + "name": "album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "rotation_album_id_library_id_fk": { + "name": "rotation_album_id_library_id_fk", + "tableFrom": "rotation", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.schedule": { + "name": "schedule", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "day": { + "name": "day", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "start_time": { + "name": "start_time", + "type": "time", + "primaryKey": false, + "notNull": true + }, + "show_duration": { + "name": "show_duration", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id": { + "name": "assigned_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id2": { + "name": "assigned_dj_id2", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "schedule_specialty_id_specialty_shows_id_fk": { + "name": "schedule_specialty_id_specialty_shows_id_fk", + "tableFrom": "schedule", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id_auth_user_id_fk": { + "name": "schedule_assigned_dj_id_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id2_auth_user_id_fk": { + "name": "schedule_assigned_dj_id2_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id2" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_session_token_key": { + "name": "auth_session_token_key", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shift_covers": { + "name": "shift_covers", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "schedule_id": { + "name": "schedule_id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "shift_timestamp": { + "name": "shift_timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "cover_dj_id": { + "name": "cover_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "covered": { + "name": "covered", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "shift_covers_schedule_id_schedule_id_fk": { + "name": "shift_covers_schedule_id_schedule_id_fk", + "tableFrom": "shift_covers", + "tableTo": "schedule", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "schedule_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shift_covers_cover_dj_id_auth_user_id_fk": { + "name": "shift_covers_cover_dj_id_auth_user_id_fk", + "tableFrom": "shift_covers", + "tableTo": "auth_user", + "columnsFrom": [ + "cover_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.show_djs": { + "name": "show_djs", + "schema": "wxyc_schema", + "columns": { + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + } + }, + "indexes": {}, + "foreignKeys": { + "show_djs_show_id_shows_id_fk": { + "name": "show_djs_show_id_shows_id_fk", + "tableFrom": "show_djs", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "show_djs_dj_id_auth_user_id_fk": { + "name": "show_djs_dj_id_auth_user_id_fk", + "tableFrom": "show_djs", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shows": { + "name": "shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "primary_dj_id": { + "name": "primary_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "show_name": { + "name": "show_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "start_time": { + "name": "start_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "end_time": { + "name": "end_time", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "shows_primary_dj_id_auth_user_id_fk": { + "name": "shows_primary_dj_id_auth_user_id_fk", + "tableFrom": "shows", + "tableTo": "auth_user", + "columnsFrom": [ + "primary_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shows_specialty_id_specialty_shows_id_fk": { + "name": "shows_specialty_id_specialty_shows_id_fk", + "tableFrom": "shows", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.specialty_shows": { + "name": "specialty_shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "specialty_name": { + "name": "specialty_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "real_name": { + "name": "real_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dj_name": { + "name": "dj_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "app_skin": { + "name": "app_skin", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'modern-light'" + }, + "is_anonymous": { + "name": "is_anonymous", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "auth_user_email_key": { + "name": "auth_user_email_key", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auth_user_username_key": { + "name": "auth_user_username_key", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_activity": { + "name": "user_activity", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_activity_user_id_auth_user_id_fk": { + "name": "user_activity_user_id_auth_user_id_fk", + "tableFrom": "user_activity", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_verification": { + "name": "auth_verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "wxyc_schema.flowsheet_entry_type": { + "name": "flowsheet_entry_type", + "schema": "wxyc_schema", + "values": [ + "track", + "show_start", + "show_end", + "dj_join", + "dj_leave", + "talkset", + "breakpoint", + "message" + ] + }, + "public.freq_enum": { + "name": "freq_enum", + "schema": "public", + "values": [ + "S", + "L", + "M", + "H" + ] + } + }, + "schemas": { + "wxyc_schema": "wxyc_schema" + }, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": { + "wxyc_schema.library_artist_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true + }, + "code_artist_number": { + "name": "code_artist_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "play_freq": { + "name": "play_freq", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"artists\".\"code_artist_number\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" < CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", + "name": "library_artist_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + }, + "wxyc_schema.rotation_library_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "play_freq": { + "name": "play_freq", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", + "name": "rotation_library_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + } + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/shared/database/src/migrations/meta/_journal.json b/shared/database/src/migrations/meta/_journal.json index 05d5c99..a35dbf0 100644 --- a/shared/database/src/migrations/meta/_journal.json +++ b/shared/database/src/migrations/meta/_journal.json @@ -162,6 +162,13 @@ "when": 1768890229444, "tag": "0025_rate_limiting_tables", "breakpoints": true + }, + { + "idx": 26, + "version": "7", + "when": 1770938861646, + "tag": "0026_cron_job_tracking", + "breakpoints": true } ] -} +} \ No newline at end of file diff --git a/shared/database/src/schema.ts b/shared/database/src/schema.ts index f17f2b3..5825fc1 100644 --- a/shared/database/src/schema.ts +++ b/shared/database/src/schema.ts @@ -194,6 +194,13 @@ export const shift_covers = wxyc_schema.table('shift_covers', { covered: boolean('covered').default(false), }); +export type NewCronjobRun = InferInsertModel; +export type CronjobRun = InferSelectModel; +export const cronjob_runs = wxyc_schema.table('cronjob_runs', { + job_name: varchar('job_name', { length: 64 }).primaryKey(), + last_run: timestamp('last_run', { withTimezone: true }).notNull().defaultNow(), +}); + export type NewArtist = InferInsertModel; export type Artist = InferSelectModel; export const artists = wxyc_schema.table( @@ -204,7 +211,7 @@ export const artists = wxyc_schema.table( .references(() => genres.id) .notNull(), artist_name: varchar('artist_name', { length: 128 }).notNull(), - code_letters: varchar('code_letters', { length: 2 }).notNull(), + code_letters: varchar('code_letters', { length: 4 }).notNull(), code_artist_number: smallint('code_artist_number').notNull(), add_date: date('add_date').defaultNow().notNull(), last_modified: timestamp('last_modified').defaultNow().notNull(), @@ -245,6 +252,7 @@ export const library = wxyc_schema.table( album_title: varchar('album_title', { length: 128 }).notNull(), label: varchar('label', { length: 128 }), code_number: smallint('code_number').notNull(), + code_volume_letters: varchar('code_volume_letters', { length: 4 }), disc_quantity: smallint('disc_quantity').default(1).notNull(), plays: integer('plays').default(0).notNull(), add_date: timestamp('add_date').defaultNow().notNull(), @@ -444,7 +452,7 @@ export const library_artist_view = wxyc_schema.view('library_artist_view').as((q .innerJoin(genres, eq(genres.id, library.genre_id)) .leftJoin( rotation, - sql`${rotation.album_id} = ${library.id} AND (${rotation.kill_date} < CURRENT_DATE OR ${rotation.kill_date} IS NULL)` + sql`${rotation.album_id} = ${library.id} AND (${rotation.kill_date} > CURRENT_DATE OR ${rotation.kill_date} IS NULL)` ); }); From 279f14caebd761074baeb9e5f327cde1e55f15fe Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Thu, 12 Feb 2026 18:54:54 -0500 Subject: [PATCH 05/17] Add dockerfile for job --- Dockerfile.library-etl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Dockerfile.library-etl diff --git a/Dockerfile.library-etl b/Dockerfile.library-etl new file mode 100644 index 0000000..6d952e9 --- /dev/null +++ b/Dockerfile.library-etl @@ -0,0 +1,27 @@ +#Build stage +FROM node:22-alpine AS builder + +WORKDIR /library-etl-builder + +COPY ./package.json ./ +COPY ./tsconfig.base.json ./ +COPY ./shared/database ./shared/database +COPY ./jobs/library-etl ./jobs/library-etl + +RUN npm install && npm run build --workspace=@wxyc/database --workspace=@wxyc/library-etl + +#Production stage +FROM node:22-alpine AS prod + +WORKDIR /library-etl + +COPY ./package* ./ +COPY ./jobs/library-etl/package* ./jobs/library-etl/ +COPY ./shared/database/package* ./shared/database/ + +RUN npm install --omit=dev + +COPY --from=builder ./library-etl-builder/jobs/library-etl/dist ./jobs/library-etl/dist +COPY --from=builder ./library-etl-builder/shared/database/dist ./shared/database/dist + +CMD ["npm", "start", "--workspace=@wxyc/library-etl"] \ No newline at end of file From 00edd5db60a4982505990f0f49a6e5363da5b207 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Thu, 12 Feb 2026 19:03:17 -0500 Subject: [PATCH 06/17] update package-lock.json --- package-lock.json | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/package-lock.json b/package-lock.json index 9ef6de8..a2f2bdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "workspaces": [ "apps/*", + "jobs/*", "shared/*" ], "dependencies": { @@ -100,6 +101,20 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, + "jobs/library-etl": { + "name": "@wxyc/library-etl", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@wxyc/database": "^1.0.0" + }, + "devDependencies": { + "typescript": "^5.6.2" + }, + "peerDependencies": { + "drizzle-orm": "^0.41.0" + } + }, "node_modules/@aws-crypto/sha256-browser": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", @@ -1412,6 +1427,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1428,6 +1444,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1444,6 +1461,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1460,6 +1478,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1476,6 +1495,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1492,6 +1512,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1508,6 +1529,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1524,6 +1546,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1540,6 +1563,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1556,6 +1580,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1572,6 +1597,7 @@ "cpu": [ "loong64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1588,6 +1614,7 @@ "cpu": [ "mips64el" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1604,6 +1631,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1620,6 +1648,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1636,6 +1665,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1652,6 +1682,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1668,6 +1699,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1684,6 +1716,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1700,6 +1733,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1716,6 +1750,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1732,6 +1767,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1748,6 +1784,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1814,6 +1851,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1830,6 +1868,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1846,6 +1885,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1862,6 +1902,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1878,6 +1919,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1894,6 +1936,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1910,6 +1953,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1926,6 +1970,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1942,6 +1987,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1958,6 +2004,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1974,6 +2021,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1990,6 +2038,7 @@ "cpu": [ "loong64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2006,6 +2055,7 @@ "cpu": [ "mips64el" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2022,6 +2072,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2038,6 +2089,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2054,6 +2106,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2070,6 +2123,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2086,6 +2140,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2102,6 +2157,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2118,6 +2174,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2134,6 +2191,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2150,6 +2208,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2166,6 +2225,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2182,6 +2242,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2198,6 +2259,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2214,6 +2276,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5076,6 +5139,10 @@ "resolved": "shared/database", "link": true }, + "node_modules/@wxyc/library-etl": { + "resolved": "jobs/library-etl", + "link": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -13136,6 +13203,7 @@ "license": "MIT", "dependencies": { "drizzle-orm": "^0.41.0", + "node-ssh": "^13.2.1", "postgres": "^3.4.4" }, "devDependencies": { From 3e2b999d4b58cef64ddeb7ea17b956a195dbbc09 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Thu, 12 Feb 2026 21:36:07 -0500 Subject: [PATCH 07/17] Use a description that makes sense --- jobs/library-etl/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jobs/library-etl/package.json b/jobs/library-etl/package.json index 3787506..7fc05ee 100644 --- a/jobs/library-etl/package.json +++ b/jobs/library-etl/package.json @@ -2,7 +2,7 @@ "name": "@wxyc/library-etl", "cron-schedule": "*/30 * * * *", "version": "1.0.0", - "description": "WXYC Authentication Service using Better Auth", + "description": "WXYC Legacy Library ETL Job", "type": "module", "main": "./dist/job.js", "scripts": { From bcb14faac3813938eb8d382d8f18b1a66fa8901d Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Thu, 12 Feb 2026 21:36:18 -0500 Subject: [PATCH 08/17] Add coverage --- jest.unit.config.ts | 2 +- jobs/library-etl/job.ts | 13 ++ tests/unit/jobs/library-etl.test.ts | 278 ++++++++++++++++++++++++++++ 3 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 tests/unit/jobs/library-etl.test.ts diff --git a/jest.unit.config.ts b/jest.unit.config.ts index 405242e..51d6a41 100644 --- a/jest.unit.config.ts +++ b/jest.unit.config.ts @@ -22,7 +22,7 @@ const config: Config = { // Remove .js extensions from relative imports (ESM compatibility) '^(\\.{1,2}/.*)\\.(js)$': '$1', }, - collectCoverageFrom: ['apps/backend/**/*.ts', '!**/*.d.ts', '!**/dist/**'], + collectCoverageFrom: ['apps/backend/**/*.ts', 'jobs/**/*.ts', '!**/*.d.ts', '!**/dist/**'], clearMocks: true, }; diff --git a/jobs/library-etl/job.ts b/jobs/library-etl/job.ts index 40055ec..efdca68 100644 --- a/jobs/library-etl/job.ts +++ b/jobs/library-etl/job.ts @@ -434,6 +434,19 @@ const run = async () => { } }; +// Exported for unit testing +export { + parseTabRow, + toNullableString, + toNullableNumber, + isDbOnlyGenre, + normalizeArtistName, + normalizeCodeLetters, + parseFormatAndDiscs, + toDateOrUndefined, + toDateOnlyString, +}; + run().catch((error) => { console.error('[library-etl] Failed:', error); process.exitCode = 1; diff --git a/tests/unit/jobs/library-etl.test.ts b/tests/unit/jobs/library-etl.test.ts new file mode 100644 index 0000000..7cb6fe6 --- /dev/null +++ b/tests/unit/jobs/library-etl.test.ts @@ -0,0 +1,278 @@ +/** + * Unit tests for library-etl job helpers + * + * Tests the pure parsing and normalization functions used by the ETL. + * Database and legacy MirrorSQL are mocked so the job module can load. + */ + +const mockSend = jest.fn().mockResolvedValue(''); +const mockClose = jest.fn(); + +jest.mock('@wxyc/database', () => { + const chainResolve = (value: unknown = []) => ({ + select: jest.fn().mockReturnThis(), + from: jest.fn().mockReturnThis(), + where: jest.fn().mockReturnThis(), + limit: jest.fn().mockResolvedValue(value), + insert: jest.fn().mockReturnThis(), + values: jest.fn().mockReturnThis(), + onConflictDoUpdate: jest.fn().mockResolvedValue(undefined), + returning: jest.fn().mockResolvedValue([{ id: 1 }]), + }); + const dbChain = chainResolve([]); + return { + db: { + ...dbChain, + select: jest.fn().mockReturnValue({ + from: jest.fn().mockReturnValue({ + where: jest.fn().mockReturnValue({ + limit: jest.fn().mockResolvedValue([]), + }), + }), + }), + insert: jest.fn().mockReturnValue({ + values: jest.fn().mockReturnValue({ + onConflictDoUpdate: jest.fn().mockResolvedValue(undefined), + }), + }), + transaction: jest.fn().mockImplementation(async (cb: (tx: unknown) => Promise) => { + const tx = { + select: jest.fn().mockReturnValue({ from: jest.fn().mockResolvedValue([]) }), + insert: jest.fn().mockReturnValue({ + values: jest.fn().mockReturnValue({ + onConflictDoUpdate: jest.fn().mockResolvedValue(undefined), + returning: jest.fn().mockResolvedValue([{ id: 1 }]), + }), + }), + }; + return cb(tx); + }), + }, + MirrorSQL: { + instance: () => ({ send: mockSend, close: mockClose }), + }, + artists: {}, + genres: {}, + format: {}, + library: {}, + cronjob_runs: {}, + genre_artist_crossreference: {}, + closeDatabaseConnection: jest.fn().mockResolvedValue(undefined), + }; +}); + +jest.mock('drizzle-orm', () => ({ + eq: jest.fn((a: unknown, b: unknown) => ({ eq: [a, b] })), + and: jest.fn((...args: unknown[]) => ({ and: args })), + isNull: jest.fn((col: unknown) => ({ isNull: col })), +})); + +import { + parseTabRow, + toNullableString, + toNullableNumber, + isDbOnlyGenre, + normalizeArtistName, + normalizeCodeLetters, + parseFormatAndDiscs, + toDateOrUndefined, + toDateOnlyString, +} from '../../../jobs/library-etl/job'; + +describe('library-etl job helpers', () => { + describe('parseTabRow', () => { + it('returns array when column count matches', () => { + expect(parseTabRow('a\tb\tc', 3)).toEqual(['a', 'b', 'c']); + expect(parseTabRow('one', 1)).toEqual(['one']); + }); + + it('returns null when column count does not match', () => { + expect(parseTabRow('a\tb', 3)).toBeNull(); + expect(parseTabRow('a\tb\tc', 2)).toBeNull(); + expect(parseTabRow('', 2)).toBeNull(); // '' split gives [''], length 1 + }); + }); + + describe('toNullableString', () => { + it('returns trimmed non-empty string', () => { + expect(toNullableString(' hello ')).toBe('hello'); + expect(toNullableString('x')).toBe('x'); + }); + + it('returns null for empty or whitespace', () => { + expect(toNullableString('')).toBeNull(); + expect(toNullableString(' ')).toBeNull(); + expect(toNullableString('\t')).toBeNull(); + }); + + it('returns null for undefined', () => { + expect(toNullableString(undefined)).toBeNull(); + }); + }); + + describe('toNullableNumber', () => { + it('parses valid numeric strings', () => { + expect(toNullableNumber('42')).toBe(42); + expect(toNullableNumber('0')).toBe(0); + expect(toNullableNumber(' -5 ')).toBe(-5); + }); + + it('returns null for empty or invalid', () => { + expect(toNullableNumber('')).toBeNull(); + expect(toNullableNumber(' ')).toBeNull(); + expect(toNullableNumber('abc')).toBeNull(); + expect(toNullableNumber(undefined)).toBeNull(); + }); + + it('returns null for non-finite parse result', () => { + expect(toNullableNumber('NaN')).toBeNull(); + expect(toNullableNumber('Infinity')).toBeNull(); + }); + }); + + describe('isDbOnlyGenre', () => { + it('returns true for db_only (case insensitive)', () => { + expect(isDbOnlyGenre('db_only')).toBe(true); + expect(isDbOnlyGenre('DB_ONLY')).toBe(true); + expect(isDbOnlyGenre(' Db_Only ')).toBe(true); + }); + + it('returns false for other values', () => { + expect(isDbOnlyGenre('rock')).toBe(false); + expect(isDbOnlyGenre('')).toBe(false); + expect(isDbOnlyGenre(null)).toBe(false); + expect(isDbOnlyGenre(undefined)).toBe(false); + }); + }); + + describe('normalizeArtistName', () => { + it('normalizes "Various Artists - ..." to Various Artists', () => { + const r = normalizeArtistName('Various Artists - latin'); + expect(r.name).toBe('Various Artists'); + expect(r.isVarious).toBe(true); + }); + + it('is case insensitive for various artists prefix', () => { + const r = normalizeArtistName(' VARIOUS ARTISTS - Something '); + expect(r.name).toBe('Various Artists'); + expect(r.isVarious).toBe(true); + }); + + it('returns trimmed name and isVarious false for regular artists', () => { + const r = normalizeArtistName(' FKA twigs '); + expect(r.name).toBe('FKA twigs'); + expect(r.isVarious).toBe(false); + }); + + it('does not match without hyphen after "Various Artists"', () => { + const r = normalizeArtistName('Various Artists'); + expect(r.name).toBe('Various Artists'); + expect(r.isVarious).toBe(false); + }); + }); + + describe('normalizeCodeLetters', () => { + it('returns first two chars uppercased', () => { + expect(normalizeCodeLetters('ab')).toBe('AB'); + expect(normalizeCodeLetters('xyz')).toBe('XY'); + }); + + it('returns null for empty or null', () => { + expect(normalizeCodeLetters(null)).toBeNull(); + expect(normalizeCodeLetters('')).toBeNull(); + expect(normalizeCodeLetters(' ')).toBeNull(); + }); + + it('trims then takes first two', () => { + expect(normalizeCodeLetters(' xy ')).toBe('XY'); + }); + }); + + describe('parseFormatAndDiscs', () => { + describe('CD', () => { + it('parses "cd" as cd, 1 disc', () => { + expect(parseFormatAndDiscs('cd')).toEqual({ formatName: 'cd', discQuantity: 1 }); + expect(parseFormatAndDiscs('CD')).toEqual({ formatName: 'cd', discQuantity: 1 }); + }); + + it('parses "cd x 2" as cd, 2 discs', () => { + expect(parseFormatAndDiscs('cd x 2')).toEqual({ formatName: 'cd', discQuantity: 2 }); + }); + + it('parses "cd box" as cd, 1 disc', () => { + expect(parseFormatAndDiscs('cd box')).toEqual({ formatName: 'cd', discQuantity: 1 }); + }); + }); + + describe('CD-R', () => { + it('parses "cdr" as cdr, 1 disc', () => { + expect(parseFormatAndDiscs('cdr')).toEqual({ formatName: 'cdr', discQuantity: 1 }); + }); + }); + + describe('vinyl', () => { + it('parses "vinyl" as vinyl (no size), 1 disc', () => { + expect(parseFormatAndDiscs('vinyl')).toEqual({ formatName: 'vinyl', discQuantity: 1 }); + }); + + it('parses 7" as vinyl 7"', () => { + expect(parseFormatAndDiscs('vinyl 7"')).toEqual({ formatName: 'vinyl 7"', discQuantity: 1 }); + }); + + it('parses 10" as vinyl 10"', () => { + expect(parseFormatAndDiscs('vinyl 10"')).toEqual({ formatName: 'vinyl 10"', discQuantity: 1 }); + }); + + it('parses 12" or lp as vinyl 12"', () => { + expect(parseFormatAndDiscs('vinyl 12"')).toEqual({ formatName: 'vinyl 12"', discQuantity: 1 }); + expect(parseFormatAndDiscs('vinyl lp')).toEqual({ formatName: 'vinyl 12"', discQuantity: 1 }); + }); + + it('parses vinyl x 2 as 2 discs', () => { + expect(parseFormatAndDiscs('vinyl x 2')).toEqual({ formatName: 'vinyl', discQuantity: 2 }); + }); + + it('parses vinyl 12" x 2 as 2 discs', () => { + expect(parseFormatAndDiscs('vinyl 12" x 2')).toEqual({ formatName: 'vinyl 12"', discQuantity: 2 }); + }); + }); + + it('returns null for unsupported format', () => { + expect(parseFormatAndDiscs('cassette')).toBeNull(); + expect(parseFormatAndDiscs('digital')).toBeNull(); + expect(parseFormatAndDiscs('')).toBeNull(); + }); + }); + + describe('toDateOrUndefined', () => { + it('returns Date for valid timestamp', () => { + const ts = new Date('2024-02-01').getTime(); + const d = toDateOrUndefined(ts); + expect(d).toBeInstanceOf(Date); + expect(d?.getTime()).toBe(ts); + }); + + it('returns undefined for null', () => { + expect(toDateOrUndefined(null)).toBeUndefined(); + }); + + it('returns undefined for invalid timestamp', () => { + expect(toDateOrUndefined(Number.NaN)).toBeUndefined(); + }); + }); + + describe('toDateOnlyString', () => { + it('returns YYYY-MM-DD for valid timestamp', () => { + const ts = new Date('2024-02-01T15:30:00Z').getTime(); + expect(toDateOnlyString(ts)).toBe('2024-02-01'); + }); + + it('returns undefined for null', () => { + expect(toDateOnlyString(null)).toBeUndefined(); + }); + + it('returns undefined for invalid timestamp', () => { + expect(toDateOnlyString(Number.NaN)).toBeUndefined(); + }); + }); +}); From 66a4666417cb21f93d4387ac4e18348d057388f1 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Fri, 27 Feb 2026 20:24:26 -0500 Subject: [PATCH 09/17] account for genre in job caching --- jobs/library-etl/job.ts | 45 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/jobs/library-etl/job.ts b/jobs/library-etl/job.ts index efdca68..e23286b 100644 --- a/jobs/library-etl/job.ts +++ b/jobs/library-etl/job.ts @@ -206,28 +206,37 @@ const ensureArtist = async ( isVarious: boolean, genreId: number, codeLetters: string | null, - codeArtistNumber: number | null, + artistGenreCode: number, artistCache: Map, addDate?: string, lastModified?: Date ) => { const normalizedLetters = codeLetters ?? '??'; - const normalizedNumber = codeArtistNumber ?? 0; - const artistKey = `${artistName.toLowerCase()}|${normalizedLetters}|${normalizedNumber}`; + const artistKey = isVarious + ? `${artistName.toLowerCase()}|${normalizedLetters}` + : `${artistName.toLowerCase()}|${normalizedLetters}|${genreId}|${artistGenreCode}`; const cached = artistCache.get(artistKey); if (cached) return cached; - const baseConditions = [ - eq(artists.artist_name, artistName), - eq(artists.code_letters, normalizedLetters), - eq(artists.code_artist_number, normalizedNumber), - ]; - - const query = dbClient - .select({ id: artists.id }) - .from(artists) - .where(isVarious ? and(...baseConditions) : and(...baseConditions, eq(artists.genre_id, genreId))) - .limit(1); + const query = isVarious + ? dbClient + .select({ id: artists.id }) + .from(artists) + .where(and(eq(artists.artist_name, artistName), eq(artists.code_letters, normalizedLetters))) + .limit(1) + : dbClient + .select({ id: artists.id }) + .from(artists) + .innerJoin(genre_artist_crossreference, eq(genre_artist_crossreference.artist_id, artists.id)) + .where( + and( + eq(artists.artist_name, artistName), + eq(artists.code_letters, normalizedLetters), + eq(genre_artist_crossreference.genre_id, genreId), + eq(genre_artist_crossreference.artist_genre_code, artistGenreCode) + ) + ) + .limit(1); const existing = await query; if (existing.length) { @@ -239,9 +248,7 @@ const ensureArtist = async ( .insert(artists) .values({ artist_name: artistName, - genre_id: genreId, code_letters: normalizedLetters, - code_artist_number: normalizedNumber, add_date: addDate, last_modified: lastModified, }) @@ -362,7 +369,7 @@ const run = async () => { const codeLetters = artistInfo.isVarious ? VARIOUS_ARTISTS_CODE_LETTERS : normalizeCodeLetters(release.artist_call_letters); - const codeArtistNumber = artistInfo.isVarious + const artistGenreCode = artistInfo.isVarious ? VARIOUS_ARTISTS_CODE_NUMBER : (release.artist_call_numbers ?? 0); @@ -372,7 +379,7 @@ const run = async () => { artistInfo.isVarious, genreId, codeLetters, - codeArtistNumber, + artistGenreCode, artistCache, toDateOnlyString(release.release_time_created), toDateOrUndefined(release.release_last_modified) @@ -382,7 +389,7 @@ const run = async () => { tx, artistId, genreId, - artistInfo.isVarious ? VARIOUS_ARTISTS_CODE_NUMBER : (release.artist_call_numbers ?? 0) + artistGenreCode ); const albumTitle = release.release_title.trim(); From f10a2cba2a1e43cea8da961270ad303b93db6d0b Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Fri, 27 Feb 2026 23:06:35 -0500 Subject: [PATCH 10/17] Add if not exists constraints to table alterations and creations --- shared/database/src/migrations/0026_cron_job_tracking.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/database/src/migrations/0026_cron_job_tracking.sql b/shared/database/src/migrations/0026_cron_job_tracking.sql index 1338abe..7be64bc 100644 --- a/shared/database/src/migrations/0026_cron_job_tracking.sql +++ b/shared/database/src/migrations/0026_cron_job_tracking.sql @@ -1,4 +1,4 @@ -CREATE TABLE "wxyc_schema"."cronjob_runs" ( +CREATE TABLE IF NOT EXISTS "wxyc_schema"."cronjob_runs" ( "job_name" varchar(64) PRIMARY KEY NOT NULL, "last_run" timestamp with time zone DEFAULT now() NOT NULL ); @@ -11,7 +11,7 @@ DROP VIEW IF EXISTS "wxyc_schema"."library_artist_view"; ALTER TABLE "wxyc_schema"."artists" ALTER COLUMN "code_letters" SET DATA TYPE varchar(4); --> statement-breakpoint -ALTER TABLE "wxyc_schema"."library" ADD COLUMN "code_volume_letters" varchar(4); +ALTER TABLE "wxyc_schema"."library" ADD COLUMN IF NOT EXISTS "code_volume_letters" varchar(4); --> statement-breakpoint --> Recreate view with the altered column in the artists table From 35312819159043b6c93c0430ff5d6e05dfa43517 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Fri, 27 Feb 2026 23:07:27 -0500 Subject: [PATCH 11/17] fix chain of snapshots --- shared/database/src/migrations/meta/0024_snapshot.json | 2 +- shared/database/src/migrations/meta/0025_snapshot.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/database/src/migrations/meta/0024_snapshot.json b/shared/database/src/migrations/meta/0024_snapshot.json index 6554c34..8c2677c 100644 --- a/shared/database/src/migrations/meta/0024_snapshot.json +++ b/shared/database/src/migrations/meta/0024_snapshot.json @@ -1,6 +1,6 @@ { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", - "prevId": "335ff99b-a9d0-49ec-a275-2bf4e9b2edf7", + "prevId": "d6f81c6c-fc0b-44d7-9d07-d4a7646446a2", "version": "7", "dialect": "postgresql", "tables": { diff --git a/shared/database/src/migrations/meta/0025_snapshot.json b/shared/database/src/migrations/meta/0025_snapshot.json index a7841f0..78632ff 100644 --- a/shared/database/src/migrations/meta/0025_snapshot.json +++ b/shared/database/src/migrations/meta/0025_snapshot.json @@ -1,6 +1,6 @@ { "id": "335ff99b-a9d0-49ec-a275-2bf4e9b2edf7", - "prevId": "28b0c268-097b-41b0-8ae6-883f933c63bb", + "prevId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "version": "7", "dialect": "postgresql", "tables": { From 837a4a77bdd7a29a30fe8f9042dd473ef39363a6 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Fri, 27 Feb 2026 23:08:48 -0500 Subject: [PATCH 12/17] Remove explicit genre_id attached to each artist and only use cross reference to maintain atomic artist entries. --- apps/backend/app.yaml | 22 + .../backend/controllers/library.controller.ts | 66 +- apps/backend/routes/library.route.ts | 2 + apps/backend/services/djs.service.ts | 10 +- apps/backend/services/library.service.ts | 85 +- dev_env/seed_db.sql | 44 +- .../0027_drop_genre_from_artist_table.sql | 6 + .../src/migrations/meta/0027_snapshot.json | 2662 +++++++++++++++++ .../src/migrations/meta/_journal.json | 7 + shared/database/src/schema.ts | 15 +- tests/integration/library.spec.js | 54 +- tests/utils/fixtures.ts | 6 +- 12 files changed, 2914 insertions(+), 65 deletions(-) create mode 100644 shared/database/src/migrations/0027_drop_genre_from_artist_table.sql create mode 100644 shared/database/src/migrations/meta/0027_snapshot.json diff --git a/apps/backend/app.yaml b/apps/backend/app.yaml index c727223..f92306b 100644 --- a/apps/backend/app.yaml +++ b/apps/backend/app.yaml @@ -885,10 +885,32 @@ paths: type: string genre_id: type: integer + code_number: + type: integer responses: '200': description: Successfully added artist + /library/artists/peek-code: + get: + summary: Peek next artist code number for a given genre and code letters + security: + - BearerAuth: ['station-management'] + parameters: + - in: query + name: code_letters + required: true + schema: + type: string + - in: query + name: genre_id + required: true + schema: + type: integer + responses: + '200': + description: Next available artist code number + /library/formats: get: summary: Get format list diff --git a/apps/backend/controllers/library.controller.ts b/apps/backend/controllers/library.controller.ts index 587628b..37c5203 100644 --- a/apps/backend/controllers/library.controller.ts +++ b/apps/backend/controllers/library.controller.ts @@ -122,28 +122,48 @@ type NewArtistRequest = { artist_name: string; code_letters: string; genre_id: number; + code_number: number; }; export const addArtist: RequestHandler = async (req: Request, res, next) => { const { body } = req; //TODO auto_generate artist code letters and make it an optional parameter - if (body.artist_name === undefined || body.code_letters === undefined || body.genre_id === undefined) { + if ( + body.artist_name === undefined || + body.code_letters === undefined || + body.genre_id === undefined || + body.code_number === undefined + ) { res.status(400); - res.send('Missing Request Parameters: artist_name, code_letters, or genre_id'); + res.send('Missing Request Parameters: artist_name, code_letters, genre_id, or code_number'); } else { try { - const generatedArtistNumber = await libraryService.generateArtistNumber(body.code_letters, body.genre_id); + const existingArtist = await libraryService.getArtistByCode( + body.code_letters, + body.genre_id, + body.code_number + ); + if (existingArtist) { + res.status(409).json({ + message: 'Artist code already exists for that genre and code letters.', + artist: existingArtist, + }); + return; + } const new_artist: NewArtist = { artist_name: body.artist_name, code_letters: body.code_letters, - code_artist_number: generatedArtistNumber, - genre_id: body.genre_id, }; const response: Artist = await libraryService.insertArtist(new_artist); + await libraryService.insertArtistGenreCrossreference(response.id, body.genre_id, body.code_number); res.status(200); - res.send(response); + res.json({ + ...response, + code_number: body.code_number, + genre_id: body.genre_id, + }); } catch (e) { console.error('Error: Failed to add new artist'); console.error(e); @@ -152,6 +172,40 @@ export const addArtist: RequestHandler = async (req: Request, + res, + next +) => { + const { query } = req; + if (!query.code_letters || !query.genre_id) { + res.status(400); + res.send('Missing query parameters: code_letters and genre_id'); + return; + } + + const genreId = Number(query.genre_id); + if (!Number.isFinite(genreId)) { + res.status(400); + res.send('Invalid genre_id'); + return; + } + + try { + const nextCode = await libraryService.generateArtistNumber(query.code_letters, genreId); + res.status(200).json({ next_code_number: nextCode }); + } catch (e) { + console.error('Error: Failed to generate artist number'); + console.error(e); + next(e); + } +}; + export const getRotation: RequestHandler = async (req, res, next) => { try { const rotation = await libraryService.getRotationFromDB(); diff --git a/apps/backend/routes/library.route.ts b/apps/backend/routes/library.route.ts index 0d65147..34a679c 100644 --- a/apps/backend/routes/library.route.ts +++ b/apps/backend/routes/library.route.ts @@ -22,6 +22,8 @@ library_route.patch('/rotation', requirePermissions({ catalog: ['write'] }), lib library_route.post('/artists', requirePermissions({ catalog: ['write'] }), libraryController.addArtist); +library_route.get('/artists/peek-code', requirePermissions({ catalog: ['write'] }), libraryController.peekArtistNumber); + library_route.get('/formats', requirePermissions({ catalog: ['read'] }), libraryController.getFormats); library_route.post('/formats', requirePermissions({ catalog: ['write'] }), libraryController.addFormat); diff --git a/apps/backend/services/djs.service.ts b/apps/backend/services/djs.service.ts index f25e317..8035def 100644 --- a/apps/backend/services/djs.service.ts +++ b/apps/backend/services/djs.service.ts @@ -7,6 +7,7 @@ import { db, flowsheet, format, + genre_artist_crossreference, genres, library, show_djs, @@ -37,7 +38,7 @@ export const getBinFromDB = async (dj_id: string) => { artist_name: artists.artist_name, label: library.label, code_letters: artists.code_letters, - code_artist_number: artists.code_artist_number, + code_artist_number: genre_artist_crossreference.artist_genre_code, code_number: library.code_number, format_name: format.format_name, genre_name: genres.genre_name, @@ -47,6 +48,13 @@ export const getBinFromDB = async (dj_id: string) => { .innerJoin(artists, eq(library.artist_id, artists.id)) .innerJoin(format, eq(format.id, library.format_id)) .innerJoin(genres, eq(genres.id, library.genre_id)) + .innerJoin( + genre_artist_crossreference, + and( + eq(genre_artist_crossreference.artist_id, library.artist_id), + eq(genre_artist_crossreference.genre_id, library.genre_id) + ) + ) .where(eq(bins.dj_id, dj_id)); return dj_bin; diff --git a/apps/backend/services/library.service.ts b/apps/backend/services/library.service.ts index b6c82fb..3f0aa9e 100644 --- a/apps/backend/services/library.service.ts +++ b/apps/backend/services/library.service.ts @@ -1,4 +1,4 @@ -import { desc, eq, sql } from 'drizzle-orm'; +import { and, desc, eq, sql } from 'drizzle-orm'; import { RotationAddRequest } from '../controllers/library.controller.js'; import { db } from '@wxyc/database'; import { @@ -8,6 +8,7 @@ import { NewGenre, RotationRelease, artists, + genre_artist_crossreference, format, genres, library, @@ -54,7 +55,7 @@ export const getRotationFromDB = async (): Promise => { .select({ id: library.id, code_letters: artists.code_letters, - code_artist_number: artists.code_artist_number, + code_artist_number: genre_artist_crossreference.artist_genre_code, code_number: library.code_number, artist_name: artists.artist_name, album_title: library.album_title, @@ -71,8 +72,15 @@ export const getRotationFromDB = async (): Promise => { .from(library) .innerJoin(rotation, eq(library.id, rotation.album_id)) .innerJoin(artists, eq(artists.id, library.artist_id)) - .innerJoin(genres, eq(artists.genre_id, genres.id)) .innerJoin(format, eq(library.format_id, format.id)) + .innerJoin(genres, eq(library.genre_id, genres.id)) + .innerJoin( + genre_artist_crossreference, + and( + eq(genre_artist_crossreference.artist_id, library.artist_id), + eq(genre_artist_crossreference.genre_id, library.genre_id) + ) + ) .where(sql`${rotation.kill_date} > CURRENT_DATE OR ${rotation.kill_date} IS NULL`); return rotation_albums; @@ -142,7 +150,13 @@ export const artistIdFromName = async (artist_name: string, genre_id: number): P const response = await db .select({ id: artists.id }) .from(artists) - .where(sql`lower(${artists.artist_name}) = lower(${artist_name}) AND ${artists.genre_id} = ${genre_id}`) + .innerJoin(genre_artist_crossreference, eq(genre_artist_crossreference.artist_id, artists.id)) + .where( + and( + sql`lower(${artists.artist_name}) = lower(${artist_name})`, + eq(genre_artist_crossreference.genre_id, genre_id) + ) + ) .limit(1); if (!response.length) { @@ -157,6 +171,44 @@ export const insertArtist = async (new_artist: NewArtist) => { return response[0]; }; +export const insertArtistGenreCrossreference = async ( + artist_id: number, + genre_id: number, + artist_genre_code: number +) => { + const response = await db + .insert(genre_artist_crossreference) + .values({ artist_id, genre_id, artist_genre_code }) + .returning(); + return response[0]; +}; + +export const getArtistByCode = async ( + code_letters: string, + genre_id: number, + artist_genre_code: number +): Promise<{ artist_id: number; artist_name: string; code_letters: string } | null> => { + const response = await db + .select({ + artist_id: genre_artist_crossreference.artist_id, + artist_name: artists.artist_name, + code_letters: artists.code_letters, + }) + .from(genre_artist_crossreference) + .innerJoin(artists, eq(genre_artist_crossreference.artist_id, artists.id)) + .where( + and( + eq(artists.code_letters, code_letters), + eq(genre_artist_crossreference.genre_id, genre_id), + eq(genre_artist_crossreference.artist_genre_code, artist_genre_code) + ) + ) + .limit(1); + + // return null if no artist found + return response[0] ?? null; +}; + export const generateAlbumCodeNumber = async (artist_id: number): Promise => { const response = await db .select({ code_number: library.code_number }) @@ -174,17 +226,19 @@ export const generateAlbumCodeNumber = async (artist_id: number): Promise => { const response = await db - .select({ code_artist_number: artists.code_artist_number }) - .from(artists) - .where(sql`${artists.code_letters} = ${code_letters} AND ${artists.genre_id} = ${genre_id}`) - .orderBy(desc(artists.code_artist_number)) + .select({ artist_genre_code: genre_artist_crossreference.artist_genre_code }) + .from(genre_artist_crossreference) + .innerJoin(artists, eq(genre_artist_crossreference.artist_id, artists.id)) + .where(and(eq(artists.code_letters, code_letters), eq(genre_artist_crossreference.genre_id, genre_id))) + .orderBy(desc(genre_artist_crossreference.artist_genre_code)) .limit(1); - let code_artist_number = 1; + // default to being first artist in the genre + let artist_genre_code = 1; if (response.length) { - code_artist_number = response[0].code_artist_number + 1; //otherwise we increment on the last value + artist_genre_code = response[0].artist_genre_code + 1; //otherwise we increment on the last value } - return code_artist_number; + return artist_genre_code; }; export const getAlbumFromDB = async (album_id: number) => { @@ -192,7 +246,7 @@ export const getAlbumFromDB = async (album_id: number) => { .select({ id: library.id, code_letters: artists.code_letters, - code_artist_number: artists.code_letters, + code_artist_number: genre_artist_crossreference.artist_genre_code, code_number: library.code_number, artist_name: artists.artist_name, album_title: library.album_title, @@ -203,6 +257,13 @@ export const getAlbumFromDB = async (album_id: number) => { }) .from(library) .innerJoin(artists, eq(artists.id, library.artist_id)) + .innerJoin( + genre_artist_crossreference, + and( + eq(genre_artist_crossreference.artist_id, library.artist_id), + eq(genre_artist_crossreference.genre_id, library.genre_id) + ) + ) .where(eq(library.id, album_id)) .limit(1); diff --git a/dev_env/seed_db.sql b/dev_env/seed_db.sql index ab47523..5a1abed 100644 --- a/dev_env/seed_db.sql +++ b/dev_env/seed_db.sql @@ -106,17 +106,21 @@ INSERT INTO wxyc_schema.genres(genre_name) VALUES ('Hiphop'); INSERT INTO wxyc_schema.format(format_name) VALUES ('cd'); INSERT INTO wxyc_schema.format(format_name) VALUES ('vinyl'); -INSERT INTO wxyc_schema.artists( - artist_name, code_letters, code_artist_number, genre_id) - VALUES ('Built to Spill', 'BU', 60, 1); +INSERT INTO wxyc_schema.artists(artist_name, code_letters) + VALUES ('Built to Spill', 'BU'); -INSERT INTO wxyc_schema.artists( - artist_name, code_letters, code_artist_number, genre_id) - VALUES ('Ravyn Lenae', 'LE', 35, 2); +INSERT INTO wxyc_schema.artists(artist_name, code_letters) + VALUES ('Ravyn Lenae', 'LE'); -INSERT INTO wxyc_schema.artists( - artist_name, code_letters, code_artist_number, genre_id) - VALUES ('Jockstrap', 'JO', 108, 1); +INSERT INTO wxyc_schema.artists(artist_name, code_letters) + VALUES ('Jockstrap', 'JO'); + +INSERT INTO wxyc_schema.genre_artist_crossreference(artist_id, genre_id, artist_genre_code) + VALUES (1, 1, 60); +INSERT INTO wxyc_schema.genre_artist_crossreference(artist_id, genre_id, artist_genre_code) + VALUES (2, 2, 35); +INSERT INTO wxyc_schema.genre_artist_crossreference(artist_id, genre_id, artist_genre_code) + VALUES (3, 1, 108); INSERT INTO wxyc_schema.library( artist_id, genre_id, format_id, album_title, code_number) @@ -131,17 +135,21 @@ INSERT INTO wxyc_schema.library( VALUES (3, 1, 2, 'I Love You Jennifer B', 1); -- Additional artists for parallel test isolation (metadata.spec.js uses albums 4-6) -INSERT INTO wxyc_schema.artists( - artist_name, code_letters, code_artist_number, genre_id) - VALUES ('Sufjan Stevens', 'ST', 42, 1); +INSERT INTO wxyc_schema.artists(artist_name, code_letters) + VALUES ('Sufjan Stevens', 'ST'); + +INSERT INTO wxyc_schema.artists(artist_name, code_letters) + VALUES ('Kendrick Lamar', 'LA'); -INSERT INTO wxyc_schema.artists( - artist_name, code_letters, code_artist_number, genre_id) - VALUES ('Kendrick Lamar', 'LA', 15, 2); +INSERT INTO wxyc_schema.artists(artist_name, code_letters) + VALUES ('Bjork', 'BJ'); -INSERT INTO wxyc_schema.artists( - artist_name, code_letters, code_artist_number, genre_id) - VALUES ('Bjork', 'BJ', 22, 1); +INSERT INTO wxyc_schema.genre_artist_crossreference(artist_id, genre_id, artist_genre_code) + VALUES (4, 1, 42); +INSERT INTO wxyc_schema.genre_artist_crossreference(artist_id, genre_id, artist_genre_code) + VALUES (5, 2, 15); +INSERT INTO wxyc_schema.genre_artist_crossreference(artist_id, genre_id, artist_genre_code) + VALUES (6, 1, 22); -- Additional albums for parallel test isolation (IDs 4, 5, 6 for metadata.spec.js) INSERT INTO wxyc_schema.library( diff --git a/shared/database/src/migrations/0027_drop_genre_from_artist_table.sql b/shared/database/src/migrations/0027_drop_genre_from_artist_table.sql new file mode 100644 index 0000000..b7ac514 --- /dev/null +++ b/shared/database/src/migrations/0027_drop_genre_from_artist_table.sql @@ -0,0 +1,6 @@ +DROP VIEW "wxyc_schema"."library_artist_view";--> statement-breakpoint +ALTER TABLE "wxyc_schema"."artists" DROP CONSTRAINT "artists_genre_id_genres_id_fk"; +--> statement-breakpoint +ALTER TABLE "wxyc_schema"."artists" DROP COLUMN "genre_id";--> statement-breakpoint +ALTER TABLE "wxyc_schema"."artists" DROP COLUMN "code_artist_number";--> statement-breakpoint +CREATE VIEW "wxyc_schema"."library_artist_view" AS (select "wxyc_schema"."library"."id", "wxyc_schema"."artists"."code_letters", "wxyc_schema"."genre_artist_crossreference"."artist_genre_code", "wxyc_schema"."library"."code_number", "wxyc_schema"."artists"."artist_name", "wxyc_schema"."library"."album_title", "wxyc_schema"."format"."format_name", "wxyc_schema"."genres"."genre_name", "wxyc_schema"."rotation"."play_freq", "wxyc_schema"."library"."add_date", "wxyc_schema"."library"."label" from "wxyc_schema"."library" inner join "wxyc_schema"."artists" on "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id" inner join "wxyc_schema"."format" on "wxyc_schema"."format"."id" = "wxyc_schema"."library"."format_id" inner join "wxyc_schema"."genres" on "wxyc_schema"."genres"."id" = "wxyc_schema"."library"."genre_id" inner join "wxyc_schema"."genre_artist_crossreference" on ("wxyc_schema"."genre_artist_crossreference"."artist_id" = "wxyc_schema"."library"."artist_id" and "wxyc_schema"."genre_artist_crossreference"."genre_id" = "wxyc_schema"."library"."genre_id") left join "wxyc_schema"."rotation" on "wxyc_schema"."rotation"."album_id" = "wxyc_schema"."library"."id" AND ("wxyc_schema"."rotation"."kill_date" > CURRENT_DATE OR "wxyc_schema"."rotation"."kill_date" IS NULL)); \ No newline at end of file diff --git a/shared/database/src/migrations/meta/0027_snapshot.json b/shared/database/src/migrations/meta/0027_snapshot.json new file mode 100644 index 0000000..3a0fb52 --- /dev/null +++ b/shared/database/src/migrations/meta/0027_snapshot.json @@ -0,0 +1,2662 @@ +{ + "id": "4ff8acd5-61dc-4941-b1db-d2b67c2ff32e", + "prevId": "1bcc0430-ce5d-4cd6-bcc3-9a5bb8823f61", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_account_provider_account_key": { + "name": "auth_account_provider_account_key", + "columns": [ + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.album_metadata": { + "name": "album_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "discogs_release_id": { + "name": "discogs_release_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "discogs_url": { + "name": "discogs_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "release_year": { + "name": "release_year", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "artwork_url": { + "name": "artwork_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "spotify_url": { + "name": "spotify_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "apple_music_url": { + "name": "apple_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "youtube_music_url": { + "name": "youtube_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "bandcamp_url": { + "name": "bandcamp_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "soundcloud_url": { + "name": "soundcloud_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "is_rotation": { + "name": "is_rotation", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "album_metadata_album_id_idx": { + "name": "album_metadata_album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_cache_key_idx": { + "name": "album_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_last_accessed_idx": { + "name": "album_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "album_metadata_album_id_library_id_fk": { + "name": "album_metadata_album_id_library_id_fk", + "tableFrom": "album_metadata", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "album_metadata_album_id_unique": { + "name": "album_metadata_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + }, + "album_metadata_cache_key_unique": { + "name": "album_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.anonymous_devices": { + "name": "anonymous_devices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "device_id": { + "name": "device_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "blocked": { + "name": "blocked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "blocked_at": { + "name": "blocked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "anonymous_devices_device_id_key": { + "name": "anonymous_devices_device_id_key", + "columns": [ + { + "expression": "device_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "anonymous_devices_device_id_unique": { + "name": "anonymous_devices_device_id_unique", + "nullsNotDistinct": false, + "columns": [ + "device_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_library_crossreference": { + "name": "artist_library_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "library_id": { + "name": "library_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "library_id_artist_id": { + "name": "library_id_artist_id", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "library_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_library_crossreference_artist_id_artists_id_fk": { + "name": "artist_library_crossreference_artist_id_artists_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "artist_library_crossreference_library_id_library_id_fk": { + "name": "artist_library_crossreference_library_id_library_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_metadata": { + "name": "artist_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "discogs_artist_id": { + "name": "discogs_artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "wikipedia_url": { + "name": "wikipedia_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_metadata_artist_id_idx": { + "name": "artist_metadata_artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_cache_key_idx": { + "name": "artist_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_last_accessed_idx": { + "name": "artist_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_metadata_artist_id_artists_id_fk": { + "name": "artist_metadata_artist_id_artists_id_fk", + "tableFrom": "artist_metadata", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "artist_metadata_artist_id_unique": { + "name": "artist_metadata_artist_id_unique", + "nullsNotDistinct": false, + "columns": [ + "artist_id" + ] + }, + "artist_metadata_cache_key_unique": { + "name": "artist_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artists": { + "name": "artists", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_name_trgm_idx": { + "name": "artist_name_trgm_idx", + "columns": [ + { + "expression": "\"artist_name\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "code_letters_idx": { + "name": "code_letters_idx", + "columns": [ + { + "expression": "code_letters", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.bins": { + "name": "bins", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "bins_dj_id_auth_user_id_fk": { + "name": "bins_dj_id_auth_user_id_fk", + "tableFrom": "bins", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bins_album_id_library_id_fk": { + "name": "bins_album_id_library_id_fk", + "tableFrom": "bins", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.cronjob_runs": { + "name": "cronjob_runs", + "schema": "wxyc_schema", + "columns": { + "job_name": { + "name": "job_name", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "last_run": { + "name": "last_run", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.dj_stats": { + "name": "dj_stats", + "schema": "wxyc_schema", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "shows_covered": { + "name": "shows_covered", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "dj_stats_user_id_auth_user_id_fk": { + "name": "dj_stats_user_id_auth_user_id_fk", + "tableFrom": "dj_stats", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.flowsheet": { + "name": "flowsheet", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rotation_id": { + "name": "rotation_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "entry_type": { + "name": "entry_type", + "type": "flowsheet_entry_type", + "typeSchema": "wxyc_schema", + "primaryKey": false, + "notNull": true, + "default": "'track'" + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "record_label": { + "name": "record_label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "play_order": { + "name": "play_order", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "request_flag": { + "name": "request_flag", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "message": { + "name": "message", + "type": "varchar(250)", + "primaryKey": false, + "notNull": false + }, + "add_time": { + "name": "add_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "flowsheet_show_id_shows_id_fk": { + "name": "flowsheet_show_id_shows_id_fk", + "tableFrom": "flowsheet", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_album_id_library_id_fk": { + "name": "flowsheet_album_id_library_id_fk", + "tableFrom": "flowsheet", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_rotation_id_rotation_id_fk": { + "name": "flowsheet_rotation_id_rotation_id_fk", + "tableFrom": "flowsheet", + "tableTo": "rotation", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "rotation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.format": { + "name": "format", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genre_artist_crossreference": { + "name": "genre_artist_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "artist_genre_key": { + "name": "artist_genre_key", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "genre_artist_crossreference_artist_id_artists_id_fk": { + "name": "genre_artist_crossreference_artist_id_artists_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "genre_artist_crossreference_genre_id_genres_id_fk": { + "name": "genre_artist_crossreference_genre_id_genres_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genres": { + "name": "genres", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_invitation": { + "name": "auth_invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "inviter_id": { + "name": "inviter_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_invitation_email_idx": { + "name": "auth_invitation_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_invitation_organization_id_auth_organization_id_fk": { + "name": "auth_invitation_organization_id_auth_organization_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_invitation_inviter_id_auth_user_id_fk": { + "name": "auth_invitation_inviter_id_auth_user_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_jwks": { + "name": "auth_jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.library": { + "name": "library", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "format_id": { + "name": "format_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "alternate_artist_name": { + "name": "alternate_artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "code_volume_letters": { + "name": "code_volume_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": false + }, + "disc_quantity": { + "name": "disc_quantity", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "title_trgm_idx": { + "name": "title_trgm_idx", + "columns": [ + { + "expression": "\"album_title\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "genre_id_idx": { + "name": "genre_id_idx", + "columns": [ + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "format_id_idx": { + "name": "format_id_idx", + "columns": [ + { + "expression": "format_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_id_idx": { + "name": "artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "library_artist_id_artists_id_fk": { + "name": "library_artist_id_artists_id_fk", + "tableFrom": "library", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_genre_id_genres_id_fk": { + "name": "library_genre_id_genres_id_fk", + "tableFrom": "library", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_format_id_format_id_fk": { + "name": "library_format_id_format_id_fk", + "tableFrom": "library", + "tableTo": "format", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "format_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_member": { + "name": "auth_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_member_org_user_key": { + "name": "auth_member_org_user_key", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_member_organization_id_auth_organization_id_fk": { + "name": "auth_member_organization_id_auth_organization_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_member_user_id_auth_user_id_fk": { + "name": "auth_member_user_id_auth_user_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_organization": { + "name": "auth_organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_organization_slug_key": { + "name": "auth_organization_slug_key", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.reviews": { + "name": "reviews", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "review": { + "name": "review", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "author": { + "name": "author", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "reviews_album_id_library_id_fk": { + "name": "reviews_album_id_library_id_fk", + "tableFrom": "reviews", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reviews_album_id_unique": { + "name": "reviews_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.rotation": { + "name": "rotation", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "play_freq": { + "name": "play_freq", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "album_id_idx": { + "name": "album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "rotation_album_id_library_id_fk": { + "name": "rotation_album_id_library_id_fk", + "tableFrom": "rotation", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.schedule": { + "name": "schedule", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "day": { + "name": "day", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "start_time": { + "name": "start_time", + "type": "time", + "primaryKey": false, + "notNull": true + }, + "show_duration": { + "name": "show_duration", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id": { + "name": "assigned_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id2": { + "name": "assigned_dj_id2", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "schedule_specialty_id_specialty_shows_id_fk": { + "name": "schedule_specialty_id_specialty_shows_id_fk", + "tableFrom": "schedule", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id_auth_user_id_fk": { + "name": "schedule_assigned_dj_id_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id2_auth_user_id_fk": { + "name": "schedule_assigned_dj_id2_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id2" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_session_token_key": { + "name": "auth_session_token_key", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shift_covers": { + "name": "shift_covers", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "schedule_id": { + "name": "schedule_id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "shift_timestamp": { + "name": "shift_timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "cover_dj_id": { + "name": "cover_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "covered": { + "name": "covered", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "shift_covers_schedule_id_schedule_id_fk": { + "name": "shift_covers_schedule_id_schedule_id_fk", + "tableFrom": "shift_covers", + "tableTo": "schedule", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "schedule_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shift_covers_cover_dj_id_auth_user_id_fk": { + "name": "shift_covers_cover_dj_id_auth_user_id_fk", + "tableFrom": "shift_covers", + "tableTo": "auth_user", + "columnsFrom": [ + "cover_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.show_djs": { + "name": "show_djs", + "schema": "wxyc_schema", + "columns": { + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + } + }, + "indexes": {}, + "foreignKeys": { + "show_djs_show_id_shows_id_fk": { + "name": "show_djs_show_id_shows_id_fk", + "tableFrom": "show_djs", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "show_djs_dj_id_auth_user_id_fk": { + "name": "show_djs_dj_id_auth_user_id_fk", + "tableFrom": "show_djs", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shows": { + "name": "shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "primary_dj_id": { + "name": "primary_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "show_name": { + "name": "show_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "start_time": { + "name": "start_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "end_time": { + "name": "end_time", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "shows_primary_dj_id_auth_user_id_fk": { + "name": "shows_primary_dj_id_auth_user_id_fk", + "tableFrom": "shows", + "tableTo": "auth_user", + "columnsFrom": [ + "primary_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shows_specialty_id_specialty_shows_id_fk": { + "name": "shows_specialty_id_specialty_shows_id_fk", + "tableFrom": "shows", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.specialty_shows": { + "name": "specialty_shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "specialty_name": { + "name": "specialty_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "real_name": { + "name": "real_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dj_name": { + "name": "dj_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "app_skin": { + "name": "app_skin", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'modern-light'" + }, + "is_anonymous": { + "name": "is_anonymous", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "auth_user_email_key": { + "name": "auth_user_email_key", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auth_user_username_key": { + "name": "auth_user_username_key", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_activity": { + "name": "user_activity", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_activity_user_id_auth_user_id_fk": { + "name": "user_activity_user_id_auth_user_id_fk", + "tableFrom": "user_activity", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_verification": { + "name": "auth_verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "wxyc_schema.flowsheet_entry_type": { + "name": "flowsheet_entry_type", + "schema": "wxyc_schema", + "values": [ + "track", + "show_start", + "show_end", + "dj_join", + "dj_leave", + "talkset", + "breakpoint", + "message" + ] + }, + "public.freq_enum": { + "name": "freq_enum", + "schema": "public", + "values": [ + "S", + "L", + "M", + "H" + ] + } + }, + "schemas": { + "wxyc_schema": "wxyc_schema" + }, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": { + "wxyc_schema.library_artist_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true + }, + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "play_freq": { + "name": "play_freq", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"genre_artist_crossreference\".\"artist_genre_code\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" inner join \"wxyc_schema\".\"genre_artist_crossreference\" on (\"wxyc_schema\".\"genre_artist_crossreference\".\"artist_id\" = \"wxyc_schema\".\"library\".\"artist_id\" and \"wxyc_schema\".\"genre_artist_crossreference\".\"genre_id\" = \"wxyc_schema\".\"library\".\"genre_id\") left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" > CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", + "name": "library_artist_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + }, + "wxyc_schema.rotation_library_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "play_freq": { + "name": "play_freq", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", + "name": "rotation_library_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + } + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/shared/database/src/migrations/meta/_journal.json b/shared/database/src/migrations/meta/_journal.json index a35dbf0..9e41184 100644 --- a/shared/database/src/migrations/meta/_journal.json +++ b/shared/database/src/migrations/meta/_journal.json @@ -169,6 +169,13 @@ "when": 1770938861646, "tag": "0026_cron_job_tracking", "breakpoints": true + }, + { + "idx": 27, + "version": "7", + "when": 1770992362056, + "tag": "0027_drop_genre_from_artist_table", + "breakpoints": true } ] } \ No newline at end of file diff --git a/shared/database/src/schema.ts b/shared/database/src/schema.ts index 5825fc1..9bd1c47 100644 --- a/shared/database/src/schema.ts +++ b/shared/database/src/schema.ts @@ -1,5 +1,5 @@ import { InferInsertModel, InferSelectModel } from 'drizzle-orm'; -import { sql, eq } from 'drizzle-orm'; +import { sql, eq, and } from 'drizzle-orm'; import { pgSchema, pgTable, @@ -207,12 +207,8 @@ export const artists = wxyc_schema.table( 'artists', { id: serial('id').primaryKey(), - genre_id: integer('genre_id') - .references(() => genres.id) - .notNull(), artist_name: varchar('artist_name', { length: 128 }).notNull(), code_letters: varchar('code_letters', { length: 4 }).notNull(), - code_artist_number: smallint('code_artist_number').notNull(), add_date: date('add_date').defaultNow().notNull(), last_modified: timestamp('last_modified').defaultNow().notNull(), }, @@ -436,7 +432,7 @@ export const library_artist_view = wxyc_schema.view('library_artist_view').as((q .select({ id: library.id, code_letters: artists.code_letters, - code_artist_number: artists.code_artist_number, + code_artist_number: genre_artist_crossreference.artist_genre_code, code_number: library.code_number, artist_name: artists.artist_name, album_title: library.album_title, @@ -450,6 +446,13 @@ export const library_artist_view = wxyc_schema.view('library_artist_view').as((q .innerJoin(artists, eq(artists.id, library.artist_id)) .innerJoin(format, eq(format.id, library.format_id)) .innerJoin(genres, eq(genres.id, library.genre_id)) + .innerJoin( + genre_artist_crossreference, + and( + eq(genre_artist_crossreference.artist_id, library.artist_id), + eq(genre_artist_crossreference.genre_id, library.genre_id) + ) + ) .leftJoin( rotation, sql`${rotation.album_id} = ${library.id} AND (${rotation.kill_date} > CURRENT_DATE OR ${rotation.kill_date} IS NULL)` diff --git a/tests/integration/library.spec.js b/tests/integration/library.spec.js index d8eb002..46d1c58 100644 --- a/tests/integration/library.spec.js +++ b/tests/integration/library.spec.js @@ -313,40 +313,22 @@ describe('Library Artists', () => { artist_name: `Test Artist ${uniqueSuffix}`, code_letters: uniqueSuffix, genre_id: 1, + code_number: 1, }) .expect(200); - expectFields(res.body, 'id', 'artist_name', 'code_letters', 'code_artist_number'); + expectFields(res.body, 'id', 'artist_name', 'code_letters', 'code_number'); expect(res.body.artist_name).toContain('Test Artist'); expect(res.body.code_letters).toBe(uniqueSuffix); }); - test('generates incremented code_artist_number', async () => { - const uniqueCode = Date.now().toString(36).toUpperCase().slice(-2); - - const res1 = await auth.post('/library/artists').send({ - artist_name: `Test Artist A ${uniqueCode}`, - code_letters: uniqueCode, - genre_id: 1, - }); - - const res2 = await auth.post('/library/artists').send({ - artist_name: `Test Artist B ${uniqueCode}`, - code_letters: uniqueCode, - genre_id: 1, - }); - - if (res1.body.code_artist_number && res2.body.code_artist_number) { - expect(res2.body.code_artist_number).toBeGreaterThan(res1.body.code_artist_number); - } - }); - test('returns 400 when artist_name is missing', async () => { const res = await auth .post('/library/artists') .send({ code_letters: 'TS', genre_id: 1, + code_number: 1, }) .expect(400); @@ -359,6 +341,7 @@ describe('Library Artists', () => { .send({ artist_name: 'Test Artist', genre_id: 1, + code_number: 1, }) .expect(400); @@ -371,6 +354,20 @@ describe('Library Artists', () => { .send({ artist_name: 'Test Artist', code_letters: 'TS', + code_number: 1, + }) + .expect(400); + + expectErrorContains(res, 'Missing Request Parameters'); + }); + + test('returns 400 when code_number is missing', async () => { + const res = await auth + .post('/library/artists') + .send({ + artist_name: 'Test Artist', + code_letters: 'TS', + genre_id: 1, }) .expect(400); @@ -379,6 +376,21 @@ describe('Library Artists', () => { }); }); +describe('Library Artists Peek Code', () => { + let auth; + + beforeAll(() => { + auth = createAuthRequest(request, global.access_token); + }); + + test('peeks next code_artist_number', async () => { + const res = await auth.get('/library/artists/peek-code').query({ code_letters: 'BU', genre_id: 1 }).expect(200); + + // BU is the code for Built to Spill and has artist_genre_code 60 + expect(res.body.next_code_number).toBe(61); + }); +}); + describe('Library Formats', () => { let auth; diff --git a/tests/utils/fixtures.ts b/tests/utils/fixtures.ts index 0f94841..561f506 100644 --- a/tests/utils/fixtures.ts +++ b/tests/utils/fixtures.ts @@ -6,8 +6,12 @@ export const testArtist = { id: 1, artist_name: 'Test Artist', code_letters: 'RO', - code_artist_number: 1, +}; + +export const testArtistGenreCrossref = { + artist_id: 1, genre_id: 1, + artist_genre_code: 1, }; export const testAlbum = { From 4db976dbaa1d1bb60aef831e955bbe7a33cf5ed4 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Fri, 27 Feb 2026 23:10:45 -0500 Subject: [PATCH 13/17] remove no-longer used migration script --- .../src/migrations/migration_script.mjs | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 shared/database/src/migrations/migration_script.mjs diff --git a/shared/database/src/migrations/migration_script.mjs b/shared/database/src/migrations/migration_script.mjs deleted file mode 100644 index 7ec301c..0000000 --- a/shared/database/src/migrations/migration_script.mjs +++ /dev/null @@ -1,20 +0,0 @@ -import { drizzle } from 'drizzle-orm/postgres-js'; -import postgres from 'postgres'; -import { migrate } from 'drizzle-orm/postgres-js/migrator'; - -const migrationClient = postgres( - { - host: process.env.DB_HOST, - port: process.env.DB_PORT, - database: process.env.DB_NAME, - username: process.env.DB_USERNAME, - password: process.env.DB_PASSWORD, - }, - { max: 1 } -); - -const db = drizzle(migrationClient); - -migrate(db, { migrationsFolder: 'src/db/migrations' }) - .catch((e) => console.error(e)) - .then(() => console.log('MIGRATION COMPLETE!')); From 1fa150db8129a4e7a944d65fc8733666bbacf78d Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Fri, 27 Feb 2026 23:14:08 -0500 Subject: [PATCH 14/17] remove auth on test event trigger route that caused integration test failures --- apps/backend/routes/events.route.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/backend/routes/events.route.ts b/apps/backend/routes/events.route.ts index 13148c8..4b19873 100644 --- a/apps/backend/routes/events.route.ts +++ b/apps/backend/routes/events.route.ts @@ -4,9 +4,11 @@ import * as serverEvents from '../controllers/events.conroller.js'; export const events_route = Router(); -//TODO: secure - mgmt & individual dj +//TODO: You shouldn't have to be authenticated to register an event client. +// Each topic has it's own permissions, some of which are public. events_route.post('/register', requirePermissions({ flowsheet: ['read'] }), serverEvents.registerEventClient); +//TODO: You shouldn't have to be authenticated to subscribe to a topic events_route.put('/subscribe', requirePermissions({ flowsheet: ['read'] }), serverEvents.subscribeToTopic); -events_route.get('/test', requirePermissions({ flowsheet: ['read'] }), serverEvents.testTrigger); +events_route.get('/test', serverEvents.testTrigger); From d281b4f02579dfca328823d16563eb40f7f90856 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Sat, 28 Feb 2026 11:25:21 -0500 Subject: [PATCH 15/17] Add support for alphabetical_name for artists --- .../backend/controllers/library.controller.ts | 9 +- apps/backend/services/djs.service.ts | 1 + apps/backend/services/library.service.ts | 4 + apps/backend/services/requestLine/types.ts | 2 + dev_env/seed_db.sql | 24 +- jobs/library-etl/job.ts | 28 +- .../0028_add_artists_alphabetical_name.sql | 5 + .../src/migrations/meta/0028_snapshot.json | 2680 +++++++++++++++++ .../src/migrations/meta/_journal.json | 7 + shared/database/src/schema.ts | 4 + tests/integration/library.spec.js | 25 +- tests/unit/jobs/library-etl.test.ts | 19 + tests/utils/fixtures.ts | 1 + 13 files changed, 2778 insertions(+), 31 deletions(-) create mode 100644 shared/database/src/migrations/0028_add_artists_alphabetical_name.sql create mode 100644 shared/database/src/migrations/meta/0028_snapshot.json diff --git a/apps/backend/controllers/library.controller.ts b/apps/backend/controllers/library.controller.ts index 37c5203..01177b6 100644 --- a/apps/backend/controllers/library.controller.ts +++ b/apps/backend/controllers/library.controller.ts @@ -120,6 +120,7 @@ export const searchForAlbum: RequestHandler = async ( type NewArtistRequest = { artist_name: string; + alphabetical_name?: string; code_letters: string; genre_id: number; code_number: number; @@ -127,7 +128,6 @@ type NewArtistRequest = { export const addArtist: RequestHandler = async (req: Request, res, next) => { const { body } = req; - //TODO auto_generate artist code letters and make it an optional parameter if ( body.artist_name === undefined || body.code_letters === undefined || @@ -138,11 +138,7 @@ export const addArtist: RequestHandler = async (req: Request { album_id: bins.album_id, album_title: library.album_title, artist_name: artists.artist_name, + alphabetical_name: artists.alphabetical_name, label: library.label, code_letters: artists.code_letters, code_artist_number: genre_artist_crossreference.artist_genre_code, diff --git a/apps/backend/services/library.service.ts b/apps/backend/services/library.service.ts index 3f0aa9e..3fef5b1 100644 --- a/apps/backend/services/library.service.ts +++ b/apps/backend/services/library.service.ts @@ -38,6 +38,7 @@ export interface Rotation { code_artist_number: number; code_number: number; artist_name: string; + alphabetical_name: string; album_title: string; record_label: string | null; genre_name: string; @@ -58,6 +59,7 @@ export const getRotationFromDB = async (): Promise => { code_artist_number: genre_artist_crossreference.artist_genre_code, code_number: library.code_number, artist_name: artists.artist_name, + alphabetical_name: artists.alphabetical_name, album_title: library.album_title, record_label: library.label, genre_name: genres.genre_name, @@ -249,6 +251,7 @@ export const getAlbumFromDB = async (album_id: number) => { code_artist_number: genre_artist_crossreference.artist_genre_code, code_number: library.code_number, artist_name: artists.artist_name, + alphabetical_name: artists.alphabetical_name, album_title: library.album_title, record_label: library.label, plays: library.plays, @@ -297,6 +300,7 @@ function viewRowToLibraryResult(row: LibraryArtistViewEntry): LibraryResult { id: row.id, title: row.album_title, artist: row.artist_name, + alphabeticalName: row.alphabetical_name, codeLetters: row.code_letters, codeArtistNumber: row.code_artist_number, codeNumber: row.code_number, diff --git a/apps/backend/services/requestLine/types.ts b/apps/backend/services/requestLine/types.ts index f0b219d..6b976b6 100644 --- a/apps/backend/services/requestLine/types.ts +++ b/apps/backend/services/requestLine/types.ts @@ -51,6 +51,8 @@ export interface LibraryResult { title: string | null; /** Artist name */ artist: string | null; + /** Alphabetical sort name (e.g. "Beatles, The") */ + alphabeticalName?: string | null; /** Genre code letters (e.g., "RO" for Rock) */ codeLetters: string | null; /** Artist number within genre */ diff --git a/dev_env/seed_db.sql b/dev_env/seed_db.sql index 5a1abed..607f471 100644 --- a/dev_env/seed_db.sql +++ b/dev_env/seed_db.sql @@ -106,14 +106,14 @@ INSERT INTO wxyc_schema.genres(genre_name) VALUES ('Hiphop'); INSERT INTO wxyc_schema.format(format_name) VALUES ('cd'); INSERT INTO wxyc_schema.format(format_name) VALUES ('vinyl'); -INSERT INTO wxyc_schema.artists(artist_name, code_letters) - VALUES ('Built to Spill', 'BU'); +INSERT INTO wxyc_schema.artists(artist_name, alphabetical_name, code_letters) + VALUES ('Built to Spill', 'Built to Spill', 'BU'); -INSERT INTO wxyc_schema.artists(artist_name, code_letters) - VALUES ('Ravyn Lenae', 'LE'); +INSERT INTO wxyc_schema.artists(artist_name, alphabetical_name, code_letters) + VALUES ('Ravyn Lenae', 'Ravyn Lenae', 'LE'); -INSERT INTO wxyc_schema.artists(artist_name, code_letters) - VALUES ('Jockstrap', 'JO'); +INSERT INTO wxyc_schema.artists(artist_name, alphabetical_name, code_letters) + VALUES ('Jockstrap', 'Jockstrap', 'JO'); INSERT INTO wxyc_schema.genre_artist_crossreference(artist_id, genre_id, artist_genre_code) VALUES (1, 1, 60); @@ -135,14 +135,14 @@ INSERT INTO wxyc_schema.library( VALUES (3, 1, 2, 'I Love You Jennifer B', 1); -- Additional artists for parallel test isolation (metadata.spec.js uses albums 4-6) -INSERT INTO wxyc_schema.artists(artist_name, code_letters) - VALUES ('Sufjan Stevens', 'ST'); +INSERT INTO wxyc_schema.artists(artist_name, alphabetical_name, code_letters) + VALUES ('Sufjan Stevens', 'Sufjan Stevens', 'ST'); -INSERT INTO wxyc_schema.artists(artist_name, code_letters) - VALUES ('Kendrick Lamar', 'LA'); +INSERT INTO wxyc_schema.artists(artist_name, alphabetical_name, code_letters) + VALUES ('Kendrick Lamar', 'Kendrick Lamar', 'LA'); -INSERT INTO wxyc_schema.artists(artist_name, code_letters) - VALUES ('Bjork', 'BJ'); +INSERT INTO wxyc_schema.artists(artist_name, alphabetical_name, code_letters) + VALUES ('Bjork', 'Bjork', 'BJ'); INSERT INTO wxyc_schema.genre_artist_crossreference(artist_id, genre_id, artist_genre_code) VALUES (4, 1, 42); diff --git a/jobs/library-etl/job.ts b/jobs/library-etl/job.ts index e23286b..249d805 100644 --- a/jobs/library-etl/job.ts +++ b/jobs/library-etl/job.ts @@ -66,6 +66,18 @@ const normalizeArtistName = (name: string) => { return { name: trimmed, isVarious: false }; }; +/** + * Derive alphabetical sort name (e.g. "The Beatles" -> "Beatles, The"). + * Uses legacy value when provided and non-empty. + */ +const toAlphabeticalName = (artistName: string, fromLegacy?: string | null): string => { + const legacy = fromLegacy?.trim(); + if (legacy && legacy.length > 0) return legacy; + // This shouldn't be necessary, but just in case since alphabetical_name is not nullable in database + const match = artistName.trim().match(/^The\s+(.+)$/i); + return match ? `${match[1]}, The` : artistName.trim(); +}; + const normalizeCodeLetters = (code: string | null) => { if (!code) return null; const trimmed = code.trim(); @@ -203,6 +215,7 @@ const fetchLegacyReleases = async (lastRunMs: number | null) => { const ensureArtist = async ( dbClient: DbClient, artistName: string, + alphabeticalName: string, isVarious: boolean, genreId: number, codeLetters: string | null, @@ -248,6 +261,7 @@ const ensureArtist = async ( .insert(artists) .values({ artist_name: artistName, + alphabetical_name: alphabeticalName, code_letters: normalizedLetters, add_date: addDate, last_modified: lastModified, @@ -366,16 +380,16 @@ const run = async () => { skippedCount += 1; continue; } + const alphabeticalName = toAlphabeticalName(artistInfo.name, release.artist_alpha_name); const codeLetters = artistInfo.isVarious ? VARIOUS_ARTISTS_CODE_LETTERS : normalizeCodeLetters(release.artist_call_letters); - const artistGenreCode = artistInfo.isVarious - ? VARIOUS_ARTISTS_CODE_NUMBER - : (release.artist_call_numbers ?? 0); + const artistGenreCode = artistInfo.isVarious ? VARIOUS_ARTISTS_CODE_NUMBER : (release.artist_call_numbers ?? 0); const artistId = await ensureArtist( tx, artistInfo.name, + alphabeticalName, artistInfo.isVarious, genreId, codeLetters, @@ -385,12 +399,7 @@ const run = async () => { toDateOrUndefined(release.release_last_modified) ); - await ensureGenreArtistCrossref( - tx, - artistId, - genreId, - artistGenreCode - ); + await ensureGenreArtistCrossref(tx, artistId, genreId, artistGenreCode); const albumTitle = release.release_title.trim(); if (albumTitle.length === 0) { @@ -448,6 +457,7 @@ export { toNullableNumber, isDbOnlyGenre, normalizeArtistName, + toAlphabeticalName, normalizeCodeLetters, parseFormatAndDiscs, toDateOrUndefined, diff --git a/shared/database/src/migrations/0028_add_artists_alphabetical_name.sql b/shared/database/src/migrations/0028_add_artists_alphabetical_name.sql new file mode 100644 index 0000000..2ca5ece --- /dev/null +++ b/shared/database/src/migrations/0028_add_artists_alphabetical_name.sql @@ -0,0 +1,5 @@ +DROP VIEW IF EXISTS "wxyc_schema"."library_artist_view";--> statement-breakpoint +DROP VIEW IF EXISTS "wxyc_schema"."rotation_library_view";--> statement-breakpoint +ALTER TABLE "wxyc_schema"."artists" ADD COLUMN "alphabetical_name" varchar(128) NOT NULL;--> statement-breakpoint +CREATE VIEW "wxyc_schema"."library_artist_view" AS (select "wxyc_schema"."library"."id", "wxyc_schema"."artists"."code_letters", "wxyc_schema"."genre_artist_crossreference"."artist_genre_code", "wxyc_schema"."library"."code_number", "wxyc_schema"."artists"."artist_name", "wxyc_schema"."artists"."alphabetical_name", "wxyc_schema"."library"."album_title", "wxyc_schema"."format"."format_name", "wxyc_schema"."genres"."genre_name", "wxyc_schema"."rotation"."play_freq", "wxyc_schema"."library"."add_date", "wxyc_schema"."library"."label" from "wxyc_schema"."library" inner join "wxyc_schema"."artists" on "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id" inner join "wxyc_schema"."format" on "wxyc_schema"."format"."id" = "wxyc_schema"."library"."format_id" inner join "wxyc_schema"."genres" on "wxyc_schema"."genres"."id" = "wxyc_schema"."library"."genre_id" inner join "wxyc_schema"."genre_artist_crossreference" on ("wxyc_schema"."genre_artist_crossreference"."artist_id" = "wxyc_schema"."library"."artist_id" and "wxyc_schema"."genre_artist_crossreference"."genre_id" = "wxyc_schema"."library"."genre_id") left join "wxyc_schema"."rotation" on "wxyc_schema"."rotation"."album_id" = "wxyc_schema"."library"."id" AND ("wxyc_schema"."rotation"."kill_date" > CURRENT_DATE OR "wxyc_schema"."rotation"."kill_date" IS NULL));--> statement-breakpoint +CREATE VIEW "wxyc_schema"."rotation_library_view" AS (select "wxyc_schema"."library"."id" AS "library_id", "wxyc_schema"."rotation"."id" AS "rotation_id", "wxyc_schema"."library"."label", "wxyc_schema"."rotation"."play_freq", "wxyc_schema"."library"."album_title", "wxyc_schema"."artists"."artist_name", "wxyc_schema"."artists"."alphabetical_name", "wxyc_schema"."rotation"."kill_date" from "wxyc_schema"."library" inner join "wxyc_schema"."rotation" on "wxyc_schema"."library"."id" = "wxyc_schema"."rotation"."album_id" inner join "wxyc_schema"."artists" on "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id"); \ No newline at end of file diff --git a/shared/database/src/migrations/meta/0028_snapshot.json b/shared/database/src/migrations/meta/0028_snapshot.json new file mode 100644 index 0000000..d12ac74 --- /dev/null +++ b/shared/database/src/migrations/meta/0028_snapshot.json @@ -0,0 +1,2680 @@ +{ + "id": "5c36b9a8-cc3d-4608-9b64-43eb41651775", + "prevId": "4ff8acd5-61dc-4941-b1db-d2b67c2ff32e", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_account_provider_account_key": { + "name": "auth_account_provider_account_key", + "columns": [ + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.album_metadata": { + "name": "album_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "discogs_release_id": { + "name": "discogs_release_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "discogs_url": { + "name": "discogs_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "release_year": { + "name": "release_year", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "artwork_url": { + "name": "artwork_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "spotify_url": { + "name": "spotify_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "apple_music_url": { + "name": "apple_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "youtube_music_url": { + "name": "youtube_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "bandcamp_url": { + "name": "bandcamp_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "soundcloud_url": { + "name": "soundcloud_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "is_rotation": { + "name": "is_rotation", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "album_metadata_album_id_idx": { + "name": "album_metadata_album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_cache_key_idx": { + "name": "album_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_last_accessed_idx": { + "name": "album_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "album_metadata_album_id_library_id_fk": { + "name": "album_metadata_album_id_library_id_fk", + "tableFrom": "album_metadata", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "album_metadata_album_id_unique": { + "name": "album_metadata_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + }, + "album_metadata_cache_key_unique": { + "name": "album_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.anonymous_devices": { + "name": "anonymous_devices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "device_id": { + "name": "device_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "blocked": { + "name": "blocked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "blocked_at": { + "name": "blocked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "anonymous_devices_device_id_key": { + "name": "anonymous_devices_device_id_key", + "columns": [ + { + "expression": "device_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "anonymous_devices_device_id_unique": { + "name": "anonymous_devices_device_id_unique", + "nullsNotDistinct": false, + "columns": [ + "device_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_library_crossreference": { + "name": "artist_library_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "library_id": { + "name": "library_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "library_id_artist_id": { + "name": "library_id_artist_id", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "library_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_library_crossreference_artist_id_artists_id_fk": { + "name": "artist_library_crossreference_artist_id_artists_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "artist_library_crossreference_library_id_library_id_fk": { + "name": "artist_library_crossreference_library_id_library_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_metadata": { + "name": "artist_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "discogs_artist_id": { + "name": "discogs_artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "wikipedia_url": { + "name": "wikipedia_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_metadata_artist_id_idx": { + "name": "artist_metadata_artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_cache_key_idx": { + "name": "artist_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_last_accessed_idx": { + "name": "artist_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_metadata_artist_id_artists_id_fk": { + "name": "artist_metadata_artist_id_artists_id_fk", + "tableFrom": "artist_metadata", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "artist_metadata_artist_id_unique": { + "name": "artist_metadata_artist_id_unique", + "nullsNotDistinct": false, + "columns": [ + "artist_id" + ] + }, + "artist_metadata_cache_key_unique": { + "name": "artist_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artists": { + "name": "artists", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "alphabetical_name": { + "name": "alphabetical_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_name_trgm_idx": { + "name": "artist_name_trgm_idx", + "columns": [ + { + "expression": "\"artist_name\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "code_letters_idx": { + "name": "code_letters_idx", + "columns": [ + { + "expression": "code_letters", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.bins": { + "name": "bins", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "bins_dj_id_auth_user_id_fk": { + "name": "bins_dj_id_auth_user_id_fk", + "tableFrom": "bins", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bins_album_id_library_id_fk": { + "name": "bins_album_id_library_id_fk", + "tableFrom": "bins", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.cronjob_runs": { + "name": "cronjob_runs", + "schema": "wxyc_schema", + "columns": { + "job_name": { + "name": "job_name", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "last_run": { + "name": "last_run", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.dj_stats": { + "name": "dj_stats", + "schema": "wxyc_schema", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "shows_covered": { + "name": "shows_covered", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "dj_stats_user_id_auth_user_id_fk": { + "name": "dj_stats_user_id_auth_user_id_fk", + "tableFrom": "dj_stats", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.flowsheet": { + "name": "flowsheet", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rotation_id": { + "name": "rotation_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "entry_type": { + "name": "entry_type", + "type": "flowsheet_entry_type", + "typeSchema": "wxyc_schema", + "primaryKey": false, + "notNull": true, + "default": "'track'" + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "record_label": { + "name": "record_label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "play_order": { + "name": "play_order", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "request_flag": { + "name": "request_flag", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "message": { + "name": "message", + "type": "varchar(250)", + "primaryKey": false, + "notNull": false + }, + "add_time": { + "name": "add_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "flowsheet_show_id_shows_id_fk": { + "name": "flowsheet_show_id_shows_id_fk", + "tableFrom": "flowsheet", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_album_id_library_id_fk": { + "name": "flowsheet_album_id_library_id_fk", + "tableFrom": "flowsheet", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_rotation_id_rotation_id_fk": { + "name": "flowsheet_rotation_id_rotation_id_fk", + "tableFrom": "flowsheet", + "tableTo": "rotation", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "rotation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.format": { + "name": "format", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genre_artist_crossreference": { + "name": "genre_artist_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "artist_genre_key": { + "name": "artist_genre_key", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "genre_artist_crossreference_artist_id_artists_id_fk": { + "name": "genre_artist_crossreference_artist_id_artists_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "genre_artist_crossreference_genre_id_genres_id_fk": { + "name": "genre_artist_crossreference_genre_id_genres_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genres": { + "name": "genres", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_invitation": { + "name": "auth_invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "inviter_id": { + "name": "inviter_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_invitation_email_idx": { + "name": "auth_invitation_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_invitation_organization_id_auth_organization_id_fk": { + "name": "auth_invitation_organization_id_auth_organization_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_invitation_inviter_id_auth_user_id_fk": { + "name": "auth_invitation_inviter_id_auth_user_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_jwks": { + "name": "auth_jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.library": { + "name": "library", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "format_id": { + "name": "format_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "alternate_artist_name": { + "name": "alternate_artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "code_volume_letters": { + "name": "code_volume_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": false + }, + "disc_quantity": { + "name": "disc_quantity", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "title_trgm_idx": { + "name": "title_trgm_idx", + "columns": [ + { + "expression": "\"album_title\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "genre_id_idx": { + "name": "genre_id_idx", + "columns": [ + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "format_id_idx": { + "name": "format_id_idx", + "columns": [ + { + "expression": "format_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_id_idx": { + "name": "artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "library_artist_id_artists_id_fk": { + "name": "library_artist_id_artists_id_fk", + "tableFrom": "library", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_genre_id_genres_id_fk": { + "name": "library_genre_id_genres_id_fk", + "tableFrom": "library", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_format_id_format_id_fk": { + "name": "library_format_id_format_id_fk", + "tableFrom": "library", + "tableTo": "format", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "format_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_member": { + "name": "auth_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_member_org_user_key": { + "name": "auth_member_org_user_key", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_member_organization_id_auth_organization_id_fk": { + "name": "auth_member_organization_id_auth_organization_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_member_user_id_auth_user_id_fk": { + "name": "auth_member_user_id_auth_user_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_organization": { + "name": "auth_organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_organization_slug_key": { + "name": "auth_organization_slug_key", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.reviews": { + "name": "reviews", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "review": { + "name": "review", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "author": { + "name": "author", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "reviews_album_id_library_id_fk": { + "name": "reviews_album_id_library_id_fk", + "tableFrom": "reviews", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reviews_album_id_unique": { + "name": "reviews_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.rotation": { + "name": "rotation", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "play_freq": { + "name": "play_freq", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "album_id_idx": { + "name": "album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "rotation_album_id_library_id_fk": { + "name": "rotation_album_id_library_id_fk", + "tableFrom": "rotation", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.schedule": { + "name": "schedule", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "day": { + "name": "day", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "start_time": { + "name": "start_time", + "type": "time", + "primaryKey": false, + "notNull": true + }, + "show_duration": { + "name": "show_duration", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id": { + "name": "assigned_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id2": { + "name": "assigned_dj_id2", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "schedule_specialty_id_specialty_shows_id_fk": { + "name": "schedule_specialty_id_specialty_shows_id_fk", + "tableFrom": "schedule", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id_auth_user_id_fk": { + "name": "schedule_assigned_dj_id_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id2_auth_user_id_fk": { + "name": "schedule_assigned_dj_id2_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id2" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_session_token_key": { + "name": "auth_session_token_key", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shift_covers": { + "name": "shift_covers", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "schedule_id": { + "name": "schedule_id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "shift_timestamp": { + "name": "shift_timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "cover_dj_id": { + "name": "cover_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "covered": { + "name": "covered", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "shift_covers_schedule_id_schedule_id_fk": { + "name": "shift_covers_schedule_id_schedule_id_fk", + "tableFrom": "shift_covers", + "tableTo": "schedule", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "schedule_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shift_covers_cover_dj_id_auth_user_id_fk": { + "name": "shift_covers_cover_dj_id_auth_user_id_fk", + "tableFrom": "shift_covers", + "tableTo": "auth_user", + "columnsFrom": [ + "cover_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.show_djs": { + "name": "show_djs", + "schema": "wxyc_schema", + "columns": { + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + } + }, + "indexes": {}, + "foreignKeys": { + "show_djs_show_id_shows_id_fk": { + "name": "show_djs_show_id_shows_id_fk", + "tableFrom": "show_djs", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "show_djs_dj_id_auth_user_id_fk": { + "name": "show_djs_dj_id_auth_user_id_fk", + "tableFrom": "show_djs", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shows": { + "name": "shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "primary_dj_id": { + "name": "primary_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "show_name": { + "name": "show_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "start_time": { + "name": "start_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "end_time": { + "name": "end_time", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "shows_primary_dj_id_auth_user_id_fk": { + "name": "shows_primary_dj_id_auth_user_id_fk", + "tableFrom": "shows", + "tableTo": "auth_user", + "columnsFrom": [ + "primary_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shows_specialty_id_specialty_shows_id_fk": { + "name": "shows_specialty_id_specialty_shows_id_fk", + "tableFrom": "shows", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.specialty_shows": { + "name": "specialty_shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "specialty_name": { + "name": "specialty_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "real_name": { + "name": "real_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dj_name": { + "name": "dj_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "app_skin": { + "name": "app_skin", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'modern-light'" + }, + "is_anonymous": { + "name": "is_anonymous", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "auth_user_email_key": { + "name": "auth_user_email_key", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auth_user_username_key": { + "name": "auth_user_username_key", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_activity": { + "name": "user_activity", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_activity_user_id_auth_user_id_fk": { + "name": "user_activity_user_id_auth_user_id_fk", + "tableFrom": "user_activity", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_verification": { + "name": "auth_verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "wxyc_schema.flowsheet_entry_type": { + "name": "flowsheet_entry_type", + "schema": "wxyc_schema", + "values": [ + "track", + "show_start", + "show_end", + "dj_join", + "dj_leave", + "talkset", + "breakpoint", + "message" + ] + }, + "public.freq_enum": { + "name": "freq_enum", + "schema": "public", + "values": [ + "S", + "L", + "M", + "H" + ] + } + }, + "schemas": { + "wxyc_schema": "wxyc_schema" + }, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": { + "wxyc_schema.library_artist_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true + }, + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "alphabetical_name": { + "name": "alphabetical_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "play_freq": { + "name": "play_freq", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"genre_artist_crossreference\".\"artist_genre_code\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"artists\".\"alphabetical_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" inner join \"wxyc_schema\".\"genre_artist_crossreference\" on (\"wxyc_schema\".\"genre_artist_crossreference\".\"artist_id\" = \"wxyc_schema\".\"library\".\"artist_id\" and \"wxyc_schema\".\"genre_artist_crossreference\".\"genre_id\" = \"wxyc_schema\".\"library\".\"genre_id\") left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" > CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", + "name": "library_artist_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + }, + "wxyc_schema.rotation_library_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "play_freq": { + "name": "play_freq", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "alphabetical_name": { + "name": "alphabetical_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"artists\".\"alphabetical_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", + "name": "rotation_library_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + } + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/shared/database/src/migrations/meta/_journal.json b/shared/database/src/migrations/meta/_journal.json index 9e41184..f404fe0 100644 --- a/shared/database/src/migrations/meta/_journal.json +++ b/shared/database/src/migrations/meta/_journal.json @@ -176,6 +176,13 @@ "when": 1770992362056, "tag": "0027_drop_genre_from_artist_table", "breakpoints": true + }, + { + "idx": 28, + "version": "7", + "when": 1772287838030, + "tag": "0028_add_artists_alphabetical_name", + "breakpoints": true } ] } \ No newline at end of file diff --git a/shared/database/src/schema.ts b/shared/database/src/schema.ts index 9bd1c47..9ea3a81 100644 --- a/shared/database/src/schema.ts +++ b/shared/database/src/schema.ts @@ -208,6 +208,7 @@ export const artists = wxyc_schema.table( { id: serial('id').primaryKey(), artist_name: varchar('artist_name', { length: 128 }).notNull(), + alphabetical_name: varchar('alphabetical_name', { length: 128 }).notNull(), code_letters: varchar('code_letters', { length: 4 }).notNull(), add_date: date('add_date').defaultNow().notNull(), last_modified: timestamp('last_modified').defaultNow().notNull(), @@ -420,6 +421,7 @@ export type LibraryArtistViewEntry = { code_artist_number: number; code_number: number; artist_name: string; + alphabetical_name: string; album_title: string; format_name: string; genre_name: string; @@ -435,6 +437,7 @@ export const library_artist_view = wxyc_schema.view('library_artist_view').as((q code_artist_number: genre_artist_crossreference.artist_genre_code, code_number: library.code_number, artist_name: artists.artist_name, + alphabetical_name: artists.alphabetical_name, album_title: library.album_title, format_name: format.format_name, genre_name: genres.genre_name, @@ -468,6 +471,7 @@ export const rotation_library_view = wxyc_schema.view('rotation_library_view').a play_freq: rotation.play_freq, album_title: library.album_title, artist_name: artists.artist_name, + alphabetical_name: artists.alphabetical_name, kill_date: rotation.kill_date, }) .from(library) diff --git a/tests/integration/library.spec.js b/tests/integration/library.spec.js index 46d1c58..9142ba4 100644 --- a/tests/integration/library.spec.js +++ b/tests/integration/library.spec.js @@ -183,7 +183,7 @@ describe('Library Rotation', () => { const res = await auth.get('/library/rotation').expect(200); if (res.body.length > 0) { - expectFields(res.body[0], 'id', 'artist_name', 'album_title', 'play_freq', 'rotation_id'); + expectFields(res.body[0], 'id', 'artist_name', 'alphabetical_name', 'album_title', 'play_freq', 'rotation_id'); } }); }); @@ -317,8 +317,9 @@ describe('Library Artists', () => { }) .expect(200); - expectFields(res.body, 'id', 'artist_name', 'code_letters', 'code_number'); + expectFields(res.body, 'id', 'artist_name', 'alphabetical_name', 'code_letters', 'code_number'); expect(res.body.artist_name).toContain('Test Artist'); + expect(res.body.alphabetical_name).toBeDefined(); expect(res.body.code_letters).toBe(uniqueSuffix); }); @@ -373,6 +374,22 @@ describe('Library Artists', () => { expectErrorContains(res, 'Missing Request Parameters'); }); + + test('accepts optional alphabetical_name and returns it', async () => { + const uniqueSuffix = Date.now().toString(36).toUpperCase().slice(-3); + const res = await auth + .post('/library/artists') + .send({ + artist_name: `The Band ${uniqueSuffix}`, + alphabetical_name: `Band ${uniqueSuffix}, The`, + code_letters: uniqueSuffix, + genre_id: 1, + code_number: 1, + }) + .expect(200); + + expect(res.body.alphabetical_name).toBe(`Band ${uniqueSuffix}, The`); + }); }); }); @@ -511,14 +528,14 @@ describe('Library Album Info', () => { test('returns album info for valid album_id', async () => { const res = await auth.get('/library/info').query({ album_id: 1 }).expect(200); - expectFields(res.body, 'id', 'artist_name', 'album_title'); + expectFields(res.body, 'id', 'artist_name', 'alphabetical_name', 'album_title'); expect(res.body.id).toBe(1); }); test('returns album with all expected fields', async () => { const res = await auth.get('/library/info').query({ album_id: 1 }).expect(200); - expectFields(res.body, 'id', 'artist_name', 'album_title', 'code_letters', 'code_number', 'plays'); + expectFields(res.body, 'id', 'artist_name', 'alphabetical_name', 'album_title', 'code_letters', 'code_number', 'plays'); }); test('returns 400 when album_id is missing', async () => { diff --git a/tests/unit/jobs/library-etl.test.ts b/tests/unit/jobs/library-etl.test.ts index 7cb6fe6..cc57877 100644 --- a/tests/unit/jobs/library-etl.test.ts +++ b/tests/unit/jobs/library-etl.test.ts @@ -73,6 +73,7 @@ import { toNullableNumber, isDbOnlyGenre, normalizeArtistName, + toAlphabeticalName, normalizeCodeLetters, parseFormatAndDiscs, toDateOrUndefined, @@ -171,6 +172,24 @@ describe('library-etl job helpers', () => { }); }); + describe('toAlphabeticalName', () => { + it('uses legacy value when provided and non-empty', () => { + expect(toAlphabeticalName('The Beatles', 'Beatles, The')).toBe('Beatles, The'); + expect(toAlphabeticalName('Some Artist', 'Artist, Some')).toBe('Artist, Some'); + }); + + it('derives "The X" as "X, The" when no legacy', () => { + expect(toAlphabeticalName('The Beatles', null)).toBe('Beatles, The'); + expect(toAlphabeticalName('The Beatles', '')).toBe('Beatles, The'); + expect(toAlphabeticalName(' The Rolling Stones ', undefined)).toBe('Rolling Stones, The'); + }); + + it('returns trimmed artist name when no "The" prefix and no legacy', () => { + expect(toAlphabeticalName('Built to Spill', null)).toBe('Built to Spill'); + expect(toAlphabeticalName(' FKA twigs ', '')).toBe('FKA twigs'); + }); + }); + describe('normalizeCodeLetters', () => { it('returns first two chars uppercased', () => { expect(normalizeCodeLetters('ab')).toBe('AB'); diff --git a/tests/utils/fixtures.ts b/tests/utils/fixtures.ts index 561f506..c88e987 100644 --- a/tests/utils/fixtures.ts +++ b/tests/utils/fixtures.ts @@ -5,6 +5,7 @@ export const testArtist = { id: 1, artist_name: 'Test Artist', + alphabetical_name: 'Test Artist', code_letters: 'RO', }; From 0f6c0c668fd62cbb8eaf03e90219e756f606f63b Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Sat, 28 Feb 2026 12:06:23 -0500 Subject: [PATCH 16/17] address migrations --- .../src/migrations/0026_cron_job_tracking.sql | 36 - .../0027_drop_genre_from_artist_table.sql | 6 - .../0028_add_artists_alphabetical_name.sql | 5 - .../src/migrations/meta/0026_snapshot.json | 2689 ----------------- .../src/migrations/meta/0027_snapshot.json | 2662 ---------------- .../src/migrations/meta/0028_snapshot.json | 2680 ---------------- .../src/migrations/meta/_journal.json | 21 - 7 files changed, 8099 deletions(-) delete mode 100644 shared/database/src/migrations/0026_cron_job_tracking.sql delete mode 100644 shared/database/src/migrations/0027_drop_genre_from_artist_table.sql delete mode 100644 shared/database/src/migrations/0028_add_artists_alphabetical_name.sql delete mode 100644 shared/database/src/migrations/meta/0026_snapshot.json delete mode 100644 shared/database/src/migrations/meta/0027_snapshot.json delete mode 100644 shared/database/src/migrations/meta/0028_snapshot.json diff --git a/shared/database/src/migrations/0026_cron_job_tracking.sql b/shared/database/src/migrations/0026_cron_job_tracking.sql deleted file mode 100644 index 7be64bc..0000000 --- a/shared/database/src/migrations/0026_cron_job_tracking.sql +++ /dev/null @@ -1,36 +0,0 @@ -CREATE TABLE IF NOT EXISTS "wxyc_schema"."cronjob_runs" ( - "job_name" varchar(64) PRIMARY KEY NOT NULL, - "last_run" timestamp with time zone DEFAULT now() NOT NULL -); ---> statement-breakpoint - ---> Drop view in order to alter the artists table -DROP VIEW IF EXISTS "wxyc_schema"."library_artist_view"; ---> statement-breakpoint - -ALTER TABLE "wxyc_schema"."artists" ALTER COLUMN "code_letters" SET DATA TYPE varchar(4); ---> statement-breakpoint - -ALTER TABLE "wxyc_schema"."library" ADD COLUMN IF NOT EXISTS "code_volume_letters" varchar(4); ---> statement-breakpoint - ---> Recreate view with the altered column in the artists table -CREATE VIEW "wxyc_schema"."library_artist_view" AS -SELECT "library"."id", - "artists"."code_letters", - "artists"."code_artist_number", - "library"."code_number", - "artists"."artist_name", - "library"."album_title", - "library"."label", - "format"."format_name", - "genres"."genre_name", - "rotation"."play_freq", - "library"."add_date" -FROM "wxyc_schema"."library" - INNER JOIN "wxyc_schema"."artists" ON "artists"."id" = "library"."artist_id" - INNER JOIN "wxyc_schema"."genres" ON "genres"."id" = "library"."genre_id" - INNER JOIN "wxyc_schema"."format" ON "format"."id" = "library"."format_id" - LEFT JOIN "wxyc_schema"."rotation" - ON "rotation"."album_id" = "library"."id" AND ("rotation"."kill_date" > CURRENT_DATE OR "rotation"."kill_date" IS NULL); ---> statement-breakpoint \ No newline at end of file diff --git a/shared/database/src/migrations/0027_drop_genre_from_artist_table.sql b/shared/database/src/migrations/0027_drop_genre_from_artist_table.sql deleted file mode 100644 index b7ac514..0000000 --- a/shared/database/src/migrations/0027_drop_genre_from_artist_table.sql +++ /dev/null @@ -1,6 +0,0 @@ -DROP VIEW "wxyc_schema"."library_artist_view";--> statement-breakpoint -ALTER TABLE "wxyc_schema"."artists" DROP CONSTRAINT "artists_genre_id_genres_id_fk"; ---> statement-breakpoint -ALTER TABLE "wxyc_schema"."artists" DROP COLUMN "genre_id";--> statement-breakpoint -ALTER TABLE "wxyc_schema"."artists" DROP COLUMN "code_artist_number";--> statement-breakpoint -CREATE VIEW "wxyc_schema"."library_artist_view" AS (select "wxyc_schema"."library"."id", "wxyc_schema"."artists"."code_letters", "wxyc_schema"."genre_artist_crossreference"."artist_genre_code", "wxyc_schema"."library"."code_number", "wxyc_schema"."artists"."artist_name", "wxyc_schema"."library"."album_title", "wxyc_schema"."format"."format_name", "wxyc_schema"."genres"."genre_name", "wxyc_schema"."rotation"."play_freq", "wxyc_schema"."library"."add_date", "wxyc_schema"."library"."label" from "wxyc_schema"."library" inner join "wxyc_schema"."artists" on "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id" inner join "wxyc_schema"."format" on "wxyc_schema"."format"."id" = "wxyc_schema"."library"."format_id" inner join "wxyc_schema"."genres" on "wxyc_schema"."genres"."id" = "wxyc_schema"."library"."genre_id" inner join "wxyc_schema"."genre_artist_crossreference" on ("wxyc_schema"."genre_artist_crossreference"."artist_id" = "wxyc_schema"."library"."artist_id" and "wxyc_schema"."genre_artist_crossreference"."genre_id" = "wxyc_schema"."library"."genre_id") left join "wxyc_schema"."rotation" on "wxyc_schema"."rotation"."album_id" = "wxyc_schema"."library"."id" AND ("wxyc_schema"."rotation"."kill_date" > CURRENT_DATE OR "wxyc_schema"."rotation"."kill_date" IS NULL)); \ No newline at end of file diff --git a/shared/database/src/migrations/0028_add_artists_alphabetical_name.sql b/shared/database/src/migrations/0028_add_artists_alphabetical_name.sql deleted file mode 100644 index 2ca5ece..0000000 --- a/shared/database/src/migrations/0028_add_artists_alphabetical_name.sql +++ /dev/null @@ -1,5 +0,0 @@ -DROP VIEW IF EXISTS "wxyc_schema"."library_artist_view";--> statement-breakpoint -DROP VIEW IF EXISTS "wxyc_schema"."rotation_library_view";--> statement-breakpoint -ALTER TABLE "wxyc_schema"."artists" ADD COLUMN "alphabetical_name" varchar(128) NOT NULL;--> statement-breakpoint -CREATE VIEW "wxyc_schema"."library_artist_view" AS (select "wxyc_schema"."library"."id", "wxyc_schema"."artists"."code_letters", "wxyc_schema"."genre_artist_crossreference"."artist_genre_code", "wxyc_schema"."library"."code_number", "wxyc_schema"."artists"."artist_name", "wxyc_schema"."artists"."alphabetical_name", "wxyc_schema"."library"."album_title", "wxyc_schema"."format"."format_name", "wxyc_schema"."genres"."genre_name", "wxyc_schema"."rotation"."play_freq", "wxyc_schema"."library"."add_date", "wxyc_schema"."library"."label" from "wxyc_schema"."library" inner join "wxyc_schema"."artists" on "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id" inner join "wxyc_schema"."format" on "wxyc_schema"."format"."id" = "wxyc_schema"."library"."format_id" inner join "wxyc_schema"."genres" on "wxyc_schema"."genres"."id" = "wxyc_schema"."library"."genre_id" inner join "wxyc_schema"."genre_artist_crossreference" on ("wxyc_schema"."genre_artist_crossreference"."artist_id" = "wxyc_schema"."library"."artist_id" and "wxyc_schema"."genre_artist_crossreference"."genre_id" = "wxyc_schema"."library"."genre_id") left join "wxyc_schema"."rotation" on "wxyc_schema"."rotation"."album_id" = "wxyc_schema"."library"."id" AND ("wxyc_schema"."rotation"."kill_date" > CURRENT_DATE OR "wxyc_schema"."rotation"."kill_date" IS NULL));--> statement-breakpoint -CREATE VIEW "wxyc_schema"."rotation_library_view" AS (select "wxyc_schema"."library"."id" AS "library_id", "wxyc_schema"."rotation"."id" AS "rotation_id", "wxyc_schema"."library"."label", "wxyc_schema"."rotation"."play_freq", "wxyc_schema"."library"."album_title", "wxyc_schema"."artists"."artist_name", "wxyc_schema"."artists"."alphabetical_name", "wxyc_schema"."rotation"."kill_date" from "wxyc_schema"."library" inner join "wxyc_schema"."rotation" on "wxyc_schema"."library"."id" = "wxyc_schema"."rotation"."album_id" inner join "wxyc_schema"."artists" on "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id"); \ No newline at end of file diff --git a/shared/database/src/migrations/meta/0026_snapshot.json b/shared/database/src/migrations/meta/0026_snapshot.json deleted file mode 100644 index f4d45ed..0000000 --- a/shared/database/src/migrations/meta/0026_snapshot.json +++ /dev/null @@ -1,2689 +0,0 @@ -{ - "id": "1bcc0430-ce5d-4cd6-bcc3-9a5bb8823f61", - "prevId": "335ff99b-a9d0-49ec-a275-2bf4e9b2edf7", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.auth_account": { - "name": "auth_account", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "account_id": { - "name": "account_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider_id": { - "name": "provider_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "access_token_expires_at": { - "name": "access_token_expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "refresh_token_expires_at": { - "name": "refresh_token_expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "scope": { - "name": "scope", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "auth_account_provider_account_key": { - "name": "auth_account_provider_account_key", - "columns": [ - { - "expression": "provider_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "account_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_account_user_id_auth_user_id_fk": { - "name": "auth_account_user_id_auth_user_id_fk", - "tableFrom": "auth_account", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.album_metadata": { - "name": "album_metadata", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "cache_key": { - "name": "cache_key", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "discogs_release_id": { - "name": "discogs_release_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "discogs_url": { - "name": "discogs_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "release_year": { - "name": "release_year", - "type": "smallint", - "primaryKey": false, - "notNull": false - }, - "artwork_url": { - "name": "artwork_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "spotify_url": { - "name": "spotify_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "apple_music_url": { - "name": "apple_music_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "youtube_music_url": { - "name": "youtube_music_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "bandcamp_url": { - "name": "bandcamp_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "soundcloud_url": { - "name": "soundcloud_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "is_rotation": { - "name": "is_rotation", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "last_accessed": { - "name": "last_accessed", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "album_metadata_album_id_idx": { - "name": "album_metadata_album_id_idx", - "columns": [ - { - "expression": "album_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "album_metadata_cache_key_idx": { - "name": "album_metadata_cache_key_idx", - "columns": [ - { - "expression": "cache_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "album_metadata_last_accessed_idx": { - "name": "album_metadata_last_accessed_idx", - "columns": [ - { - "expression": "last_accessed", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "album_metadata_album_id_library_id_fk": { - "name": "album_metadata_album_id_library_id_fk", - "tableFrom": "album_metadata", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "album_metadata_album_id_unique": { - "name": "album_metadata_album_id_unique", - "nullsNotDistinct": false, - "columns": [ - "album_id" - ] - }, - "album_metadata_cache_key_unique": { - "name": "album_metadata_cache_key_unique", - "nullsNotDistinct": false, - "columns": [ - "cache_key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.anonymous_devices": { - "name": "anonymous_devices", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "device_id": { - "name": "device_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_seen_at": { - "name": "last_seen_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "blocked": { - "name": "blocked", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "blocked_at": { - "name": "blocked_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "blocked_reason": { - "name": "blocked_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "request_count": { - "name": "request_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": { - "anonymous_devices_device_id_key": { - "name": "anonymous_devices_device_id_key", - "columns": [ - { - "expression": "device_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "anonymous_devices_device_id_unique": { - "name": "anonymous_devices_device_id_unique", - "nullsNotDistinct": false, - "columns": [ - "device_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.artist_library_crossreference": { - "name": "artist_library_crossreference", - "schema": "wxyc_schema", - "columns": { - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "library_id": { - "name": "library_id", - "type": "integer", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "library_id_artist_id": { - "name": "library_id_artist_id", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "library_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "artist_library_crossreference_artist_id_artists_id_fk": { - "name": "artist_library_crossreference_artist_id_artists_id_fk", - "tableFrom": "artist_library_crossreference", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "artist_library_crossreference_library_id_library_id_fk": { - "name": "artist_library_crossreference_library_id_library_id_fk", - "tableFrom": "artist_library_crossreference", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "library_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.artist_metadata": { - "name": "artist_metadata", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "cache_key": { - "name": "cache_key", - "type": "varchar(256)", - "primaryKey": false, - "notNull": false - }, - "discogs_artist_id": { - "name": "discogs_artist_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "bio": { - "name": "bio", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "wikipedia_url": { - "name": "wikipedia_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "last_accessed": { - "name": "last_accessed", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "artist_metadata_artist_id_idx": { - "name": "artist_metadata_artist_id_idx", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "artist_metadata_cache_key_idx": { - "name": "artist_metadata_cache_key_idx", - "columns": [ - { - "expression": "cache_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "artist_metadata_last_accessed_idx": { - "name": "artist_metadata_last_accessed_idx", - "columns": [ - { - "expression": "last_accessed", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "artist_metadata_artist_id_artists_id_fk": { - "name": "artist_metadata_artist_id_artists_id_fk", - "tableFrom": "artist_metadata", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "artist_metadata_artist_id_unique": { - "name": "artist_metadata_artist_id_unique", - "nullsNotDistinct": false, - "columns": [ - "artist_id" - ] - }, - "artist_metadata_cache_key_unique": { - "name": "artist_metadata_cache_key_unique", - "nullsNotDistinct": false, - "columns": [ - "cache_key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.artists": { - "name": "artists", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "genre_id": { - "name": "genre_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "code_letters": { - "name": "code_letters", - "type": "varchar(4)", - "primaryKey": false, - "notNull": true - }, - "code_artist_number": { - "name": "code_artist_number", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "artist_name_trgm_idx": { - "name": "artist_name_trgm_idx", - "columns": [ - { - "expression": "\"artist_name\" gin_trgm_ops", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "gin", - "with": {} - }, - "code_letters_idx": { - "name": "code_letters_idx", - "columns": [ - { - "expression": "code_letters", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "artists_genre_id_genres_id_fk": { - "name": "artists_genre_id_genres_id_fk", - "tableFrom": "artists", - "tableTo": "genres", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "genre_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.bins": { - "name": "bins", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "dj_id": { - "name": "dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "track_title": { - "name": "track_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "bins_dj_id_auth_user_id_fk": { - "name": "bins_dj_id_auth_user_id_fk", - "tableFrom": "bins", - "tableTo": "auth_user", - "columnsFrom": [ - "dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "bins_album_id_library_id_fk": { - "name": "bins_album_id_library_id_fk", - "tableFrom": "bins", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.cronjob_runs": { - "name": "cronjob_runs", - "schema": "wxyc_schema", - "columns": { - "job_name": { - "name": "job_name", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "last_run": { - "name": "last_run", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.dj_stats": { - "name": "dj_stats", - "schema": "wxyc_schema", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "shows_covered": { - "name": "shows_covered", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": {}, - "foreignKeys": { - "dj_stats_user_id_auth_user_id_fk": { - "name": "dj_stats_user_id_auth_user_id_fk", - "tableFrom": "dj_stats", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.flowsheet": { - "name": "flowsheet", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "show_id": { - "name": "show_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "rotation_id": { - "name": "rotation_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "entry_type": { - "name": "entry_type", - "type": "flowsheet_entry_type", - "typeSchema": "wxyc_schema", - "primaryKey": false, - "notNull": true, - "default": "'track'" - }, - "track_title": { - "name": "track_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "record_label": { - "name": "record_label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "play_order": { - "name": "play_order", - "type": "serial", - "primaryKey": false, - "notNull": true - }, - "request_flag": { - "name": "request_flag", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "message": { - "name": "message", - "type": "varchar(250)", - "primaryKey": false, - "notNull": false - }, - "add_time": { - "name": "add_time", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "flowsheet_show_id_shows_id_fk": { - "name": "flowsheet_show_id_shows_id_fk", - "tableFrom": "flowsheet", - "tableTo": "shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "show_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "flowsheet_album_id_library_id_fk": { - "name": "flowsheet_album_id_library_id_fk", - "tableFrom": "flowsheet", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "flowsheet_rotation_id_rotation_id_fk": { - "name": "flowsheet_rotation_id_rotation_id_fk", - "tableFrom": "flowsheet", - "tableTo": "rotation", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "rotation_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.format": { - "name": "format", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "format_name": { - "name": "format_name", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.genre_artist_crossreference": { - "name": "genre_artist_crossreference", - "schema": "wxyc_schema", - "columns": { - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "genre_id": { - "name": "genre_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "artist_genre_code": { - "name": "artist_genre_code", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "artist_genre_key": { - "name": "artist_genre_key", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "genre_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "genre_artist_crossreference_artist_id_artists_id_fk": { - "name": "genre_artist_crossreference_artist_id_artists_id_fk", - "tableFrom": "genre_artist_crossreference", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "genre_artist_crossreference_genre_id_genres_id_fk": { - "name": "genre_artist_crossreference_genre_id_genres_id_fk", - "tableFrom": "genre_artist_crossreference", - "tableTo": "genres", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "genre_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.genres": { - "name": "genres", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "genre_name": { - "name": "genre_name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "plays": { - "name": "plays", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_invitation": { - "name": "auth_invitation", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "inviter_id": { - "name": "inviter_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "auth_invitation_email_idx": { - "name": "auth_invitation_email_idx", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_invitation_organization_id_auth_organization_id_fk": { - "name": "auth_invitation_organization_id_auth_organization_id_fk", - "tableFrom": "auth_invitation", - "tableTo": "auth_organization", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auth_invitation_inviter_id_auth_user_id_fk": { - "name": "auth_invitation_inviter_id_auth_user_id_fk", - "tableFrom": "auth_invitation", - "tableTo": "auth_user", - "columnsFrom": [ - "inviter_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_jwks": { - "name": "auth_jwks", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "public_key": { - "name": "public_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "private_key": { - "name": "private_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.library": { - "name": "library", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "genre_id": { - "name": "genre_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "format_id": { - "name": "format_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "alternate_artist_name": { - "name": "alternate_artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "label": { - "name": "label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "code_number": { - "name": "code_number", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "code_volume_letters": { - "name": "code_volume_letters", - "type": "varchar(4)", - "primaryKey": false, - "notNull": false - }, - "disc_quantity": { - "name": "disc_quantity", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "default": 1 - }, - "plays": { - "name": "plays", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "add_date": { - "name": "add_date", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "title_trgm_idx": { - "name": "title_trgm_idx", - "columns": [ - { - "expression": "\"album_title\" gin_trgm_ops", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "gin", - "with": {} - }, - "genre_id_idx": { - "name": "genre_id_idx", - "columns": [ - { - "expression": "genre_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "format_id_idx": { - "name": "format_id_idx", - "columns": [ - { - "expression": "format_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "artist_id_idx": { - "name": "artist_id_idx", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "library_artist_id_artists_id_fk": { - "name": "library_artist_id_artists_id_fk", - "tableFrom": "library", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "library_genre_id_genres_id_fk": { - "name": "library_genre_id_genres_id_fk", - "tableFrom": "library", - "tableTo": "genres", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "genre_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "library_format_id_format_id_fk": { - "name": "library_format_id_format_id_fk", - "tableFrom": "library", - "tableTo": "format", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "format_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_member": { - "name": "auth_member", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true, - "default": "'member'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "auth_member_org_user_key": { - "name": "auth_member_org_user_key", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_member_organization_id_auth_organization_id_fk": { - "name": "auth_member_organization_id_auth_organization_id_fk", - "tableFrom": "auth_member", - "tableTo": "auth_organization", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auth_member_user_id_auth_user_id_fk": { - "name": "auth_member_user_id_auth_user_id_fk", - "tableFrom": "auth_member", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_organization": { - "name": "auth_organization", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "logo": { - "name": "logo", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "metadata": { - "name": "metadata", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "auth_organization_slug_key": { - "name": "auth_organization_slug_key", - "columns": [ - { - "expression": "slug", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.reviews": { - "name": "reviews", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "review": { - "name": "review", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "author": { - "name": "author", - "type": "varchar(32)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "reviews_album_id_library_id_fk": { - "name": "reviews_album_id_library_id_fk", - "tableFrom": "reviews", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "reviews_album_id_unique": { - "name": "reviews_album_id_unique", - "nullsNotDistinct": false, - "columns": [ - "album_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.rotation": { - "name": "rotation", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "play_freq": { - "name": "play_freq", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "kill_date": { - "name": "kill_date", - "type": "date", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "album_id_idx": { - "name": "album_id_idx", - "columns": [ - { - "expression": "album_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "rotation_album_id_library_id_fk": { - "name": "rotation_album_id_library_id_fk", - "tableFrom": "rotation", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.schedule": { - "name": "schedule", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "day": { - "name": "day", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "start_time": { - "name": "start_time", - "type": "time", - "primaryKey": false, - "notNull": true - }, - "show_duration": { - "name": "show_duration", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "specialty_id": { - "name": "specialty_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "assigned_dj_id": { - "name": "assigned_dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "assigned_dj_id2": { - "name": "assigned_dj_id2", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "schedule_specialty_id_specialty_shows_id_fk": { - "name": "schedule_specialty_id_specialty_shows_id_fk", - "tableFrom": "schedule", - "tableTo": "specialty_shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "specialty_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "schedule_assigned_dj_id_auth_user_id_fk": { - "name": "schedule_assigned_dj_id_auth_user_id_fk", - "tableFrom": "schedule", - "tableTo": "auth_user", - "columnsFrom": [ - "assigned_dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "schedule_assigned_dj_id2_auth_user_id_fk": { - "name": "schedule_assigned_dj_id2_auth_user_id_fk", - "tableFrom": "schedule", - "tableTo": "auth_user", - "columnsFrom": [ - "assigned_dj_id2" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_session": { - "name": "auth_session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "ip_address": { - "name": "ip_address", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_agent": { - "name": "user_agent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "impersonated_by": { - "name": "impersonated_by", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "active_organization_id": { - "name": "active_organization_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "auth_session_token_key": { - "name": "auth_session_token_key", - "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_session_user_id_auth_user_id_fk": { - "name": "auth_session_user_id_auth_user_id_fk", - "tableFrom": "auth_session", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.shift_covers": { - "name": "shift_covers", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "schedule_id": { - "name": "schedule_id", - "type": "serial", - "primaryKey": false, - "notNull": true - }, - "shift_timestamp": { - "name": "shift_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "cover_dj_id": { - "name": "cover_dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "covered": { - "name": "covered", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "shift_covers_schedule_id_schedule_id_fk": { - "name": "shift_covers_schedule_id_schedule_id_fk", - "tableFrom": "shift_covers", - "tableTo": "schedule", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "schedule_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "shift_covers_cover_dj_id_auth_user_id_fk": { - "name": "shift_covers_cover_dj_id_auth_user_id_fk", - "tableFrom": "shift_covers", - "tableTo": "auth_user", - "columnsFrom": [ - "cover_dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.show_djs": { - "name": "show_djs", - "schema": "wxyc_schema", - "columns": { - "show_id": { - "name": "show_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "dj_id": { - "name": "dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "active": { - "name": "active", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - } - }, - "indexes": {}, - "foreignKeys": { - "show_djs_show_id_shows_id_fk": { - "name": "show_djs_show_id_shows_id_fk", - "tableFrom": "show_djs", - "tableTo": "shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "show_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "show_djs_dj_id_auth_user_id_fk": { - "name": "show_djs_dj_id_auth_user_id_fk", - "tableFrom": "show_djs", - "tableTo": "auth_user", - "columnsFrom": [ - "dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.shows": { - "name": "shows", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "primary_dj_id": { - "name": "primary_dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "specialty_id": { - "name": "specialty_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "show_name": { - "name": "show_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "start_time": { - "name": "start_time", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "end_time": { - "name": "end_time", - "type": "timestamp", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "shows_primary_dj_id_auth_user_id_fk": { - "name": "shows_primary_dj_id_auth_user_id_fk", - "tableFrom": "shows", - "tableTo": "auth_user", - "columnsFrom": [ - "primary_dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "shows_specialty_id_specialty_shows_id_fk": { - "name": "shows_specialty_id_specialty_shows_id_fk", - "tableFrom": "shows", - "tableTo": "specialty_shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "specialty_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.specialty_shows": { - "name": "specialty_shows", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "specialty_name": { - "name": "specialty_name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_user": { - "name": "auth_user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email_verified": { - "name": "email_verified", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "role": { - "name": "role", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "banned": { - "name": "banned", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "ban_reason": { - "name": "ban_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ban_expires": { - "name": "ban_expires", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "username": { - "name": "username", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "display_username": { - "name": "display_username", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "real_name": { - "name": "real_name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "dj_name": { - "name": "dj_name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "app_skin": { - "name": "app_skin", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true, - "default": "'modern-light'" - }, - "is_anonymous": { - "name": "is_anonymous", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": { - "auth_user_email_key": { - "name": "auth_user_email_key", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "auth_user_username_key": { - "name": "auth_user_username_key", - "columns": [ - { - "expression": "username", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user_activity": { - "name": "user_activity", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "request_count": { - "name": "request_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "last_seen_at": { - "name": "last_seen_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "user_activity_user_id_auth_user_id_fk": { - "name": "user_activity_user_id_auth_user_id_fk", - "tableFrom": "user_activity", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_verification": { - "name": "auth_verification", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "identifier": { - "name": "identifier", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "wxyc_schema.flowsheet_entry_type": { - "name": "flowsheet_entry_type", - "schema": "wxyc_schema", - "values": [ - "track", - "show_start", - "show_end", - "dj_join", - "dj_leave", - "talkset", - "breakpoint", - "message" - ] - }, - "public.freq_enum": { - "name": "freq_enum", - "schema": "public", - "values": [ - "S", - "L", - "M", - "H" - ] - } - }, - "schemas": { - "wxyc_schema": "wxyc_schema" - }, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": { - "wxyc_schema.library_artist_view": { - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "code_letters": { - "name": "code_letters", - "type": "varchar(4)", - "primaryKey": false, - "notNull": true - }, - "code_artist_number": { - "name": "code_artist_number", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "code_number": { - "name": "code_number", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "format_name": { - "name": "format_name", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "genre_name": { - "name": "genre_name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "play_freq": { - "name": "play_freq", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "label": { - "name": "label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - } - }, - "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"artists\".\"code_artist_number\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" < CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", - "name": "library_artist_view", - "schema": "wxyc_schema", - "isExisting": false, - "materialized": false - }, - "wxyc_schema.rotation_library_view": { - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "label": { - "name": "label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "play_freq": { - "name": "play_freq", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "kill_date": { - "name": "kill_date", - "type": "date", - "primaryKey": false, - "notNull": false - } - }, - "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", - "name": "rotation_library_view", - "schema": "wxyc_schema", - "isExisting": false, - "materialized": false - } - }, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/shared/database/src/migrations/meta/0027_snapshot.json b/shared/database/src/migrations/meta/0027_snapshot.json deleted file mode 100644 index 3a0fb52..0000000 --- a/shared/database/src/migrations/meta/0027_snapshot.json +++ /dev/null @@ -1,2662 +0,0 @@ -{ - "id": "4ff8acd5-61dc-4941-b1db-d2b67c2ff32e", - "prevId": "1bcc0430-ce5d-4cd6-bcc3-9a5bb8823f61", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.auth_account": { - "name": "auth_account", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "account_id": { - "name": "account_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider_id": { - "name": "provider_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "access_token_expires_at": { - "name": "access_token_expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "refresh_token_expires_at": { - "name": "refresh_token_expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "scope": { - "name": "scope", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "auth_account_provider_account_key": { - "name": "auth_account_provider_account_key", - "columns": [ - { - "expression": "provider_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "account_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_account_user_id_auth_user_id_fk": { - "name": "auth_account_user_id_auth_user_id_fk", - "tableFrom": "auth_account", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.album_metadata": { - "name": "album_metadata", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "cache_key": { - "name": "cache_key", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "discogs_release_id": { - "name": "discogs_release_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "discogs_url": { - "name": "discogs_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "release_year": { - "name": "release_year", - "type": "smallint", - "primaryKey": false, - "notNull": false - }, - "artwork_url": { - "name": "artwork_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "spotify_url": { - "name": "spotify_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "apple_music_url": { - "name": "apple_music_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "youtube_music_url": { - "name": "youtube_music_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "bandcamp_url": { - "name": "bandcamp_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "soundcloud_url": { - "name": "soundcloud_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "is_rotation": { - "name": "is_rotation", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "last_accessed": { - "name": "last_accessed", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "album_metadata_album_id_idx": { - "name": "album_metadata_album_id_idx", - "columns": [ - { - "expression": "album_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "album_metadata_cache_key_idx": { - "name": "album_metadata_cache_key_idx", - "columns": [ - { - "expression": "cache_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "album_metadata_last_accessed_idx": { - "name": "album_metadata_last_accessed_idx", - "columns": [ - { - "expression": "last_accessed", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "album_metadata_album_id_library_id_fk": { - "name": "album_metadata_album_id_library_id_fk", - "tableFrom": "album_metadata", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "album_metadata_album_id_unique": { - "name": "album_metadata_album_id_unique", - "nullsNotDistinct": false, - "columns": [ - "album_id" - ] - }, - "album_metadata_cache_key_unique": { - "name": "album_metadata_cache_key_unique", - "nullsNotDistinct": false, - "columns": [ - "cache_key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.anonymous_devices": { - "name": "anonymous_devices", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "device_id": { - "name": "device_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_seen_at": { - "name": "last_seen_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "blocked": { - "name": "blocked", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "blocked_at": { - "name": "blocked_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "blocked_reason": { - "name": "blocked_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "request_count": { - "name": "request_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": { - "anonymous_devices_device_id_key": { - "name": "anonymous_devices_device_id_key", - "columns": [ - { - "expression": "device_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "anonymous_devices_device_id_unique": { - "name": "anonymous_devices_device_id_unique", - "nullsNotDistinct": false, - "columns": [ - "device_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.artist_library_crossreference": { - "name": "artist_library_crossreference", - "schema": "wxyc_schema", - "columns": { - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "library_id": { - "name": "library_id", - "type": "integer", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "library_id_artist_id": { - "name": "library_id_artist_id", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "library_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "artist_library_crossreference_artist_id_artists_id_fk": { - "name": "artist_library_crossreference_artist_id_artists_id_fk", - "tableFrom": "artist_library_crossreference", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "artist_library_crossreference_library_id_library_id_fk": { - "name": "artist_library_crossreference_library_id_library_id_fk", - "tableFrom": "artist_library_crossreference", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "library_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.artist_metadata": { - "name": "artist_metadata", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "cache_key": { - "name": "cache_key", - "type": "varchar(256)", - "primaryKey": false, - "notNull": false - }, - "discogs_artist_id": { - "name": "discogs_artist_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "bio": { - "name": "bio", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "wikipedia_url": { - "name": "wikipedia_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "last_accessed": { - "name": "last_accessed", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "artist_metadata_artist_id_idx": { - "name": "artist_metadata_artist_id_idx", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "artist_metadata_cache_key_idx": { - "name": "artist_metadata_cache_key_idx", - "columns": [ - { - "expression": "cache_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "artist_metadata_last_accessed_idx": { - "name": "artist_metadata_last_accessed_idx", - "columns": [ - { - "expression": "last_accessed", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "artist_metadata_artist_id_artists_id_fk": { - "name": "artist_metadata_artist_id_artists_id_fk", - "tableFrom": "artist_metadata", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "artist_metadata_artist_id_unique": { - "name": "artist_metadata_artist_id_unique", - "nullsNotDistinct": false, - "columns": [ - "artist_id" - ] - }, - "artist_metadata_cache_key_unique": { - "name": "artist_metadata_cache_key_unique", - "nullsNotDistinct": false, - "columns": [ - "cache_key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.artists": { - "name": "artists", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "code_letters": { - "name": "code_letters", - "type": "varchar(4)", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "artist_name_trgm_idx": { - "name": "artist_name_trgm_idx", - "columns": [ - { - "expression": "\"artist_name\" gin_trgm_ops", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "gin", - "with": {} - }, - "code_letters_idx": { - "name": "code_letters_idx", - "columns": [ - { - "expression": "code_letters", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.bins": { - "name": "bins", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "dj_id": { - "name": "dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "track_title": { - "name": "track_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "bins_dj_id_auth_user_id_fk": { - "name": "bins_dj_id_auth_user_id_fk", - "tableFrom": "bins", - "tableTo": "auth_user", - "columnsFrom": [ - "dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "bins_album_id_library_id_fk": { - "name": "bins_album_id_library_id_fk", - "tableFrom": "bins", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.cronjob_runs": { - "name": "cronjob_runs", - "schema": "wxyc_schema", - "columns": { - "job_name": { - "name": "job_name", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "last_run": { - "name": "last_run", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.dj_stats": { - "name": "dj_stats", - "schema": "wxyc_schema", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "shows_covered": { - "name": "shows_covered", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": {}, - "foreignKeys": { - "dj_stats_user_id_auth_user_id_fk": { - "name": "dj_stats_user_id_auth_user_id_fk", - "tableFrom": "dj_stats", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.flowsheet": { - "name": "flowsheet", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "show_id": { - "name": "show_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "rotation_id": { - "name": "rotation_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "entry_type": { - "name": "entry_type", - "type": "flowsheet_entry_type", - "typeSchema": "wxyc_schema", - "primaryKey": false, - "notNull": true, - "default": "'track'" - }, - "track_title": { - "name": "track_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "record_label": { - "name": "record_label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "play_order": { - "name": "play_order", - "type": "serial", - "primaryKey": false, - "notNull": true - }, - "request_flag": { - "name": "request_flag", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "message": { - "name": "message", - "type": "varchar(250)", - "primaryKey": false, - "notNull": false - }, - "add_time": { - "name": "add_time", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "flowsheet_show_id_shows_id_fk": { - "name": "flowsheet_show_id_shows_id_fk", - "tableFrom": "flowsheet", - "tableTo": "shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "show_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "flowsheet_album_id_library_id_fk": { - "name": "flowsheet_album_id_library_id_fk", - "tableFrom": "flowsheet", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "flowsheet_rotation_id_rotation_id_fk": { - "name": "flowsheet_rotation_id_rotation_id_fk", - "tableFrom": "flowsheet", - "tableTo": "rotation", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "rotation_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.format": { - "name": "format", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "format_name": { - "name": "format_name", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.genre_artist_crossreference": { - "name": "genre_artist_crossreference", - "schema": "wxyc_schema", - "columns": { - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "genre_id": { - "name": "genre_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "artist_genre_code": { - "name": "artist_genre_code", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "artist_genre_key": { - "name": "artist_genre_key", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "genre_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "genre_artist_crossreference_artist_id_artists_id_fk": { - "name": "genre_artist_crossreference_artist_id_artists_id_fk", - "tableFrom": "genre_artist_crossreference", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "genre_artist_crossreference_genre_id_genres_id_fk": { - "name": "genre_artist_crossreference_genre_id_genres_id_fk", - "tableFrom": "genre_artist_crossreference", - "tableTo": "genres", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "genre_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.genres": { - "name": "genres", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "genre_name": { - "name": "genre_name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "plays": { - "name": "plays", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_invitation": { - "name": "auth_invitation", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "inviter_id": { - "name": "inviter_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "auth_invitation_email_idx": { - "name": "auth_invitation_email_idx", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_invitation_organization_id_auth_organization_id_fk": { - "name": "auth_invitation_organization_id_auth_organization_id_fk", - "tableFrom": "auth_invitation", - "tableTo": "auth_organization", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auth_invitation_inviter_id_auth_user_id_fk": { - "name": "auth_invitation_inviter_id_auth_user_id_fk", - "tableFrom": "auth_invitation", - "tableTo": "auth_user", - "columnsFrom": [ - "inviter_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_jwks": { - "name": "auth_jwks", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "public_key": { - "name": "public_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "private_key": { - "name": "private_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.library": { - "name": "library", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "genre_id": { - "name": "genre_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "format_id": { - "name": "format_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "alternate_artist_name": { - "name": "alternate_artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "label": { - "name": "label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "code_number": { - "name": "code_number", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "code_volume_letters": { - "name": "code_volume_letters", - "type": "varchar(4)", - "primaryKey": false, - "notNull": false - }, - "disc_quantity": { - "name": "disc_quantity", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "default": 1 - }, - "plays": { - "name": "plays", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "add_date": { - "name": "add_date", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "title_trgm_idx": { - "name": "title_trgm_idx", - "columns": [ - { - "expression": "\"album_title\" gin_trgm_ops", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "gin", - "with": {} - }, - "genre_id_idx": { - "name": "genre_id_idx", - "columns": [ - { - "expression": "genre_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "format_id_idx": { - "name": "format_id_idx", - "columns": [ - { - "expression": "format_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "artist_id_idx": { - "name": "artist_id_idx", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "library_artist_id_artists_id_fk": { - "name": "library_artist_id_artists_id_fk", - "tableFrom": "library", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "library_genre_id_genres_id_fk": { - "name": "library_genre_id_genres_id_fk", - "tableFrom": "library", - "tableTo": "genres", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "genre_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "library_format_id_format_id_fk": { - "name": "library_format_id_format_id_fk", - "tableFrom": "library", - "tableTo": "format", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "format_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_member": { - "name": "auth_member", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true, - "default": "'member'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "auth_member_org_user_key": { - "name": "auth_member_org_user_key", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_member_organization_id_auth_organization_id_fk": { - "name": "auth_member_organization_id_auth_organization_id_fk", - "tableFrom": "auth_member", - "tableTo": "auth_organization", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auth_member_user_id_auth_user_id_fk": { - "name": "auth_member_user_id_auth_user_id_fk", - "tableFrom": "auth_member", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_organization": { - "name": "auth_organization", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "logo": { - "name": "logo", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "metadata": { - "name": "metadata", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "auth_organization_slug_key": { - "name": "auth_organization_slug_key", - "columns": [ - { - "expression": "slug", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.reviews": { - "name": "reviews", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "review": { - "name": "review", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "author": { - "name": "author", - "type": "varchar(32)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "reviews_album_id_library_id_fk": { - "name": "reviews_album_id_library_id_fk", - "tableFrom": "reviews", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "reviews_album_id_unique": { - "name": "reviews_album_id_unique", - "nullsNotDistinct": false, - "columns": [ - "album_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.rotation": { - "name": "rotation", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "play_freq": { - "name": "play_freq", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "kill_date": { - "name": "kill_date", - "type": "date", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "album_id_idx": { - "name": "album_id_idx", - "columns": [ - { - "expression": "album_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "rotation_album_id_library_id_fk": { - "name": "rotation_album_id_library_id_fk", - "tableFrom": "rotation", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.schedule": { - "name": "schedule", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "day": { - "name": "day", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "start_time": { - "name": "start_time", - "type": "time", - "primaryKey": false, - "notNull": true - }, - "show_duration": { - "name": "show_duration", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "specialty_id": { - "name": "specialty_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "assigned_dj_id": { - "name": "assigned_dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "assigned_dj_id2": { - "name": "assigned_dj_id2", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "schedule_specialty_id_specialty_shows_id_fk": { - "name": "schedule_specialty_id_specialty_shows_id_fk", - "tableFrom": "schedule", - "tableTo": "specialty_shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "specialty_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "schedule_assigned_dj_id_auth_user_id_fk": { - "name": "schedule_assigned_dj_id_auth_user_id_fk", - "tableFrom": "schedule", - "tableTo": "auth_user", - "columnsFrom": [ - "assigned_dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "schedule_assigned_dj_id2_auth_user_id_fk": { - "name": "schedule_assigned_dj_id2_auth_user_id_fk", - "tableFrom": "schedule", - "tableTo": "auth_user", - "columnsFrom": [ - "assigned_dj_id2" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_session": { - "name": "auth_session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "ip_address": { - "name": "ip_address", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_agent": { - "name": "user_agent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "impersonated_by": { - "name": "impersonated_by", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "active_organization_id": { - "name": "active_organization_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "auth_session_token_key": { - "name": "auth_session_token_key", - "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_session_user_id_auth_user_id_fk": { - "name": "auth_session_user_id_auth_user_id_fk", - "tableFrom": "auth_session", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.shift_covers": { - "name": "shift_covers", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "schedule_id": { - "name": "schedule_id", - "type": "serial", - "primaryKey": false, - "notNull": true - }, - "shift_timestamp": { - "name": "shift_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "cover_dj_id": { - "name": "cover_dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "covered": { - "name": "covered", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "shift_covers_schedule_id_schedule_id_fk": { - "name": "shift_covers_schedule_id_schedule_id_fk", - "tableFrom": "shift_covers", - "tableTo": "schedule", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "schedule_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "shift_covers_cover_dj_id_auth_user_id_fk": { - "name": "shift_covers_cover_dj_id_auth_user_id_fk", - "tableFrom": "shift_covers", - "tableTo": "auth_user", - "columnsFrom": [ - "cover_dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.show_djs": { - "name": "show_djs", - "schema": "wxyc_schema", - "columns": { - "show_id": { - "name": "show_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "dj_id": { - "name": "dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "active": { - "name": "active", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - } - }, - "indexes": {}, - "foreignKeys": { - "show_djs_show_id_shows_id_fk": { - "name": "show_djs_show_id_shows_id_fk", - "tableFrom": "show_djs", - "tableTo": "shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "show_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "show_djs_dj_id_auth_user_id_fk": { - "name": "show_djs_dj_id_auth_user_id_fk", - "tableFrom": "show_djs", - "tableTo": "auth_user", - "columnsFrom": [ - "dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.shows": { - "name": "shows", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "primary_dj_id": { - "name": "primary_dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "specialty_id": { - "name": "specialty_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "show_name": { - "name": "show_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "start_time": { - "name": "start_time", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "end_time": { - "name": "end_time", - "type": "timestamp", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "shows_primary_dj_id_auth_user_id_fk": { - "name": "shows_primary_dj_id_auth_user_id_fk", - "tableFrom": "shows", - "tableTo": "auth_user", - "columnsFrom": [ - "primary_dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "shows_specialty_id_specialty_shows_id_fk": { - "name": "shows_specialty_id_specialty_shows_id_fk", - "tableFrom": "shows", - "tableTo": "specialty_shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "specialty_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.specialty_shows": { - "name": "specialty_shows", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "specialty_name": { - "name": "specialty_name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_user": { - "name": "auth_user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email_verified": { - "name": "email_verified", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "role": { - "name": "role", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "banned": { - "name": "banned", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "ban_reason": { - "name": "ban_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ban_expires": { - "name": "ban_expires", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "username": { - "name": "username", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "display_username": { - "name": "display_username", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "real_name": { - "name": "real_name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "dj_name": { - "name": "dj_name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "app_skin": { - "name": "app_skin", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true, - "default": "'modern-light'" - }, - "is_anonymous": { - "name": "is_anonymous", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": { - "auth_user_email_key": { - "name": "auth_user_email_key", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "auth_user_username_key": { - "name": "auth_user_username_key", - "columns": [ - { - "expression": "username", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user_activity": { - "name": "user_activity", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "request_count": { - "name": "request_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "last_seen_at": { - "name": "last_seen_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "user_activity_user_id_auth_user_id_fk": { - "name": "user_activity_user_id_auth_user_id_fk", - "tableFrom": "user_activity", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_verification": { - "name": "auth_verification", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "identifier": { - "name": "identifier", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "wxyc_schema.flowsheet_entry_type": { - "name": "flowsheet_entry_type", - "schema": "wxyc_schema", - "values": [ - "track", - "show_start", - "show_end", - "dj_join", - "dj_leave", - "talkset", - "breakpoint", - "message" - ] - }, - "public.freq_enum": { - "name": "freq_enum", - "schema": "public", - "values": [ - "S", - "L", - "M", - "H" - ] - } - }, - "schemas": { - "wxyc_schema": "wxyc_schema" - }, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": { - "wxyc_schema.library_artist_view": { - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "code_letters": { - "name": "code_letters", - "type": "varchar(4)", - "primaryKey": false, - "notNull": true - }, - "artist_genre_code": { - "name": "artist_genre_code", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "code_number": { - "name": "code_number", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "format_name": { - "name": "format_name", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "genre_name": { - "name": "genre_name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "play_freq": { - "name": "play_freq", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "label": { - "name": "label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - } - }, - "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"genre_artist_crossreference\".\"artist_genre_code\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" inner join \"wxyc_schema\".\"genre_artist_crossreference\" on (\"wxyc_schema\".\"genre_artist_crossreference\".\"artist_id\" = \"wxyc_schema\".\"library\".\"artist_id\" and \"wxyc_schema\".\"genre_artist_crossreference\".\"genre_id\" = \"wxyc_schema\".\"library\".\"genre_id\") left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" > CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", - "name": "library_artist_view", - "schema": "wxyc_schema", - "isExisting": false, - "materialized": false - }, - "wxyc_schema.rotation_library_view": { - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "label": { - "name": "label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "play_freq": { - "name": "play_freq", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "kill_date": { - "name": "kill_date", - "type": "date", - "primaryKey": false, - "notNull": false - } - }, - "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", - "name": "rotation_library_view", - "schema": "wxyc_schema", - "isExisting": false, - "materialized": false - } - }, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/shared/database/src/migrations/meta/0028_snapshot.json b/shared/database/src/migrations/meta/0028_snapshot.json deleted file mode 100644 index d12ac74..0000000 --- a/shared/database/src/migrations/meta/0028_snapshot.json +++ /dev/null @@ -1,2680 +0,0 @@ -{ - "id": "5c36b9a8-cc3d-4608-9b64-43eb41651775", - "prevId": "4ff8acd5-61dc-4941-b1db-d2b67c2ff32e", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.auth_account": { - "name": "auth_account", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "account_id": { - "name": "account_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "provider_id": { - "name": "provider_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "access_token": { - "name": "access_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "refresh_token": { - "name": "refresh_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "id_token": { - "name": "id_token", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "access_token_expires_at": { - "name": "access_token_expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "refresh_token_expires_at": { - "name": "refresh_token_expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "scope": { - "name": "scope", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "password": { - "name": "password", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "auth_account_provider_account_key": { - "name": "auth_account_provider_account_key", - "columns": [ - { - "expression": "provider_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "account_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_account_user_id_auth_user_id_fk": { - "name": "auth_account_user_id_auth_user_id_fk", - "tableFrom": "auth_account", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.album_metadata": { - "name": "album_metadata", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "cache_key": { - "name": "cache_key", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "discogs_release_id": { - "name": "discogs_release_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "discogs_url": { - "name": "discogs_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "release_year": { - "name": "release_year", - "type": "smallint", - "primaryKey": false, - "notNull": false - }, - "artwork_url": { - "name": "artwork_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "spotify_url": { - "name": "spotify_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "apple_music_url": { - "name": "apple_music_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "youtube_music_url": { - "name": "youtube_music_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "bandcamp_url": { - "name": "bandcamp_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "soundcloud_url": { - "name": "soundcloud_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "is_rotation": { - "name": "is_rotation", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "last_accessed": { - "name": "last_accessed", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "album_metadata_album_id_idx": { - "name": "album_metadata_album_id_idx", - "columns": [ - { - "expression": "album_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "album_metadata_cache_key_idx": { - "name": "album_metadata_cache_key_idx", - "columns": [ - { - "expression": "cache_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "album_metadata_last_accessed_idx": { - "name": "album_metadata_last_accessed_idx", - "columns": [ - { - "expression": "last_accessed", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "album_metadata_album_id_library_id_fk": { - "name": "album_metadata_album_id_library_id_fk", - "tableFrom": "album_metadata", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "album_metadata_album_id_unique": { - "name": "album_metadata_album_id_unique", - "nullsNotDistinct": false, - "columns": [ - "album_id" - ] - }, - "album_metadata_cache_key_unique": { - "name": "album_metadata_cache_key_unique", - "nullsNotDistinct": false, - "columns": [ - "cache_key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.anonymous_devices": { - "name": "anonymous_devices", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "device_id": { - "name": "device_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_seen_at": { - "name": "last_seen_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "blocked": { - "name": "blocked", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "blocked_at": { - "name": "blocked_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "blocked_reason": { - "name": "blocked_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "request_count": { - "name": "request_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": { - "anonymous_devices_device_id_key": { - "name": "anonymous_devices_device_id_key", - "columns": [ - { - "expression": "device_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "anonymous_devices_device_id_unique": { - "name": "anonymous_devices_device_id_unique", - "nullsNotDistinct": false, - "columns": [ - "device_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.artist_library_crossreference": { - "name": "artist_library_crossreference", - "schema": "wxyc_schema", - "columns": { - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "library_id": { - "name": "library_id", - "type": "integer", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "library_id_artist_id": { - "name": "library_id_artist_id", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "library_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "artist_library_crossreference_artist_id_artists_id_fk": { - "name": "artist_library_crossreference_artist_id_artists_id_fk", - "tableFrom": "artist_library_crossreference", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "artist_library_crossreference_library_id_library_id_fk": { - "name": "artist_library_crossreference_library_id_library_id_fk", - "tableFrom": "artist_library_crossreference", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "library_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.artist_metadata": { - "name": "artist_metadata", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "cache_key": { - "name": "cache_key", - "type": "varchar(256)", - "primaryKey": false, - "notNull": false - }, - "discogs_artist_id": { - "name": "discogs_artist_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "bio": { - "name": "bio", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "wikipedia_url": { - "name": "wikipedia_url", - "type": "varchar(512)", - "primaryKey": false, - "notNull": false - }, - "last_accessed": { - "name": "last_accessed", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "artist_metadata_artist_id_idx": { - "name": "artist_metadata_artist_id_idx", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "artist_metadata_cache_key_idx": { - "name": "artist_metadata_cache_key_idx", - "columns": [ - { - "expression": "cache_key", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "artist_metadata_last_accessed_idx": { - "name": "artist_metadata_last_accessed_idx", - "columns": [ - { - "expression": "last_accessed", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "artist_metadata_artist_id_artists_id_fk": { - "name": "artist_metadata_artist_id_artists_id_fk", - "tableFrom": "artist_metadata", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "artist_metadata_artist_id_unique": { - "name": "artist_metadata_artist_id_unique", - "nullsNotDistinct": false, - "columns": [ - "artist_id" - ] - }, - "artist_metadata_cache_key_unique": { - "name": "artist_metadata_cache_key_unique", - "nullsNotDistinct": false, - "columns": [ - "cache_key" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.artists": { - "name": "artists", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "alphabetical_name": { - "name": "alphabetical_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "code_letters": { - "name": "code_letters", - "type": "varchar(4)", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "artist_name_trgm_idx": { - "name": "artist_name_trgm_idx", - "columns": [ - { - "expression": "\"artist_name\" gin_trgm_ops", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "gin", - "with": {} - }, - "code_letters_idx": { - "name": "code_letters_idx", - "columns": [ - { - "expression": "code_letters", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.bins": { - "name": "bins", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "dj_id": { - "name": "dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "track_title": { - "name": "track_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "bins_dj_id_auth_user_id_fk": { - "name": "bins_dj_id_auth_user_id_fk", - "tableFrom": "bins", - "tableTo": "auth_user", - "columnsFrom": [ - "dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "bins_album_id_library_id_fk": { - "name": "bins_album_id_library_id_fk", - "tableFrom": "bins", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.cronjob_runs": { - "name": "cronjob_runs", - "schema": "wxyc_schema", - "columns": { - "job_name": { - "name": "job_name", - "type": "varchar(64)", - "primaryKey": true, - "notNull": true - }, - "last_run": { - "name": "last_run", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.dj_stats": { - "name": "dj_stats", - "schema": "wxyc_schema", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "shows_covered": { - "name": "shows_covered", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "default": 0 - } - }, - "indexes": {}, - "foreignKeys": { - "dj_stats_user_id_auth_user_id_fk": { - "name": "dj_stats_user_id_auth_user_id_fk", - "tableFrom": "dj_stats", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.flowsheet": { - "name": "flowsheet", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "show_id": { - "name": "show_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "rotation_id": { - "name": "rotation_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "entry_type": { - "name": "entry_type", - "type": "flowsheet_entry_type", - "typeSchema": "wxyc_schema", - "primaryKey": false, - "notNull": true, - "default": "'track'" - }, - "track_title": { - "name": "track_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "record_label": { - "name": "record_label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "play_order": { - "name": "play_order", - "type": "serial", - "primaryKey": false, - "notNull": true - }, - "request_flag": { - "name": "request_flag", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "message": { - "name": "message", - "type": "varchar(250)", - "primaryKey": false, - "notNull": false - }, - "add_time": { - "name": "add_time", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "flowsheet_show_id_shows_id_fk": { - "name": "flowsheet_show_id_shows_id_fk", - "tableFrom": "flowsheet", - "tableTo": "shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "show_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "flowsheet_album_id_library_id_fk": { - "name": "flowsheet_album_id_library_id_fk", - "tableFrom": "flowsheet", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "flowsheet_rotation_id_rotation_id_fk": { - "name": "flowsheet_rotation_id_rotation_id_fk", - "tableFrom": "flowsheet", - "tableTo": "rotation", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "rotation_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.format": { - "name": "format", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "format_name": { - "name": "format_name", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.genre_artist_crossreference": { - "name": "genre_artist_crossreference", - "schema": "wxyc_schema", - "columns": { - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "genre_id": { - "name": "genre_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "artist_genre_code": { - "name": "artist_genre_code", - "type": "integer", - "primaryKey": false, - "notNull": true - } - }, - "indexes": { - "artist_genre_key": { - "name": "artist_genre_key", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "genre_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "genre_artist_crossreference_artist_id_artists_id_fk": { - "name": "genre_artist_crossreference_artist_id_artists_id_fk", - "tableFrom": "genre_artist_crossreference", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "genre_artist_crossreference_genre_id_genres_id_fk": { - "name": "genre_artist_crossreference_genre_id_genres_id_fk", - "tableFrom": "genre_artist_crossreference", - "tableTo": "genres", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "genre_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.genres": { - "name": "genres", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "genre_name": { - "name": "genre_name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "plays": { - "name": "plays", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_invitation": { - "name": "auth_invitation", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "status": { - "name": "status", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true, - "default": "'pending'" - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "inviter_id": { - "name": "inviter_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "auth_invitation_email_idx": { - "name": "auth_invitation_email_idx", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_invitation_organization_id_auth_organization_id_fk": { - "name": "auth_invitation_organization_id_auth_organization_id_fk", - "tableFrom": "auth_invitation", - "tableTo": "auth_organization", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auth_invitation_inviter_id_auth_user_id_fk": { - "name": "auth_invitation_inviter_id_auth_user_id_fk", - "tableFrom": "auth_invitation", - "tableTo": "auth_user", - "columnsFrom": [ - "inviter_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_jwks": { - "name": "auth_jwks", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "public_key": { - "name": "public_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "private_key": { - "name": "private_key", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.library": { - "name": "library", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "artist_id": { - "name": "artist_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "genre_id": { - "name": "genre_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "format_id": { - "name": "format_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "alternate_artist_name": { - "name": "alternate_artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "label": { - "name": "label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "code_number": { - "name": "code_number", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "code_volume_letters": { - "name": "code_volume_letters", - "type": "varchar(4)", - "primaryKey": false, - "notNull": false - }, - "disc_quantity": { - "name": "disc_quantity", - "type": "smallint", - "primaryKey": false, - "notNull": true, - "default": 1 - }, - "plays": { - "name": "plays", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "add_date": { - "name": "add_date", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "title_trgm_idx": { - "name": "title_trgm_idx", - "columns": [ - { - "expression": "\"album_title\" gin_trgm_ops", - "asc": true, - "isExpression": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "gin", - "with": {} - }, - "genre_id_idx": { - "name": "genre_id_idx", - "columns": [ - { - "expression": "genre_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "format_id_idx": { - "name": "format_id_idx", - "columns": [ - { - "expression": "format_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - }, - "artist_id_idx": { - "name": "artist_id_idx", - "columns": [ - { - "expression": "artist_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "library_artist_id_artists_id_fk": { - "name": "library_artist_id_artists_id_fk", - "tableFrom": "library", - "tableTo": "artists", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "artist_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "library_genre_id_genres_id_fk": { - "name": "library_genre_id_genres_id_fk", - "tableFrom": "library", - "tableTo": "genres", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "genre_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "library_format_id_format_id_fk": { - "name": "library_format_id_format_id_fk", - "tableFrom": "library", - "tableTo": "format", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "format_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_member": { - "name": "auth_member", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "organization_id": { - "name": "organization_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "role": { - "name": "role", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true, - "default": "'member'" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": { - "auth_member_org_user_key": { - "name": "auth_member_org_user_key", - "columns": [ - { - "expression": "organization_id", - "isExpression": false, - "asc": true, - "nulls": "last" - }, - { - "expression": "user_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_member_organization_id_auth_organization_id_fk": { - "name": "auth_member_organization_id_auth_organization_id_fk", - "tableFrom": "auth_member", - "tableTo": "auth_organization", - "columnsFrom": [ - "organization_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - }, - "auth_member_user_id_auth_user_id_fk": { - "name": "auth_member_user_id_auth_user_id_fk", - "tableFrom": "auth_member", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_organization": { - "name": "auth_organization", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "slug": { - "name": "slug", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "logo": { - "name": "logo", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "metadata": { - "name": "metadata", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "auth_organization_slug_key": { - "name": "auth_organization_slug_key", - "columns": [ - { - "expression": "slug", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.reviews": { - "name": "reviews", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "review": { - "name": "review", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "author": { - "name": "author", - "type": "varchar(32)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "reviews_album_id_library_id_fk": { - "name": "reviews_album_id_library_id_fk", - "tableFrom": "reviews", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "reviews_album_id_unique": { - "name": "reviews_album_id_unique", - "nullsNotDistinct": false, - "columns": [ - "album_id" - ] - } - }, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.rotation": { - "name": "rotation", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "album_id": { - "name": "album_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "play_freq": { - "name": "play_freq", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "kill_date": { - "name": "kill_date", - "type": "date", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "album_id_idx": { - "name": "album_id_idx", - "columns": [ - { - "expression": "album_id", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": false, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "rotation_album_id_library_id_fk": { - "name": "rotation_album_id_library_id_fk", - "tableFrom": "rotation", - "tableTo": "library", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "album_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.schedule": { - "name": "schedule", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "day": { - "name": "day", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "start_time": { - "name": "start_time", - "type": "time", - "primaryKey": false, - "notNull": true - }, - "show_duration": { - "name": "show_duration", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "specialty_id": { - "name": "specialty_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "assigned_dj_id": { - "name": "assigned_dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "assigned_dj_id2": { - "name": "assigned_dj_id2", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "schedule_specialty_id_specialty_shows_id_fk": { - "name": "schedule_specialty_id_specialty_shows_id_fk", - "tableFrom": "schedule", - "tableTo": "specialty_shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "specialty_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "schedule_assigned_dj_id_auth_user_id_fk": { - "name": "schedule_assigned_dj_id_auth_user_id_fk", - "tableFrom": "schedule", - "tableTo": "auth_user", - "columnsFrom": [ - "assigned_dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "schedule_assigned_dj_id2_auth_user_id_fk": { - "name": "schedule_assigned_dj_id2_auth_user_id_fk", - "tableFrom": "schedule", - "tableTo": "auth_user", - "columnsFrom": [ - "assigned_dj_id2" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_session": { - "name": "auth_session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "token": { - "name": "token", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "ip_address": { - "name": "ip_address", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "user_agent": { - "name": "user_agent", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "impersonated_by": { - "name": "impersonated_by", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "active_organization_id": { - "name": "active_organization_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - } - }, - "indexes": { - "auth_session_token_key": { - "name": "auth_session_token_key", - "columns": [ - { - "expression": "token", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": { - "auth_session_user_id_auth_user_id_fk": { - "name": "auth_session_user_id_auth_user_id_fk", - "tableFrom": "auth_session", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.shift_covers": { - "name": "shift_covers", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "schedule_id": { - "name": "schedule_id", - "type": "serial", - "primaryKey": false, - "notNull": true - }, - "shift_timestamp": { - "name": "shift_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true - }, - "cover_dj_id": { - "name": "cover_dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "covered": { - "name": "covered", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": { - "shift_covers_schedule_id_schedule_id_fk": { - "name": "shift_covers_schedule_id_schedule_id_fk", - "tableFrom": "shift_covers", - "tableTo": "schedule", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "schedule_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "shift_covers_cover_dj_id_auth_user_id_fk": { - "name": "shift_covers_cover_dj_id_auth_user_id_fk", - "tableFrom": "shift_covers", - "tableTo": "auth_user", - "columnsFrom": [ - "cover_dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.show_djs": { - "name": "show_djs", - "schema": "wxyc_schema", - "columns": { - "show_id": { - "name": "show_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "dj_id": { - "name": "dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "active": { - "name": "active", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": true - } - }, - "indexes": {}, - "foreignKeys": { - "show_djs_show_id_shows_id_fk": { - "name": "show_djs_show_id_shows_id_fk", - "tableFrom": "show_djs", - "tableTo": "shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "show_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "show_djs_dj_id_auth_user_id_fk": { - "name": "show_djs_dj_id_auth_user_id_fk", - "tableFrom": "show_djs", - "tableTo": "auth_user", - "columnsFrom": [ - "dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.shows": { - "name": "shows", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "primary_dj_id": { - "name": "primary_dj_id", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "specialty_id": { - "name": "specialty_id", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "show_name": { - "name": "show_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "start_time": { - "name": "start_time", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "end_time": { - "name": "end_time", - "type": "timestamp", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "shows_primary_dj_id_auth_user_id_fk": { - "name": "shows_primary_dj_id_auth_user_id_fk", - "tableFrom": "shows", - "tableTo": "auth_user", - "columnsFrom": [ - "primary_dj_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "shows_specialty_id_specialty_shows_id_fk": { - "name": "shows_specialty_id_specialty_shows_id_fk", - "tableFrom": "shows", - "tableTo": "specialty_shows", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "specialty_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "wxyc_schema.specialty_shows": { - "name": "specialty_shows", - "schema": "wxyc_schema", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "specialty_name": { - "name": "specialty_name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "description": { - "name": "description", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "add_date": { - "name": "add_date", - "type": "date", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "last_modified": { - "name": "last_modified", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_user": { - "name": "auth_user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email": { - "name": "email", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "email_verified": { - "name": "email_verified", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - }, - "image": { - "name": "image", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "role": { - "name": "role", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "banned": { - "name": "banned", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "ban_reason": { - "name": "ban_reason", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "ban_expires": { - "name": "ban_expires", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": false - }, - "username": { - "name": "username", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "display_username": { - "name": "display_username", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "real_name": { - "name": "real_name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "dj_name": { - "name": "dj_name", - "type": "varchar(255)", - "primaryKey": false, - "notNull": false - }, - "app_skin": { - "name": "app_skin", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true, - "default": "'modern-light'" - }, - "is_anonymous": { - "name": "is_anonymous", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": { - "auth_user_email_key": { - "name": "auth_user_email_key", - "columns": [ - { - "expression": "email", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - }, - "auth_user_username_key": { - "name": "auth_user_username_key", - "columns": [ - { - "expression": "username", - "isExpression": false, - "asc": true, - "nulls": "last" - } - ], - "isUnique": true, - "concurrently": false, - "method": "btree", - "with": {} - } - }, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.user_activity": { - "name": "user_activity", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "request_count": { - "name": "request_count", - "type": "integer", - "primaryKey": false, - "notNull": true, - "default": 0 - }, - "last_seen_at": { - "name": "last_seen_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "user_activity_user_id_auth_user_id_fk": { - "name": "user_activity_user_id_auth_user_id_fk", - "tableFrom": "user_activity", - "tableTo": "auth_user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - }, - "public.auth_verification": { - "name": "auth_verification", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "varchar(255)", - "primaryKey": true, - "notNull": true - }, - "identifier": { - "name": "identifier", - "type": "varchar(255)", - "primaryKey": false, - "notNull": true - }, - "value": { - "name": "value", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "expires_at": { - "name": "expires_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true - }, - "created_at": { - "name": "created_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "updated_at": { - "name": "updated_at", - "type": "timestamp with time zone", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {}, - "policies": {}, - "checkConstraints": {}, - "isRLSEnabled": false - } - }, - "enums": { - "wxyc_schema.flowsheet_entry_type": { - "name": "flowsheet_entry_type", - "schema": "wxyc_schema", - "values": [ - "track", - "show_start", - "show_end", - "dj_join", - "dj_leave", - "talkset", - "breakpoint", - "message" - ] - }, - "public.freq_enum": { - "name": "freq_enum", - "schema": "public", - "values": [ - "S", - "L", - "M", - "H" - ] - } - }, - "schemas": { - "wxyc_schema": "wxyc_schema" - }, - "sequences": {}, - "roles": {}, - "policies": {}, - "views": { - "wxyc_schema.library_artist_view": { - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "code_letters": { - "name": "code_letters", - "type": "varchar(4)", - "primaryKey": false, - "notNull": true - }, - "artist_genre_code": { - "name": "artist_genre_code", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "code_number": { - "name": "code_number", - "type": "smallint", - "primaryKey": false, - "notNull": true - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "alphabetical_name": { - "name": "alphabetical_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "format_name": { - "name": "format_name", - "type": "varchar", - "primaryKey": false, - "notNull": true - }, - "genre_name": { - "name": "genre_name", - "type": "varchar(64)", - "primaryKey": false, - "notNull": true - }, - "play_freq": { - "name": "play_freq", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "add_date": { - "name": "add_date", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "label": { - "name": "label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - } - }, - "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"genre_artist_crossreference\".\"artist_genre_code\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"artists\".\"alphabetical_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" inner join \"wxyc_schema\".\"genre_artist_crossreference\" on (\"wxyc_schema\".\"genre_artist_crossreference\".\"artist_id\" = \"wxyc_schema\".\"library\".\"artist_id\" and \"wxyc_schema\".\"genre_artist_crossreference\".\"genre_id\" = \"wxyc_schema\".\"library\".\"genre_id\") left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" > CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", - "name": "library_artist_view", - "schema": "wxyc_schema", - "isExisting": false, - "materialized": false - }, - "wxyc_schema.rotation_library_view": { - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "label": { - "name": "label", - "type": "varchar(128)", - "primaryKey": false, - "notNull": false - }, - "play_freq": { - "name": "play_freq", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true - }, - "album_title": { - "name": "album_title", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "artist_name": { - "name": "artist_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "alphabetical_name": { - "name": "alphabetical_name", - "type": "varchar(128)", - "primaryKey": false, - "notNull": true - }, - "kill_date": { - "name": "kill_date", - "type": "date", - "primaryKey": false, - "notNull": false - } - }, - "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"play_freq\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"artists\".\"alphabetical_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", - "name": "rotation_library_view", - "schema": "wxyc_schema", - "isExisting": false, - "materialized": false - } - }, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file diff --git a/shared/database/src/migrations/meta/_journal.json b/shared/database/src/migrations/meta/_journal.json index f404fe0..8683aab 100644 --- a/shared/database/src/migrations/meta/_journal.json +++ b/shared/database/src/migrations/meta/_journal.json @@ -162,27 +162,6 @@ "when": 1768890229444, "tag": "0025_rate_limiting_tables", "breakpoints": true - }, - { - "idx": 26, - "version": "7", - "when": 1770938861646, - "tag": "0026_cron_job_tracking", - "breakpoints": true - }, - { - "idx": 27, - "version": "7", - "when": 1770992362056, - "tag": "0027_drop_genre_from_artist_table", - "breakpoints": true - }, - { - "idx": 28, - "version": "7", - "when": 1772287838030, - "tag": "0028_add_artists_alphabetical_name", - "breakpoints": true } ] } \ No newline at end of file From 2a889d9efc0cb6bea201ddd5a45e929528c94c01 Mon Sep 17 00:00:00 2001 From: Adrian Bruno Date: Sat, 28 Feb 2026 15:28:11 -0500 Subject: [PATCH 17/17] address db migration issues --- ...0026_rename_play_freq_to_rotation_bin.sql} | 0 .../src/migrations/0027_cron_job_tracking.sql | 34 + .../0028_drop_genre_from_artist_table.sql | 13 + .../0029_add_artists_alphabetical_name.sql | 13 + .../src/migrations/meta/0026_snapshot.json | 2635 ++++++++++++++++ .../src/migrations/meta/0027_snapshot.json | 2667 +++++++++++++++++ .../src/migrations/meta/0028_snapshot.json | 2662 ++++++++++++++++ .../src/migrations/meta/0029_snapshot.json | 159 +- .../src/migrations/meta/_journal.json | 23 +- 9 files changed, 8148 insertions(+), 58 deletions(-) rename shared/database/src/migrations/{0029_rename_play_freq_to_rotation_bin.sql => 0026_rename_play_freq_to_rotation_bin.sql} (100%) create mode 100644 shared/database/src/migrations/0027_cron_job_tracking.sql create mode 100644 shared/database/src/migrations/0028_drop_genre_from_artist_table.sql create mode 100644 shared/database/src/migrations/0029_add_artists_alphabetical_name.sql create mode 100644 shared/database/src/migrations/meta/0026_snapshot.json create mode 100644 shared/database/src/migrations/meta/0027_snapshot.json create mode 100644 shared/database/src/migrations/meta/0028_snapshot.json diff --git a/shared/database/src/migrations/0029_rename_play_freq_to_rotation_bin.sql b/shared/database/src/migrations/0026_rename_play_freq_to_rotation_bin.sql similarity index 100% rename from shared/database/src/migrations/0029_rename_play_freq_to_rotation_bin.sql rename to shared/database/src/migrations/0026_rename_play_freq_to_rotation_bin.sql diff --git a/shared/database/src/migrations/0027_cron_job_tracking.sql b/shared/database/src/migrations/0027_cron_job_tracking.sql new file mode 100644 index 0000000..66af31d --- /dev/null +++ b/shared/database/src/migrations/0027_cron_job_tracking.sql @@ -0,0 +1,34 @@ +CREATE TABLE IF NOT EXISTS "wxyc_schema"."cronjob_runs" ( + "job_name" varchar(64) PRIMARY KEY NOT NULL, + "last_run" timestamp with time zone DEFAULT now() NOT NULL +); +--> statement-breakpoint + +DROP VIEW IF EXISTS "wxyc_schema"."library_artist_view"; +--> statement-breakpoint + +ALTER TABLE "wxyc_schema"."artists" ALTER COLUMN "code_letters" SET DATA TYPE varchar(4); +--> statement-breakpoint + +ALTER TABLE "wxyc_schema"."library" ADD COLUMN IF NOT EXISTS "code_volume_letters" varchar(4); +--> statement-breakpoint + +CREATE VIEW "wxyc_schema"."library_artist_view" AS +SELECT "wxyc_schema"."library"."id", + "wxyc_schema"."artists"."code_letters", + "wxyc_schema"."artists"."code_artist_number", + "wxyc_schema"."library"."code_number", + "wxyc_schema"."artists"."artist_name", + "wxyc_schema"."library"."album_title", + "wxyc_schema"."format"."format_name", + "wxyc_schema"."genres"."genre_name", + "wxyc_schema"."rotation"."rotation_bin", + "wxyc_schema"."library"."add_date", + "wxyc_schema"."library"."label" +FROM "wxyc_schema"."library" + INNER JOIN "wxyc_schema"."artists" ON "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id" + INNER JOIN "wxyc_schema"."genres" ON "wxyc_schema"."genres"."id" = "wxyc_schema"."library"."genre_id" + INNER JOIN "wxyc_schema"."format" ON "wxyc_schema"."format"."id" = "wxyc_schema"."library"."format_id" + LEFT JOIN "wxyc_schema"."rotation" + ON "wxyc_schema"."rotation"."album_id" = "wxyc_schema"."library"."id" + AND ("wxyc_schema"."rotation"."kill_date" > CURRENT_DATE OR "wxyc_schema"."rotation"."kill_date" IS NULL); diff --git a/shared/database/src/migrations/0028_drop_genre_from_artist_table.sql b/shared/database/src/migrations/0028_drop_genre_from_artist_table.sql new file mode 100644 index 0000000..9319da7 --- /dev/null +++ b/shared/database/src/migrations/0028_drop_genre_from_artist_table.sql @@ -0,0 +1,13 @@ +DROP VIEW "wxyc_schema"."library_artist_view"; +--> statement-breakpoint + +ALTER TABLE "wxyc_schema"."artists" DROP CONSTRAINT "artists_genre_id_genres_id_fk"; +--> statement-breakpoint + +ALTER TABLE "wxyc_schema"."artists" DROP COLUMN "genre_id"; +--> statement-breakpoint + +ALTER TABLE "wxyc_schema"."artists" DROP COLUMN "code_artist_number"; +--> statement-breakpoint + +CREATE VIEW "wxyc_schema"."library_artist_view" AS (select "wxyc_schema"."library"."id", "wxyc_schema"."artists"."code_letters", "wxyc_schema"."genre_artist_crossreference"."artist_genre_code", "wxyc_schema"."library"."code_number", "wxyc_schema"."artists"."artist_name", "wxyc_schema"."library"."album_title", "wxyc_schema"."format"."format_name", "wxyc_schema"."genres"."genre_name", "wxyc_schema"."rotation"."rotation_bin", "wxyc_schema"."library"."add_date", "wxyc_schema"."library"."label" from "wxyc_schema"."library" inner join "wxyc_schema"."artists" on "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id" inner join "wxyc_schema"."format" on "wxyc_schema"."format"."id" = "wxyc_schema"."library"."format_id" inner join "wxyc_schema"."genres" on "wxyc_schema"."genres"."id" = "wxyc_schema"."library"."genre_id" inner join "wxyc_schema"."genre_artist_crossreference" on ("wxyc_schema"."genre_artist_crossreference"."artist_id" = "wxyc_schema"."library"."artist_id" and "wxyc_schema"."genre_artist_crossreference"."genre_id" = "wxyc_schema"."library"."genre_id") left join "wxyc_schema"."rotation" on "wxyc_schema"."rotation"."album_id" = "wxyc_schema"."library"."id" AND ("wxyc_schema"."rotation"."kill_date" > CURRENT_DATE OR "wxyc_schema"."rotation"."kill_date" IS NULL)); diff --git a/shared/database/src/migrations/0029_add_artists_alphabetical_name.sql b/shared/database/src/migrations/0029_add_artists_alphabetical_name.sql new file mode 100644 index 0000000..faac8cd --- /dev/null +++ b/shared/database/src/migrations/0029_add_artists_alphabetical_name.sql @@ -0,0 +1,13 @@ +DROP VIEW IF EXISTS "wxyc_schema"."library_artist_view"; +--> statement-breakpoint + +DROP VIEW IF EXISTS "wxyc_schema"."rotation_library_view"; +--> statement-breakpoint + +ALTER TABLE "wxyc_schema"."artists" ADD COLUMN "alphabetical_name" varchar(128) NOT NULL; +--> statement-breakpoint + +CREATE VIEW "wxyc_schema"."library_artist_view" AS (select "wxyc_schema"."library"."id", "wxyc_schema"."artists"."code_letters", "wxyc_schema"."genre_artist_crossreference"."artist_genre_code", "wxyc_schema"."library"."code_number", "wxyc_schema"."artists"."artist_name", "wxyc_schema"."artists"."alphabetical_name", "wxyc_schema"."library"."album_title", "wxyc_schema"."format"."format_name", "wxyc_schema"."genres"."genre_name", "wxyc_schema"."rotation"."rotation_bin", "wxyc_schema"."library"."add_date", "wxyc_schema"."library"."label" from "wxyc_schema"."library" inner join "wxyc_schema"."artists" on "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id" inner join "wxyc_schema"."format" on "wxyc_schema"."format"."id" = "wxyc_schema"."library"."format_id" inner join "wxyc_schema"."genres" on "wxyc_schema"."genres"."id" = "wxyc_schema"."library"."genre_id" inner join "wxyc_schema"."genre_artist_crossreference" on ("wxyc_schema"."genre_artist_crossreference"."artist_id" = "wxyc_schema"."library"."artist_id" and "wxyc_schema"."genre_artist_crossreference"."genre_id" = "wxyc_schema"."library"."genre_id") left join "wxyc_schema"."rotation" on "wxyc_schema"."rotation"."album_id" = "wxyc_schema"."library"."id" AND ("wxyc_schema"."rotation"."kill_date" > CURRENT_DATE OR "wxyc_schema"."rotation"."kill_date" IS NULL)); +--> statement-breakpoint + +CREATE VIEW "wxyc_schema"."rotation_library_view" AS (select "wxyc_schema"."library"."id" AS "library_id", "wxyc_schema"."rotation"."id" AS "rotation_id", "wxyc_schema"."library"."label", "wxyc_schema"."rotation"."rotation_bin", "wxyc_schema"."library"."album_title", "wxyc_schema"."artists"."artist_name", "wxyc_schema"."artists"."alphabetical_name", "wxyc_schema"."rotation"."kill_date" from "wxyc_schema"."library" inner join "wxyc_schema"."rotation" on "wxyc_schema"."library"."id" = "wxyc_schema"."rotation"."album_id" inner join "wxyc_schema"."artists" on "wxyc_schema"."artists"."id" = "wxyc_schema"."library"."artist_id"); diff --git a/shared/database/src/migrations/meta/0026_snapshot.json b/shared/database/src/migrations/meta/0026_snapshot.json new file mode 100644 index 0000000..0426bcf --- /dev/null +++ b/shared/database/src/migrations/meta/0026_snapshot.json @@ -0,0 +1,2635 @@ +{ + "id": "df397568-f27d-4a06-9aba-08264d97ae8e", + "prevId": "335ff99b-a9d0-49ec-a275-2bf4e9b2edf7", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_account_provider_account_key": { + "name": "auth_account_provider_account_key", + "columns": [ + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.album_metadata": { + "name": "album_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "discogs_release_id": { + "name": "discogs_release_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "discogs_url": { + "name": "discogs_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "release_year": { + "name": "release_year", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "artwork_url": { + "name": "artwork_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "spotify_url": { + "name": "spotify_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "apple_music_url": { + "name": "apple_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "youtube_music_url": { + "name": "youtube_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "bandcamp_url": { + "name": "bandcamp_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "soundcloud_url": { + "name": "soundcloud_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "is_rotation": { + "name": "is_rotation", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "album_metadata_album_id_idx": { + "name": "album_metadata_album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_cache_key_idx": { + "name": "album_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_last_accessed_idx": { + "name": "album_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "album_metadata_album_id_library_id_fk": { + "name": "album_metadata_album_id_library_id_fk", + "tableFrom": "album_metadata", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "album_metadata_album_id_unique": { + "name": "album_metadata_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + }, + "album_metadata_cache_key_unique": { + "name": "album_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.anonymous_devices": { + "name": "anonymous_devices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "device_id": { + "name": "device_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "blocked": { + "name": "blocked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "blocked_at": { + "name": "blocked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "anonymous_devices_device_id_key": { + "name": "anonymous_devices_device_id_key", + "columns": [ + { + "expression": "device_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "anonymous_devices_device_id_unique": { + "name": "anonymous_devices_device_id_unique", + "nullsNotDistinct": false, + "columns": [ + "device_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_library_crossreference": { + "name": "artist_library_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "library_id": { + "name": "library_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "library_id_artist_id": { + "name": "library_id_artist_id", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "library_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_library_crossreference_artist_id_artists_id_fk": { + "name": "artist_library_crossreference_artist_id_artists_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "artist_library_crossreference_library_id_library_id_fk": { + "name": "artist_library_crossreference_library_id_library_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_metadata": { + "name": "artist_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "discogs_artist_id": { + "name": "discogs_artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "wikipedia_url": { + "name": "wikipedia_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_metadata_artist_id_idx": { + "name": "artist_metadata_artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_cache_key_idx": { + "name": "artist_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_last_accessed_idx": { + "name": "artist_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_metadata_artist_id_artists_id_fk": { + "name": "artist_metadata_artist_id_artists_id_fk", + "tableFrom": "artist_metadata", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "artist_metadata_artist_id_unique": { + "name": "artist_metadata_artist_id_unique", + "nullsNotDistinct": false, + "columns": [ + "artist_id" + ] + }, + "artist_metadata_cache_key_unique": { + "name": "artist_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artists": { + "name": "artists", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(2)", + "primaryKey": false, + "notNull": true + }, + "code_artist_number": { + "name": "code_artist_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_name_trgm_idx": { + "name": "artist_name_trgm_idx", + "columns": [ + { + "expression": "\"artist_name\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "code_letters_idx": { + "name": "code_letters_idx", + "columns": [ + { + "expression": "code_letters", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artists_genre_id_genres_id_fk": { + "name": "artists_genre_id_genres_id_fk", + "tableFrom": "artists", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.bins": { + "name": "bins", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "bins_dj_id_auth_user_id_fk": { + "name": "bins_dj_id_auth_user_id_fk", + "tableFrom": "bins", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bins_album_id_library_id_fk": { + "name": "bins_album_id_library_id_fk", + "tableFrom": "bins", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.dj_stats": { + "name": "dj_stats", + "schema": "wxyc_schema", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "shows_covered": { + "name": "shows_covered", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "dj_stats_user_id_auth_user_id_fk": { + "name": "dj_stats_user_id_auth_user_id_fk", + "tableFrom": "dj_stats", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.flowsheet": { + "name": "flowsheet", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rotation_id": { + "name": "rotation_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "record_label": { + "name": "record_label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "play_order": { + "name": "play_order", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "request_flag": { + "name": "request_flag", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "message": { + "name": "message", + "type": "varchar(250)", + "primaryKey": false, + "notNull": false + }, + "add_time": { + "name": "add_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "flowsheet_show_id_shows_id_fk": { + "name": "flowsheet_show_id_shows_id_fk", + "tableFrom": "flowsheet", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_album_id_library_id_fk": { + "name": "flowsheet_album_id_library_id_fk", + "tableFrom": "flowsheet", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_rotation_id_rotation_id_fk": { + "name": "flowsheet_rotation_id_rotation_id_fk", + "tableFrom": "flowsheet", + "tableTo": "rotation", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "rotation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.format": { + "name": "format", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genre_artist_crossreference": { + "name": "genre_artist_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "artist_genre_key": { + "name": "artist_genre_key", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "genre_artist_crossreference_artist_id_artists_id_fk": { + "name": "genre_artist_crossreference_artist_id_artists_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "genre_artist_crossreference_genre_id_genres_id_fk": { + "name": "genre_artist_crossreference_genre_id_genres_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genres": { + "name": "genres", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_invitation": { + "name": "auth_invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "inviter_id": { + "name": "inviter_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_invitation_email_idx": { + "name": "auth_invitation_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_invitation_organization_id_auth_organization_id_fk": { + "name": "auth_invitation_organization_id_auth_organization_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_invitation_inviter_id_auth_user_id_fk": { + "name": "auth_invitation_inviter_id_auth_user_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_jwks": { + "name": "auth_jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.library": { + "name": "library", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "format_id": { + "name": "format_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "alternate_artist_name": { + "name": "alternate_artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "disc_quantity": { + "name": "disc_quantity", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "title_trgm_idx": { + "name": "title_trgm_idx", + "columns": [ + { + "expression": "\"album_title\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "genre_id_idx": { + "name": "genre_id_idx", + "columns": [ + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "format_id_idx": { + "name": "format_id_idx", + "columns": [ + { + "expression": "format_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_id_idx": { + "name": "artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "library_artist_id_artists_id_fk": { + "name": "library_artist_id_artists_id_fk", + "tableFrom": "library", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_genre_id_genres_id_fk": { + "name": "library_genre_id_genres_id_fk", + "tableFrom": "library", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_format_id_format_id_fk": { + "name": "library_format_id_format_id_fk", + "tableFrom": "library", + "tableTo": "format", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "format_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_member": { + "name": "auth_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_member_org_user_key": { + "name": "auth_member_org_user_key", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_member_organization_id_auth_organization_id_fk": { + "name": "auth_member_organization_id_auth_organization_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_member_user_id_auth_user_id_fk": { + "name": "auth_member_user_id_auth_user_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_organization": { + "name": "auth_organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_organization_slug_key": { + "name": "auth_organization_slug_key", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.reviews": { + "name": "reviews", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "review": { + "name": "review", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "author": { + "name": "author", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "reviews_album_id_library_id_fk": { + "name": "reviews_album_id_library_id_fk", + "tableFrom": "reviews", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reviews_album_id_unique": { + "name": "reviews_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.rotation": { + "name": "rotation", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "album_id_idx": { + "name": "album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "rotation_album_id_library_id_fk": { + "name": "rotation_album_id_library_id_fk", + "tableFrom": "rotation", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.schedule": { + "name": "schedule", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "day": { + "name": "day", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "start_time": { + "name": "start_time", + "type": "time", + "primaryKey": false, + "notNull": true + }, + "show_duration": { + "name": "show_duration", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id": { + "name": "assigned_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id2": { + "name": "assigned_dj_id2", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "schedule_specialty_id_specialty_shows_id_fk": { + "name": "schedule_specialty_id_specialty_shows_id_fk", + "tableFrom": "schedule", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id_auth_user_id_fk": { + "name": "schedule_assigned_dj_id_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id2_auth_user_id_fk": { + "name": "schedule_assigned_dj_id2_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id2" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_session_token_key": { + "name": "auth_session_token_key", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shift_covers": { + "name": "shift_covers", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "schedule_id": { + "name": "schedule_id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "shift_timestamp": { + "name": "shift_timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "cover_dj_id": { + "name": "cover_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "covered": { + "name": "covered", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "shift_covers_schedule_id_schedule_id_fk": { + "name": "shift_covers_schedule_id_schedule_id_fk", + "tableFrom": "shift_covers", + "tableTo": "schedule", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "schedule_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shift_covers_cover_dj_id_auth_user_id_fk": { + "name": "shift_covers_cover_dj_id_auth_user_id_fk", + "tableFrom": "shift_covers", + "tableTo": "auth_user", + "columnsFrom": [ + "cover_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.show_djs": { + "name": "show_djs", + "schema": "wxyc_schema", + "columns": { + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + } + }, + "indexes": {}, + "foreignKeys": { + "show_djs_show_id_shows_id_fk": { + "name": "show_djs_show_id_shows_id_fk", + "tableFrom": "show_djs", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "show_djs_dj_id_auth_user_id_fk": { + "name": "show_djs_dj_id_auth_user_id_fk", + "tableFrom": "show_djs", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shows": { + "name": "shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "primary_dj_id": { + "name": "primary_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "show_name": { + "name": "show_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "start_time": { + "name": "start_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "end_time": { + "name": "end_time", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "shows_primary_dj_id_auth_user_id_fk": { + "name": "shows_primary_dj_id_auth_user_id_fk", + "tableFrom": "shows", + "tableTo": "auth_user", + "columnsFrom": [ + "primary_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shows_specialty_id_specialty_shows_id_fk": { + "name": "shows_specialty_id_specialty_shows_id_fk", + "tableFrom": "shows", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.specialty_shows": { + "name": "specialty_shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "specialty_name": { + "name": "specialty_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "real_name": { + "name": "real_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dj_name": { + "name": "dj_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "app_skin": { + "name": "app_skin", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'modern-light'" + }, + "is_anonymous": { + "name": "is_anonymous", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "auth_user_email_key": { + "name": "auth_user_email_key", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auth_user_username_key": { + "name": "auth_user_username_key", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_activity": { + "name": "user_activity", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_activity_user_id_auth_user_id_fk": { + "name": "user_activity_user_id_auth_user_id_fk", + "tableFrom": "user_activity", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_verification": { + "name": "auth_verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.freq_enum": { + "name": "freq_enum", + "schema": "public", + "values": [ + "S", + "L", + "M", + "H" + ] + } + }, + "schemas": { + "wxyc_schema": "wxyc_schema" + }, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": { + "wxyc_schema.library_artist_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(2)", + "primaryKey": false, + "notNull": true + }, + "code_artist_number": { + "name": "code_artist_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"artists\".\"code_artist_number\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" < CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", + "name": "library_artist_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + }, + "wxyc_schema.rotation_library_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", + "name": "rotation_library_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + } + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/shared/database/src/migrations/meta/0027_snapshot.json b/shared/database/src/migrations/meta/0027_snapshot.json new file mode 100644 index 0000000..cbd4c37 --- /dev/null +++ b/shared/database/src/migrations/meta/0027_snapshot.json @@ -0,0 +1,2667 @@ +{ + "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", + "prevId": "df397568-f27d-4a06-9aba-08264d97ae8e", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_account_provider_account_key": { + "name": "auth_account_provider_account_key", + "columns": [ + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.album_metadata": { + "name": "album_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "discogs_release_id": { + "name": "discogs_release_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "discogs_url": { + "name": "discogs_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "release_year": { + "name": "release_year", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "artwork_url": { + "name": "artwork_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "spotify_url": { + "name": "spotify_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "apple_music_url": { + "name": "apple_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "youtube_music_url": { + "name": "youtube_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "bandcamp_url": { + "name": "bandcamp_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "soundcloud_url": { + "name": "soundcloud_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "is_rotation": { + "name": "is_rotation", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "album_metadata_album_id_idx": { + "name": "album_metadata_album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_cache_key_idx": { + "name": "album_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_last_accessed_idx": { + "name": "album_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "album_metadata_album_id_library_id_fk": { + "name": "album_metadata_album_id_library_id_fk", + "tableFrom": "album_metadata", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "album_metadata_album_id_unique": { + "name": "album_metadata_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + }, + "album_metadata_cache_key_unique": { + "name": "album_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.anonymous_devices": { + "name": "anonymous_devices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "device_id": { + "name": "device_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "blocked": { + "name": "blocked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "blocked_at": { + "name": "blocked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "anonymous_devices_device_id_key": { + "name": "anonymous_devices_device_id_key", + "columns": [ + { + "expression": "device_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "anonymous_devices_device_id_unique": { + "name": "anonymous_devices_device_id_unique", + "nullsNotDistinct": false, + "columns": [ + "device_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_library_crossreference": { + "name": "artist_library_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "library_id": { + "name": "library_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "library_id_artist_id": { + "name": "library_id_artist_id", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "library_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_library_crossreference_artist_id_artists_id_fk": { + "name": "artist_library_crossreference_artist_id_artists_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "artist_library_crossreference_library_id_library_id_fk": { + "name": "artist_library_crossreference_library_id_library_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_metadata": { + "name": "artist_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "discogs_artist_id": { + "name": "discogs_artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "wikipedia_url": { + "name": "wikipedia_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_metadata_artist_id_idx": { + "name": "artist_metadata_artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_cache_key_idx": { + "name": "artist_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_last_accessed_idx": { + "name": "artist_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_metadata_artist_id_artists_id_fk": { + "name": "artist_metadata_artist_id_artists_id_fk", + "tableFrom": "artist_metadata", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "artist_metadata_artist_id_unique": { + "name": "artist_metadata_artist_id_unique", + "nullsNotDistinct": false, + "columns": [ + "artist_id" + ] + }, + "artist_metadata_cache_key_unique": { + "name": "artist_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artists": { + "name": "artists", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true + }, + "code_artist_number": { + "name": "code_artist_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_name_trgm_idx": { + "name": "artist_name_trgm_idx", + "columns": [ + { + "expression": "\"artist_name\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "code_letters_idx": { + "name": "code_letters_idx", + "columns": [ + { + "expression": "code_letters", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artists_genre_id_genres_id_fk": { + "name": "artists_genre_id_genres_id_fk", + "tableFrom": "artists", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.cronjob_runs": { + "name": "cronjob_runs", + "schema": "wxyc_schema", + "columns": { + "job_name": { + "name": "job_name", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "last_run": { + "name": "last_run", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.bins": { + "name": "bins", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "bins_dj_id_auth_user_id_fk": { + "name": "bins_dj_id_auth_user_id_fk", + "tableFrom": "bins", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bins_album_id_library_id_fk": { + "name": "bins_album_id_library_id_fk", + "tableFrom": "bins", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.dj_stats": { + "name": "dj_stats", + "schema": "wxyc_schema", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "shows_covered": { + "name": "shows_covered", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "dj_stats_user_id_auth_user_id_fk": { + "name": "dj_stats_user_id_auth_user_id_fk", + "tableFrom": "dj_stats", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.flowsheet": { + "name": "flowsheet", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rotation_id": { + "name": "rotation_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "record_label": { + "name": "record_label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "play_order": { + "name": "play_order", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "request_flag": { + "name": "request_flag", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "message": { + "name": "message", + "type": "varchar(250)", + "primaryKey": false, + "notNull": false + }, + "add_time": { + "name": "add_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "flowsheet_show_id_shows_id_fk": { + "name": "flowsheet_show_id_shows_id_fk", + "tableFrom": "flowsheet", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_album_id_library_id_fk": { + "name": "flowsheet_album_id_library_id_fk", + "tableFrom": "flowsheet", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_rotation_id_rotation_id_fk": { + "name": "flowsheet_rotation_id_rotation_id_fk", + "tableFrom": "flowsheet", + "tableTo": "rotation", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "rotation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.format": { + "name": "format", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genre_artist_crossreference": { + "name": "genre_artist_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "artist_genre_key": { + "name": "artist_genre_key", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "genre_artist_crossreference_artist_id_artists_id_fk": { + "name": "genre_artist_crossreference_artist_id_artists_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "genre_artist_crossreference_genre_id_genres_id_fk": { + "name": "genre_artist_crossreference_genre_id_genres_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genres": { + "name": "genres", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_invitation": { + "name": "auth_invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "inviter_id": { + "name": "inviter_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_invitation_email_idx": { + "name": "auth_invitation_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_invitation_organization_id_auth_organization_id_fk": { + "name": "auth_invitation_organization_id_auth_organization_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_invitation_inviter_id_auth_user_id_fk": { + "name": "auth_invitation_inviter_id_auth_user_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_jwks": { + "name": "auth_jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.library": { + "name": "library", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "format_id": { + "name": "format_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "alternate_artist_name": { + "name": "alternate_artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "code_volume_letters": { + "name": "code_volume_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": false + }, + "disc_quantity": { + "name": "disc_quantity", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "title_trgm_idx": { + "name": "title_trgm_idx", + "columns": [ + { + "expression": "\"album_title\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "genre_id_idx": { + "name": "genre_id_idx", + "columns": [ + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "format_id_idx": { + "name": "format_id_idx", + "columns": [ + { + "expression": "format_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_id_idx": { + "name": "artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "library_artist_id_artists_id_fk": { + "name": "library_artist_id_artists_id_fk", + "tableFrom": "library", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_genre_id_genres_id_fk": { + "name": "library_genre_id_genres_id_fk", + "tableFrom": "library", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_format_id_format_id_fk": { + "name": "library_format_id_format_id_fk", + "tableFrom": "library", + "tableTo": "format", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "format_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_member": { + "name": "auth_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_member_org_user_key": { + "name": "auth_member_org_user_key", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_member_organization_id_auth_organization_id_fk": { + "name": "auth_member_organization_id_auth_organization_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_member_user_id_auth_user_id_fk": { + "name": "auth_member_user_id_auth_user_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_organization": { + "name": "auth_organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_organization_slug_key": { + "name": "auth_organization_slug_key", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.reviews": { + "name": "reviews", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "review": { + "name": "review", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "author": { + "name": "author", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "reviews_album_id_library_id_fk": { + "name": "reviews_album_id_library_id_fk", + "tableFrom": "reviews", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reviews_album_id_unique": { + "name": "reviews_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.rotation": { + "name": "rotation", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "album_id_idx": { + "name": "album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "rotation_album_id_library_id_fk": { + "name": "rotation_album_id_library_id_fk", + "tableFrom": "rotation", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.schedule": { + "name": "schedule", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "day": { + "name": "day", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "start_time": { + "name": "start_time", + "type": "time", + "primaryKey": false, + "notNull": true + }, + "show_duration": { + "name": "show_duration", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id": { + "name": "assigned_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id2": { + "name": "assigned_dj_id2", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "schedule_specialty_id_specialty_shows_id_fk": { + "name": "schedule_specialty_id_specialty_shows_id_fk", + "tableFrom": "schedule", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id_auth_user_id_fk": { + "name": "schedule_assigned_dj_id_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id2_auth_user_id_fk": { + "name": "schedule_assigned_dj_id2_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id2" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_session_token_key": { + "name": "auth_session_token_key", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shift_covers": { + "name": "shift_covers", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "schedule_id": { + "name": "schedule_id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "shift_timestamp": { + "name": "shift_timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "cover_dj_id": { + "name": "cover_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "covered": { + "name": "covered", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "shift_covers_schedule_id_schedule_id_fk": { + "name": "shift_covers_schedule_id_schedule_id_fk", + "tableFrom": "shift_covers", + "tableTo": "schedule", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "schedule_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shift_covers_cover_dj_id_auth_user_id_fk": { + "name": "shift_covers_cover_dj_id_auth_user_id_fk", + "tableFrom": "shift_covers", + "tableTo": "auth_user", + "columnsFrom": [ + "cover_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.show_djs": { + "name": "show_djs", + "schema": "wxyc_schema", + "columns": { + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + } + }, + "indexes": {}, + "foreignKeys": { + "show_djs_show_id_shows_id_fk": { + "name": "show_djs_show_id_shows_id_fk", + "tableFrom": "show_djs", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "show_djs_dj_id_auth_user_id_fk": { + "name": "show_djs_dj_id_auth_user_id_fk", + "tableFrom": "show_djs", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shows": { + "name": "shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "primary_dj_id": { + "name": "primary_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "show_name": { + "name": "show_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "start_time": { + "name": "start_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "end_time": { + "name": "end_time", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "shows_primary_dj_id_auth_user_id_fk": { + "name": "shows_primary_dj_id_auth_user_id_fk", + "tableFrom": "shows", + "tableTo": "auth_user", + "columnsFrom": [ + "primary_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shows_specialty_id_specialty_shows_id_fk": { + "name": "shows_specialty_id_specialty_shows_id_fk", + "tableFrom": "shows", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.specialty_shows": { + "name": "specialty_shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "specialty_name": { + "name": "specialty_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "real_name": { + "name": "real_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dj_name": { + "name": "dj_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "app_skin": { + "name": "app_skin", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'modern-light'" + }, + "is_anonymous": { + "name": "is_anonymous", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "auth_user_email_key": { + "name": "auth_user_email_key", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auth_user_username_key": { + "name": "auth_user_username_key", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_activity": { + "name": "user_activity", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_activity_user_id_auth_user_id_fk": { + "name": "user_activity_user_id_auth_user_id_fk", + "tableFrom": "user_activity", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_verification": { + "name": "auth_verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.freq_enum": { + "name": "freq_enum", + "schema": "public", + "values": [ + "S", + "L", + "M", + "H" + ] + } + }, + "schemas": { + "wxyc_schema": "wxyc_schema" + }, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": { + "wxyc_schema.library_artist_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(2)", + "primaryKey": false, + "notNull": true + }, + "code_artist_number": { + "name": "code_artist_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"artists\".\"code_artist_number\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" < CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", + "name": "library_artist_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + }, + "wxyc_schema.rotation_library_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", + "name": "rotation_library_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + } + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/shared/database/src/migrations/meta/0028_snapshot.json b/shared/database/src/migrations/meta/0028_snapshot.json new file mode 100644 index 0000000..46f5bca --- /dev/null +++ b/shared/database/src/migrations/meta/0028_snapshot.json @@ -0,0 +1,2662 @@ +{ + "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "prevId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.auth_account": { + "name": "auth_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_account_provider_account_key": { + "name": "auth_account_provider_account_key", + "columns": [ + { + "expression": "provider_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_account_user_id_auth_user_id_fk": { + "name": "auth_account_user_id_auth_user_id_fk", + "tableFrom": "auth_account", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.album_metadata": { + "name": "album_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "discogs_release_id": { + "name": "discogs_release_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "discogs_url": { + "name": "discogs_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "release_year": { + "name": "release_year", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "artwork_url": { + "name": "artwork_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "spotify_url": { + "name": "spotify_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "apple_music_url": { + "name": "apple_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "youtube_music_url": { + "name": "youtube_music_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "bandcamp_url": { + "name": "bandcamp_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "soundcloud_url": { + "name": "soundcloud_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "is_rotation": { + "name": "is_rotation", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "album_metadata_album_id_idx": { + "name": "album_metadata_album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_cache_key_idx": { + "name": "album_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "album_metadata_last_accessed_idx": { + "name": "album_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "album_metadata_album_id_library_id_fk": { + "name": "album_metadata_album_id_library_id_fk", + "tableFrom": "album_metadata", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "album_metadata_album_id_unique": { + "name": "album_metadata_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + }, + "album_metadata_cache_key_unique": { + "name": "album_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.anonymous_devices": { + "name": "anonymous_devices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "device_id": { + "name": "device_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "blocked": { + "name": "blocked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "blocked_at": { + "name": "blocked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "anonymous_devices_device_id_key": { + "name": "anonymous_devices_device_id_key", + "columns": [ + { + "expression": "device_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "anonymous_devices_device_id_unique": { + "name": "anonymous_devices_device_id_unique", + "nullsNotDistinct": false, + "columns": [ + "device_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_library_crossreference": { + "name": "artist_library_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "library_id": { + "name": "library_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "library_id_artist_id": { + "name": "library_id_artist_id", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "library_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_library_crossreference_artist_id_artists_id_fk": { + "name": "artist_library_crossreference_artist_id_artists_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "artist_library_crossreference_library_id_library_id_fk": { + "name": "artist_library_crossreference_library_id_library_id_fk", + "tableFrom": "artist_library_crossreference", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artist_metadata": { + "name": "artist_metadata", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cache_key": { + "name": "cache_key", + "type": "varchar(256)", + "primaryKey": false, + "notNull": false + }, + "discogs_artist_id": { + "name": "discogs_artist_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "wikipedia_url": { + "name": "wikipedia_url", + "type": "varchar(512)", + "primaryKey": false, + "notNull": false + }, + "last_accessed": { + "name": "last_accessed", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_metadata_artist_id_idx": { + "name": "artist_metadata_artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_cache_key_idx": { + "name": "artist_metadata_cache_key_idx", + "columns": [ + { + "expression": "cache_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_metadata_last_accessed_idx": { + "name": "artist_metadata_last_accessed_idx", + "columns": [ + { + "expression": "last_accessed", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "artist_metadata_artist_id_artists_id_fk": { + "name": "artist_metadata_artist_id_artists_id_fk", + "tableFrom": "artist_metadata", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "artist_metadata_artist_id_unique": { + "name": "artist_metadata_artist_id_unique", + "nullsNotDistinct": false, + "columns": [ + "artist_id" + ] + }, + "artist_metadata_cache_key_unique": { + "name": "artist_metadata_cache_key_unique", + "nullsNotDistinct": false, + "columns": [ + "cache_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.artists": { + "name": "artists", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "artist_name_trgm_idx": { + "name": "artist_name_trgm_idx", + "columns": [ + { + "expression": "\"artist_name\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "code_letters_idx": { + "name": "code_letters_idx", + "columns": [ + { + "expression": "code_letters", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.bins": { + "name": "bins", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "bins_dj_id_auth_user_id_fk": { + "name": "bins_dj_id_auth_user_id_fk", + "tableFrom": "bins", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bins_album_id_library_id_fk": { + "name": "bins_album_id_library_id_fk", + "tableFrom": "bins", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.cronjob_runs": { + "name": "cronjob_runs", + "schema": "wxyc_schema", + "columns": { + "job_name": { + "name": "job_name", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "last_run": { + "name": "last_run", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.dj_stats": { + "name": "dj_stats", + "schema": "wxyc_schema", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "shows_covered": { + "name": "shows_covered", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "dj_stats_user_id_auth_user_id_fk": { + "name": "dj_stats_user_id_auth_user_id_fk", + "tableFrom": "dj_stats", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.flowsheet": { + "name": "flowsheet", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rotation_id": { + "name": "rotation_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "entry_type": { + "name": "entry_type", + "type": "flowsheet_entry_type", + "typeSchema": "wxyc_schema", + "primaryKey": false, + "notNull": true, + "default": "'track'" + }, + "track_title": { + "name": "track_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "record_label": { + "name": "record_label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "play_order": { + "name": "play_order", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "request_flag": { + "name": "request_flag", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "message": { + "name": "message", + "type": "varchar(250)", + "primaryKey": false, + "notNull": false + }, + "add_time": { + "name": "add_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "flowsheet_show_id_shows_id_fk": { + "name": "flowsheet_show_id_shows_id_fk", + "tableFrom": "flowsheet", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_album_id_library_id_fk": { + "name": "flowsheet_album_id_library_id_fk", + "tableFrom": "flowsheet", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "flowsheet_rotation_id_rotation_id_fk": { + "name": "flowsheet_rotation_id_rotation_id_fk", + "tableFrom": "flowsheet", + "tableTo": "rotation", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "rotation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.format": { + "name": "format", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genre_artist_crossreference": { + "name": "genre_artist_crossreference", + "schema": "wxyc_schema", + "columns": { + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "artist_genre_key": { + "name": "artist_genre_key", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "genre_artist_crossreference_artist_id_artists_id_fk": { + "name": "genre_artist_crossreference_artist_id_artists_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "genre_artist_crossreference_genre_id_genres_id_fk": { + "name": "genre_artist_crossreference_genre_id_genres_id_fk", + "tableFrom": "genre_artist_crossreference", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.genres": { + "name": "genres", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_invitation": { + "name": "auth_invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "inviter_id": { + "name": "inviter_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_invitation_email_idx": { + "name": "auth_invitation_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_invitation_organization_id_auth_organization_id_fk": { + "name": "auth_invitation_organization_id_auth_organization_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_invitation_inviter_id_auth_user_id_fk": { + "name": "auth_invitation_inviter_id_auth_user_id_fk", + "tableFrom": "auth_invitation", + "tableTo": "auth_user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_jwks": { + "name": "auth_jwks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.library": { + "name": "library", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "artist_id": { + "name": "artist_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "genre_id": { + "name": "genre_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "format_id": { + "name": "format_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "alternate_artist_name": { + "name": "alternate_artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "code_volume_letters": { + "name": "code_volume_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": false + }, + "disc_quantity": { + "name": "disc_quantity", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "plays": { + "name": "plays", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "title_trgm_idx": { + "name": "title_trgm_idx", + "columns": [ + { + "expression": "\"album_title\" gin_trgm_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "genre_id_idx": { + "name": "genre_id_idx", + "columns": [ + { + "expression": "genre_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "format_id_idx": { + "name": "format_id_idx", + "columns": [ + { + "expression": "format_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "artist_id_idx": { + "name": "artist_id_idx", + "columns": [ + { + "expression": "artist_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "library_artist_id_artists_id_fk": { + "name": "library_artist_id_artists_id_fk", + "tableFrom": "library", + "tableTo": "artists", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "artist_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_genre_id_genres_id_fk": { + "name": "library_genre_id_genres_id_fk", + "tableFrom": "library", + "tableTo": "genres", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "library_format_id_format_id_fk": { + "name": "library_format_id_format_id_fk", + "tableFrom": "library", + "tableTo": "format", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "format_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_member": { + "name": "auth_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_member_org_user_key": { + "name": "auth_member_org_user_key", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_member_organization_id_auth_organization_id_fk": { + "name": "auth_member_organization_id_auth_organization_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "auth_member_user_id_auth_user_id_fk": { + "name": "auth_member_user_id_auth_user_id_fk", + "tableFrom": "auth_member", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_organization": { + "name": "auth_organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_organization_slug_key": { + "name": "auth_organization_slug_key", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.reviews": { + "name": "reviews", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "review": { + "name": "review", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "author": { + "name": "author", + "type": "varchar(32)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "reviews_album_id_library_id_fk": { + "name": "reviews_album_id_library_id_fk", + "tableFrom": "reviews", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reviews_album_id_unique": { + "name": "reviews_album_id_unique", + "nullsNotDistinct": false, + "columns": [ + "album_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.rotation": { + "name": "rotation", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "album_id": { + "name": "album_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "album_id_idx": { + "name": "album_id_idx", + "columns": [ + { + "expression": "album_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "rotation_album_id_library_id_fk": { + "name": "rotation_album_id_library_id_fk", + "tableFrom": "rotation", + "tableTo": "library", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "album_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.schedule": { + "name": "schedule", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "day": { + "name": "day", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "start_time": { + "name": "start_time", + "type": "time", + "primaryKey": false, + "notNull": true + }, + "show_duration": { + "name": "show_duration", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id": { + "name": "assigned_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "assigned_dj_id2": { + "name": "assigned_dj_id2", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "schedule_specialty_id_specialty_shows_id_fk": { + "name": "schedule_specialty_id_specialty_shows_id_fk", + "tableFrom": "schedule", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id_auth_user_id_fk": { + "name": "schedule_assigned_dj_id_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "schedule_assigned_dj_id2_auth_user_id_fk": { + "name": "schedule_assigned_dj_id2_auth_user_id_fk", + "tableFrom": "schedule", + "tableTo": "auth_user", + "columnsFrom": [ + "assigned_dj_id2" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_session": { + "name": "auth_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ip_address": { + "name": "ip_address", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "auth_session_token_key": { + "name": "auth_session_token_key", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_session_user_id_auth_user_id_fk": { + "name": "auth_session_user_id_auth_user_id_fk", + "tableFrom": "auth_session", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shift_covers": { + "name": "shift_covers", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "schedule_id": { + "name": "schedule_id", + "type": "serial", + "primaryKey": false, + "notNull": true + }, + "shift_timestamp": { + "name": "shift_timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "cover_dj_id": { + "name": "cover_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "covered": { + "name": "covered", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "shift_covers_schedule_id_schedule_id_fk": { + "name": "shift_covers_schedule_id_schedule_id_fk", + "tableFrom": "shift_covers", + "tableTo": "schedule", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "schedule_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shift_covers_cover_dj_id_auth_user_id_fk": { + "name": "shift_covers_cover_dj_id_auth_user_id_fk", + "tableFrom": "shift_covers", + "tableTo": "auth_user", + "columnsFrom": [ + "cover_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.show_djs": { + "name": "show_djs", + "schema": "wxyc_schema", + "columns": { + "show_id": { + "name": "show_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "dj_id": { + "name": "dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + } + }, + "indexes": {}, + "foreignKeys": { + "show_djs_show_id_shows_id_fk": { + "name": "show_djs_show_id_shows_id_fk", + "tableFrom": "show_djs", + "tableTo": "shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "show_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "show_djs_dj_id_auth_user_id_fk": { + "name": "show_djs_dj_id_auth_user_id_fk", + "tableFrom": "show_djs", + "tableTo": "auth_user", + "columnsFrom": [ + "dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.shows": { + "name": "shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "primary_dj_id": { + "name": "primary_dj_id", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "specialty_id": { + "name": "specialty_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "show_name": { + "name": "show_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "start_time": { + "name": "start_time", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "end_time": { + "name": "end_time", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "shows_primary_dj_id_auth_user_id_fk": { + "name": "shows_primary_dj_id_auth_user_id_fk", + "tableFrom": "shows", + "tableTo": "auth_user", + "columnsFrom": [ + "primary_dj_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "shows_specialty_id_specialty_shows_id_fk": { + "name": "shows_specialty_id_specialty_shows_id_fk", + "tableFrom": "shows", + "tableTo": "specialty_shows", + "schemaTo": "wxyc_schema", + "columnsFrom": [ + "specialty_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "wxyc_schema.specialty_shows": { + "name": "specialty_shows", + "schema": "wxyc_schema", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "specialty_name": { + "name": "specialty_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "add_date": { + "name": "add_date", + "type": "date", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_modified": { + "name": "last_modified", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_user": { + "name": "auth_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "role": { + "name": "role", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "username": { + "name": "username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "real_name": { + "name": "real_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "dj_name": { + "name": "dj_name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "app_skin": { + "name": "app_skin", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true, + "default": "'modern-light'" + }, + "is_anonymous": { + "name": "is_anonymous", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "auth_user_email_key": { + "name": "auth_user_email_key", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auth_user_username_key": { + "name": "auth_user_username_key", + "columns": [ + { + "expression": "username", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_activity": { + "name": "user_activity", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_activity_user_id_auth_user_id_fk": { + "name": "user_activity_user_id_auth_user_id_fk", + "tableFrom": "user_activity", + "tableTo": "auth_user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_verification": { + "name": "auth_verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "varchar(255)", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "wxyc_schema.flowsheet_entry_type": { + "name": "flowsheet_entry_type", + "schema": "wxyc_schema", + "values": [ + "track", + "show_start", + "show_end", + "dj_join", + "dj_leave", + "talkset", + "breakpoint", + "message" + ] + }, + "public.freq_enum": { + "name": "freq_enum", + "schema": "public", + "values": [ + "S", + "L", + "M", + "H" + ] + } + }, + "schemas": { + "wxyc_schema": "wxyc_schema" + }, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": { + "wxyc_schema.library_artist_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": true + }, + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "code_number": { + "name": "code_number", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "format_name": { + "name": "format_name", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "genre_name": { + "name": "genre_name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "add_date": { + "name": "add_date", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"genre_artist_crossreference\".\"artist_genre_code\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" inner join \"wxyc_schema\".\"genre_artist_crossreference\" on (\"wxyc_schema\".\"genre_artist_crossreference\".\"artist_id\" = \"wxyc_schema\".\"library\".\"artist_id\" and \"wxyc_schema\".\"genre_artist_crossreference\".\"genre_id\" = \"wxyc_schema\".\"library\".\"genre_id\") left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" > CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", + "name": "library_artist_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + }, + "wxyc_schema.rotation_library_view": { + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "label": { + "name": "label", + "type": "varchar(128)", + "primaryKey": false, + "notNull": false + }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "album_title": { + "name": "album_title", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "artist_name": { + "name": "artist_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, + "kill_date": { + "name": "kill_date", + "type": "date", + "primaryKey": false, + "notNull": false + } + }, + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", + "name": "rotation_library_view", + "schema": "wxyc_schema", + "isExisting": false, + "materialized": false + } + }, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/shared/database/src/migrations/meta/0029_snapshot.json b/shared/database/src/migrations/meta/0029_snapshot.json index 0426bcf..589289a 100644 --- a/shared/database/src/migrations/meta/0029_snapshot.json +++ b/shared/database/src/migrations/meta/0029_snapshot.json @@ -1,6 +1,6 @@ { - "id": "df397568-f27d-4a06-9aba-08264d97ae8e", - "prevId": "335ff99b-a9d0-49ec-a275-2bf4e9b2edf7", + "id": "07863e5f-57cb-4b4e-9c35-d33a78a8b5f0", + "prevId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "version": "7", "dialect": "postgresql", "tables": { @@ -629,27 +629,21 @@ "primaryKey": true, "notNull": true }, - "genre_id": { - "name": "genre_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, "artist_name": { "name": "artist_name", "type": "varchar(128)", "primaryKey": false, "notNull": true }, - "code_letters": { - "name": "code_letters", - "type": "varchar(2)", + "alphabetical_name": { + "name": "alphabetical_name", + "type": "varchar(128)", "primaryKey": false, "notNull": true }, - "code_artist_number": { - "name": "code_artist_number", - "type": "smallint", + "code_letters": { + "name": "code_letters", + "type": "varchar(4)", "primaryKey": false, "notNull": true }, @@ -700,22 +694,7 @@ "with": {} } }, - "foreignKeys": { - "artists_genre_id_genres_id_fk": { - "name": "artists_genre_id_genres_id_fk", - "tableFrom": "artists", - "tableTo": "genres", - "schemaTo": "wxyc_schema", - "columnsFrom": [ - "genre_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, + "foreignKeys": {}, "compositePrimaryKeys": {}, "uniqueConstraints": {}, "policies": {}, @@ -787,6 +766,32 @@ "checkConstraints": {}, "isRLSEnabled": false }, + "wxyc_schema.cronjob_runs": { + "name": "cronjob_runs", + "schema": "wxyc_schema", + "columns": { + "job_name": { + "name": "job_name", + "type": "varchar(64)", + "primaryKey": true, + "notNull": true + }, + "last_run": { + "name": "last_run", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, "wxyc_schema.dj_stats": { "name": "dj_stats", "schema": "wxyc_schema", @@ -855,6 +860,14 @@ "primaryKey": false, "notNull": false }, + "entry_type": { + "name": "entry_type", + "type": "flowsheet_entry_type", + "typeSchema": "wxyc_schema", + "primaryKey": false, + "notNull": true, + "default": "'track'" + }, "track_title": { "name": "track_title", "type": "varchar(128)", @@ -1319,6 +1332,12 @@ "primaryKey": false, "notNull": true }, + "code_volume_letters": { + "name": "code_volume_letters", + "type": "varchar(4)", + "primaryKey": false, + "notNull": false + }, "disc_quantity": { "name": "disc_quantity", "type": "smallint", @@ -1710,6 +1729,13 @@ "primaryKey": false, "notNull": true }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, "add_date": { "name": "add_date", "type": "date", @@ -1722,13 +1748,6 @@ "type": "date", "primaryKey": false, "notNull": false - }, - "rotation_bin": { - "name": "rotation_bin", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true } }, "indexes": { @@ -2485,6 +2504,20 @@ } }, "enums": { + "wxyc_schema.flowsheet_entry_type": { + "name": "flowsheet_entry_type", + "schema": "wxyc_schema", + "values": [ + "track", + "show_start", + "show_end", + "dj_join", + "dj_leave", + "talkset", + "breakpoint", + "message" + ] + }, "public.freq_enum": { "name": "freq_enum", "schema": "public", @@ -2513,13 +2546,13 @@ }, "code_letters": { "name": "code_letters", - "type": "varchar(2)", + "type": "varchar(4)", "primaryKey": false, "notNull": true }, - "code_artist_number": { - "name": "code_artist_number", - "type": "smallint", + "artist_genre_code": { + "name": "artist_genre_code", + "type": "integer", "primaryKey": false, "notNull": true }, @@ -2535,6 +2568,12 @@ "primaryKey": false, "notNull": true }, + "alphabetical_name": { + "name": "alphabetical_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, "album_title": { "name": "album_title", "type": "varchar(128)", @@ -2553,6 +2592,13 @@ "primaryKey": false, "notNull": true }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, "add_date": { "name": "add_date", "type": "timestamp", @@ -2565,16 +2611,9 @@ "type": "varchar(128)", "primaryKey": false, "notNull": false - }, - "rotation_bin": { - "name": "rotation_bin", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true } }, - "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"artists\".\"code_artist_number\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" < CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"artists\".\"code_letters\", \"wxyc_schema\".\"genre_artist_crossreference\".\"artist_genre_code\", \"wxyc_schema\".\"library\".\"code_number\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"artists\".\"alphabetical_name\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"format\".\"format_name\", \"wxyc_schema\".\"genres\".\"genre_name\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"add_date\", \"wxyc_schema\".\"library\".\"label\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\" inner join \"wxyc_schema\".\"format\" on \"wxyc_schema\".\"format\".\"id\" = \"wxyc_schema\".\"library\".\"format_id\" inner join \"wxyc_schema\".\"genres\" on \"wxyc_schema\".\"genres\".\"id\" = \"wxyc_schema\".\"library\".\"genre_id\" inner join \"wxyc_schema\".\"genre_artist_crossreference\" on (\"wxyc_schema\".\"genre_artist_crossreference\".\"artist_id\" = \"wxyc_schema\".\"library\".\"artist_id\" and \"wxyc_schema\".\"genre_artist_crossreference\".\"genre_id\" = \"wxyc_schema\".\"library\".\"genre_id\") left join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"rotation\".\"album_id\" = \"wxyc_schema\".\"library\".\"id\" AND (\"wxyc_schema\".\"rotation\".\"kill_date\" > CURRENT_DATE OR \"wxyc_schema\".\"rotation\".\"kill_date\" IS NULL)", "name": "library_artist_view", "schema": "wxyc_schema", "isExisting": false, @@ -2594,6 +2633,13 @@ "primaryKey": false, "notNull": false }, + "rotation_bin": { + "name": "rotation_bin", + "type": "freq_enum", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, "album_title": { "name": "album_title", "type": "varchar(128)", @@ -2606,21 +2652,20 @@ "primaryKey": false, "notNull": true }, + "alphabetical_name": { + "name": "alphabetical_name", + "type": "varchar(128)", + "primaryKey": false, + "notNull": true + }, "kill_date": { "name": "kill_date", "type": "date", "primaryKey": false, "notNull": false - }, - "rotation_bin": { - "name": "rotation_bin", - "type": "freq_enum", - "typeSchema": "public", - "primaryKey": false, - "notNull": true } }, - "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", + "definition": "select \"wxyc_schema\".\"library\".\"id\", \"wxyc_schema\".\"rotation\".\"id\", \"wxyc_schema\".\"library\".\"label\", \"wxyc_schema\".\"rotation\".\"rotation_bin\", \"wxyc_schema\".\"library\".\"album_title\", \"wxyc_schema\".\"artists\".\"artist_name\", \"wxyc_schema\".\"artists\".\"alphabetical_name\", \"wxyc_schema\".\"rotation\".\"kill_date\" from \"wxyc_schema\".\"library\" inner join \"wxyc_schema\".\"rotation\" on \"wxyc_schema\".\"library\".\"id\" = \"wxyc_schema\".\"rotation\".\"album_id\" inner join \"wxyc_schema\".\"artists\" on \"wxyc_schema\".\"artists\".\"id\" = \"wxyc_schema\".\"library\".\"artist_id\"", "name": "rotation_library_view", "schema": "wxyc_schema", "isExisting": false, diff --git a/shared/database/src/migrations/meta/_journal.json b/shared/database/src/migrations/meta/_journal.json index 074a113..9e45d1b 100644 --- a/shared/database/src/migrations/meta/_journal.json +++ b/shared/database/src/migrations/meta/_journal.json @@ -167,7 +167,28 @@ "idx": 26, "version": "7", "when": 1771099200000, - "tag": "0029_rename_play_freq_to_rotation_bin", + "tag": "0026_rename_play_freq_to_rotation_bin", + "breakpoints": true + }, + { + "idx": 27, + "version": "7", + "when": 1772298699137, + "tag": "0027_cron_job_tracking", + "breakpoints": true + }, + { + "idx": 28, + "version": "7", + "when": 1772298699138, + "tag": "0028_drop_genre_from_artist_table", + "breakpoints": true + }, + { + "idx": 29, + "version": "7", + "when": 1772298699139, + "tag": "0029_add_artists_alphabetical_name", "breakpoints": true } ]