55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
import type { InferSelectModel } from "drizzle-orm";
|
|
import type { party, partyMember, user } from "./db/schema";
|
|
|
|
export type Party = Omit<InferSelectModel<typeof party>, "data"> & {
|
|
data: QuizState;
|
|
};
|
|
export type PartyMember = InferSelectModel<typeof partyMember>;
|
|
export type User = InferSelectModel<typeof user>;
|
|
|
|
export type PartyMemberWithUser = PartyMember & { user: User | null };
|
|
|
|
export const PARTY_STATUS = ["created", "started", "ended"] as const;
|
|
export type PartyStatus = (typeof PARTY_STATUS)[number];
|
|
|
|
export type PartySnapshot = {
|
|
party: Party;
|
|
members: PartyMemberWithUser[];
|
|
};
|
|
|
|
export type PartyState = {
|
|
party: Party | null;
|
|
members: PartyMemberWithUser[];
|
|
};
|
|
|
|
export type PartySocketOutgoing =
|
|
| { type: "ping" }
|
|
| { type: "member_payload"; payload: unknown };
|
|
|
|
export type Question = {
|
|
text: string;
|
|
options: string[];
|
|
correct: number;
|
|
startTimestamp: number;
|
|
endTimestamp: number;
|
|
points: number;
|
|
};
|
|
|
|
export type QuizState = {
|
|
status: "running" | "results";
|
|
workflowId: string | null;
|
|
questionIndex: number;
|
|
currentQuestion: Question | null;
|
|
answers: Record<
|
|
string,
|
|
{ playerId: string; selected: number; correct: boolean }
|
|
>;
|
|
scores: Record<string, number>;
|
|
};
|
|
|
|
export type PartySocketEvent =
|
|
| { type: "snapshot"; party: Party | null; members: PartyMemberWithUser[] }
|
|
| { type: "party_status"; party: Party; members: PartyMemberWithUser[] }
|
|
| { type: "member_payload"; fromUserId: string; payload: unknown }
|
|
| { type: "error"; message: string }
|
|
| { type: "pong" };
|