use granblueId in database URLs instead of UUID
- rename route folders from [id] to [granblueId] - update all server load functions to use params.granblueId - update detail/edit/new pages to navigate with granblueId - update cross-entity links (recruits, recruitedBy) - update TanStack Query keys to use granblueId backend's IdResolvable already supports fetching by granblueId
This commit is contained in:
parent
4d7d2c563e
commit
6ba89dc216
18 changed files with 57 additions and 57 deletions
|
|
@ -21,25 +21,25 @@ import { entityAdapter, type WeaponKeyQueryParams } from '$lib/api/adapters/enti
|
|||
* import { createQuery } from '@tanstack/svelte-query'
|
||||
* import { entityQueries } from '$lib/api/queries/entity.queries'
|
||||
*
|
||||
* // Single weapon by ID
|
||||
* const weapon = createQuery(() => entityQueries.weapon(id))
|
||||
* // Single weapon by granblueId
|
||||
* const weapon = createQuery(() => entityQueries.weapon(granblueId))
|
||||
*
|
||||
* // Single character by ID
|
||||
* const character = createQuery(() => entityQueries.character(id))
|
||||
* // Single character by granblueId
|
||||
* const character = createQuery(() => entityQueries.character(granblueId))
|
||||
* ```
|
||||
*/
|
||||
export const entityQueries = {
|
||||
/**
|
||||
* Single weapon query options
|
||||
*
|
||||
* @param id - Weapon ID
|
||||
* @param granblueId - Weapon granblueId (e.g., "1040001000")
|
||||
* @returns Query options for fetching a single weapon
|
||||
*/
|
||||
weapon: (id: string) =>
|
||||
weapon: (granblueId: string) =>
|
||||
queryOptions({
|
||||
queryKey: ['weapon', id] as const,
|
||||
queryFn: () => entityAdapter.getWeapon(id),
|
||||
enabled: !!id,
|
||||
queryKey: ['weapon', granblueId] as const,
|
||||
queryFn: () => entityAdapter.getWeapon(granblueId),
|
||||
enabled: !!granblueId,
|
||||
staleTime: 1000 * 60 * 60, // 1 hour - canonical data rarely changes
|
||||
gcTime: 1000 * 60 * 60 * 24 // 24 hours
|
||||
}),
|
||||
|
|
@ -47,14 +47,14 @@ export const entityQueries = {
|
|||
/**
|
||||
* Single character query options
|
||||
*
|
||||
* @param id - Character ID
|
||||
* @param granblueId - Character granblueId (e.g., "3040001000")
|
||||
* @returns Query options for fetching a single character
|
||||
*/
|
||||
character: (id: string) =>
|
||||
character: (granblueId: string) =>
|
||||
queryOptions({
|
||||
queryKey: ['character', id] as const,
|
||||
queryFn: () => entityAdapter.getCharacter(id),
|
||||
enabled: !!id,
|
||||
queryKey: ['character', granblueId] as const,
|
||||
queryFn: () => entityAdapter.getCharacter(granblueId),
|
||||
enabled: !!granblueId,
|
||||
staleTime: 1000 * 60 * 60, // 1 hour - canonical data rarely changes
|
||||
gcTime: 1000 * 60 * 60 * 24 // 24 hours
|
||||
}),
|
||||
|
|
@ -62,14 +62,14 @@ export const entityQueries = {
|
|||
/**
|
||||
* Single summon query options
|
||||
*
|
||||
* @param id - Summon ID
|
||||
* @param granblueId - Summon granblueId (e.g., "2040001000")
|
||||
* @returns Query options for fetching a single summon
|
||||
*/
|
||||
summon: (id: string) =>
|
||||
summon: (granblueId: string) =>
|
||||
queryOptions({
|
||||
queryKey: ['summon', id] as const,
|
||||
queryFn: () => entityAdapter.getSummon(id),
|
||||
enabled: !!id,
|
||||
queryKey: ['summon', granblueId] as const,
|
||||
queryFn: () => entityAdapter.getSummon(granblueId),
|
||||
enabled: !!granblueId,
|
||||
staleTime: 1000 * 60 * 60, // 1 hour - canonical data rarely changes
|
||||
gcTime: 1000 * 60 * 60 * 24 // 24 hours
|
||||
}),
|
||||
|
|
@ -186,8 +186,8 @@ export const entityQueries = {
|
|||
*
|
||||
* const queryClient = useQueryClient()
|
||||
*
|
||||
* // Invalidate a specific weapon
|
||||
* queryClient.invalidateQueries({ queryKey: entityKeys.weapon('abc123') })
|
||||
* // Invalidate a specific weapon by granblueId
|
||||
* queryClient.invalidateQueries({ queryKey: entityKeys.weapon('1040001000') })
|
||||
*
|
||||
* // Invalidate all weapons
|
||||
* queryClient.invalidateQueries({ queryKey: entityKeys.weapons() })
|
||||
|
|
@ -195,11 +195,11 @@ export const entityQueries = {
|
|||
*/
|
||||
export const entityKeys = {
|
||||
weapons: () => ['weapon'] as const,
|
||||
weapon: (id: string) => [...entityKeys.weapons(), id] as const,
|
||||
weapon: (granblueId: string) => [...entityKeys.weapons(), granblueId] as const,
|
||||
characters: () => ['character'] as const,
|
||||
character: (id: string) => [...entityKeys.characters(), id] as const,
|
||||
character: (granblueId: string) => [...entityKeys.characters(), granblueId] as const,
|
||||
summons: () => ['summon'] as const,
|
||||
summon: (id: string) => [...entityKeys.summons(), id] as const,
|
||||
summon: (granblueId: string) => [...entityKeys.summons(), granblueId] as const,
|
||||
weaponKeys: (params?: WeaponKeyQueryParams) =>
|
||||
['weaponKeys', params?.seriesSlug, params?.slot, params?.group] as const,
|
||||
weaponSeriesList: () => ['weaponSeries', 'list'] as const,
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@
|
|||
{/if}
|
||||
{#if character.recruitedBy}
|
||||
<DetailItem label="Recruited By">
|
||||
<a href="/database/weapons/{character.recruitedBy.id}" class="recruited-by-link">
|
||||
<a href="/database/weapons/{character.recruitedBy.granblueId}" class="recruited-by-link">
|
||||
<img
|
||||
src={getWeaponImage(character.recruitedBy.granblueId, 'square')}
|
||||
alt={character.recruitedBy.name.en || 'Recruiting weapon'}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
</DetailItem>
|
||||
{#if weapon.recruits}
|
||||
<DetailItem label="Recruits">
|
||||
<a href="/database/characters/{weapon.recruits.id}" class="recruits-link">
|
||||
<a href="/database/characters/{weapon.recruits.granblueId}" class="recruits-link">
|
||||
<img
|
||||
src={getCharacterImage(weapon.recruits.granblueId, 'square', '01')}
|
||||
alt={weapon.recruits.name.en || 'Recruited character'}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export const load: PageServerLoad = async ({ params, parent }) => {
|
|||
// Get parent data to access role
|
||||
const parentData = await parent()
|
||||
|
||||
const character = await entityAdapter.getCharacter(params.id)
|
||||
const character = await entityAdapter.getCharacter(params.granblueId)
|
||||
|
||||
if (!character) {
|
||||
throw error(404, 'Character not found')
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
// Use TanStack Query with SSR initial data
|
||||
const characterQuery = createQuery(() => ({
|
||||
...entityQueries.character(data.character?.id ?? ''),
|
||||
...entityQueries.character(data.character?.granblueId ?? ''),
|
||||
...withInitialData(data.character)
|
||||
}))
|
||||
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
const canEdit = $derived(userRole >= 7)
|
||||
|
||||
// Edit URL for navigation
|
||||
const editUrl = $derived(character?.id ? `/database/characters/${character.id}/edit` : undefined)
|
||||
const editUrl = $derived(character?.granblueId ? `/database/characters/${character.granblueId}/edit` : undefined)
|
||||
|
||||
// Query for related characters (same character_id)
|
||||
const relatedQuery = createQuery(() => ({
|
||||
|
|
@ -260,7 +260,7 @@
|
|||
<DetailsContainer title="Related Units">
|
||||
<div class="related-units">
|
||||
{#each relatedQuery.data as related}
|
||||
<a href="/database/characters/{related.id}" class="related-unit">
|
||||
<a href="/database/characters/{related.granblueId}" class="related-unit">
|
||||
<img
|
||||
src={getCharacterImage(related.granblueId, 'grid', '01')}
|
||||
alt={related.name.en}
|
||||
|
|
@ -8,11 +8,11 @@ export const load: PageServerLoad = async ({ params, parent }) => {
|
|||
|
||||
// Role check - must be editor level (>= 7) to edit
|
||||
if (!parentData.role || parentData.role < 7) {
|
||||
throw redirect(303, `/database/characters/${params.id}`)
|
||||
throw redirect(303, `/database/characters/${params.granblueId}`)
|
||||
}
|
||||
|
||||
try {
|
||||
const character = await entityAdapter.getCharacter(params.id)
|
||||
const character = await entityAdapter.getCharacter(params.granblueId)
|
||||
|
||||
if (!character) {
|
||||
throw error(404, 'Character not found')
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
// Use TanStack Query with SSR initial data
|
||||
const characterQuery = createQuery(() => ({
|
||||
...entityQueries.character(data.character?.id ?? ''),
|
||||
...entityQueries.character(data.character?.granblueId ?? ''),
|
||||
...withInitialData(data.character)
|
||||
}))
|
||||
|
||||
|
|
@ -142,10 +142,10 @@
|
|||
await entityAdapter.updateCharacter(character.id, payload)
|
||||
|
||||
// Invalidate TanStack Query cache to refetch fresh data
|
||||
await queryClient.invalidateQueries({ queryKey: ['character', character.id] })
|
||||
await queryClient.invalidateQueries({ queryKey: ['character', character.granblueId] })
|
||||
|
||||
// Navigate back to detail page
|
||||
goto(`/database/characters/${character.id}`)
|
||||
goto(`/database/characters/${character.granblueId}`)
|
||||
} catch (error) {
|
||||
saveError = 'Failed to save changes. Please try again.'
|
||||
console.error('Save error:', error)
|
||||
|
|
@ -155,7 +155,7 @@
|
|||
}
|
||||
|
||||
function handleCancel() {
|
||||
goto(`/database/characters/${character?.id}`)
|
||||
goto(`/database/characters/${character?.granblueId}`)
|
||||
}
|
||||
|
||||
// Helper function for character grid image
|
||||
|
|
@ -223,7 +223,7 @@
|
|||
const newCharacter = await entityAdapter.createCharacter(payload)
|
||||
// Trigger image download in background (don't await - it queues a job)
|
||||
entityAdapter.downloadCharacterImages(newCharacter.id).catch(console.error)
|
||||
await goto(`/database/characters/${newCharacter.id}`)
|
||||
await goto(`/database/characters/${newCharacter.granblueId}`)
|
||||
} catch (error) {
|
||||
saveError = 'Failed to create character. Please try again.'
|
||||
console.error('Create error:', error)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export const load: PageServerLoad = async ({ params, parent }) => {
|
|||
// Get parent data to access role
|
||||
const parentData = await parent()
|
||||
|
||||
const summon = await entityAdapter.getSummon(params.id)
|
||||
const summon = await entityAdapter.getSummon(params.granblueId)
|
||||
|
||||
if (!summon) {
|
||||
throw error(404, 'Summon not found')
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
// Use TanStack Query with SSR initial data
|
||||
const summonQuery = createQuery(() => ({
|
||||
...entityQueries.summon(data.summon?.id ?? ''),
|
||||
...entityQueries.summon(data.summon?.granblueId ?? ''),
|
||||
...withInitialData(data.summon)
|
||||
}))
|
||||
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
const canEdit = $derived(userRole >= 7)
|
||||
|
||||
// Edit URL for navigation
|
||||
const editUrl = $derived(summon?.id ? `/database/summons/${summon.id}/edit` : undefined)
|
||||
const editUrl = $derived(summon?.granblueId ? `/database/summons/${summon.granblueId}/edit` : undefined)
|
||||
|
||||
// Query for raw data (only when on raw tab)
|
||||
const rawDataQuery = createQuery(() => ({
|
||||
|
|
@ -8,11 +8,11 @@ export const load: PageServerLoad = async ({ params, parent }) => {
|
|||
|
||||
// Role check - must be editor level (>= 7) to edit
|
||||
if (!parentData.role || parentData.role < 7) {
|
||||
throw redirect(303, `/database/summons/${params.id}`)
|
||||
throw redirect(303, `/database/summons/${params.granblueId}`)
|
||||
}
|
||||
|
||||
try {
|
||||
const summon = await entityAdapter.getSummon(params.id)
|
||||
const summon = await entityAdapter.getSummon(params.granblueId)
|
||||
|
||||
if (!summon) {
|
||||
throw error(404, 'Summon not found')
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
// Use TanStack Query with SSR initial data
|
||||
const summonQuery = createQuery(() => ({
|
||||
...entityQueries.summon(data.summon?.id ?? ''),
|
||||
...entityQueries.summon(data.summon?.granblueId ?? ''),
|
||||
...withInitialData(data.summon)
|
||||
}))
|
||||
|
||||
|
|
@ -168,10 +168,10 @@
|
|||
await entityAdapter.updateSummon(summon.id, payload)
|
||||
|
||||
// Invalidate TanStack Query cache to refetch fresh data
|
||||
await queryClient.invalidateQueries({ queryKey: ['summon', summon.id] })
|
||||
await queryClient.invalidateQueries({ queryKey: ['summon', summon.granblueId] })
|
||||
|
||||
// Navigate back to detail page
|
||||
goto(`/database/summons/${summon.id}`)
|
||||
goto(`/database/summons/${summon.granblueId}`)
|
||||
} catch (error) {
|
||||
saveError = 'Failed to save changes. Please try again.'
|
||||
console.error('Save error:', error)
|
||||
|
|
@ -181,7 +181,7 @@
|
|||
}
|
||||
|
||||
function handleCancel() {
|
||||
goto(`/database/summons/${summon?.id}`)
|
||||
goto(`/database/summons/${summon?.granblueId}`)
|
||||
}
|
||||
|
||||
// Helper function for summon grid image
|
||||
|
|
@ -203,7 +203,7 @@
|
|||
const newSummon = await entityAdapter.createSummon(payload)
|
||||
// Trigger image download in background (don't await - it queues a job)
|
||||
entityAdapter.downloadSummonImages(newSummon.id).catch(console.error)
|
||||
await goto(`/database/summons/${newSummon.id}`)
|
||||
await goto(`/database/summons/${newSummon.granblueId}`)
|
||||
} catch (error) {
|
||||
saveError = 'Failed to create summon. Please try again.'
|
||||
console.error('Create error:', error)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export const load: PageServerLoad = async ({ params, parent }) => {
|
|||
// Get parent data to access role
|
||||
const parentData = await parent()
|
||||
|
||||
const weapon = await entityAdapter.getWeapon(params.id)
|
||||
const weapon = await entityAdapter.getWeapon(params.granblueId)
|
||||
|
||||
if (!weapon) {
|
||||
throw error(404, 'Weapon not found')
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
// Use TanStack Query with SSR initial data
|
||||
const weaponQuery = createQuery(() => ({
|
||||
...entityQueries.weapon(data.weapon?.id ?? ''),
|
||||
...entityQueries.weapon(data.weapon?.granblueId ?? ''),
|
||||
...withInitialData(data.weapon)
|
||||
}))
|
||||
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
const canEdit = $derived(userRole >= 7)
|
||||
|
||||
// Edit URL for navigation
|
||||
const editUrl = $derived(weapon?.id ? `/database/weapons/${weapon.id}/edit` : undefined)
|
||||
const editUrl = $derived(weapon?.granblueId ? `/database/weapons/${weapon.granblueId}/edit` : undefined)
|
||||
|
||||
// Query for raw data (only when on raw tab)
|
||||
const rawDataQuery = createQuery(() => ({
|
||||
|
|
@ -8,11 +8,11 @@ export const load: PageServerLoad = async ({ params, parent }) => {
|
|||
|
||||
// Role check - must be editor level (>= 7) to edit
|
||||
if (!parentData.role || parentData.role < 7) {
|
||||
throw redirect(303, `/database/weapons/${params.id}`)
|
||||
throw redirect(303, `/database/weapons/${params.granblueId}`)
|
||||
}
|
||||
|
||||
try {
|
||||
const weapon = await entityAdapter.getWeapon(params.id)
|
||||
const weapon = await entityAdapter.getWeapon(params.granblueId)
|
||||
|
||||
if (!weapon) {
|
||||
throw error(404, 'Weapon not found')
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
// Use TanStack Query with SSR initial data
|
||||
const weaponQuery = createQuery(() => ({
|
||||
...entityQueries.weapon(data.weapon?.id ?? ''),
|
||||
...entityQueries.weapon(data.weapon?.granblueId ?? ''),
|
||||
...withInitialData(data.weapon)
|
||||
}))
|
||||
|
||||
|
|
@ -179,10 +179,10 @@
|
|||
await entityAdapter.updateWeapon(weapon.id, payload)
|
||||
|
||||
// Invalidate TanStack Query cache to refetch fresh data
|
||||
await queryClient.invalidateQueries({ queryKey: ['weapon', weapon.id] })
|
||||
await queryClient.invalidateQueries({ queryKey: ['weapon', weapon.granblueId] })
|
||||
|
||||
// Navigate back to detail page
|
||||
goto(`/database/weapons/${weapon.id}`)
|
||||
goto(`/database/weapons/${weapon.granblueId}`)
|
||||
} catch (error) {
|
||||
saveError = 'Failed to save changes. Please try again.'
|
||||
console.error('Save error:', error)
|
||||
|
|
@ -192,7 +192,7 @@
|
|||
}
|
||||
|
||||
function handleCancel() {
|
||||
goto(`/database/weapons/${weapon?.id}`)
|
||||
goto(`/database/weapons/${weapon?.granblueId}`)
|
||||
}
|
||||
|
||||
// Helper function for weapon grid image
|
||||
|
|
@ -210,7 +210,7 @@
|
|||
const newWeapon = await entityAdapter.createWeapon(payload)
|
||||
// Trigger image download in background (don't await - it queues a job)
|
||||
entityAdapter.downloadWeaponImages(newWeapon.id).catch(console.error)
|
||||
await goto(`/database/weapons/${newWeapon.id}`)
|
||||
await goto(`/database/weapons/${newWeapon.granblueId}`)
|
||||
} catch (error) {
|
||||
saveError = 'Failed to create weapon. Please try again.'
|
||||
console.error('Create error:', error)
|
||||
|
|
|
|||
Loading…
Reference in a new issue