diff --git a/client/src/routes/home.tsx b/client/src/routes/home.tsx
index f3251a9..73cbe63 100644
--- a/client/src/routes/home.tsx
+++ b/client/src/routes/home.tsx
@@ -14,14 +14,16 @@ function Bundle(bundle) {
return (
{bundle.username} - {bundle.seller}
-
{bundle.total} {bundle.currency}
+
{bundle.items.length} items - {bundle.total} {bundle.currency}
Ships: {bundle.mentionsAustralia && 'AU'} {bundle.mentionsWorldwide && 'WORLD'}
{bundle.items.map(i => (
))}
diff --git a/client/src/style/index.less b/client/src/style/index.less
index 61c32c0..eca50c8 100644
--- a/client/src/style/index.less
+++ b/client/src/style/index.less
@@ -28,6 +28,7 @@ html, body {
.bundle {
flex: 1;
+ padding-right: 1em;
}
}
diff --git a/server/global.d.ts b/server/global.d.ts
index d29ff47..6052638 100644
--- a/server/global.d.ts
+++ b/server/global.d.ts
@@ -4,6 +4,7 @@ type UUID = string;
type DiscogsName = string;
type DiscogsListing = number;
+type DiscogsRelease = number;
type DiscogsSeller = number;
type BundleCandidate = {
diff --git a/server/index.ts b/server/index.ts
index f8ce6f0..1ada495 100644
--- a/server/index.ts
+++ b/server/index.ts
@@ -14,38 +14,9 @@ async function start(log) {
const prisma = new PrismaClient();
const pg = pgService(log, prisma);
const discogs = discogsService(log, pg);
- const api = createApi(log, pg);
-
- const usernames = [
- 'vanderbabe',
- 'margh',
- 'jmcdermid1',
- ];
-
- async function populateUserListings(user) {
- log.info(user);
- const wants = await discogs.wantlist(user);
-
- // const latest = await discogs.wantlistLatest(user);
- // if (wants.length !== latest.length)
- log.info({ username: user.discogs, wantCount: wants.length });
-
- return Promise.mapSeries(wants, async want => {
- const listings = await discogs.listings(want);
- const populated = listings.filter(l => l);
- log.info({ id: want.id, release: want.release, populated: populated.length, total: listings.length });
- return populated;
- });
- }
-
- // await Promise.mapSeries(usernames, async u => {
- // const user = await discogs.user(u)
- // return populateUserListings(user);
- // });
+ const api = createApi(log, pg, discogs);
await api.listen();
-
- // return getBundles();
}
async function run() {
diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma
index 8f02d3a..fea6d9f 100644
--- a/server/prisma/schema.prisma
+++ b/server/prisma/schema.prisma
@@ -25,9 +25,9 @@ model Listing {
model User {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
- discogs String? @unique
name String @default("unknown")
- data Json
+ discogs String? @unique
+ data Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
diff --git a/server/src/api.ts b/server/src/api.ts
index 87a3fac..aea5030 100644
--- a/server/src/api.ts
+++ b/server/src/api.ts
@@ -2,13 +2,14 @@ import express from 'express';
import http from 'http';
import cors from 'cors';
import { groupBy } from 'lodash';
+import Bluebird from 'bluebird';
import type Log from 'bunyan';
import { Pg } from './pg';
-import type { Listing, User, Prisma } from '@prisma/client';
+import type { Listing, User, Want, Prisma } from '@prisma/client';
-export default function createApi(log: Log, pg: Pg) {
+export default function createApi(log: Log, pg: Pg, discogs) {
const PORT = 41337;
const app = express();
@@ -32,7 +33,7 @@ export default function createApi(log: Log, pg: Pg) {
currency: l.data.original_price.curr_abbr,
condition: l.data.condition,
uri: l.data.uri,
- user: l.want.user.discogs,
+ user: l.want.user.name,
}));
const shipping = b[0]?.data.seller.shipping;
@@ -57,6 +58,24 @@ export default function createApi(log: Log, pg: Pg) {
}
+ async function populateUserListings(user: User) {
+ log.info(user);
+
+ const wants = await discogs.wantlist(user);
+
+ // const latest = await discogs.wantlistLatest(user);
+ // if (wants.length !== latest.length)
+
+ log.info({ username: user.discogs, wantCount: wants.length });
+
+ return Bluebird.mapSeries(wants, async want => {
+ const listings = await discogs.listings(want);
+ const populated = listings.filter(l => l);
+ log.info({ id: want.id, release: want.release, populated: populated.length, total: listings.length });
+ return populated;
+ });
+ }
+
function listen() {
return new Promise((resolve, reject) => {
server.on('error', err => {
@@ -70,6 +89,7 @@ export default function createApi(log: Log, pg: Pg) {
}
app.use(cors());
+ app.use(express.json())
app.get('/bundles', async (req, res, next) => {
const bundles = await getBundles();
@@ -77,6 +97,38 @@ export default function createApi(log: Log, pg: Pg) {
res.json(bundles);
})
+ app.get('/user/:id/offers', async function userOffersGet(req, res, next) {
+ const { id } = req.params;
+ const user = await pg.userFindId(id);
+ res.json(user);
+ });
+
+ app.post('/user', async function usersPost(req, res, next) {
+ const { name } = req.body;
+ const user = await pg.userUpsert(null, name, null);
+ res.json(user);
+ });
+
+ app.post('/user/populate', async function usersPopulate(req, res, next) {
+ const { userId } = req.body;
+ const user = await pg.userFindId(userId);
+ const listings = await populateUserListings(user);
+ res.json(listings);
+ });
+
+ app.post('/want', async function wantPost(req, res, next) {
+ const { userId, releaseId } = req.body;
+ const user = await pg.userFindId(userId);
+ const release = await discogs.release(releaseId);
+ const want = await pg.wantUpsert(release, user);
+ return res.json(want);
+ });
+
+ app.use(function errorHandler(req, res, next, error) {
+ log.warn(error);
+ res.status(500).send({ error });
+ });
+
return {
app,
listen,
diff --git a/server/src/discogs.ts b/server/src/discogs.ts
index 44fd437..9caeff3 100644
--- a/server/src/discogs.ts
+++ b/server/src/discogs.ts
@@ -35,13 +35,19 @@ export default function discogs(log: Log, pg: Pg) {
const user = await pg.userFindName(discogs);
if (user) return user;
log.debug('fetching user', discogs);
- const res = await api.get(`${apiBase}/users/${discogs}`);
- return pg.userUpsert(res.data);
+ const { data } = await api.get(`${apiBase}/users/${discogs}`);
+ return pg.userUpsert(data.username, data.username, data);
}
async function wantlist(user: User): Promise {
const stored = await pg.userWants(user);
if (stored.length) return stored;
+
+ if (!user.discogs) {
+ log.error(user, 'attempted to fetch wantlist of non discogs user');
+ throw new Error('User is not associated with a discogs account');
+ }
+
return wantlistLatest(user);
}
@@ -51,6 +57,11 @@ export default function discogs(log: Log, pg: Pg) {
return Bluebird.mapSeries(wants, async r => pg.wantUpsert(r, user));
}
+ async function release(id: DiscogsRelease): Promise {
+ const { data } = await api.get(`${apiBase}/releases/${id}`);
+ return data;
+ }
+
async function inventory(user: string) {
const res = await api.get(`${apiBase}/users/${user}/inventory`);
return res.data.listings;
@@ -91,5 +102,6 @@ export default function discogs(log: Log, pg: Pg) {
inventory,
listings,
listing,
+ release,
};
}
\ No newline at end of file
diff --git a/server/src/pg.ts b/server/src/pg.ts
index ca23502..5083366 100644
--- a/server/src/pg.ts
+++ b/server/src/pg.ts
@@ -5,7 +5,7 @@ import * as Bluebird from 'bluebird';
export interface Pg {
userFindId: (id: UUID) => Promise,
userFindName: (name: DiscogsName) => Promise,
- userUpsert: (user: User) => Promise,
+ userUpsert: (discogs: DiscogsName | null, name: string, data: any) => Promise,
userWants: (user: User) => Promise,
wantUpsert: (want: Want, user: User) => Promise,
@@ -17,7 +17,7 @@ export interface Pg {
}
export default function createPg(log: Log, prisma: PrismaClient): Pg {
- async function userFindId(id) {
+ async function userFindId(id: UUID) {
return prisma.user.findUnique({ where: { id }});
}
@@ -29,18 +29,23 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
return prisma.want.findMany({ where: { userId: user.id }});
}
- async function userUpsert(user) {
- const data = {
- discogs: user.username,
- data: user as Prisma.JsonObject,
+ async function userUpsert(discogs: DiscogsName | null, name: string, data: any) {
+ const insert = {
+ discogs,
+ name,
+ data,
};
- return prisma.user.upsert({
+ if (discogs) return prisma.user.upsert({
where: {
- discogs: user.username,
+ discogs,
},
- update: data,
- create: data,
+ update: insert,
+ create: insert,
+ });
+
+ return prisma.user.create({
+ data: { name },
});
}
@@ -111,7 +116,7 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
select
seller, count(distinct("wantId")), array_agg(id) as listings
from
- "Listing"
+ listings
group by
seller
order by