|
| 1 | +# FwLite Commenting |
| 2 | + |
| 3 | +Collaborative discussion attached to dictionary data (entries, senses, example sentences). Comments sync via Harmony; read status is local-only per device (not synced, not per Lexbox user account). |
| 4 | + |
| 5 | +## Language |
| 6 | + |
| 7 | +**Comment thread**: |
| 8 | +A conversation anchored to one dictionary object. Has its own identity separate from the object it discusses. Can be open or closed. |
| 9 | +_Avoid_: Thread (alone, ambiguous), conversation |
| 10 | + |
| 11 | +**User comment**: |
| 12 | +A single message within a comment thread, authored by a project participant. |
| 13 | +_Avoid_: Comment (alone, when the type name matters), note |
| 14 | + |
| 15 | +**Subject**: |
| 16 | +The dictionary object a comment thread is about — an entry, sense, or example sentence. |
| 17 | +_Avoid_: Entity, parent, anchor, target |
| 18 | + |
| 19 | +**SubjectId**: |
| 20 | +The GUID of the subject object. |
| 21 | +_Avoid_: EntityId, ParentId |
| 22 | + |
| 23 | +**SubjectType**: |
| 24 | +Which kind of dictionary object the subject is: Entry, Sense, or ExampleSentence. |
| 25 | +_Avoid_: ParentEntityType, EntityType |
| 26 | + |
| 27 | +**Open thread**: |
| 28 | +A thread that accepts new replies (enforced at the API layer). |
| 29 | +_Avoid_: Active, unresolved |
| 30 | + |
| 31 | +**Closed thread**: |
| 32 | +A thread whose `Status` is `Closed`. Local replies are rejected by the API. Synced replies remain visible and unread; the thread does not auto-reopen — users reopen explicitly if they want to continue. |
| 33 | +_Avoid_: Resolved (reserved — epic #1765 mentions "resolving" but close ≠ resolve in v1), optimistic close, derived close state |
| 34 | + |
| 35 | +**Synced reply on closed thread**: |
| 36 | +A comment that arrives via sync while the thread is closed. It remains visible, counts as unread, and does not change thread status. |
| 37 | + |
| 38 | +**Subject cardinality**: |
| 39 | +A subject may have many comment threads. There is no uniqueness constraint on `(SubjectId, SubjectType)`. |
| 40 | +_Avoid_: One thread per entry/sense/example (not a v1 rule) |
| 41 | + |
| 42 | +**Subject deletion**: |
| 43 | +When a subject is soft-deleted, its comment threads are soft-deleted via Harmony reference cascade, and their comments are soft-deleted in turn. Threads do not survive as orphans. |
| 44 | +_Future_: If subject merge were supported, comments would move with the subject; out of scope for v1. |
| 45 | +_Avoid_: Orphan threads on deleted subjects |
| 46 | + |
| 47 | +**PreviousCommentId**: |
| 48 | +The comment the author had seen when writing this reply. Used to detect parallel forks under sync — not the sole source of display order. |
| 49 | +_Avoid_: Parent comment, reply-to (when meaning the fork chain) |
| 50 | + |
| 51 | +**Fork warning**: |
| 52 | +Shown when a comment's `PreviousCommentId` does not match the comment immediately before it in `CreatedAt` display order. Indicates the author likely did not see intervening comment(s). |
| 53 | +_Avoid_: Conflict indicator, merge warning |
| 54 | + |
| 55 | +**Deleted-predecessor notice**: |
| 56 | +When `PreviousCommentId` points to a soft-deleted comment, show an informational notice — not a fork warning. |
| 57 | + |
| 58 | +**CRDT-only (v1)**: |
| 59 | +Comments exist only in the Harmony/CRDT store. They are not mirrored to FwData or round-tripped through `FwLiteProjectSync`. If FieldWorks gains native comment support later, syncing comments in becomes a separate effort. |
| 60 | +_Avoid_: Assuming FwData parity, LF import as sync |
| 61 | + |
| 62 | +**Read status**: |
| 63 | +Per-device, non-synced seen-comment records keyed by `CommentId`. Account switching on the same OS user is out of scope; project data is already per OS user. |
| 64 | +_Avoid_: Per-user read sync, cross-device read continuity |
| 65 | + |
| 66 | +**Open thread (read side effect)**: |
| 67 | +Opening a thread marks all comments currently in that thread as read on this device. |
| 68 | +_Avoid_: Auto-read on sync, auto-read on close |
| 69 | + |
| 70 | +**In-thread arrival (nice to have)**: |
| 71 | +A comment that arrives via sync while the thread is already open may stay unread until the user explicitly acknowledges it (e.g. popup). Not required for v1. |
| 72 | + |
| 73 | +**Delete comment**: |
| 74 | +Authors may delete their own comments. Managers may delete any comment. |
| 75 | +_Avoid_: Editors deleting others' comments |
| 76 | + |
| 77 | +**Delete thread**: |
| 78 | +Managers may delete a thread (cascades to comments via Harmony). |
| 79 | +_Avoid_: Any editor deleting threads |
| 80 | + |
| 81 | +**Commenter role**: |
| 82 | +For commenting permissions, Commenter is equivalent to Editor — can create threads, reply, and edit/delete own comments. Does not grant manager moderation powers. |
| 83 | + |
| 84 | +**Edited comment**: |
| 85 | +When `UpdatedAt > CreatedAt`, show an edited badge. Hover reveals the updated date/time. Prior text versions are not shown in v1; Harmony commit history can power a history view later. |
| 86 | +_Avoid_: Inline diff, version chain on the model (v1) |
| 87 | + |
| 88 | +**Subject scope (v1)**: |
| 89 | +Comment threads attach to whole objects only — Entry, Sense, or ExampleSentence. Field-level anchoring (e.g. a specific gloss or writing system) is out of scope; reviewers can name the field in prose. |
| 90 | +_Future_: Field-level anchoring if LF import or workflow requires it. |
| 91 | +_Avoid_: Field comments, property-level threads (v1) |
| 92 | + |
| 93 | +**Comment text**: |
| 94 | +Plain text only in v1 (no Markdown or rich formatting). Display as-is; URL auto-linking in the UI is optional. Maximum **2,000 characters** per comment; empty/whitespace rejected at API. Limit may be raised later. |
| 95 | +_Future_: Markdown subset if formatting is needed. |
| 96 | +_Avoid_: Rich text, HTML, validating length in change classes (API/UI only) |
| 97 | + |
| 98 | +**Activity view (deferred)**: |
| 99 | +Presentation (per-comment, per-thread, or per-subject list; sort by authored date vs sync date) is a UI concern. The v1 model supports all three via queries over `CommentThread`, `UserComment`, and local read status — no extra Harmony fields required. Initial UI will likely use the simplest shape (flat unread comments by `CreatedAt`). |
| 100 | +_Future_: Sync-date sort may need a local per-device `SyncedAt` on receipt, similar to read status — not in Harmony model. |
0 commit comments