@fgbg/mdocs 0.6.1 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/server/access/access-control.js +23 -8
  2. package/dist/server/access/access-control.js.map +1 -1
  3. package/dist/server/access/access-control.test.js +66 -0
  4. package/dist/server/access/access-control.test.js.map +1 -1
  5. package/dist/server/app.js +27 -0
  6. package/dist/server/app.js.map +1 -1
  7. package/dist/server/cli/main.js +50 -10
  8. package/dist/server/cli/main.js.map +1 -1
  9. package/dist/server/db/repositories/bookmark.repo.js +68 -0
  10. package/dist/server/db/repositories/bookmark.repo.js.map +1 -0
  11. package/dist/server/db/repositories/document-comment.repo.js +104 -0
  12. package/dist/server/db/repositories/document-comment.repo.js.map +1 -0
  13. package/dist/server/db/repositories/document.repo.js +14 -0
  14. package/dist/server/db/repositories/document.repo.js.map +1 -1
  15. package/dist/server/db/repositories/visitor.repo.js +19 -4
  16. package/dist/server/db/repositories/visitor.repo.js.map +1 -1
  17. package/dist/server/db/schema.js +24 -1
  18. package/dist/server/db/schema.js.map +1 -1
  19. package/dist/server/documents/document-comment.service.js +58 -0
  20. package/dist/server/documents/document-comment.service.js.map +1 -0
  21. package/dist/server/documents/document-comment.service.test.js +283 -0
  22. package/dist/server/documents/document-comment.service.test.js.map +1 -0
  23. package/dist/server/documents/document.service.js +78 -2
  24. package/dist/server/documents/document.service.js.map +1 -1
  25. package/dist/server/documents/tree-and-folders.test.js +81 -2
  26. package/dist/server/documents/tree-and-folders.test.js.map +1 -1
  27. package/dist/server/documents/tree.service.js +16 -4
  28. package/dist/server/documents/tree.service.js.map +1 -1
  29. package/dist/server/identity/auth.middleware.js +6 -1
  30. package/dist/server/identity/auth.middleware.js.map +1 -1
  31. package/dist/server/identity/visitor.service.js +13 -7
  32. package/dist/server/identity/visitor.service.js.map +1 -1
  33. package/dist/server/identity/visitor.service.test.js +4 -3
  34. package/dist/server/identity/visitor.service.test.js.map +1 -1
  35. package/dist/server/routes/bookmarks.routes.js +108 -0
  36. package/dist/server/routes/bookmarks.routes.js.map +1 -0
  37. package/dist/server/routes/document-comments.routes.js +47 -0
  38. package/dist/server/routes/document-comments.routes.js.map +1 -0
  39. package/dist/server/routes/documents.routes.js +26 -2
  40. package/dist/server/routes/documents.routes.js.map +1 -1
  41. package/dist/server/routes/visitors.routes.js +22 -2
  42. package/dist/server/routes/visitors.routes.js.map +1 -1
  43. package/dist/server/search/document-index-manager.js +14 -8
  44. package/dist/server/search/document-index-manager.js.map +1 -1
  45. package/dist/shared/permissions.js +29 -0
  46. package/dist/shared/permissions.js.map +1 -0
  47. package/dist/web/assets/_baseUniq-GvNMhSGA.js +1 -0
  48. package/dist/web/assets/arc-DB-MBQ_7.js +1 -0
  49. package/dist/web/assets/architectureDiagram-Q4EWVU46-B6fIJCqj.js +36 -0
  50. package/dist/web/assets/{blockDiagram-DXYQGD6D-B_xmfn8A.js → blockDiagram-DXYQGD6D-U0T3XkPP.js} +2 -2
  51. package/dist/web/assets/{c4Diagram-AHTNJAMY-mzXC4HGz.js → c4Diagram-AHTNJAMY-_ik3C_bT.js} +2 -2
  52. package/dist/web/assets/channel-CptILkTi.js +1 -0
  53. package/dist/web/assets/chunk-4BX2VUAB-C-KFRd1D.js +1 -0
  54. package/dist/web/assets/{chunk-4TB4RGXK-CHrqLnxu.js → chunk-4TB4RGXK-B5h_MoAS.js} +1 -1
  55. package/dist/web/assets/chunk-55IACEB6-Dq50eCA0.js +1 -0
  56. package/dist/web/assets/chunk-EDXVE4YY-D5er4rHs.js +1 -0
  57. package/dist/web/assets/{chunk-FMBD7UC4-CqM95lCi.js → chunk-FMBD7UC4-AqKqMyp7.js} +1 -1
  58. package/dist/web/assets/{chunk-OYMX7WX6-B4xt0fDi.js → chunk-OYMX7WX6-ClN2hoBH.js} +1 -1
  59. package/dist/web/assets/chunk-QZHKN3VN-CCl-uS54.js +1 -0
  60. package/dist/web/assets/chunk-YZCP3GAM-Cz4KL9JQ.js +1 -0
  61. package/dist/web/assets/classDiagram-6PBFFD2Q-wee7frTV.js +1 -0
  62. package/dist/web/assets/classDiagram-v2-HSJHXN6E-wee7frTV.js +1 -0
  63. package/dist/web/assets/clone-CE7ZzRl-.js +1 -0
  64. package/dist/web/assets/cose-bilkent-S5V4N54A-DCqKkloN.js +1 -0
  65. package/dist/web/assets/dagre-KV5264BT-CBrTGiwg.js +4 -0
  66. package/dist/web/assets/diagram-5BDNPKRD-VICEQzUR.js +10 -0
  67. package/dist/web/assets/diagram-G4DWMVQ6-DaoEItNN.js +24 -0
  68. package/dist/web/assets/diagram-MMDJMWI5-DvvqKBgR.js +43 -0
  69. package/dist/web/assets/diagram-TYMM5635-b8KlP0s4.js +24 -0
  70. package/dist/web/assets/{erDiagram-SMLLAGMA-BRhKGp7p.js → erDiagram-SMLLAGMA-Bg3JFEyu.js} +2 -2
  71. package/dist/web/assets/{flowDiagram-DWJPFMVM-CVXEyDGV.js → flowDiagram-DWJPFMVM-BYeJ-7SE.js} +2 -2
  72. package/dist/web/assets/ganttDiagram-T4ZO3ILL-CGgDK6Uk.js +292 -0
  73. package/dist/web/assets/gitGraphDiagram-UUTBAWPF-BfS-vmec.js +106 -0
  74. package/dist/web/assets/graph-DnoW4mMs.js +1 -0
  75. package/dist/web/assets/index-BqmdUIYA.css +1 -0
  76. package/dist/web/assets/index-C-wD6L-6.js +5749 -0
  77. package/dist/web/assets/infoDiagram-42DDH7IO-BhblG3CD.js +2 -0
  78. package/dist/web/assets/{ishikawaDiagram-UXIWVN3A-CBGPMeRX.js → ishikawaDiagram-UXIWVN3A-7Tfh-5tN.js} +5 -5
  79. package/dist/web/assets/{journeyDiagram-VCZTEJTY-BojXYLpZ.js → journeyDiagram-VCZTEJTY-CD9_KODe.js} +2 -2
  80. package/dist/web/assets/{kanban-definition-6JOO6SKY-COB1p8N4.js → kanban-definition-6JOO6SKY-7FYoOrz1.js} +2 -2
  81. package/dist/web/assets/layout-CgpZb7aT.js +1 -0
  82. package/dist/web/assets/linear-DXlSVFPI.js +1 -0
  83. package/dist/web/assets/min-CbvyKZdW.js +1 -0
  84. package/dist/web/assets/{mindmap-definition-QFDTVHPH-WuIIFDk0.js → mindmap-definition-QFDTVHPH-D_7IpwOr.js} +2 -2
  85. package/dist/web/assets/{pieDiagram-DEJITSTG-0yTTbTnK.js → pieDiagram-DEJITSTG-C4oHxK29.js} +2 -2
  86. package/dist/web/assets/{quadrantDiagram-34T5L4WZ-BVGxiAic.js → quadrantDiagram-34T5L4WZ-qaARXrbR.js} +2 -2
  87. package/dist/web/assets/{requirementDiagram-MS252O5E-DxoKkLjF.js → requirementDiagram-MS252O5E-B0OnR3WQ.js} +2 -2
  88. package/dist/web/assets/sankeyDiagram-XADWPNL6-CgrqxXXq.js +10 -0
  89. package/dist/web/assets/{sequenceDiagram-FGHM5R23-qQBtlmdr.js → sequenceDiagram-FGHM5R23-ieRKRAqs.js} +2 -2
  90. package/dist/web/assets/stateDiagram-FHFEXIEX-ju-e_AqR.js +1 -0
  91. package/dist/web/assets/stateDiagram-v2-QKLJ7IA2-Clz1rvlo.js +1 -0
  92. package/dist/web/assets/{timeline-definition-GMOUNBTQ-DMZNkVLR.js → timeline-definition-GMOUNBTQ-DtcIDFGX.js} +2 -2
  93. package/dist/web/assets/{vennDiagram-DHZGUBPP-dqHjP-hQ.js → vennDiagram-DHZGUBPP-DG2V75Il.js} +2 -2
  94. package/dist/web/assets/wardley-RL74JXVD-CI6hl6LN.js +162 -0
  95. package/dist/web/assets/{wardleyDiagram-NUSXRM2D-Be4N5UZh.js → wardleyDiagram-NUSXRM2D-CUGNCU53.js} +2 -2
  96. package/dist/web/assets/{xychartDiagram-5P7HB3ND-CqeRqtaT.js → xychartDiagram-5P7HB3ND-SxZFqO2V.js} +2 -2
  97. package/dist/web/index.html +2 -2
  98. package/package.json +4 -2
  99. package/dist/web/assets/_baseUniq-mbOGdjgO.js +0 -1
  100. package/dist/web/assets/arc-D-WSUdNG.js +0 -1
  101. package/dist/web/assets/architectureDiagram-Q4EWVU46-0jRUx91A.js +0 -36
  102. package/dist/web/assets/channel-C5iQ1-e2.js +0 -1
  103. package/dist/web/assets/chunk-4BX2VUAB-Bn7yoqIc.js +0 -1
  104. package/dist/web/assets/chunk-55IACEB6-D9CzRsCu.js +0 -1
  105. package/dist/web/assets/chunk-EDXVE4YY-DUGGXqt0.js +0 -1
  106. package/dist/web/assets/chunk-QZHKN3VN-CB4tazF4.js +0 -1
  107. package/dist/web/assets/chunk-YZCP3GAM-CJdC-SLE.js +0 -1
  108. package/dist/web/assets/classDiagram-6PBFFD2Q-3PggZSgZ.js +0 -1
  109. package/dist/web/assets/classDiagram-v2-HSJHXN6E-3PggZSgZ.js +0 -1
  110. package/dist/web/assets/clone-BRenlKxE.js +0 -1
  111. package/dist/web/assets/cose-bilkent-S5V4N54A-CNME-K3v.js +0 -1
  112. package/dist/web/assets/dagre-KV5264BT-BiWVn1mI.js +0 -4
  113. package/dist/web/assets/diagram-5BDNPKRD-DOah-MqT.js +0 -10
  114. package/dist/web/assets/diagram-G4DWMVQ6-U2XDwT09.js +0 -24
  115. package/dist/web/assets/diagram-MMDJMWI5-CVDLI2Md.js +0 -43
  116. package/dist/web/assets/diagram-TYMM5635-DYVPY1ys.js +0 -24
  117. package/dist/web/assets/ganttDiagram-T4ZO3ILL-CbymDUCg.js +0 -292
  118. package/dist/web/assets/gitGraphDiagram-UUTBAWPF-BKDun02F.js +0 -106
  119. package/dist/web/assets/graph-BXEbNgSu.js +0 -1
  120. package/dist/web/assets/index-DYHwr9jx.css +0 -1
  121. package/dist/web/assets/index-a4S5-Ob1.js +0 -5315
  122. package/dist/web/assets/infoDiagram-42DDH7IO-Dn0tTehG.js +0 -2
  123. package/dist/web/assets/layout-ZFfRWIoj.js +0 -1
  124. package/dist/web/assets/linear-2a3E1vTB.js +0 -1
  125. package/dist/web/assets/mermaid.core-DBH2e0Kt.js +0 -309
  126. package/dist/web/assets/min-CXNTeEK6.js +0 -1
  127. package/dist/web/assets/sankeyDiagram-XADWPNL6-UpSdvRJr.js +0 -10
  128. package/dist/web/assets/stateDiagram-FHFEXIEX-nBMIkJdm.js +0 -1
  129. package/dist/web/assets/stateDiagram-v2-QKLJ7IA2-DD5wjWd9.js +0 -1
  130. package/dist/web/assets/wardley-RL74JXVD-D8TklWsQ.js +0 -162
@@ -1 +1 @@
1
- {"version":3,"file":"document.repo.js","sourceRoot":"","sources":["../../../../src/server/db/repositories/document.repo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"document.repo.js","sourceRoot":"","sources":["../../../../src/server/db/repositories/document.repo.ts"],"names":[],"mappings":"AA8CA;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,EAAqB,EAAE,QAAgB;IAC5E,mCAAmC;IACnC,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CACN,yDAAyD,CAC1D;SACA,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjB,oBAAoB;IACpB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAAqB,EAAE,QAAgB;IAC3E,OAAO,EAAE;SACN,OAAO,CACN;;;iEAG2D,CAC5D;SACA,GAAG,CAAC,QAAQ,CAAC,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAqB,EAAE,UAAkB;IACxE,OAAO,EAAE;SACN,OAAO,CACN;;;4CAGsC,CACvC;SACA,GAAG,CAAC,UAAU,CAAC,CAAC;AACrB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAqB,EAAE,QAAgB,EAAE,YAAoB;IAC9F,OAAO,EAAE;SACN,OAAO,CACN;;;gEAG0D,CAC3D;SACA,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,EAAqB,EAAE,KAA0B;IAC9E,EAAE,CAAC,OAAO,CACR;;;;oDAIgD,CACjD,CAAC,GAAG,CACH,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,QAAQ,IAAI,IAAI,EACtB,KAAK,CAAC,QAAQ,IAAI,IAAI,CACvB,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAAqB,EAAE,KAAiC;IAC5F,+BAA+B;IAC/B,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,EAAE,CAAC,OAAO,CACR;;6BAEuB,CACxB,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACpH,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,OAAO,CACR;;6BAEuB,CACxB,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAClG,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,EAAqB,EAAE,UAAkB;IACtE,EAAE,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CACvC,EAAqB,EACrB,QAAgB,EAChB,UAAkB;IAElB,OAAO,EAAE;SACN,OAAO,CACN,sEAAsE,CACvE;SACA,GAAG,CAAC,QAAQ,EAAE,GAAG,UAAU,GAAG,CAAC,CAAC;AACrC,CAAC;AASD;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,EAAqB,EACrB,UAAkB,EAClB,SAAiB;IAEjB,OAAO,EAAE;SACN,OAAO,CACN,2GAA2G,CAC5G;SACA,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,EAAqB,EACrB,UAAkB,EAClB,SAAiB,EACjB,UAAkB;IAElB,EAAE,CAAC,OAAO,CACR;yFACqF,CACtF,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,EAAqB,EAAE,UAAkB,EAAE,SAAiB;IAC/F,EAAE,CAAC,OAAO,CAAC,uEAAuE,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AACjH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAqB,EAAE,UAAkB;IAC3E,OAAO,EAAE;SACN,OAAO,CACN,wFAAwF,CACzF;SACA,GAAG,CAAC,UAAU,CAAC,CAAC;AACrB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yCAAyC,CAAC,EAAqB,EAAE,SAAiB;IAChG,MAAM,IAAI,GAAG,EAAE;SACZ,OAAO,CACN;;;+BAGyB,CAC1B;SACA,GAAG,CAAC,SAAS,CAAC,CAAC;IAClB,gBAAgB;IAChB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB,CACvC,EAAqB,EACrB,QAAgB,EAChB,SAAiB;IAEjB,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CACN;;;;eAIS,CACV;SACA,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC5B,iCAAiC;IACjC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,EAAqB,EAAE,QAAgB;IAC1E,OAAO,EAAE;SACN,OAAO,CACN;;;iEAG2D,CAC5D;SACA,GAAG,CAAC,QAAQ,CAAC,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAAqB,EAAE,QAAgB;IAC3E,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CACN,yDAAyD,CAC1D;SACA,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC"}
@@ -22,6 +22,15 @@ export function findVisitorById(db, visitorId) {
22
22
  .prepare(`SELECT * FROM visitors WHERE visitor_id = ?`)
23
23
  .get(visitorId);
24
24
  }
25
+ /**
26
+ * 根据访客名称查找访客(支持按名称迁移)。
27
+ * 只返回未禁用的访客。
28
+ */
29
+ export function findVisitorByName(db, visitorName) {
30
+ return db
31
+ .prepare(`SELECT * FROM visitors WHERE visitor_name = ? AND disabled_at IS NULL`)
32
+ .get(visitorName);
33
+ }
25
34
  /**
26
35
  * 更新指定访客的 last_seen_at 字段。
27
36
  */
@@ -39,10 +48,16 @@ export function disableVisitor(db, visitorId, mergedInto, at) {
39
48
  /**
40
49
  * 列出所有访客,按创建时间降序排列。
41
50
  */
42
- export function listVisitors(db) {
43
- return db
44
- .prepare(`SELECT * FROM visitors ORDER BY created_at DESC`)
45
- .all();
51
+ export function listVisitors(db, filter = "all") {
52
+ let sql = `SELECT * FROM visitors`;
53
+ if (filter === "active") {
54
+ sql += ` WHERE disabled_at IS NULL`;
55
+ }
56
+ else if (filter === "disabled") {
57
+ sql += ` WHERE disabled_at IS NOT NULL`;
58
+ }
59
+ sql += ` ORDER BY created_at DESC`;
60
+ return db.prepare(sql).all();
46
61
  }
47
62
  /**
48
63
  * 根据恢复码哈希查找访客。
@@ -1 +1 @@
1
- {"version":3,"file":"visitor.repo.js","sourceRoot":"","sources":["../../../../src/server/db/repositories/visitor.repo.ts"],"names":[],"mappings":"AAuBA;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,EAAqB,EAAE,KAAyB;IAC5E,EAAE,CAAC,OAAO,CACR;;6BAEyB,CAC1B,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;AACrH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,SAAiB;IAEjB,OAAO,EAAE;SACN,OAAO,CACN,qDAAqD,CACtD;SACA,GAAG,CAAC,SAAS,CAAC,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,EAAqB,EACrB,SAAiB;IAEjB,OAAO,EAAE;SACN,OAAO,CAAqB,6CAA6C,CAAC;SAC1E,GAAG,CAAC,SAAS,CAAC,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,EAAqB,EACrB,SAAiB,EACjB,EAAU;IAEV,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC,GAAG,CACzE,EAAE,EACF,SAAS,CACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,EAAqB,EACrB,SAAiB,EACjB,UAAkB,EAClB,EAAU;IAEV,EAAE,CAAC,OAAO,CACR;;0BAEsB,CACvB,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,EAAqB;IAChD,OAAO,EAAE;SACN,OAAO,CAAiB,iDAAiD,CAAC;SAC1E,GAAG,EAAE,CAAC;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,6BAA6B,CAC3C,EAAqB,EACrB,gBAAwB;IAExB,OAAO,EAAE;SACN,OAAO,CACN,6EAA6E,CAC9E;SACA,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,SAAiB,EACjB,IAAmB;IAEnB,EAAE,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC,GAAG,CAC/E,IAAI,EACJ,SAAS,CACV,CAAC;AACJ,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,2BAA2B,CACzC,EAAqB;IAErB,OAAO,EAAE;SACN,OAAO,CACN;;4CAEsC,CACvC;SACA,GAAG,EAAE,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"visitor.repo.js","sourceRoot":"","sources":["../../../../src/server/db/repositories/visitor.repo.ts"],"names":[],"mappings":"AAuBA;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,EAAqB,EAAE,KAAyB;IAC5E,EAAE,CAAC,OAAO,CACR;;6BAEyB,CAC1B,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;AACrH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,SAAiB;IAEjB,OAAO,EAAE;SACN,OAAO,CACN,qDAAqD,CACtD;SACA,GAAG,CAAC,SAAS,CAAC,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,EAAqB,EACrB,SAAiB;IAEjB,OAAO,EAAE;SACN,OAAO,CAAqB,6CAA6C,CAAC;SAC1E,GAAG,CAAC,SAAS,CAAC,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,EAAqB,EACrB,WAAmB;IAEnB,OAAO,EAAE;SACN,OAAO,CAAqB,uEAAuE,CAAC;SACpG,GAAG,CAAC,WAAW,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,EAAqB,EACrB,SAAiB,EACjB,EAAU;IAEV,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAC,GAAG,CACzE,EAAE,EACF,SAAS,CACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,EAAqB,EACrB,SAAiB,EACjB,UAAkB,EAClB,EAAU;IAEV,EAAE,CAAC,OAAO,CACR;;0BAEsB,CACvB,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,EAAqB,EAAE,SAAwC,KAAK;IAC/F,IAAI,GAAG,GAAG,wBAAwB,CAAC;IACnC,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,GAAG,IAAI,4BAA4B,CAAC;IACtC,CAAC;SAAM,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,GAAG,IAAI,gCAAgC,CAAC;IAC1C,CAAC;IACD,GAAG,IAAI,2BAA2B,CAAC;IACnC,OAAO,EAAE,CAAC,OAAO,CAAiB,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,6BAA6B,CAC3C,EAAqB,EACrB,gBAAwB;IAExB,OAAO,EAAE;SACN,OAAO,CACN,6EAA6E,CAC9E;SACA,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,SAAiB,EACjB,IAAmB;IAEnB,EAAE,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC,GAAG,CAC/E,IAAI,EACJ,SAAS,CACV,CAAC;AACJ,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,2BAA2B,CACzC,EAAqB;IAErB,OAAO,EAAE;SACN,OAAO,CACN;;4CAEsC,CACvC;SACA,GAAG,EAAE,CAAC;AACX,CAAC"}
@@ -2,7 +2,7 @@
2
2
  const SCHEMA_STATEMENTS = [
3
3
  `CREATE TABLE IF NOT EXISTS visitors (
4
4
  visitor_id TEXT PRIMARY KEY,
5
- visitor_name TEXT NOT NULL,
5
+ visitor_name TEXT NOT NULL UNIQUE,
6
6
  visitor_token_hash TEXT NOT NULL UNIQUE,
7
7
  created_at TEXT NOT NULL,
8
8
  last_seen_at TEXT,
@@ -113,6 +113,29 @@ const SCHEMA_STATEMENTS = [
113
113
  created_at TEXT NOT NULL
114
114
  )`,
115
115
  `CREATE INDEX IF NOT EXISTS idx_cli_tokens_visitor ON cli_tokens (visitor_id)`,
116
+ `CREATE TABLE IF NOT EXISTS document_bookmarks (
117
+ visitor_id TEXT NOT NULL,
118
+ document_id TEXT NOT NULL,
119
+ created_at TEXT NOT NULL,
120
+ PRIMARY KEY (visitor_id, document_id)
121
+ )`,
122
+ `CREATE INDEX IF NOT EXISTS idx_bookmarks_visitor ON document_bookmarks (visitor_id)`,
123
+ `CREATE TABLE IF NOT EXISTS document_comments (
124
+ comment_id TEXT PRIMARY KEY,
125
+ document_id TEXT NOT NULL,
126
+ visitor_id TEXT NOT NULL,
127
+ visitor_name TEXT NOT NULL,
128
+ parent_id TEXT,
129
+ reply_to_visitor_id TEXT,
130
+ reply_to_visitor_name TEXT,
131
+ content TEXT NOT NULL,
132
+ is_deleted INTEGER NOT NULL DEFAULT 0,
133
+ created_at TEXT NOT NULL,
134
+ updated_at TEXT NOT NULL
135
+ )`,
136
+ `CREATE INDEX IF NOT EXISTS idx_comments_document ON document_comments (document_id, created_at DESC)`,
137
+ `CREATE INDEX IF NOT EXISTS idx_comments_parent ON document_comments (parent_id)`,
138
+ `CREATE INDEX IF NOT EXISTS idx_comments_visitor ON document_comments (visitor_id)`,
116
139
  ];
117
140
  /**
118
141
  * 在数据库上应用完整 Schema。
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/server/db/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/server/db/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { getDb } from "../db/connection.js";
2
+ import { DocumentCommentRepository } from "../db/repositories/document-comment.repo.js";
3
+ export class DocumentCommentService {
4
+ repo;
5
+ db;
6
+ constructor(db = getDb()) {
7
+ this.db = db;
8
+ this.repo = new DocumentCommentRepository(db);
9
+ }
10
+ /** 创建评论 */
11
+ async createComment(params) {
12
+ // 校验:如果有 parentId,必须是根评论(保证两层结构)
13
+ if (params.parentId) {
14
+ const isRoot = await this.repo.isRootComment(params.parentId);
15
+ if (!isRoot) {
16
+ throw new Error("只能回复根评论,不支持更深层级嵌套");
17
+ }
18
+ }
19
+ if (!params.content.trim()) {
20
+ throw new Error("评论内容不能为空");
21
+ }
22
+ if (params.content.length > 512) {
23
+ throw new Error("评论内容不能超过 512 个字符");
24
+ }
25
+ return this.repo.create(params);
26
+ }
27
+ /** 获取文档的所有评论 */
28
+ async getCommentsByDocumentId(documentId) {
29
+ return this.repo.getByDocumentId(documentId);
30
+ }
31
+ /** 删除评论(软删除)
32
+ * - 评论作者可以删除自己的评论
33
+ * - 文档创建者可以删除该文档下的所有评论
34
+ */
35
+ async deleteComment(commentId, visitorId) {
36
+ const comment = await this.repo.getById(commentId);
37
+ if (!comment) {
38
+ throw new Error("评论不存在");
39
+ }
40
+ // 获取文档信息,检查是否是文档创建者
41
+ const doc = this.db
42
+ .prepare("SELECT owner_visitor_id FROM documents WHERE document_id = ?")
43
+ .get(comment.documentId);
44
+ const isDocOwner = doc && doc.owner_visitor_id === visitorId;
45
+ const isCommentAuthor = comment.visitorId === visitorId;
46
+ // 只有评论作者或文档创建者可以删除
47
+ if (!isCommentAuthor && !isDocOwner) {
48
+ throw new Error("只能删除自己的评论或文档下的评论");
49
+ }
50
+ return this.repo.softDelete(commentId);
51
+ }
52
+ /** 获取文档评论数 */
53
+ async countComments(documentId) {
54
+ return this.repo.countByDocumentId(documentId);
55
+ }
56
+ }
57
+ export const documentCommentService = new DocumentCommentService();
58
+ //# sourceMappingURL=document-comment.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-comment.service.js","sourceRoot":"","sources":["../../../src/server/documents/document-comment.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAExF,MAAM,OAAO,sBAAsB;IAChB,IAAI,CAA4B;IAChC,EAAE,CAAoB;IAEvC,YAAY,EAAE,GAAG,KAAK,EAAE;QACtB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,IAAI,yBAAyB,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,WAAW;IACX,KAAK,CAAC,aAAa,CAAC,MAQnB;QACC,iCAAiC;QACjC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC9D,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QAC9B,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,gBAAgB;IAChB,KAAK,CAAC,uBAAuB,CAAC,UAAkB;QAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa,CAAC,SAAiB,EAAE,SAAiB;QACtD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAED,oBAAoB;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CAAC,8DAA8D,CAAC;aACvE,GAAG,CAAC,OAAO,CAAC,UAAU,CAA6C,CAAC;QAEvE,MAAM,UAAU,GAAG,GAAG,IAAI,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC;QAC7D,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;QAExD,mBAAmB;QACnB,IAAI,CAAC,eAAe,IAAI,CAAC,UAAU,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,cAAc;IACd,KAAK,CAAC,aAAa,CAAC,UAAkB;QACpC,OAAO,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC;CACF;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,283 @@
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
+ import Database from "better-sqlite3";
3
+ import { DocumentCommentRepository } from "../db/repositories/document-comment.repo.js";
4
+ import { DocumentCommentService } from "./document-comment.service.js";
5
+ function createTestDb() {
6
+ const db = new Database(":memory:");
7
+ db.exec(`
8
+ CREATE TABLE documents (
9
+ document_id TEXT PRIMARY KEY,
10
+ domain_id TEXT NOT NULL,
11
+ relative_path TEXT NOT NULL,
12
+ display_name TEXT NOT NULL,
13
+ owner_visitor_id TEXT NOT NULL,
14
+ created_by TEXT NOT NULL,
15
+ updated_by TEXT NOT NULL,
16
+ content_hash TEXT NOT NULL,
17
+ created_at TEXT NOT NULL,
18
+ updated_at TEXT NOT NULL,
19
+ permission INTEGER NOT NULL DEFAULT 1,
20
+ file_type TEXT NOT NULL DEFAULT 'md',
21
+ parent_id TEXT
22
+ );
23
+
24
+ CREATE TABLE document_comments (
25
+ comment_id TEXT PRIMARY KEY,
26
+ document_id TEXT NOT NULL,
27
+ visitor_id TEXT NOT NULL,
28
+ visitor_name TEXT NOT NULL,
29
+ parent_id TEXT,
30
+ reply_to_visitor_id TEXT,
31
+ reply_to_visitor_name TEXT,
32
+ content TEXT NOT NULL,
33
+ is_deleted INTEGER NOT NULL DEFAULT 0,
34
+ created_at TEXT NOT NULL,
35
+ updated_at TEXT NOT NULL
36
+ );
37
+ `);
38
+ return db;
39
+ }
40
+ describe("DocumentCommentService", () => {
41
+ let db;
42
+ let repo;
43
+ let service;
44
+ beforeEach(() => {
45
+ db = createTestDb();
46
+ repo = new DocumentCommentRepository(db);
47
+ service = new DocumentCommentService(db);
48
+ });
49
+ describe("createComment", () => {
50
+ it("应该能创建根评论", async () => {
51
+ const comment = await service.createComment({
52
+ documentId: "doc-1",
53
+ visitorId: "visitor-a",
54
+ visitorName: "Alice",
55
+ parentId: null,
56
+ replyToVisitorId: null,
57
+ replyToVisitorName: null,
58
+ content: "这是一篇评论",
59
+ });
60
+ expect(comment.commentId).toBeTruthy();
61
+ expect(comment.documentId).toBe("doc-1");
62
+ expect(comment.visitorId).toBe("visitor-a");
63
+ expect(comment.visitorName).toBe("Alice");
64
+ expect(comment.content).toBe("这是一篇评论");
65
+ expect(comment.parentId).toBeNull();
66
+ expect(comment.isDeleted).toBe(false);
67
+ });
68
+ it("应该能回复根评论(两级结构)", async () => {
69
+ // 先创建根评论
70
+ const rootComment = await service.createComment({
71
+ documentId: "doc-1",
72
+ visitorId: "visitor-a",
73
+ visitorName: "Alice",
74
+ parentId: null,
75
+ replyToVisitorId: null,
76
+ replyToVisitorName: null,
77
+ content: "根评论",
78
+ });
79
+ // 回复根评论
80
+ const reply = await service.createComment({
81
+ documentId: "doc-1",
82
+ visitorId: "visitor-b",
83
+ visitorName: "Bob",
84
+ parentId: rootComment.commentId,
85
+ replyToVisitorId: "visitor-a",
86
+ replyToVisitorName: "Alice",
87
+ content: "回复根评论",
88
+ });
89
+ expect(reply.parentId).toBe(rootComment.commentId);
90
+ expect(reply.replyToVisitorId).toBe("visitor-a");
91
+ expect(reply.replyToVisitorName).toBe("Alice");
92
+ });
93
+ it("不允许回复非根评论(防止超过两级)", async () => {
94
+ // 创建根评论
95
+ const rootComment = await service.createComment({
96
+ documentId: "doc-1",
97
+ visitorId: "visitor-a",
98
+ visitorName: "Alice",
99
+ parentId: null,
100
+ replyToVisitorId: null,
101
+ replyToVisitorName: null,
102
+ content: "根评论",
103
+ });
104
+ // 创建回复
105
+ const reply = await service.createComment({
106
+ documentId: "doc-1",
107
+ visitorId: "visitor-b",
108
+ visitorName: "Bob",
109
+ parentId: rootComment.commentId,
110
+ replyToVisitorId: "visitor-a",
111
+ replyToVisitorName: "Alice",
112
+ content: "回复",
113
+ });
114
+ // 尝试回复回复(应该失败)
115
+ await expect(service.createComment({
116
+ documentId: "doc-1",
117
+ visitorId: "visitor-c",
118
+ visitorName: "Charlie",
119
+ parentId: reply.commentId,
120
+ replyToVisitorId: "visitor-b",
121
+ replyToVisitorName: "Bob",
122
+ content: "回复的回复",
123
+ })).rejects.toThrow("只能回复根评论,不支持更深层级嵌套");
124
+ });
125
+ it("不允许创建空评论", async () => {
126
+ await expect(service.createComment({
127
+ documentId: "doc-1",
128
+ visitorId: "visitor-a",
129
+ visitorName: "Alice",
130
+ parentId: null,
131
+ replyToVisitorId: null,
132
+ replyToVisitorName: null,
133
+ content: " ",
134
+ })).rejects.toThrow("评论内容不能为空");
135
+ });
136
+ it("不允许创建超过 512 个字符的评论", async () => {
137
+ const longContent = "a".repeat(513);
138
+ await expect(service.createComment({
139
+ documentId: "doc-1",
140
+ visitorId: "visitor-a",
141
+ visitorName: "Alice",
142
+ parentId: null,
143
+ replyToVisitorId: null,
144
+ replyToVisitorName: null,
145
+ content: longContent,
146
+ })).rejects.toThrow("评论内容不能超过 512 个字符");
147
+ });
148
+ it("恰好 512 个字符的评论应该允许", async () => {
149
+ const content = "a".repeat(512);
150
+ const comment = await service.createComment({
151
+ documentId: "doc-1",
152
+ visitorId: "visitor-a",
153
+ visitorName: "Alice",
154
+ parentId: null,
155
+ replyToVisitorId: null,
156
+ replyToVisitorName: null,
157
+ content,
158
+ });
159
+ expect(comment.content.length).toBe(512);
160
+ });
161
+ });
162
+ describe("deleteComment", () => {
163
+ it("评论作者可以删除自己的评论", async () => {
164
+ const comment = await service.createComment({
165
+ documentId: "doc-1",
166
+ visitorId: "visitor-a",
167
+ visitorName: "Alice",
168
+ parentId: null,
169
+ replyToVisitorId: null,
170
+ replyToVisitorName: null,
171
+ content: "我的评论",
172
+ });
173
+ const result = await service.deleteComment(comment.commentId, "visitor-a");
174
+ expect(result).toBe(true);
175
+ const deleted = await repo.getById(comment.commentId);
176
+ expect(deleted?.isDeleted).toBe(true);
177
+ });
178
+ it("文档创建者可以删除该文档下的任意评论", async () => {
179
+ // 先创建文档,owner 是 visitor-a
180
+ db.prepare(`
181
+ INSERT INTO documents (
182
+ document_id, domain_id, relative_path, display_name,
183
+ owner_visitor_id, created_by, updated_by, content_hash,
184
+ created_at, updated_at
185
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
186
+ `).run("doc-1", "default", "test.md", "Test", "visitor-a", // 文档创建者
187
+ "visitor-a", "visitor-a", "hash", new Date().toISOString(), new Date().toISOString());
188
+ // visitor-b 发表评论
189
+ const comment = await service.createComment({
190
+ documentId: "doc-1",
191
+ visitorId: "visitor-b",
192
+ visitorName: "Bob",
193
+ parentId: null,
194
+ replyToVisitorId: null,
195
+ replyToVisitorName: null,
196
+ content: "别人的评论",
197
+ });
198
+ // 文档创建者 visitor-a 可以删除 visitor-b 的评论
199
+ const result = await service.deleteComment(comment.commentId, "visitor-a");
200
+ expect(result).toBe(true);
201
+ const deleted = await repo.getById(comment.commentId);
202
+ expect(deleted?.isDeleted).toBe(true);
203
+ });
204
+ it("非作者且非文档创建者不能删除评论", async () => {
205
+ // 创建文档,owner 是 visitor-a
206
+ db.prepare(`
207
+ INSERT INTO documents (
208
+ document_id, domain_id, relative_path, display_name,
209
+ owner_visitor_id, created_by, updated_by, content_hash,
210
+ created_at, updated_at
211
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
212
+ `).run("doc-1", "default", "test.md", "Test", "visitor-a", "visitor-a", "visitor-a", "hash", new Date().toISOString(), new Date().toISOString());
213
+ // visitor-b 发表评论
214
+ const comment = await service.createComment({
215
+ documentId: "doc-1",
216
+ visitorId: "visitor-b",
217
+ visitorName: "Bob",
218
+ parentId: null,
219
+ replyToVisitorId: null,
220
+ replyToVisitorName: null,
221
+ content: "别人的评论",
222
+ });
223
+ // visitor-c 既不是作者也不是文档创建者,不能删除
224
+ await expect(service.deleteComment(comment.commentId, "visitor-c")).rejects.toThrow("只能删除自己的评论或文档下的评论");
225
+ });
226
+ it("删除不存在的评论应该报错", async () => {
227
+ await expect(service.deleteComment("non-existent-id", "visitor-a")).rejects.toThrow("评论不存在");
228
+ });
229
+ });
230
+ describe("getCommentsByDocumentId", () => {
231
+ it("应该能获取文档的所有评论", async () => {
232
+ await service.createComment({
233
+ documentId: "doc-1",
234
+ visitorId: "visitor-a",
235
+ visitorName: "Alice",
236
+ parentId: null,
237
+ replyToVisitorId: null,
238
+ replyToVisitorName: null,
239
+ content: "评论 1",
240
+ });
241
+ await service.createComment({
242
+ documentId: "doc-1",
243
+ visitorId: "visitor-b",
244
+ visitorName: "Bob",
245
+ parentId: null,
246
+ replyToVisitorId: null,
247
+ replyToVisitorName: null,
248
+ content: "评论 2",
249
+ });
250
+ const comments = await service.getCommentsByDocumentId("doc-1");
251
+ expect(comments.length).toBe(2);
252
+ expect(comments.some((c) => c.content === "评论 1")).toBe(true);
253
+ expect(comments.some((c) => c.content === "评论 2")).toBe(true);
254
+ });
255
+ it("获取不同文档的评论应该隔离", async () => {
256
+ await service.createComment({
257
+ documentId: "doc-1",
258
+ visitorId: "visitor-a",
259
+ visitorName: "Alice",
260
+ parentId: null,
261
+ replyToVisitorId: null,
262
+ replyToVisitorName: null,
263
+ content: "文档 1 的评论",
264
+ });
265
+ await service.createComment({
266
+ documentId: "doc-2",
267
+ visitorId: "visitor-b",
268
+ visitorName: "Bob",
269
+ parentId: null,
270
+ replyToVisitorId: null,
271
+ replyToVisitorName: null,
272
+ content: "文档 2 的评论",
273
+ });
274
+ const comments1 = await service.getCommentsByDocumentId("doc-1");
275
+ const comments2 = await service.getCommentsByDocumentId("doc-2");
276
+ expect(comments1.length).toBe(1);
277
+ expect(comments2.length).toBe(1);
278
+ expect(comments1[0].content).toBe("文档 1 的评论");
279
+ expect(comments2[0].content).toBe("文档 2 的评论");
280
+ });
281
+ });
282
+ });
283
+ //# sourceMappingURL=document-comment.service.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-comment.service.test.js","sourceRoot":"","sources":["../../../src/server/documents/document-comment.service.test.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { getDb } from "../db/connection.js";
3
- import { deleteDocument, findDocumentById, findDocumentByPath, insertDocument, insertDocumentInvite, deleteDocumentInvite, listDocumentInvites, listDocumentsByDomain, updateDocumentContent, } from "../db/repositories/document.repo.js";
3
+ import { deleteDocument, findDocumentById, findDocumentByPath, findDocumentInvite, insertDocument, insertDocumentInvite, deleteDocumentInvite, listDocumentInvites, listDocumentsByDomain, listDocumentsByPathPrefix, updateDocumentContent, } from "../db/repositories/document.repo.js";
4
4
  import { findDomainById, isDomainMember, } from "../db/repositories/domain.repo.js";
5
5
  import { resolveDomainAccess, canEnterDomainTree, } from "../access/domain-access.js";
6
6
  import { DocumentError, Permission, canReadDocument, canEditDocument, validateDomainPermission, } from "../access/access-control.js";
@@ -161,21 +161,30 @@ export function createDocument(params) {
161
161
  content,
162
162
  contentHash: write.contentHash,
163
163
  permission,
164
+ fileType: params.fileType ?? "md",
165
+ parentId: params.parentId ?? null,
164
166
  };
165
167
  }
166
168
  // ============================================================
167
169
  // 读单篇文档(调用方需先鉴权)
168
170
  // ============================================================
169
- export function getDocument(documentId) {
171
+ export function getDocument(documentId, visitorId) {
170
172
  const row = findDocumentById(getDb(), documentId);
171
173
  if (!row)
172
174
  throw new DocumentError("DOC_NOT_FOUND", "文档不存在", 404);
173
175
  const { content, contentHash } = readDocument(row.domain_id, row.relative_path);
176
+ // 检查访客是否通过邀请获得编辑权限
177
+ let invitedEdit = false;
178
+ if (visitorId && row.owner_visitor_id !== visitorId) {
179
+ const invite = findDocumentInvite(getDb(), documentId, visitorId);
180
+ invitedEdit = invite?.permission === "edit";
181
+ }
174
182
  return {
175
183
  ...rowToSummary(row),
176
184
  content,
177
185
  contentHash,
178
186
  permission: row.permission,
187
+ ...(invitedEdit ? { invitedEdit: true } : {}),
179
188
  };
180
189
  }
181
190
  // ============================================================
@@ -248,6 +257,8 @@ export function updateDocument(params) {
248
257
  content,
249
258
  contentHash: write.contentHash,
250
259
  permission: params.permission !== undefined ? params.permission : row.permission,
260
+ fileType: row.file_type,
261
+ parentId: row.parent_id,
251
262
  };
252
263
  }
253
264
  // ============================================================
@@ -279,6 +290,69 @@ export function removeDocument(params) {
279
290
  removeIndex(row.document_id);
280
291
  }
281
292
  // ============================================================
293
+ // 删除目录(批量删除目录下所有文档和子目录)
294
+ // ============================================================
295
+ export function removeFolder(params) {
296
+ const db = getDb();
297
+ let folder = findDocumentById(db, params.folderDocumentId);
298
+ if (!folder)
299
+ throw new DocumentError("DOC_NOT_FOUND", "目录不存在", 404);
300
+ // 如果传进来的是 ___desc___.md 文档,自动查找它的父目录
301
+ if (folder.file_type === "md" && folder.relative_path.endsWith("/___desc___.md")) {
302
+ if (!folder.parent_id) {
303
+ throw new DocumentError("BAD_REQUEST", "描述文档无父目录", 400);
304
+ }
305
+ folder = findDocumentById(db, folder.parent_id);
306
+ if (!folder || folder.file_type !== "dir") {
307
+ throw new DocumentError("DOC_NOT_FOUND", "父目录不存在", 404);
308
+ }
309
+ }
310
+ if (folder.file_type !== "dir") {
311
+ throw new DocumentError("BAD_REQUEST", "不是目录", 400);
312
+ }
313
+ if (folder.owner_visitor_id !== params.actorVisitorId) {
314
+ throw new DocumentError("FORBIDDEN", "仅创建者可删除此目录", 403);
315
+ }
316
+ // 目录路径前缀,用于匹配所有子文档和子目录
317
+ const pathPrefix = `${folder.relative_path}/`;
318
+ // 找出该目录下所有文档(包括子目录、描述文档、普通文档)
319
+ const allDocs = listDocumentsByPathPrefix(db, folder.domain_id, pathPrefix);
320
+ // 加上目录本身
321
+ const allToDelete = [...allDocs, folder];
322
+ if (allToDelete.length === 0)
323
+ return { deletedCount: 0 };
324
+ // 校验所有文档都是当前用户创建的
325
+ const notOwned = allToDelete.filter((d) => d.owner_visitor_id !== params.actorVisitorId);
326
+ if (notOwned.length > 0) {
327
+ throw new DocumentError("FORBIDDEN", `目录下有 ${notOwned.length} 篇文档不属于你,无法删除`, 403);
328
+ }
329
+ const now = new Date().toISOString();
330
+ const deletedIds = [];
331
+ const tx = db.transaction(() => {
332
+ for (const doc of allToDelete) {
333
+ deleteDocument(db, doc.document_id);
334
+ deletedIds.push(doc.document_id);
335
+ insertAuditLog(db, {
336
+ actorVisitorId: params.actorVisitorId,
337
+ action: doc.file_type === "dir" ? "folder.delete" : "document.delete",
338
+ targetType: doc.file_type === "dir" ? "folder" : "document",
339
+ targetId: doc.document_id,
340
+ metadata: { relativePath: doc.relative_path, viaFolderDelete: true },
341
+ createdAt: now,
342
+ });
343
+ }
344
+ });
345
+ tx();
346
+ // 删除磁盘文件和索引(只删 md 文件有内容的,dir 类型不写磁盘)
347
+ for (const doc of allToDelete) {
348
+ if (doc.file_type === "md") {
349
+ deleteDocumentFile(doc.domain_id, doc.relative_path);
350
+ removeIndex(doc.document_id);
351
+ }
352
+ }
353
+ return { deletedCount: allToDelete.length };
354
+ }
355
+ // ============================================================
282
356
  // 文档邀请
283
357
  // ============================================================
284
358
  export function addDocumentInvite(actorVisitorId, documentId, targetVisitorId, targetPermission) {
@@ -327,6 +401,8 @@ function rowToSummary(row) {
327
401
  updatedAt: row.updated_at,
328
402
  createdAt: row.created_at,
329
403
  permission: row.permission,
404
+ fileType: row.file_type,
405
+ parentId: row.parent_id,
330
406
  };
331
407
  }
332
408
  function deriveDisplayName(raw, relativePath) {