update entity adapter to use seriesSlug, add weapon series CRUD methods

This commit is contained in:
Justin Edmund 2025-12-03 11:59:07 -08:00
parent 745c162529
commit 23a2481190
3 changed files with 134 additions and 10 deletions

View file

@ -11,6 +11,12 @@
import { BaseAdapter } from './base.adapter'
import type { AdapterOptions } from './types'
import { DEFAULT_ADAPTER_CONFIG } from './config'
import type {
WeaponSeriesRef,
WeaponSeries,
CreateWeaponSeriesPayload,
UpdateWeaponSeriesPayload
} from '$lib/types/api/weaponSeries'
/**
* Canonical weapon data from the game
@ -25,7 +31,8 @@ export interface Weapon {
rarity: number
element: number
proficiency: number
series?: number
/** Weapon series - object with slug/name/flags */
series?: WeaponSeriesRef | null
weaponType?: number
/** Gacha promotions (1=Premium, 2=Classic, 3=ClassicII, 4=Flash, 5=Legend, etc.) */
promotions?: number[]
@ -182,7 +189,8 @@ export interface WeaponKey {
* Query parameters for fetching weapon keys
*/
export interface WeaponKeyQueryParams {
series?: number
/** Filter by weapon series slug (e.g., 'dark-opus', 'ultima') */
seriesSlug?: string
slot?: number
group?: number
}
@ -421,8 +429,8 @@ export interface CreateWeaponPayload {
rarity?: number
element?: number
proficiency?: number
series?: number
new_series?: number
/** Weapon series ID (UUID) */
weapon_series_id?: string
min_hp?: number
max_hp?: number
max_hp_flb?: number
@ -654,7 +662,9 @@ export class EntityAdapter extends BaseAdapter {
*/
async getWeaponKeys(params?: WeaponKeyQueryParams): Promise<WeaponKey[]> {
const searchParams = new URLSearchParams()
if (params?.series !== undefined) searchParams.set('series', String(params.series))
if (params?.seriesSlug) {
searchParams.set('series_slug', params.seriesSlug)
}
if (params?.slot !== undefined) searchParams.set('slot', String(params.slot))
if (params?.group !== undefined) searchParams.set('group', String(params.group))
@ -670,7 +680,7 @@ export class EntityAdapter extends BaseAdapter {
/**
* Clears entity cache
*/
clearEntityCache(type?: 'weapons' | 'characters' | 'summons' | 'weapon_keys') {
clearEntityCache(type?: 'weapons' | 'characters' | 'summons' | 'weapon_keys' | 'weapon_series') {
if (type) {
this.clearCache(`/${type}`)
} else {
@ -679,6 +689,7 @@ export class EntityAdapter extends BaseAdapter {
this.clearCache('/characters')
this.clearCache('/summons')
this.clearCache('/weapon_keys')
this.clearCache('/weapon_series')
}
}
@ -1176,6 +1187,87 @@ export class EntityAdapter extends BaseAdapter {
body: { wiki_pages: wikiPages }
})
}
// ============================================
// Weapon Series Methods
// ============================================
/**
* Gets all weapon series ordered by display order
* Returns minimal view (id, name, slug, order)
*/
async getWeaponSeriesList(): Promise<WeaponSeries[]> {
return this.request<WeaponSeries[]>('/weapon_series', {
method: 'GET',
cacheTTL: 3600000 // Cache for 1 hour - rarely changes
})
}
/**
* Gets a single weapon series by ID or slug
* Returns full view with boolean flags and weapon count
*
* @param idOrSlug - UUID or slug (e.g., 'dark-opus')
*/
async getWeaponSeries(idOrSlug: string): Promise<WeaponSeries> {
return this.request<WeaponSeries>(`/weapon_series/${idOrSlug}`, {
method: 'GET',
cacheTTL: 3600000 // Cache for 1 hour
})
}
/**
* Creates a new weapon series
* Requires editor role (>= 7)
*/
async createWeaponSeries(payload: CreateWeaponSeriesPayload): Promise<WeaponSeries> {
const result = await this.request<WeaponSeries>('/weapon_series', {
method: 'POST',
body: { weapon_series: payload }
})
// Clear weapon series cache
this.clearCache('/weapon_series')
return result
}
/**
* Updates an existing weapon series
* Requires editor role (>= 7)
*
* @param id - Weapon series UUID
* @param payload - Fields to update
*/
async updateWeaponSeries(id: string, payload: UpdateWeaponSeriesPayload): Promise<WeaponSeries> {
const result = await this.request<WeaponSeries>(`/weapon_series/${id}`, {
method: 'PATCH',
body: { weapon_series: payload }
})
// Clear weapon series caches
this.clearCache('/weapon_series')
return result
}
/**
* Deletes a weapon series
* Requires editor role (>= 7)
* Will fail if series has associated weapons
*
* @param id - Weapon series UUID
*/
async deleteWeaponSeries(id: string): Promise<void> {
await this.request<void>(`/weapon_series/${id}`, {
method: 'DELETE'
})
// Clear weapon series cache
this.clearCache('/weapon_series')
}
/**
* Clears weapon series cache
*/
clearWeaponSeriesCache() {
this.clearCache('/weapon_series')
}
}
/**

View file

@ -167,8 +167,8 @@ export interface SearchFilters {
/** Filter by secondary proficiency (characters only) */
proficiency2?: number[] | undefined
/** Filter by weapon series */
series?: number[] | undefined
/** Filter by weapon series (accepts series IDs or slugs) */
series?: string[] | undefined
/** Filter by character season (1=Standard, 2=Valentine, etc.) */
season?: number[] | undefined

View file

@ -82,10 +82,39 @@ export const entityQueries = {
*/
weaponKeys: (params?: WeaponKeyQueryParams) =>
queryOptions({
queryKey: ['weaponKeys', params?.series, params?.slot, params?.group] as const,
queryKey: ['weaponKeys', params?.seriesSlug, params?.slot, params?.group] as const,
queryFn: () => entityAdapter.getWeaponKeys(params),
staleTime: 1000 * 60 * 60, // 1 hour - weapon keys rarely change
gcTime: 1000 * 60 * 60 * 24 // 24 hours
}),
/**
* All weapon series query options
* Returns list ordered by display order
*
* @returns Query options for fetching all weapon series
*/
weaponSeriesList: () =>
queryOptions({
queryKey: ['weaponSeries', 'list'] as const,
queryFn: () => entityAdapter.getWeaponSeriesList(),
staleTime: 1000 * 60 * 60, // 1 hour - rarely changes
gcTime: 1000 * 60 * 60 * 24 // 24 hours
}),
/**
* Single weapon series query options
*
* @param idOrSlug - Weapon series UUID or slug (e.g., 'dark-opus')
* @returns Query options for fetching a single weapon series with full details
*/
weaponSeries: (idOrSlug: string) =>
queryOptions({
queryKey: ['weaponSeries', idOrSlug] as const,
queryFn: () => entityAdapter.getWeaponSeries(idOrSlug),
enabled: !!idOrSlug,
staleTime: 1000 * 60 * 60, // 1 hour
gcTime: 1000 * 60 * 60 * 24 // 24 hours
})
}
@ -114,5 +143,8 @@ export const entityKeys = {
summons: () => ['summon'] as const,
summon: (id: string) => [...entityKeys.summons(), id] as const,
weaponKeys: (params?: WeaponKeyQueryParams) =>
['weaponKeys', params?.series, params?.slot, params?.group] as const
['weaponKeys', params?.seriesSlug, params?.slot, params?.group] as const,
weaponSeriesList: () => ['weaponSeries', 'list'] as const,
weaponSeries: (idOrSlug: string) => ['weaponSeries', idOrSlug] as const,
allWeaponSeries: () => ['weaponSeries'] as const
}