aboutsummaryrefslogtreecommitdiff
path: root/src/graduation-common.ts
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2026-10-17 10:23:22 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2026-10-17 10:23:22 +0200
commit198bbebd89d212faae3e45a22830bab66dec49e0 (patch)
tree1b92b64f29e0bc50f5ff845b154450c926b82a69 /src/graduation-common.ts
parent38477bab6c1c736a2d1e7dd79b75c6e122502622 (diff)
downloadbycs-sol-198bbebd89d212faae3e45a22830bab66dec49e0.tar.gz
bycs-sol-198bbebd89d212faae3e45a22830bab66dec49e0.zip
admin-tools: add export tools and improve duplicate finderHEADmain
Considered as duplicates are eequal qual changes submitted in the same hour. Bump dependencies.
Diffstat (limited to 'src/graduation-common.ts')
-rw-r--r--src/graduation-common.ts54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/graduation-common.ts b/src/graduation-common.ts
index 2d1f21d..fe244bc 100644
--- a/src/graduation-common.ts
+++ b/src/graduation-common.ts
@@ -248,6 +248,60 @@ async function deleteGraduationChange(graduation: Graduation, change: Graduation
return await db.deleteEntries([change.changeId]);
}
+export function findDuplicateChanges(
+ changes: Array<GraduationChange>,
+): Array<Array<GraduationChange>> {
+ // Sets of potential duplicates
+ const duplicates: Array<Array<GraduationChange>> = [];
+
+ // Sort the changes first by studentId and than by time
+ changes.sort((a, b): number => {
+ // Sort by studentId first
+ if (a.studentId !== b.studentId) return a.studentId - b.studentId;
+ return a.date.getTime() - b.date.getTime();
+ });
+
+ let candidates = [];
+ outer_loop: for (let i = 0; i < changes.length - 1; i++) {
+ const change = changes[i];
+ const other = changes[i + 1];
+
+ for (const key in change) {
+ let similar;
+ switch (key) {
+ case "changeId":
+ continue;
+ case "date":
+ // Are the dates less than an hour apart?
+ similar = Math.abs(change.date.getTime() - other.date.getTime()) < 24 * 60 * 60 * 1000;
+ break;
+ case "context":
+ similar = JSON.stringify(change.context) === JSON.stringify(other.context);
+ break;
+ default:
+ const tkey = key as keyof GraduationChange;
+ similar = change[tkey] === other[tkey];
+ }
+ if (!similar) {
+ // The input is sorted duplicates must be in consecutive order.
+ if (candidates.length > 0) {
+ duplicates.push(candidates);
+ candidates = [];
+ }
+ continue outer_loop;
+ }
+ }
+
+ // Found candidates
+ if (candidates.length === 0) {
+ candidates.push(change, other); // New candidate pair
+ } else {
+ candidates.push(other); // Additional candidate found
+ }
+ }
+ return duplicates;
+}
+
export {
LEVEL_NAMES,
LEVEL_IMAGES,