- pgSchema tables for auth, money, house, ref, games, cs, animaldex, site, meta (lists excluded via schemaFilter; runtime list tables are managed by meta.*) - drizzle/ baseline matches the reorged DB exactly (catalog diff = 0 on rehearsal) - db/reorg: one-time SQL that moves the flat public schema (rehearsed on a prod copy) - scripts/db-migrate.ts: migrator with --init to record the baseline and a guard against running the baseline on a non-empty, unrecorded database
151 lines
3.4 KiB
TypeScript
151 lines
3.4 KiB
TypeScript
import { defineRelations } from 'drizzle-orm';
|
|
import * as schema from './schema';
|
|
|
|
export const relations = defineRelations(schema, (r) => ({
|
|
// ── Auth ──────────────────────────────────────
|
|
user: {
|
|
sessions: r.many.session(),
|
|
accounts: r.many.account(),
|
|
entries: r.many.userEntries(),
|
|
games: r.many.userGames()
|
|
},
|
|
session: {
|
|
user: r.one.user({
|
|
from: r.session.userId,
|
|
to: r.user.id
|
|
})
|
|
},
|
|
account: {
|
|
user: r.one.user({
|
|
from: r.account.userId,
|
|
to: r.user.id
|
|
})
|
|
},
|
|
|
|
// ── Progress ──────────────────────────────────
|
|
tasks: {
|
|
tasksToTopics: r.many.tasksToTopics()
|
|
},
|
|
topics: {
|
|
topicsToTasks: r.many.tasksToTopics()
|
|
},
|
|
tasksToTopics: {
|
|
task: r.one.tasks({
|
|
from: r.tasksToTopics.taskId,
|
|
to: r.tasks.id
|
|
}),
|
|
topic: r.one.topics({
|
|
from: r.tasksToTopics.topicId,
|
|
to: r.topics.id
|
|
})
|
|
},
|
|
|
|
// ── CatchEmAll ────────────────────────────────
|
|
games: {
|
|
entries: r.many.pokemonGameEntries()
|
|
},
|
|
pokemon: {
|
|
entry: r.many.pokemonGameEntries(),
|
|
encounters: r.many.pokemonEncounters()
|
|
},
|
|
pokemonLocations: {
|
|
encounters: r.many.pokemonEncounters()
|
|
},
|
|
pokemonEncounters: {
|
|
pokemon: r.one.pokemon({
|
|
from: r.pokemonEncounters.pokemonId,
|
|
to: r.pokemon.id
|
|
}),
|
|
game: r.one.games({
|
|
from: r.pokemonEncounters.gameId,
|
|
to: r.games.id
|
|
}),
|
|
location: r.one.pokemonLocations({
|
|
from: r.pokemonEncounters.locationId,
|
|
to: r.pokemonLocations.id
|
|
})
|
|
},
|
|
pokemonGameEntries: {
|
|
game: r.one.games({
|
|
from: r.pokemonGameEntries.gameId,
|
|
to: r.games.id
|
|
}),
|
|
pokemon: r.one.pokemon({
|
|
from: r.pokemonGameEntries.pokemonId,
|
|
to: r.pokemon.id
|
|
}),
|
|
userEntries: r.many.userEntries()
|
|
},
|
|
userEntries: {
|
|
pokemonGameEntry: r.one.pokemonGameEntries({
|
|
from: r.userEntries.pokemonGameEntryId,
|
|
to: r.pokemonGameEntries.id
|
|
}),
|
|
user: r.one.user({
|
|
from: r.userEntries.userId,
|
|
to: r.user.id
|
|
})
|
|
},
|
|
userGames: {
|
|
user: r.one.user({
|
|
from: r.userGames.userId,
|
|
to: r.user.id
|
|
}),
|
|
game: r.one.games({
|
|
from: r.userGames.gameId,
|
|
to: r.games.id
|
|
})
|
|
},
|
|
|
|
// ── Game tracker ──────────────────────────────
|
|
trackerGames: {
|
|
items: r.many.trackerItems()
|
|
},
|
|
trackerItems: {
|
|
game: r.one.trackerGames({
|
|
from: r.trackerItems.gameId,
|
|
to: r.trackerGames.id
|
|
}),
|
|
progress: r.many.trackerProgress()
|
|
},
|
|
trackerProgress: {
|
|
item: r.one.trackerItems({
|
|
from: r.trackerProgress.itemId,
|
|
to: r.trackerItems.id
|
|
}),
|
|
user: r.one.user({
|
|
from: r.trackerProgress.userId,
|
|
to: r.user.id
|
|
})
|
|
},
|
|
|
|
// ── Animaldex ─────────────────────────────────
|
|
animals: {
|
|
sightings: r.many.sightings()
|
|
},
|
|
sightings: {
|
|
animal: r.one.animals({
|
|
from: r.sightings.animalId,
|
|
to: r.animals.id
|
|
}),
|
|
photos: r.many.photos()
|
|
},
|
|
photos: {
|
|
sighting: r.one.sightings({
|
|
from: r.photos.sightingId,
|
|
to: r.sightings.id
|
|
})
|
|
},
|
|
|
|
// ── Meta registry (lists live in schema `lists`, see src/lib/server/lists.ts)
|
|
metaTables: {
|
|
columns: r.many.metaColumns()
|
|
},
|
|
metaColumns: {
|
|
table: r.one.metaTables({
|
|
from: r.metaColumns.tableId,
|
|
to: r.metaTables.id
|
|
})
|
|
}
|
|
}));
|