-
Notifications
You must be signed in to change notification settings - Fork 1
list an item #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
list an item #13
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import { optional } from 'zod'; | ||
| import * as mongo from '../../util/mongo'; | ||
| import type * as Types from './market.types'; | ||
| import * as Types from './market.types'; | ||
|
|
||
| export const Market = mongo.createModel<Types.MarketDocument>('Market', { | ||
| value: { type: String, required: true }, | ||
|
|
@@ -111,3 +112,14 @@ export const MarketStockSentiment = mongo.createModel<Types.MarketStockSentiment | |
| }, | ||
| confidence: { type: Number, required: true }, | ||
| }); | ||
|
|
||
| export const MarketListing = mongo.createModel<Types.MarketListingDocument>('MarketListing', { | ||
| sellerId: { type: mongo.Schema.Types.ObjectId, required: true, ref: 'Profile' }, | ||
| quantity: { type: Number, required: true }, | ||
| currency: { type: String, required: true }, | ||
| exchange: { type: String, required: true }, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MarketExchange is a model, so why is this a string? I forgot tbh, but it doesn't make sense |
||
| marketId: { type: mongo.Schema.Types.ObjectId, required: true, ref: 'MarketStock' }, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ref MarketStock? |
||
| category: { type: String, required: true }, | ||
| status: { type: String, required: true }, | ||
| expiryDate: { type: Date, required: false }, | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,13 +4,21 @@ import { z as zod } from 'zod'; | |
| import { initTRPC, inferRouterInputs, inferRouterOutputs } from '@trpc/server'; | ||
| import { customErrorFormatter, hasRole } from '../../util/rpc'; | ||
| import type { RouterContext } from '../../types'; | ||
| import { Market, MarketPair, MarketExchange } from './market.schema'; | ||
| import { Market, MarketPair, MarketExchange, MarketListing } from './market.schema'; | ||
| import { Query, getQueryInput, getQueryOutput } from '../../schema'; | ||
|
|
||
| export const z = zod; | ||
| export const t = initTRPC.context<RouterContext>().create(); | ||
| export const router = t.router; | ||
| export const procedure = t.procedure; | ||
|
|
||
| const MarketListingsInput = z.object({ | ||
| category: z.string().optional(), | ||
| status: z.string().optional(), | ||
| exchange: z.string().optional(), | ||
| sellerId: z.string().optional(), | ||
| }); | ||
|
|
||
| export const createRouter = () => | ||
| router({ | ||
| getMarket: procedure | ||
|
|
@@ -66,6 +74,36 @@ export const createRouter = () => | |
| .use(customErrorFormatter(t)) | ||
| .input(z.object({ exchangeId: z.string(), data: MarketExchange.partial() })) | ||
| .mutation(({ input, ctx }) => (ctx.app.service.Market.updateMarketExchange as any)(input, ctx)), | ||
|
|
||
| getMarketListing: procedure | ||
| .use(hasRole('guest', t)) | ||
| .use(customErrorFormatter(t)) | ||
| .input(getQueryInput(z.object({ listingId: z.string() }))) | ||
| .query(({ input, ctx }) => (ctx.app.service.Market.getMarketListing as any)(input, ctx)), | ||
|
|
||
| createMarketListing: procedure | ||
| .use(hasRole('user', t)) | ||
| .use(customErrorFormatter(t)) | ||
| .input(getQueryInput(MarketListing)) | ||
| .mutation(({ input, ctx }) => (ctx.app.service.Market.createMarketListing as any)(input, ctx)), | ||
|
|
||
| updateMarketListing: procedure | ||
| .use(hasRole('user', t)) | ||
| .use(customErrorFormatter(t)) | ||
| .input(getQueryInput(MarketListing.partial())) | ||
| .mutation(({ input, ctx }) => (ctx.app.service.Market.updateMarketListing as any)(input, ctx)), | ||
|
|
||
| deleteMarketListing: procedure | ||
| .use(hasRole('user', t)) | ||
| .use(customErrorFormatter(t)) | ||
| .input(getQueryInput(z.object({ listingId: z.string() }))) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. .input(getQueryInput(MarketListing.partial())) |
||
| .mutation(({ input, ctx }) => (ctx.app.service.Market.deleteMarketListing as any)(input, ctx)), | ||
|
|
||
| getMarketListings: procedure | ||
| .use(hasRole('guest', t)) | ||
| .use(customErrorFormatter(t)) | ||
| .input(getQueryInput(MarketListingsInput)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prefer to keep it inline |
||
| .query(({ input, ctx }) => (ctx.app.service.Market.getMarketListings as any)(input, ctx)), | ||
| }); | ||
|
|
||
| export type Router = ReturnType<typeof createRouter>; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -138,3 +138,17 @@ export const MarketStockSentiment = Entity.merge( | |
| confidence: z.number().min(0).max(1), // overall confidence level for the analysis | ||
| }) | ||
| ); | ||
|
|
||
| export const MarketListing = Entity.merge( | ||
| z.object({ | ||
| price: z.number(), | ||
| currency: z.string(), | ||
| quantity: z.number(), | ||
| exchange: z.string(), | ||
| sellerId: ObjectId, | ||
| marketId: ObjectId, | ||
| category: z.enum(['Stock', 'ChainToken']), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we need a new category to support game items, right? |
||
| status: z.enum(['Active', 'Closed', 'Withdrawn', 'Expired']), | ||
| expiryDate: z.date().optional(), | ||
| }) | ||
| ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,11 +4,14 @@ import type { | |
| Market, | ||
| MarketPair, | ||
| MarketExchange, | ||
| MarketListing, | ||
| RouterContext, | ||
| Router, | ||
| RouterInput, | ||
| RouterOutput, | ||
| } from './market.types'; | ||
| import { getFilter } from '../../util/api'; | ||
| import { ARXError } from '../../util/rpc'; | ||
|
|
||
| export class Service { | ||
| async getMarket(input: RouterInput['getMarket'], ctx: RouterContext): Promise<RouterOutput['getMarket']> { | ||
|
|
@@ -119,4 +122,79 @@ export class Service { | |
|
|
||
| return updatedMarketExchange as MarketExchange; | ||
| } | ||
|
|
||
| async getMarketListing( | ||
| input: RouterInput['getMarketListing'], | ||
| ctx: RouterContext | ||
| ): Promise<RouterOutput['getMarketListing']> { | ||
| if (!input) throw new ARXError('NO_INPUT'); | ||
| console.log('Market.Service.getMarketListing', input); | ||
|
|
||
| const listing = await ctx.app.model.MarketListing.findOne(getFilter(input)).exec(); | ||
| if (!listing) throw new Error('MarketListing not found'); | ||
|
|
||
| return listing as MarketListing; | ||
| } | ||
|
|
||
| async createMarketListing( | ||
| input: RouterInput['createMarketListing'], | ||
| ctx: RouterContext | ||
| ): Promise<RouterOutput['createMarketListing']> { | ||
| if (!input) throw new ARXError('NO_INPUT'); | ||
| console.log('Market.Service.createMarketListing', input); | ||
|
|
||
| const marketListing = await ctx.app.model.MarketListing.create(input); | ||
| return marketListing as MarketListing; | ||
| } | ||
|
|
||
| async updateMarketListing( | ||
| input: RouterInput['updateMarketListing'], | ||
| ctx: RouterContext | ||
| ): Promise<RouterOutput['updateMarketListing']> { | ||
| if (!input) throw new ARXError('NO_INPUT'); | ||
| console.log('Market.Service.updateMarketListing', input); | ||
|
|
||
| const updatedListing = await ctx.app.model.MarketListing.findByIdAndUpdate(input.where.id.equals, input.data, { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use the helper |
||
| new: true, | ||
| }) | ||
| .lean() | ||
| .exec(); | ||
| if (!updatedListing) throw new Error('MarketListing update failed'); | ||
|
|
||
| return updatedListing as MarketListing; | ||
| } | ||
|
|
||
| async deleteMarketListing( | ||
| input: RouterInput['deleteMarketListing'], | ||
| ctx: RouterContext | ||
| ): Promise<RouterOutput['deleteMarketListing']> { | ||
| if (!input) throw new ARXError('NO_INPUT'); | ||
| console.log('Market.Service.deleteMarketListing', input); | ||
|
|
||
| const deletedListing = await ctx.app.model.MarketListing.findByIdAndDelete(input.where.id.quals).lean().exec(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
| if (!deletedListing) throw new Error('MarketListing deletion failed'); | ||
|
|
||
| return deletedListing as MarketListing; | ||
| } | ||
|
|
||
| async getMarketListings( | ||
| input: { | ||
| category?: string; | ||
| status?: string; | ||
| exchange?: string; | ||
| sellerId?: string; | ||
| }, | ||
| ctx: RouterContext | ||
| ): Promise<RouterOutput['getMarketListings']> { | ||
| console.log('Market.Service.getMarketListings', input); | ||
|
|
||
| const query: Record<string, any> = {}; | ||
| if (input.category) query.category = input.category; | ||
| if (input.status) query.status = input.status; | ||
| if (input.exchange) query.exchange = input.exchange; | ||
| if (input.sellerId) query.sellerId = input.sellerId; | ||
|
|
||
| const listings = await ctx.app.model.MarketListing.find(query).lean().exec(); | ||
| return listings as MarketListing[]; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default 1 seems fine