Commit a5e4a55
authored
feat(document-api): anchor tracked changes to text spans in extract (SD-2766) (#2973)
* feat(document-api): anchor tracked changes to text spans in extract (SD-2766)
Add `block.textSpans` so consumers can map each tracked change to the
exact run of text it covers, instead of guessing from a free-form
excerpt that's ambiguous when the same word repeats. Also add
`blockIds` and `wordRevisionIds` on each `trackedChanges[]` entry so a
review queue or RAG citation flow can navigate back without scanning
every block. Suppress the aggregate excerpt for paired replacements
(both insert and delete in one entity) where the concatenated value
was misleading; spans carry the per-half text.
The new fields are all optional and the existing `text` field is
unchanged, so non-tracked-change consumers see no diff.
* fix(document-api): detect paired tracked changes from observed mark types
Address PR review findings:
- Generalize paired-replacement detection to suppress the aggregate
excerpt for any multi-type entity, keying off mark types observed
during the span walk. The previous check looked only at imported
`wordRevisionIds`, missing in-app paired edits where no `sourceId`
is set.
- Rename `rawIdMap` → `canonicalIdByAlias` to match the existing
convention in `tracked-change-refs.ts` (the value is the canonical
entity id, not a raw mark id).
- Document `blockIds` order as document order in the public typedef.
- Inline the default value in the `type` JSDoc so readers don't chase
the cross-reference.
- Gate the visual-inspection log behind `DEBUG_EXTRACT_SAMPLE` so CI
doesn't print two pretty-printed JSON blobs per run.
- Add unit tests for the in-app paired case (no `sourceId`),
span coalescing of identical adjacent marks, and non-tracked marks
(bold) coexisting with tracked marks without affecting span
boundaries.
* test(extract): add real Word-authored DOCX with paired replacements (SD-2766)
Adds a 22 KB Word-authored fixture (74 deletes + 104 inserts, all
paired replacements with one author and one timestamp) reported by
the customer who originally asked for tracked-change anchoring. The
test asserts that title-level "Report" -> "Captain's Log" and body-
level "get started" -> "set sail" replacements come through as
distinct delete/insert spans, that every tracked change reports
blockIds, and that span text concatenates back to block.text. A
DEBUG_EXTRACT_SAMPLE-gated log prints the rendered <ins>/<del>
output for the first five tracked blocks for visual verification.1 parent d54519c commit a5e4a55
8 files changed
Lines changed: 1194 additions & 39 deletions
File tree
- apps/docs/document-api/reference
- packages
- document-api/src
- contract
- types
- super-editor/src/editors/v1
- document-api-adapters
- tests/data
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1031 | 1031 | | |
1032 | 1032 | | |
1033 | 1033 | | |
1034 | | - | |
| 1034 | + | |
1035 | 1035 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | 52 | | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
62 | 64 | | |
63 | 65 | | |
64 | 66 | | |
| |||
73 | 75 | | |
74 | 76 | | |
75 | 77 | | |
76 | | - | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
77 | 81 | | |
78 | | - | |
79 | | - | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
80 | 87 | | |
81 | 88 | | |
82 | 89 | | |
| |||
112 | 119 | | |
113 | 120 | | |
114 | 121 | | |
115 | | - | |
| 122 | + | |
116 | 123 | | |
117 | 124 | | |
118 | 125 | | |
| |||
168 | 175 | | |
169 | 176 | | |
170 | 177 | | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
171 | 221 | | |
172 | 222 | | |
173 | 223 | | |
| |||
234 | 284 | | |
235 | 285 | | |
236 | 286 | | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
237 | 294 | | |
238 | 295 | | |
239 | 296 | | |
240 | 297 | | |
241 | 298 | | |
242 | | - | |
| 299 | + | |
243 | 300 | | |
244 | 301 | | |
245 | 302 | | |
246 | | - | |
| 303 | + | |
247 | 304 | | |
248 | 305 | | |
249 | 306 | | |
| 307 | + | |
250 | 308 | | |
251 | 309 | | |
252 | 310 | | |
253 | 311 | | |
254 | 312 | | |
255 | 313 | | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
256 | 332 | | |
257 | 333 | | |
258 | 334 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2968 | 2968 | | |
2969 | 2969 | | |
2970 | 2970 | | |
2971 | | - | |
| 2971 | + | |
| 2972 | + | |
| 2973 | + | |
| 2974 | + | |
| 2975 | + | |
| 2976 | + | |
| 2977 | + | |
| 2978 | + | |
| 2979 | + | |
| 2980 | + | |
| 2981 | + | |
| 2982 | + | |
| 2983 | + | |
| 2984 | + | |
| 2985 | + | |
| 2986 | + | |
| 2987 | + | |
| 2988 | + | |
| 2989 | + | |
| 2990 | + | |
| 2991 | + | |
| 2992 | + | |
| 2993 | + | |
| 2994 | + | |
| 2995 | + | |
| 2996 | + | |
2972 | 2997 | | |
2973 | 2998 | | |
2974 | 2999 | | |
| |||
3024 | 3049 | | |
3025 | 3050 | | |
3026 | 3051 | | |
3027 | | - | |
| 3052 | + | |
| 3053 | + | |
| 3054 | + | |
| 3055 | + | |
| 3056 | + | |
| 3057 | + | |
| 3058 | + | |
| 3059 | + | |
| 3060 | + | |
| 3061 | + | |
| 3062 | + | |
| 3063 | + | |
| 3064 | + | |
| 3065 | + | |
| 3066 | + | |
| 3067 | + | |
| 3068 | + | |
| 3069 | + | |
| 3070 | + | |
| 3071 | + | |
| 3072 | + | |
| 3073 | + | |
| 3074 | + | |
| 3075 | + | |
| 3076 | + | |
3028 | 3077 | | |
3029 | | - | |
3030 | | - | |
3031 | 3078 | | |
3032 | 3079 | | |
3033 | 3080 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
37 | 71 | | |
38 | 72 | | |
39 | 73 | | |
| |||
53 | 87 | | |
54 | 88 | | |
55 | 89 | | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
56 | 96 | | |
57 | 97 | | |
58 | 98 | | |
| |||
75 | 115 | | |
76 | 116 | | |
77 | 117 | | |
78 | | - | |
| 118 | + | |
79 | 119 | | |
80 | | - | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
81 | 133 | | |
82 | | - | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
83 | 154 | | |
84 | 155 | | |
85 | 156 | | |
| |||
0 commit comments