feat(docver): derive docId from fid claim and drop [docId] URL segment
All checks were successful
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 3s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Successful in 1m9s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Successful in 4s
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Successful in 1s

- docId of every docver operation now comes from the Bearer token: the fid
  claim (e-Court fileId) is used directly as docId; segment [docId] removed
  from URLs — POST/GET /api/documents/versions and
  GET /api/documents/versions/{versionId}/download-link
- fid is required and must be a string (trim 1-200): token issuance rejects
  missing/blank/non-string fid with 400, verify rejects fid-less tokens with 401
- parseDocId removed from lib/document-versioning.ts (dead code, no callers)
- openapi spec: paths renamed, docId path params removed, fid required + string
- PLAN-DOCVER.md / CLAUDE.md / wordaddin versioningService comment updated
- tests: fid required/string cases added, parseDocId describe removed (256 pass)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
Suphonchai Phoonsawat 2026-10-26 10:05:01 +07:00
parent aad6f155fe
commit 0b2c9e6343
10 changed files with 122 additions and 158 deletions

View file

@ -6,7 +6,6 @@ import {
docverError,
isDocxBytes,
isPdfBytes,
parseDocId,
parseDownloadFormat,
parseFieldsJson,
parseVersionIdParam,
@ -23,28 +22,6 @@ function ok<T>(result: { ok: boolean } & T): asserts result is { ok: true } & T
expect(result.ok).toBe(true);
}
describe("parseDocId", () => {
it("รับ GUID / รหัส e-Court / charset ที่อนุญาตทั้งหมด และ trim รอบ ๆ", () => {
for (const raw of [
"123e4567-e89b-12d3-a456-426614174000",
"ecourt:123",
"DOC_2026.10",
" doc1 ",
"a".repeat(200),
]) {
const result = parseDocId(raw);
ok(result);
expect(result.docId).toBe(raw.trim());
}
});
it("ตกเมื่อว่าง / เกิน 200 / มีช่องว่างกลาง / ไทย / slash / '..'", () => {
for (const raw of ["", " ", "a".repeat(201), "doc 1", "เอกสาร1", "a/b", "..", "a\\b"]) {
expect(parseDocId(raw).ok).toBe(false);
}
});
});
describe("parseVersionIdParam", () => {
it("รับ UUID ทั้งพิมพ์ใหญ่/เล็ก (normalize ลงตัวพิมพ์เล็ก) + trim", () => {
const result = parseVersionIdParam(" 6F9619FF-8B86-D011-B42D-00C04FC964FF ");