Merge pull request #86 from quantified-uncertainty/new-questions
feat: firstSeen, new questions in graphql
This commit is contained in:
commit
31555615a9
|
@ -0,0 +1,28 @@
|
|||
-- questions
|
||||
ALTER TABLE "questions"
|
||||
ADD COLUMN "fetched" TIMESTAMP(6),
|
||||
ADD COLUMN "first_seen" TIMESTAMP(6);
|
||||
|
||||
UPDATE "questions"
|
||||
SET "fetched" = "timestamp", "first_seen" = "timestamp";
|
||||
|
||||
ALTER TABLE "questions"
|
||||
ALTER COLUMN "fetched" SET NOT NULL,
|
||||
ALTER COLUMN "first_seen" SET NOT NULL;
|
||||
|
||||
-- history
|
||||
ALTER TABLE "history"
|
||||
ADD COLUMN "fetched" TIMESTAMP(6);
|
||||
|
||||
UPDATE "history" SET "fetched" = "timestamp";
|
||||
|
||||
ALTER TABLE "history"
|
||||
ALTER COLUMN "fetched" SET NOT NULL;
|
||||
|
||||
-- populate first_seen
|
||||
UPDATE questions
|
||||
SET "first_seen" = h.fs
|
||||
FROM (
|
||||
SELECT id, MIN(fetched) AS fs FROM history GROUP BY id
|
||||
) as h
|
||||
WHERE questions.id = h.id;
|
14
prisma/migrations/20220520195517_indices/migration.sql
Normal file
14
prisma/migrations/20220520195517_indices/migration.sql
Normal file
|
@ -0,0 +1,14 @@
|
|||
-- CreateIndex
|
||||
CREATE INDEX "history_platform_idx" ON "history"("platform");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "history_fetched_idx" ON "history"("fetched");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "questions_platform_idx" ON "questions"("platform");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "questions_fetched_idx" ON "questions"("fetched");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "questions_first_seen_idx" ON "questions"("first_seen");
|
|
@ -24,24 +24,6 @@ model Dashboard {
|
|||
@@map("dashboards")
|
||||
}
|
||||
|
||||
model History {
|
||||
id String
|
||||
idref String?
|
||||
question Question? @relation(fields: [idref], references: [id], onDelete: SetNull, onUpdate: Restrict)
|
||||
title String
|
||||
url String
|
||||
platform String
|
||||
description String
|
||||
options Json
|
||||
timestamp DateTime @db.Timestamp(6)
|
||||
qualityindicators Json
|
||||
extra Json
|
||||
pk Int @id @default(autoincrement())
|
||||
|
||||
@@index([id])
|
||||
@@map("history")
|
||||
}
|
||||
|
||||
model Question {
|
||||
/// E.g. "fantasyscotus-580"
|
||||
id String @id
|
||||
|
@ -68,7 +50,9 @@ model Question {
|
|||
// }
|
||||
// ]
|
||||
options Json
|
||||
timestamp DateTime @db.Timestamp(6)
|
||||
timestamp DateTime @db.Timestamp(6) // deprecated
|
||||
fetched DateTime @db.Timestamp(6)
|
||||
firstSeen DateTime @map("first_seen") @db.Timestamp(6)
|
||||
|
||||
// {
|
||||
// "numforecasts": 120,
|
||||
|
@ -80,9 +64,33 @@ model Question {
|
|||
onFrontpage FrontpageId?
|
||||
history History[]
|
||||
|
||||
@@index([platform])
|
||||
@@index([fetched])
|
||||
@@index([firstSeen])
|
||||
@@map("questions")
|
||||
}
|
||||
|
||||
model History {
|
||||
id String
|
||||
idref String?
|
||||
question Question? @relation(fields: [idref], references: [id], onDelete: SetNull, onUpdate: Restrict)
|
||||
title String
|
||||
url String
|
||||
platform String
|
||||
description String
|
||||
options Json
|
||||
timestamp DateTime @db.Timestamp(6) // deprecated
|
||||
fetched DateTime @db.Timestamp(6)
|
||||
qualityindicators Json
|
||||
extra Json
|
||||
pk Int @id @default(autoincrement())
|
||||
|
||||
@@index([id])
|
||||
@@index([platform])
|
||||
@@index([fetched])
|
||||
@@map("history")
|
||||
}
|
||||
|
||||
model FrontpageId {
|
||||
question Question @relation(fields: [id], references: [id])
|
||||
id String @unique
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import { platforms } from "../platforms/registry";
|
||||
import { getPlatforms } from "../platforms/registry";
|
||||
import { executeJobByName } from "./jobs";
|
||||
|
||||
/* Do everything */
|
||||
export async function doEverything() {
|
||||
let jobNames = [...platforms.map((platform) => platform.name), "algolia"];
|
||||
let jobNames = [
|
||||
...getPlatforms().map((platform) => platform.name),
|
||||
"algolia",
|
||||
];
|
||||
|
||||
console.log("");
|
||||
console.log("");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { doEverything } from "../flow/doEverything";
|
||||
import { rebuildFrontpage } from "../frontpage";
|
||||
import { processPlatform } from "../platforms";
|
||||
import { platforms } from "../platforms/registry";
|
||||
import { getPlatforms } from "../platforms/registry";
|
||||
import { rebuildAlgoliaDatabase } from "../utils/algolia";
|
||||
import { sleep } from "../utils/sleep";
|
||||
|
||||
|
@ -14,7 +14,7 @@ interface Job<ArgNames extends string = ""> {
|
|||
}
|
||||
|
||||
export const jobs: Job<string>[] = [
|
||||
...platforms.map((platform) => ({
|
||||
...getPlatforms().map((platform) => ({
|
||||
name: platform.name,
|
||||
message: `Download predictions from ${platform.name}`,
|
||||
...(platform.version === "v2" ? { args: platform.fetcherArgs } : {}),
|
||||
|
|
|
@ -26,7 +26,7 @@ export async function rebuildFrontpage() {
|
|||
AND questions.description != ''
|
||||
AND JSONB_ARRAY_LENGTH(questions.options) > 0
|
||||
GROUP BY questions.id
|
||||
HAVING COUNT(DISTINCT history.timestamp) >= 7
|
||||
HAVING COUNT(DISTINCT history.fetched) >= 7
|
||||
ORDER BY RANDOM() LIMIT 50
|
||||
`;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ export const givewellopenphil: Platform = {
|
|||
const dataWithDate = data.map((datum: any) => ({
|
||||
...datum,
|
||||
platform: platformName,
|
||||
timestamp: new Date("2021-02-23"),
|
||||
// timestamp: new Date("2021-02-23"),
|
||||
}));
|
||||
return dataWithDate;
|
||||
},
|
||||
|
|
|
@ -2,9 +2,8 @@ import axios from "axios";
|
|||
|
||||
import { Question } from "@prisma/client";
|
||||
|
||||
import { prisma } from "../database/prisma";
|
||||
import { AlgoliaQuestion } from "../utils/algolia";
|
||||
import { FetchedQuestion, Platform, prepareQuestion } from "./";
|
||||
import { AlgoliaQuestion, questionToAlgoliaQuestion } from "../utils/algolia";
|
||||
import { FetchedQuestion, Platform, prepareQuestion, upsertSingleQuestion } from "./";
|
||||
|
||||
/* Definitions */
|
||||
const searchEndpoint =
|
||||
|
@ -55,10 +54,12 @@ async function search(query: string): Promise<AlgoliaQuestion[]> {
|
|||
const models: any[] = response.data.hits;
|
||||
const mappedModels: AlgoliaQuestion[] = models.map((model) => {
|
||||
const q = modelToQuestion(model);
|
||||
return {
|
||||
return questionToAlgoliaQuestion({
|
||||
...q,
|
||||
timestamp: String(q.timestamp),
|
||||
};
|
||||
fetched: new Date(),
|
||||
timestamp: new Date(),
|
||||
firstSeen: new Date(),
|
||||
});
|
||||
});
|
||||
|
||||
// filter for duplicates. Surprisingly common.
|
||||
|
@ -76,12 +77,8 @@ async function search(query: string): Promise<AlgoliaQuestion[]> {
|
|||
|
||||
const fetchQuestion = async (id: number): Promise<Question> => {
|
||||
const response = await axios({ url: `${apiEndpoint}/spaces/${id}` });
|
||||
let q = modelToQuestion(response.data);
|
||||
return await prisma.question.upsert({
|
||||
where: { id: q.id },
|
||||
create: q,
|
||||
update: q,
|
||||
});
|
||||
const q = modelToQuestion(response.data);
|
||||
return await upsertSingleQuestion(q);
|
||||
};
|
||||
|
||||
export const guesstimate: Platform & {
|
||||
|
|
|
@ -28,9 +28,14 @@ export interface QualityIndicators {
|
|||
|
||||
export type FetchedQuestion = Omit<
|
||||
Question,
|
||||
"extra" | "qualityindicators" | "timestamp" | "platform" | "options"
|
||||
| "extra"
|
||||
| "qualityindicators"
|
||||
| "fetched"
|
||||
| "firstSeen"
|
||||
| "timestamp"
|
||||
| "platform"
|
||||
| "options"
|
||||
> & {
|
||||
timestamp?: Date;
|
||||
extra?: object; // required in DB but annoying to return empty; also this is slightly stricter than Prisma's JsonValue
|
||||
options: QuestionOption[]; // stronger type than Prisma's JsonValue
|
||||
qualityindicators: Omit<QualityIndicators, "stars">; // slightly stronger type than Prisma's JsonValue
|
||||
|
@ -78,8 +83,14 @@ export type Platform<ArgNames extends string = ""> = {
|
|||
// So here we build a new type which should be ok to use both in place of prisma's Question type and as an input to its update or create methods.
|
||||
type PreparedQuestion = Omit<
|
||||
Question,
|
||||
"extra" | "qualityindicators" | "options"
|
||||
| "extra"
|
||||
| "qualityindicators"
|
||||
| "options"
|
||||
| "fetched"
|
||||
| "firstSeen"
|
||||
| "timestamp"
|
||||
> & {
|
||||
fetched: Date;
|
||||
extra: NonNullable<Question["extra"]>;
|
||||
qualityindicators: NonNullable<Question["qualityindicators"]>;
|
||||
options: NonNullable<Question["options"]>;
|
||||
|
@ -91,8 +102,8 @@ export const prepareQuestion = (
|
|||
): PreparedQuestion => {
|
||||
return {
|
||||
extra: {},
|
||||
timestamp: new Date(),
|
||||
...q,
|
||||
fetched: new Date(),
|
||||
platform: platform.name,
|
||||
qualityindicators: {
|
||||
...q.qualityindicators,
|
||||
|
@ -101,6 +112,21 @@ export const prepareQuestion = (
|
|||
};
|
||||
};
|
||||
|
||||
export const upsertSingleQuestion = async (
|
||||
q: PreparedQuestion
|
||||
): Promise<Question> => {
|
||||
return await prisma.question.upsert({
|
||||
where: { id: q.id },
|
||||
create: {
|
||||
...q,
|
||||
firstSeen: new Date(),
|
||||
timestamp: q.fetched, // deprecated
|
||||
},
|
||||
update: q,
|
||||
});
|
||||
// TODO - update history?
|
||||
};
|
||||
|
||||
export const processPlatform = async <T extends string = "">(
|
||||
platform: Platform<T>,
|
||||
args?: { [k in T]: string }
|
||||
|
@ -144,9 +170,9 @@ export const processPlatform = async <T extends string = "">(
|
|||
|
||||
for (const q of fetchedQuestions.map((q) => prepareQuestion(q, platform))) {
|
||||
if (oldIdsSet.has(q.id)) {
|
||||
// TODO - check if question has changed for better performance
|
||||
updatedQuestions.push(q);
|
||||
} else {
|
||||
// TODO - check if question has changed for better performance
|
||||
createdQuestions.push(q);
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +180,11 @@ export const processPlatform = async <T extends string = "">(
|
|||
const stats: { created?: number; updated?: number; deleted?: number } = {};
|
||||
|
||||
await prisma.question.createMany({
|
||||
data: createdQuestions,
|
||||
data: createdQuestions.map((q) => ({
|
||||
...q,
|
||||
firstSeen: new Date(),
|
||||
timestamp: q.fetched, // deprecated
|
||||
})),
|
||||
});
|
||||
stats.created = createdQuestions.length;
|
||||
|
||||
|
@ -181,6 +211,7 @@ export const processPlatform = async <T extends string = "">(
|
|||
await prisma.history.createMany({
|
||||
data: [...createdQuestions, ...updatedQuestions].map((q) => ({
|
||||
...q,
|
||||
timestamp: q.fetched, // deprecated
|
||||
idref: q.id,
|
||||
})),
|
||||
});
|
||||
|
|
|
@ -17,30 +17,43 @@ import { smarkets } from "./smarkets";
|
|||
import { wildeford } from "./wildeford";
|
||||
import { xrisk } from "./xrisk";
|
||||
|
||||
export const platforms: Platform<string>[] = [
|
||||
betfair,
|
||||
fantasyscotus,
|
||||
foretold,
|
||||
givewellopenphil,
|
||||
goodjudgment,
|
||||
goodjudgmentopen,
|
||||
guesstimate,
|
||||
infer,
|
||||
kalshi,
|
||||
manifold,
|
||||
metaculus,
|
||||
polymarket,
|
||||
predictit,
|
||||
rootclaim,
|
||||
smarkets,
|
||||
wildeford,
|
||||
xrisk,
|
||||
];
|
||||
// function instead of const array, this helps to fight circular dependencies
|
||||
export const getPlatforms = (): Platform<string>[] => {
|
||||
return [
|
||||
betfair,
|
||||
fantasyscotus,
|
||||
foretold,
|
||||
givewellopenphil,
|
||||
goodjudgment,
|
||||
goodjudgmentopen,
|
||||
guesstimate,
|
||||
infer,
|
||||
kalshi,
|
||||
manifold,
|
||||
metaculus,
|
||||
polymarket,
|
||||
predictit,
|
||||
rootclaim,
|
||||
smarkets,
|
||||
wildeford,
|
||||
xrisk,
|
||||
];
|
||||
};
|
||||
|
||||
let _nameToLabelCache: { [k: string]: string } | undefined;
|
||||
export function platformNameToLabel(name: string): string {
|
||||
if (!_nameToLabelCache) {
|
||||
_nameToLabelCache = Object.fromEntries(
|
||||
getPlatforms().map((platform) => [platform.name, platform.label])
|
||||
);
|
||||
}
|
||||
return _nameToLabelCache[name] || name;
|
||||
}
|
||||
|
||||
// get frontend-safe version of platforms data
|
||||
|
||||
export const getPlatformsConfig = (): PlatformConfig[] => {
|
||||
const platformsConfig = platforms.map((platform) => ({
|
||||
const platformsConfig = getPlatforms().map((platform) => ({
|
||||
name: platform.name,
|
||||
label: platform.label,
|
||||
color: platform.color,
|
||||
|
|
|
@ -162,7 +162,6 @@ async function processEventMarkets(event: any, ctx: Context) {
|
|||
url: "https://smarkets.com/event/" + market.event_id + market.slug,
|
||||
description: market.description,
|
||||
options,
|
||||
timestamp: new Date(),
|
||||
qualityindicators: {},
|
||||
extra: {
|
||||
contracts,
|
||||
|
|
|
@ -96,7 +96,8 @@ async function processPredictions(
|
|||
url: prediction["url"],
|
||||
description: prediction["Notes"] || "",
|
||||
options,
|
||||
timestamp: new Date(Date.parse(prediction["Prediction Date"] + "Z")),
|
||||
//// TODO - use `created` field for this
|
||||
// timestamp: new Date(Date.parse(prediction["Prediction Date"] + "Z")),
|
||||
qualityindicators: {},
|
||||
};
|
||||
return result;
|
||||
|
|
|
@ -3,16 +3,23 @@ import algoliasearch from "algoliasearch";
|
|||
import { Question } from "@prisma/client";
|
||||
|
||||
import { prisma } from "../database/prisma";
|
||||
import { platforms } from "../platforms/registry";
|
||||
import { platformNameToLabel } from "../platforms/registry";
|
||||
|
||||
let cookie = process.env.ALGOLIA_MASTER_API_KEY || "";
|
||||
const cookie = process.env.ALGOLIA_MASTER_API_KEY || "";
|
||||
const algoliaAppId = process.env.NEXT_PUBLIC_ALGOLIA_APP_ID || "";
|
||||
const client = algoliasearch(algoliaAppId, cookie);
|
||||
const index = client.initIndex("metaforecast");
|
||||
|
||||
export type AlgoliaQuestion = Omit<Question, "timestamp"> & {
|
||||
timestamp: string;
|
||||
export type AlgoliaQuestion = Omit<
|
||||
Question,
|
||||
"fetched" | "firstSeen" | "timestamp"
|
||||
> & {
|
||||
timestamp?: string; // deprecated
|
||||
fetched?: string;
|
||||
firstSeen?: string;
|
||||
optionsstringforsearch?: string;
|
||||
platformLabel: string;
|
||||
objectID: string;
|
||||
};
|
||||
|
||||
const getoptionsstringforsearch = (record: Question): string => {
|
||||
|
@ -26,23 +33,24 @@ const getoptionsstringforsearch = (record: Question): string => {
|
|||
return result;
|
||||
};
|
||||
|
||||
export const questionToAlgoliaQuestion = (
|
||||
question: Question
|
||||
): AlgoliaQuestion => {
|
||||
return {
|
||||
...question,
|
||||
fetched: question.fetched.toISOString(),
|
||||
timestamp: question.timestamp.toISOString(), // deprecated
|
||||
firstSeen: question.firstSeen.toISOString(),
|
||||
platformLabel: platformNameToLabel(question.platform),
|
||||
objectID: question.id,
|
||||
optionsstringforsearch: getoptionsstringforsearch(question),
|
||||
};
|
||||
};
|
||||
|
||||
export async function rebuildAlgoliaDatabase() {
|
||||
const questions = await prisma.question.findMany();
|
||||
|
||||
const platformNameToLabel = Object.fromEntries(
|
||||
platforms.map((platform) => [platform.name, platform.label])
|
||||
);
|
||||
|
||||
const records: AlgoliaQuestion[] = questions.map(
|
||||
(question, index: number) => ({
|
||||
...question,
|
||||
timestamp: `${question.timestamp}`,
|
||||
platformLabel:
|
||||
platformNameToLabel[question.platform] || question.platform,
|
||||
objectID: index,
|
||||
optionsstringforsearch: getoptionsstringforsearch(question),
|
||||
})
|
||||
);
|
||||
const records: AlgoliaQuestion[] = questions.map(questionToAlgoliaQuestion);
|
||||
|
||||
if (await index.exists()) {
|
||||
console.log("Index exists");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { prisma } from "../../backend/database/prisma";
|
||||
import { platforms } from "../../backend/platforms/registry";
|
||||
import { getPlatforms } from "../../backend/platforms/registry";
|
||||
import { builder } from "../builder";
|
||||
|
||||
export const PlatformObj = builder.objectRef<string>("Platform").implement({
|
||||
|
@ -20,7 +20,7 @@ export const PlatformObj = builder.objectRef<string>("Platform").implement({
|
|||
return "Guesstimate";
|
||||
}
|
||||
// kinda slow and repetitive, TODO - store a map {name => platform} somewhere and `getPlatform` util function?
|
||||
const platform = platforms.find((p) => p.name === platformName);
|
||||
const platform = getPlatforms().find((p) => p.name === platformName);
|
||||
if (!platform) {
|
||||
throw new Error(`Unknown platform ${platformName}`);
|
||||
}
|
||||
|
@ -36,10 +36,10 @@ export const PlatformObj = builder.objectRef<string>("Platform").implement({
|
|||
platform: platformName,
|
||||
},
|
||||
_max: {
|
||||
timestamp: true,
|
||||
fetched: true,
|
||||
},
|
||||
});
|
||||
return res._max.timestamp;
|
||||
return res._max.fetched;
|
||||
},
|
||||
}),
|
||||
}),
|
||||
|
@ -49,7 +49,7 @@ builder.queryField("platforms", (t) =>
|
|||
t.field({
|
||||
type: [PlatformObj],
|
||||
resolve: async (parent, args) => {
|
||||
return platforms.map((platform) => platform.name);
|
||||
return getPlatforms().map((platform) => platform.name);
|
||||
},
|
||||
})
|
||||
);
|
||||
|
|
|
@ -70,8 +70,21 @@ const QuestionShapeInterface = builder
|
|||
}),
|
||||
timestamp: t.field({
|
||||
type: "Date",
|
||||
description: "Timestamp at which metaforecast fetched the question",
|
||||
resolve: (parent) => parent.timestamp,
|
||||
description:
|
||||
"Last timestamp at which metaforecast fetched the question",
|
||||
deprecationReason: "Renamed to `fetched`",
|
||||
resolve: (parent) => parent.fetched,
|
||||
}),
|
||||
fetched: t.field({
|
||||
type: "Date",
|
||||
description:
|
||||
"Last timestamp at which metaforecast fetched the question",
|
||||
resolve: (parent) => parent.fetched,
|
||||
}),
|
||||
fetchedStr: t.string({
|
||||
description:
|
||||
"Last timestamp at which metaforecast fetched the question, in ISO 8601 format",
|
||||
resolve: (parent) => parent.fetched.toISOString(),
|
||||
}),
|
||||
qualityIndicators: t.field({
|
||||
type: QualityIndicatorsObj,
|
||||
|
@ -114,10 +127,20 @@ export const QuestionObj = builder.prismaObject("Question", {
|
|||
resolve: (parent) => (parent.extra as any)?.visualization, // used for guesstimate only, see searchGuesstimate.ts
|
||||
nullable: true,
|
||||
}),
|
||||
firstSeen: t.field({
|
||||
type: "Date",
|
||||
description: "First timestamp at which metaforecast fetched the question",
|
||||
resolve: (parent) => parent.firstSeen,
|
||||
}),
|
||||
firstSeenStr: t.string({
|
||||
description:
|
||||
"First timestamp at which metaforecast fetched the question, in ISO 8601 format",
|
||||
resolve: (parent) => parent.firstSeen.toISOString(),
|
||||
}),
|
||||
history: t.relation("history", {
|
||||
query: () => ({
|
||||
orderBy: {
|
||||
timestamp: "asc",
|
||||
fetched: "asc",
|
||||
},
|
||||
}),
|
||||
}),
|
||||
|
@ -130,7 +153,21 @@ builder.queryField("questions", (t) =>
|
|||
type: "Question",
|
||||
cursor: "id",
|
||||
maxSize: 1000,
|
||||
resolve: (query) => prisma.question.findMany({ ...query }),
|
||||
args: {
|
||||
orderBy: t.arg({
|
||||
type: builder.enumType("QuestionsOrderBy", {
|
||||
values: ["FIRST_SEEN_DESC"] as const,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
resolve: (query, parent, args) => {
|
||||
return prisma.question.findMany({
|
||||
...query,
|
||||
...(args.orderBy === "FIRST_SEEN_DESC"
|
||||
? { orderBy: [{ firstSeen: "desc" }, { id: "asc" }] }
|
||||
: {}), // TODO - explicit default order?
|
||||
});
|
||||
},
|
||||
},
|
||||
{},
|
||||
{}
|
||||
|
|
|
@ -63,7 +63,15 @@ builder.queryField("searchQuestions", (t) =>
|
|||
|
||||
return results.map((q) => ({
|
||||
...q,
|
||||
timestamp: new Date(q.timestamp),
|
||||
fetched: new Date(
|
||||
q.fetched || q.timestamp || new Date().toISOString() // q.timestamp is deprecated, TODO - just use `q.fetched`
|
||||
),
|
||||
timestamp: new Date(
|
||||
q.fetched || q.timestamp || new Date().toISOString()
|
||||
),
|
||||
firstSeen: new Date(
|
||||
q.firstSeen || new Date().toISOString() // TODO - q.firstSeen is not yet populated in algolia
|
||||
),
|
||||
}));
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { GetServerSideProps, NextPage } from "next";
|
||||
import React from "react";
|
||||
|
||||
import { getPlatformsConfig, platforms } from "../backend/platforms/registry";
|
||||
import { getPlatforms, getPlatformsConfig } from "../backend/platforms/registry";
|
||||
import { Layout } from "../web/common/Layout";
|
||||
import { Props, QueryParameters, SearchScreen } from "../web/search/components/SearchScreen";
|
||||
import { FrontpageDocument, SearchDocument } from "../web/search/queries.generated";
|
||||
|
@ -19,7 +19,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async (
|
|||
query: "",
|
||||
starsThreshold: 2,
|
||||
forecastsThreshold: 0,
|
||||
forecastingPlatforms: platforms.map((platform) => platform.name),
|
||||
forecastingPlatforms: getPlatforms().map((platform) => platform.name),
|
||||
};
|
||||
|
||||
const initialQueryParameters: QueryParameters = {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import { GetServerSideProps, NextPage } from "next";
|
||||
import React from "react";
|
||||
|
||||
import { platforms } from "../backend/platforms/registry";
|
||||
import { getPlatforms } from "../backend/platforms/registry";
|
||||
import { QuestionFragment } from "../web/fragments.generated";
|
||||
import { QuestionCard } from "../web/questions/components/QuestionCard";
|
||||
import { SearchDocument } from "../web/search/queries.generated";
|
||||
|
@ -23,7 +23,7 @@ export const getServerSideProps: GetServerSideProps<Props> = async (
|
|||
query: "",
|
||||
starsThreshold: 2,
|
||||
forecastsThreshold: 0,
|
||||
forecastingPlatforms: platforms.map((platform) => platform.name),
|
||||
forecastingPlatforms: getPlatforms().map((platform) => platform.name),
|
||||
...urlQuery,
|
||||
};
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ export default async function searchWithAlgolia({
|
|||
title: "No search results match your query",
|
||||
url: "https://metaforecast.org",
|
||||
platform: "metaforecast",
|
||||
platformLabel: "metaforecast",
|
||||
description: "Maybe try a broader query?",
|
||||
options: [
|
||||
{
|
||||
|
@ -109,7 +110,7 @@ export default async function searchWithAlgolia({
|
|||
type: "PROBABILITY",
|
||||
},
|
||||
],
|
||||
timestamp: `${new Date().toISOString().slice(0, 10)}`,
|
||||
fetched: new Date().toISOString(),
|
||||
qualityindicators: {
|
||||
numforecasts: 1,
|
||||
numforecasters: 1,
|
||||
|
@ -126,8 +127,10 @@ export default async function searchWithAlgolia({
|
|||
title: `Did you mean: ${queryString}?`,
|
||||
url: "https://metaforecast.org/recursion?bypassEasterEgg=true",
|
||||
platform: "metaforecast",
|
||||
platformLabel: "metaforecast",
|
||||
description:
|
||||
"Fatal error: Too much recursion. Click to proceed anyways",
|
||||
fetched: new Date().toISOString(),
|
||||
options: [
|
||||
{
|
||||
name: "Yes",
|
||||
|
@ -140,7 +143,6 @@ export default async function searchWithAlgolia({
|
|||
type: "PROBABILITY",
|
||||
},
|
||||
],
|
||||
timestamp: `${new Date().toISOString().slice(0, 10)}`,
|
||||
qualityindicators: {
|
||||
numforecasts: 1,
|
||||
numforecasters: 1,
|
||||
|
@ -161,6 +163,7 @@ export default async function searchWithAlgolia({
|
|||
title: "No search results appear to match your query",
|
||||
url: "https://metaforecast.org",
|
||||
platform: "metaforecast",
|
||||
platformLabel: "metaforecast",
|
||||
description: "Maybe try a broader query? That said, we could be wrong.",
|
||||
options: [
|
||||
{
|
||||
|
@ -174,7 +177,7 @@ export default async function searchWithAlgolia({
|
|||
type: "PROBABILITY",
|
||||
},
|
||||
],
|
||||
timestamp: `${new Date().toISOString().slice(0, 10)}`,
|
||||
fetched: new Date().toISOString(),
|
||||
qualityindicators: {
|
||||
numforecasts: 1,
|
||||
numforecasters: 1,
|
||||
|
|
Loading…
Reference in New Issue
Block a user