Filter trade counts to the last 6 months
This commit is contained in:
parent
62952b80dd
commit
3984f9c9ba
2 changed files with 43 additions and 56 deletions
|
@ -535,55 +535,6 @@ const buildItemAllOccupiedZonesLoader = (db) =>
|
|||
});
|
||||
});
|
||||
|
||||
const buildItemTradeCountsLoader = (db) =>
|
||||
new DataLoader(
|
||||
async (itemIdOwnedPairs) => {
|
||||
const qs = itemIdOwnedPairs
|
||||
.map((_) => "(closet_hangers.item_id = ? AND closet_hangers.owned = ?)")
|
||||
.join(" OR ");
|
||||
const values = itemIdOwnedPairs
|
||||
.map(({ itemId, isOwned }) => [itemId, isOwned])
|
||||
.flat();
|
||||
const [rows, _] = await db.execute(
|
||||
`
|
||||
SELECT
|
||||
closet_hangers.item_id AS item_id, closet_hangers.owned AS is_owned,
|
||||
count(DISTINCT closet_hangers.user_id) AS users_count
|
||||
FROM closet_hangers
|
||||
INNER JOIN users ON users.id = closet_hangers.user_id
|
||||
LEFT JOIN closet_lists ON closet_lists.id = closet_hangers.list_id
|
||||
WHERE (
|
||||
(${qs})
|
||||
AND (
|
||||
(closet_hangers.list_id IS NOT NULL AND closet_lists.visibility >= 2)
|
||||
OR (
|
||||
closet_hangers.list_id IS NULL AND closet_hangers.owned = 1
|
||||
AND users.owned_closet_hangers_visibility >= 2
|
||||
)
|
||||
OR (
|
||||
closet_hangers.list_id IS NULL AND closet_hangers.owned = 0
|
||||
AND users.wanted_closet_hangers_visibility >= 2
|
||||
)
|
||||
)
|
||||
)
|
||||
GROUP BY closet_hangers.item_id, closet_hangers.owned;
|
||||
`,
|
||||
values
|
||||
);
|
||||
|
||||
const entities = rows.map(normalizeRow);
|
||||
|
||||
return itemIdOwnedPairs.map(({ itemId, isOwned }) => {
|
||||
// NOTE: There may be no matching row, if there are 0 such trades.
|
||||
const entity = entities.find(
|
||||
(e) => e.itemId === itemId && Boolean(e.isOwned) === isOwned
|
||||
);
|
||||
return entity ? entity.usersCount : 0;
|
||||
});
|
||||
},
|
||||
{ cacheKeyFn: ({ itemId, isOwned }) => `${itemId}-${isOwned}` }
|
||||
);
|
||||
|
||||
const buildItemTradesLoader = (db, loaders) =>
|
||||
new DataLoader(
|
||||
async (itemIdOwnedPairs) => {
|
||||
|
@ -1261,7 +1212,6 @@ function buildLoaders(db) {
|
|||
db
|
||||
);
|
||||
loaders.itemAllOccupiedZonesLoader = buildItemAllOccupiedZonesLoader(db);
|
||||
loaders.itemTradeCountsLoader = buildItemTradeCountsLoader(db);
|
||||
loaders.itemTradesLoader = buildItemTradesLoader(db, loaders);
|
||||
loaders.petTypeLoader = buildPetTypeLoader(db, loaders);
|
||||
loaders.petTypeBySpeciesAndColorLoader = buildPetTypeBySpeciesAndColorLoader(
|
||||
|
|
|
@ -29,6 +29,7 @@ const typeDefs = gql`
|
|||
currentUserWantsThis: Boolean! @cacheControl(scope: PRIVATE)
|
||||
|
||||
# How many users are offering/seeking this in their public trade lists.
|
||||
# Excludes users that seem relatively inactive.
|
||||
numUsersOfferingThis: Int! @cacheControl(maxAge: ${oneHour})
|
||||
numUsersSeekingThis: Int! @cacheControl(maxAge: ${oneHour})
|
||||
|
||||
|
@ -268,19 +269,55 @@ const resolvers = {
|
|||
return closetHangers.some((h) => h.itemId === id && !h.owned);
|
||||
},
|
||||
|
||||
numUsersOfferingThis: async ({ id }, _, { itemTradeCountsLoader }) => {
|
||||
const count = await itemTradeCountsLoader.load({
|
||||
numUsersOfferingThis: async (
|
||||
{ id },
|
||||
_,
|
||||
{ itemTradesLoader, userLastTradeActivityLoader }
|
||||
) => {
|
||||
// First, get the trades themselves. TODO: Optimize into one query?
|
||||
const trades = await itemTradesLoader.load({
|
||||
itemId: id,
|
||||
isOwned: true,
|
||||
});
|
||||
return count;
|
||||
|
||||
// Then, get the last active dates for those users.
|
||||
const userIds = trades.map((t) => t.user.id);
|
||||
const lastActiveDates = await userLastTradeActivityLoader.loadMany(
|
||||
userIds
|
||||
);
|
||||
|
||||
// Finally, count how many of those dates were in the last 6 months.
|
||||
// Those trades get to be in the count!
|
||||
const sixMonthsAgo = new Date();
|
||||
sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
|
||||
const numTrades = lastActiveDates.filter((d) => d > sixMonthsAgo).length;
|
||||
|
||||
return numTrades;
|
||||
},
|
||||
numUsersSeekingThis: async ({ id }, _, { itemTradeCountsLoader }) => {
|
||||
const count = await itemTradeCountsLoader.load({
|
||||
numUsersSeekingThis: async (
|
||||
{ id },
|
||||
_,
|
||||
{ itemTradesLoader, userLastTradeActivityLoader }
|
||||
) => {
|
||||
// First, get the trades themselves. TODO: Optimize into one query?
|
||||
const trades = await itemTradesLoader.load({
|
||||
itemId: id,
|
||||
isOwned: false,
|
||||
});
|
||||
return count;
|
||||
|
||||
// Then, get the last active dates for those users.
|
||||
const userIds = trades.map((t) => t.user.id);
|
||||
const lastActiveDates = await userLastTradeActivityLoader.loadMany(
|
||||
userIds
|
||||
);
|
||||
|
||||
// Finally, count how many of those dates were in the last 6 months.
|
||||
// Those trades get to be in the count!
|
||||
const sixMonthsAgo = new Date();
|
||||
sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
|
||||
const numTrades = lastActiveDates.filter((d) => d > sixMonthsAgo).length;
|
||||
|
||||
return numTrades;
|
||||
},
|
||||
|
||||
tradesOffering: async ({ id }, _, { itemTradesLoader }) => {
|
||||
|
|
Loading…
Reference in a new issue