103 lines
3.5 KiB
TypeScript
103 lines
3.5 KiB
TypeScript
import { createClient } from "redis";
|
|
|
|
type LogAction = "called" | "completed" | "no-show";
|
|
type TicketStatus = "called" | "completed" | "no-show";
|
|
|
|
interface LogEntry {
|
|
ticket: string;
|
|
time: string;
|
|
action: LogAction;
|
|
room: string | null;
|
|
};
|
|
|
|
interface Ticket {
|
|
status: TicketStatus;
|
|
created: string;
|
|
room: string | null;
|
|
calledDate: string | null;
|
|
}
|
|
|
|
const redis = await createClient({
|
|
url: process.env.DATABASE_URL || "redis://localhost:6379"
|
|
}).connect();
|
|
|
|
export function logAction(entry: LogEntry) {
|
|
redis.lPush("log", JSON.stringify(entry));
|
|
}
|
|
|
|
export async function getLogEntries(): Promise<LogEntry[]> {
|
|
const entries = await redis.lRange("log", 0, -1);
|
|
return entries.map(entry => JSON.parse(entry));
|
|
}
|
|
|
|
// export async function createTicket(ticket: string) {
|
|
// // redisjson ticket:{ticket} = { status: "waiting", created: now, room: null, calledDate: null }
|
|
// await redis.json.set(`ticket:${ticket}`, "$", {
|
|
// status: "waiting" as TicketStatus,
|
|
// created: new Date().toISOString(),
|
|
// room: null,
|
|
// calledDate: null
|
|
// });
|
|
// logAction({ ticket, time: new Date().toISOString(), action: "entered", room: null });
|
|
// }
|
|
|
|
export async function callTicket(ticket: string, room: string) {
|
|
// await redis.json.set(`ticket:${ticket}`, "$.status", "called");
|
|
// await redis.json.set(`ticket:${ticket}`, "$.room", room);
|
|
// await redis.json.set(`ticket:${ticket}`, "$.calledDate", new Date().toISOString());
|
|
await redis.json.set(`ticket:${ticket}`, "$", {
|
|
status: "called" as TicketStatus,
|
|
created: new Date().toISOString(),
|
|
room,
|
|
calledDate: new Date().toISOString()
|
|
});
|
|
logAction({ ticket, time: new Date().toISOString(), action: "called", room });
|
|
}
|
|
|
|
export async function completeTicket(ticket: string) {
|
|
await redis.json.set(`ticket:${ticket}`, "$.status", "completed");
|
|
const room = await redis.json.get(`ticket:${ticket}`, { path: "$.room" }) as string | null;
|
|
logAction({ ticket, time: new Date().toISOString(), action: "completed", room });
|
|
}
|
|
|
|
export async function noShowTicket(ticket: string) {
|
|
await redis.json.set(`ticket:${ticket}`, "$.status", "no-show");
|
|
const room = await redis.json.get(`ticket:${ticket}`, { path: "$.room" }) as string | null;
|
|
logAction({ ticket, time: new Date().toISOString(), action: "no-show", room });
|
|
}
|
|
|
|
export async function getCurrentTicket(room: string): Promise<{num: string, ticket: Ticket} | null> {
|
|
const tickets = await redis.keys("ticket:*");
|
|
for (const key of tickets) {
|
|
const ticket = key.split(":")[1]!;
|
|
const ticketData = await getTicket(ticket);
|
|
if (ticketData?.status === "called" && ticketData.room === room) {
|
|
return { num: ticket, ticket: ticketData };
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export async function getDisplayTickets(): Promise<{num: string, ticket: Ticket}[]> {
|
|
const result: {num: string, ticket: Ticket}[] = [];
|
|
const tickets = await redis.keys("ticket:*");
|
|
for (const key of tickets) {
|
|
const ticket = key.split(":")[1]!;
|
|
const ticketData = await getTicket(ticket);
|
|
if (ticketData?.status === "called" || ticketData?.status === "no-show") {
|
|
result.push({ num: ticket, ticket: ticketData });
|
|
}
|
|
}
|
|
// Sort by calledDate
|
|
result.sort((a, b) => {
|
|
const dateA = new Date(a.ticket.calledDate || "1970-01-01T00:00:00.000Z");
|
|
const dateB = new Date(b.ticket.calledDate || "1970-01-01T00:00:00.000Z");
|
|
return dateA.getTime() - dateB.getTime();
|
|
});
|
|
return result;
|
|
}
|
|
|
|
export async function getTicket(ticket: string): Promise<Ticket | null> {
|
|
return await redis.json.get(`ticket:${ticket}`) as Ticket | null;
|
|
}
|