149 lines
4.4 KiB
TypeScript
149 lines
4.4 KiB
TypeScript
import { History, Question } from "@prisma/client";
|
|
|
|
import { prisma } from "../../backend/database/prisma";
|
|
import { QualityIndicators } from "../../backend/platforms";
|
|
import { builder } from "../builder";
|
|
import { PlatformObj } from "./platforms";
|
|
|
|
export const QualityIndicatorsObj = builder
|
|
.objectRef<QualityIndicators>("QualityIndicators")
|
|
.implement({
|
|
description: "Various indicators of the question's quality",
|
|
fields: (t) => {
|
|
const maybeIntField = (name: keyof QualityIndicators) =>
|
|
t.int({
|
|
nullable: true,
|
|
resolve: (parent) =>
|
|
parent[name] === undefined ? undefined : Number(parent[name]),
|
|
});
|
|
const maybeFloatField = (name: keyof QualityIndicators) =>
|
|
t.float({
|
|
nullable: true,
|
|
resolve: (parent) =>
|
|
parent[name] === undefined ? undefined : Number(parent[name]),
|
|
});
|
|
|
|
return {
|
|
stars: t.exposeInt("stars", {
|
|
description: "0 to 5",
|
|
}),
|
|
numForecasts: maybeIntField("numforecasts"),
|
|
numForecasters: maybeIntField("numforecasters"),
|
|
volume: maybeFloatField("volume"),
|
|
// yesBid: maybeNumberField("yes_bid"),
|
|
// yesAsk: maybeNumberField("yes_ask"),
|
|
spread: maybeFloatField("spread"),
|
|
sharesVolume: maybeFloatField("shares_volume"),
|
|
openInterest: maybeFloatField("open_interest"),
|
|
liquidity: maybeFloatField("liquidity"),
|
|
tradeVolume: maybeFloatField("trade_volume"),
|
|
};
|
|
},
|
|
});
|
|
|
|
export const ProbabilityOptionObj = builder
|
|
.objectRef<{ name: string; probability: number }>("ProbabilityOption")
|
|
.implement({
|
|
fields: (t) => ({
|
|
name: t.exposeString("name", { nullable: true }),
|
|
probability: t.exposeFloat("probability", {
|
|
description: "0 to 1",
|
|
nullable: true,
|
|
}),
|
|
}),
|
|
});
|
|
|
|
const QuestionShapeInterface = builder
|
|
.interfaceRef<Question | History>("QuestionShape")
|
|
.implement({
|
|
fields: (t) => ({
|
|
title: t.exposeString("title"),
|
|
description: t.exposeString("description"),
|
|
url: t.exposeString("url", {
|
|
description:
|
|
"Non-unique, a very small number of platforms have a page for more than one prediction",
|
|
}),
|
|
platform: t.field({
|
|
type: PlatformObj,
|
|
resolve: (parent) => parent.platform,
|
|
}),
|
|
timestamp: t.field({
|
|
type: "Date",
|
|
description: "Timestamp at which metaforecast fetched the question",
|
|
resolve: (parent) => parent.timestamp,
|
|
}),
|
|
qualityIndicators: t.field({
|
|
type: QualityIndicatorsObj,
|
|
resolve: (parent) =>
|
|
parent.qualityindicators as any as QualityIndicators,
|
|
}),
|
|
options: t.field({
|
|
type: [ProbabilityOptionObj],
|
|
resolve: ({ options }) => {
|
|
if (!Array.isArray(options)) {
|
|
return [];
|
|
}
|
|
return options as any[];
|
|
},
|
|
}),
|
|
}),
|
|
});
|
|
|
|
export const HistoryObj = builder.prismaObject("History", {
|
|
findUnique: (history) => ({ pk: history.pk }),
|
|
interfaces: [QuestionShapeInterface],
|
|
fields: (t) => ({
|
|
id: t.exposeID("pk", {
|
|
description: "History items are identified by their integer ids",
|
|
}),
|
|
questionId: t.exposeID("id", {
|
|
description: "Unique string which identifies the question",
|
|
}),
|
|
}),
|
|
});
|
|
|
|
export const QuestionObj = builder.prismaObject("Question", {
|
|
findUnique: (question) => ({ id: question.id }),
|
|
interfaces: [QuestionShapeInterface],
|
|
fields: (t) => ({
|
|
id: t.exposeID("id", {
|
|
description: "Unique string which identifies the question",
|
|
}),
|
|
visualization: t.string({
|
|
resolve: (parent) => (parent.extra as any)?.visualization, // used for guesstimate only, see searchGuesstimate.ts
|
|
nullable: true,
|
|
}),
|
|
history: t.relation("history", {}),
|
|
}),
|
|
});
|
|
|
|
builder.queryField("questions", (t) =>
|
|
t.prismaConnection(
|
|
{
|
|
type: "Question",
|
|
cursor: "id",
|
|
maxSize: 1000,
|
|
resolve: (query) => prisma.question.findMany({ ...query }),
|
|
},
|
|
{},
|
|
{}
|
|
)
|
|
);
|
|
|
|
builder.queryField("question", (t) =>
|
|
t.field({
|
|
type: QuestionObj,
|
|
description: "Look up a single question by its id",
|
|
args: {
|
|
id: t.arg({ type: "ID", required: true }),
|
|
},
|
|
resolve: async (parent, args) => {
|
|
return await prisma.question.findUnique({
|
|
where: {
|
|
id: String(args.id),
|
|
},
|
|
});
|
|
},
|
|
})
|
|
);
|