feat: add common utilities and feedback handling scripts

- Introduced common.js for shared functions including API calls, error reporting, and UI helpers.
- Implemented feedback.js for the feedback reporting page, including form handling and displaying feedback status.
- Added layout.js for managing galaxy and section layouts in the visualization.
- Created login.js for user authentication with session management.
- Developed search.js for term searching based on user input and synonyms.
- Implemented signup.js for user registration with validation and immediate login.
This commit is contained in:
jsahn
2026-10-06 23:14:45 +09:00
parent 04158ac442
commit 4e943700fc
62 changed files with 158771 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
// node --test tests/search.test.mjs
import test from "node:test";
import assert from "node:assert/strict";
import { buildIndex, search, choseong, initialGroup } from "../web/static/js/search.js";
import { shortestPath } from "../web/static/js/layout.js";
const terms = [
{ i: "a", n: "우선순위 설정", a: [], q: ["무엇부터"], x: "여러 문제 가운데 먼저 다룰 것을 정함" },
{ i: "b", n: "건강신념모형", a: ["Health Belief Model", "HBM"], q: [], x: "" },
{ i: "c", n: "발생률", a: ["incidence"], q: [], x: "새롭게 발생한 환자 비율" },
{ i: "d", n: "유병률", a: ["prevalence"], q: [], x: "질병을 가진 사람 비율" },
];
const idx = buildIndex(terms);
const top = (q) => search(idx, q)[0]?.t.i;
test("부분·동의어·설명 검색", () => {
assert.equal(top("우선"), "a");
assert.equal(top("hbm"), "b");
assert.equal(top("prevalence"), "d");
assert.equal(top("새롭게"), "c");
assert.equal(top("무엇부터 먼저"), "a");
});
test("초성·오타", () => {
assert.equal(top("ㄱㄱㅅㄴ"), "b");
assert.equal(top("우선순이"), "a");
assert.equal(choseong("건강"), "ㄱㄱ");
});
test("결과 없음", () => assert.equal(search(idx, "쀍쀍").length, 0));
test("가나다 묶음", () => {
assert.equal(initialGroup("쌍둥이"), "ㅅ");
assert.equal(initialGroup("WHO"), "A–Z");
});
test("최단 경로", () => {
const rels = [{ i: "r1", s: "a", t: "b" }, { i: "r2", s: "c", t: "b" }];
const adj = new Map(terms.map((t) => [t.i, []]));
for (const r of rels) { adj.get(r.s).push(r); adj.get(r.t).push(r); }
const p = shortestPath(adj, "a", "c");
assert.deepEqual(p.map((s) => s.to), ["b", "c"]);
assert.equal(p[1].forward, false);
assert.equal(shortestPath(adj, "a", "d"), null);
});