fix(shop): make purchase resolve offers the same way the view does
`purchase` listed a shop's offers with no ordering while `getShopView` orders by `sortOrder`, so the two paths answered "which offer does this key mean" by different rules, one of them at the database's discretion. Harmless today because item and bag keys are disjoint, but not a difference worth keeping. The faction lookup behind requirement labels also read every faction while the condition engine only matches enabled ones, so a gate on a disabled faction would have shown that faction's name next to a requirement the engine treats as unmeetable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -117,11 +117,16 @@ export class ShopService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// One read for the whole view: every reputation requirement needs a
|
// One read for the whole view: every reputation requirement needs a
|
||||||
// display name, and offers commonly gate on the same faction.
|
// display name, and offers commonly gate on the same faction. Restricted
|
||||||
|
// to enabled factions because that is what the condition engine evaluates
|
||||||
|
// against -- naming a faction the engine treats as absent would describe a
|
||||||
|
// requirement that can never be met.
|
||||||
const factionNames = new Map(
|
const factionNames = new Map(
|
||||||
(await this.dataSource.getRepository(ReputationFaction).find()).map(
|
(
|
||||||
(faction) => [faction.key, faction.name],
|
await this.dataSource
|
||||||
),
|
.getRepository(ReputationFaction)
|
||||||
|
.find({ where: { enabled: true } })
|
||||||
|
).map((faction) => [faction.key, faction.name]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const context = { characterId, npcId };
|
const context = { characterId, npcId };
|
||||||
@@ -205,6 +210,9 @@ export class ShopService {
|
|||||||
const offers = await manager.getRepository(ShopOffer).find({
|
const offers = await manager.getRepository(ShopOffer).find({
|
||||||
where: { shopId: shop.id, enabled: true },
|
where: { shopId: shop.id, enabled: true },
|
||||||
relations: { itemDefinition: true, lootBagDefinition: true },
|
relations: { itemDefinition: true, lootBagDefinition: true },
|
||||||
|
// Same order as the view: both paths answer "which offer does this key
|
||||||
|
// mean", so neither may answer it from an arbitrary row order.
|
||||||
|
order: { sortOrder: 'ASC' },
|
||||||
});
|
});
|
||||||
let match: ShopOffer | undefined;
|
let match: ShopOffer | undefined;
|
||||||
let target: OfferTarget | undefined;
|
let target: OfferTarget | undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user