80 lines
No EOL
2 KiB
TypeScript
80 lines
No EOL
2 KiB
TypeScript
/**
|
|
* Attendance — tracks who was in each TG.
|
|
*
|
|
* Usage:
|
|
* import { Attendance } from "@systems/attendance";
|
|
*
|
|
* Attendance.snapshot(slot)
|
|
* Attendance.players(slot)
|
|
* Attendance.allSubmitted(slot, date)
|
|
*/
|
|
|
|
import fs from "fs";
|
|
import { Paths } from "@paths";
|
|
import { UserKey, HistoryKey } from "@types";
|
|
import { Store } from "@systems/store";
|
|
|
|
interface AttendanceData {
|
|
[historyKey: HistoryKey]: UserKey[];
|
|
}
|
|
|
|
let _data: AttendanceData = {};
|
|
|
|
function load(): void {
|
|
_data = Store.readOrDefault<AttendanceData>(Paths.data("attendance.json"), {});
|
|
}
|
|
function save(): void {
|
|
Store.write(Paths.data("attendance.json"), _data);
|
|
}
|
|
|
|
load();
|
|
|
|
export const Attendance = {
|
|
/**
|
|
* Snapshot attendance from poll state at lock time.
|
|
*/
|
|
snapshot(slot: number, lockedYesKeys: Set<UserKey>): void {
|
|
const date = new Date().toISOString().slice(0, 10);
|
|
const historyKey = `${date}-${slot}` as HistoryKey;
|
|
_data[historyKey] = [...lockedYesKeys];
|
|
save();
|
|
},
|
|
|
|
/**
|
|
* Get players who attended a specific TG.
|
|
*/
|
|
players(historyKey: HistoryKey): UserKey[] {
|
|
return _data[historyKey] ?? [];
|
|
},
|
|
|
|
/**
|
|
* Check if a specific player attended.
|
|
*/
|
|
includes(historyKey: HistoryKey, userKey: UserKey): boolean {
|
|
return (_data[historyKey] ?? []).includes(userKey);
|
|
},
|
|
|
|
/**
|
|
* Check if all attendees have submitted scores.
|
|
*/
|
|
allSubmitted(historyKey: HistoryKey): boolean {
|
|
const players = _data[historyKey] ?? [];
|
|
if (players.length === 0) return false;
|
|
try {
|
|
const result = JSON.parse(
|
|
fs.readFileSync(Paths.data("tg-history", `${historyKey}.json`), "utf8")
|
|
);
|
|
const submitted = new Set(result.scores?.map((s: any) => s.userKey) ?? []);
|
|
return players.every((p) => submitted.has(p));
|
|
} catch {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get all history keys (for listing past TGs).
|
|
*/
|
|
all(): HistoryKey[] {
|
|
return Object.keys(_data) as HistoryKey[];
|
|
},
|
|
}; |