use batch endpoints for collection add operations

single request instead of one per item
This commit is contained in:
Justin Edmund 2025-12-03 09:03:47 -08:00
parent c37c4f0101
commit debf502a6c

View file

@ -102,12 +102,22 @@ export class CollectionAdapter extends BaseAdapter {
} }
/** /**
* Adds multiple characters to the collection * Adds multiple characters to the collection in a single batch request
* Makes parallel requests for each character
*/ */
async addCharacters(inputs: CollectionCharacterInput[]): Promise<CollectionCharacter[]> { async addCharacters(inputs: CollectionCharacterInput[]): Promise<CollectionCharacter[]> {
const results = await Promise.all(inputs.map((input) => this.addCharacter(input))) if (inputs.length === 0) return []
return results
const response = await this.request<{
characters: CollectionCharacter[]
meta: { created: number; skipped: number; errors: any[] }
}>('/collection/characters/batch', {
method: 'POST',
body: {
collectionCharacters: inputs
}
})
return response.characters
} }
/** /**
@ -167,15 +177,20 @@ export class CollectionAdapter extends BaseAdapter {
params: CollectionListParams = {} params: CollectionListParams = {}
): Promise<PaginatedResponse<CollectionWeapon>> { ): Promise<PaginatedResponse<CollectionWeapon>> {
const response = await this.request<{ const response = await this.request<{
weapons: CollectionWeapon[] weapons?: CollectionWeapon[]
collectionWeapons?: CollectionWeapon[]
meta: { count: number; totalPages: number; perPage: number; currentPage: number } meta: { count: number; totalPages: number; perPage: number; currentPage: number }
}>(`/users/${userId}/collection/weapons`, { }>(`/users/${userId}/collection/weapons`, {
method: 'GET', method: 'GET',
query: params query: params
}) })
// Handle both 'weapons' and 'collectionWeapons' response keys
// (backend currently returns 'collectionWeapons', should return 'weapons')
const weapons = response.weapons ?? response.collectionWeapons ?? []
return { return {
results: response.weapons, results: weapons,
page: response.meta.currentPage, page: response.meta.currentPage,
total: response.meta.count, total: response.meta.count,
totalPages: response.meta.totalPages, totalPages: response.meta.totalPages,
@ -196,26 +211,33 @@ export class CollectionAdapter extends BaseAdapter {
} }
/** /**
* Adds multiple weapons to the collection with quantity support * Adds multiple weapons to the collection in a single batch request
* Each quantity > 1 creates multiple collection entries * Handles quantity expansion - each quantity > 1 creates multiple entries
*/ */
async addWeapons( async addWeapons(
inputs: Array<CollectionWeaponInput & { quantity?: number }> inputs: Array<CollectionWeaponInput & { quantity?: number }>
): Promise<CollectionWeapon[]> { ): Promise<CollectionWeapon[]> {
// Expand inputs based on quantity // Expand inputs based on quantity
// Note: We create individual objects to ensure unique request IDs for deduplication
const expanded = inputs.flatMap((input) => { const expanded = inputs.flatMap((input) => {
const count = input.quantity ?? 1 const count = input.quantity ?? 1
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { quantity, ...rest } = input const { quantity, ...rest } = input
return Array.from({ length: count }, () => ({ ...rest })) as CollectionWeaponInput[] return Array.from({ length: count }, () => ({ ...rest })) as CollectionWeaponInput[]
}) })
// Execute sequentially to avoid request deduplication issues
const results: CollectionWeapon[] = [] if (expanded.length === 0) return []
for (const input of expanded) {
results.push(await this.addWeapon(input)) const response = await this.request<{
} weapons: CollectionWeapon[]
return results meta: { created: number; errors: any[] }
}>('/collection/weapons/batch', {
method: 'POST',
body: {
collectionWeapons: expanded
}
})
return response.weapons
} }
/** /**
@ -252,15 +274,20 @@ export class CollectionAdapter extends BaseAdapter {
params: CollectionListParams = {} params: CollectionListParams = {}
): Promise<PaginatedResponse<CollectionSummon>> { ): Promise<PaginatedResponse<CollectionSummon>> {
const response = await this.request<{ const response = await this.request<{
summons: CollectionSummon[] summons?: CollectionSummon[]
collectionSummons?: CollectionSummon[]
meta: { count: number; totalPages: number; perPage: number; currentPage: number } meta: { count: number; totalPages: number; perPage: number; currentPage: number }
}>(`/users/${userId}/collection/summons`, { }>(`/users/${userId}/collection/summons`, {
method: 'GET', method: 'GET',
query: params query: params
}) })
// Handle both 'summons' and 'collectionSummons' response keys
// (backend currently returns 'collectionSummons', should return 'summons')
const summons = response.summons ?? response.collectionSummons ?? []
return { return {
results: response.summons, results: summons,
page: response.meta.currentPage, page: response.meta.currentPage,
total: response.meta.count, total: response.meta.count,
totalPages: response.meta.totalPages, totalPages: response.meta.totalPages,
@ -281,26 +308,33 @@ export class CollectionAdapter extends BaseAdapter {
} }
/** /**
* Adds multiple summons to the collection with quantity support * Adds multiple summons to the collection in a single batch request
* Each quantity > 1 creates multiple collection entries * Handles quantity expansion - each quantity > 1 creates multiple entries
*/ */
async addSummons( async addSummons(
inputs: Array<CollectionSummonInput & { quantity?: number }> inputs: Array<CollectionSummonInput & { quantity?: number }>
): Promise<CollectionSummon[]> { ): Promise<CollectionSummon[]> {
// Expand inputs based on quantity // Expand inputs based on quantity
// Note: We create individual objects to ensure unique request IDs for deduplication
const expanded = inputs.flatMap((input) => { const expanded = inputs.flatMap((input) => {
const count = input.quantity ?? 1 const count = input.quantity ?? 1
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { quantity, ...rest } = input const { quantity, ...rest } = input
return Array.from({ length: count }, () => ({ ...rest })) as CollectionSummonInput[] return Array.from({ length: count }, () => ({ ...rest })) as CollectionSummonInput[]
}) })
// Execute sequentially to avoid request deduplication issues
const results: CollectionSummon[] = [] if (expanded.length === 0) return []
for (const input of expanded) {
results.push(await this.addSummon(input)) const response = await this.request<{
} summons: CollectionSummon[]
return results meta: { created: number; errors: any[] }
}>('/collection/summons/batch', {
method: 'POST',
body: {
collectionSummons: expanded
}
})
return response.summons
} }
/** /**