This commit is contained in:
korjik 2026-04-21 20:39:32 -07:00
parent 83fc6f0495
commit 6527b8b0f5
2 changed files with 71 additions and 2 deletions

View file

@ -208,6 +208,41 @@ class OpenAI {
})
}
normalizeDetectionResultBooks(resultBooks, books) {
if (!Array.isArray(resultBooks)) {
throw new Error('OpenAI returned an invalid books payload')
}
const expectedIds = new Set(books.map((book) => book.id))
const resultBooksById = new Map()
resultBooks.forEach((book) => {
if (!expectedIds.has(book?.id)) {
Logger.warn(`[OpenAI] Ignoring unknown book id "${book?.id}" in series-detection response`)
return
}
if (resultBooksById.has(book.id)) {
Logger.warn(`[OpenAI] Ignoring duplicate book id "${book.id}" in series-detection response`)
return
}
resultBooksById.set(book.id, book)
})
return books.map((book) => {
if (resultBooksById.has(book.id)) {
return resultBooksById.get(book.id)
}
Logger.warn(`[OpenAI] Missing series-detection result for book "${book.id}" - skipping assignment`)
return {
id: book.id,
seriesName: null,
sequence: null,
reason: 'Skipped because OpenAI omitted this book from the response'
}
})
}
validateSeriesOrderPayload(payload, books) {
const resultBooks = payload?.books
this.validateBookIds(resultBooks, books)
@ -233,8 +268,7 @@ class OpenAI {
}
validateSeriesDetectionPayload(payload, books) {
const resultBooks = payload?.books
this.validateBookIds(resultBooks, books)
const resultBooks = this.normalizeDetectionResultBooks(payload?.books, books)
const seriesSequences = new Map()
return resultBooks.map((book) => {

View file

@ -96,5 +96,40 @@ describe('OpenAI', () => {
expect(result[0].sequence).to.equal(null)
expect(result[0].reason).to.contain('skipped due to missing series name')
})
it('ignores unknown ids and backfills missing ids', () => {
const result = openAI.validateSeriesDetectionPayload(
{
books: [
{ id: 'z', seriesName: 'Wrong Series', sequence: '9' },
{ id: 'a', seriesName: 'Series Name', sequence: '1' }
]
},
[{ id: 'a' }, { id: 'b' }]
)
expect(result).to.have.length(2)
expect(result[0].id).to.equal('a')
expect(result[0].seriesName).to.equal('Series Name')
expect(result[1].id).to.equal('b')
expect(result[1].seriesName).to.equal(null)
expect(result[1].reason).to.contain('omitted this book')
})
it('ignores duplicate ids in detection payload', () => {
const result = openAI.validateSeriesDetectionPayload(
{
books: [
{ id: 'a', seriesName: 'Series Name', sequence: '1' },
{ id: 'a', seriesName: 'Other Series', sequence: '2' }
]
},
[{ id: 'a' }]
)
expect(result).to.have.length(1)
expect(result[0].seriesName).to.equal('Series Name')
expect(result[0].sequence).to.equal('1')
})
})
})