fix(v0210): importNote 가 capture revision 을 함께 INSERT (final review fix)
final code review 발견: F5 import 후 first user edit 시 import 시점 본문이 note_revisions 에 없어 history 에서 사라지는 회귀. importNote transaction 안 INSERT 추가 (createdAt = edited_at). 부수 작업: ImportNoteInput / importNote 의 "raw_text invariant guard" 주석을 v0.2.10 의 'fork-on-id-collision (sync determinism)' 정확한 의미로 갱신. 테스트 +2 — insert path / fork path 모두 capture revision 검증.
This commit is contained in:
@@ -22,7 +22,10 @@ export interface NewMediaRow {
|
||||
|
||||
export interface ImportNoteInput {
|
||||
/** Proposed id from the export file. May be replaced if it collides with
|
||||
* an existing row whose `raw_text` differs (raw_text invariant guard). */
|
||||
* an existing row whose `raw_text` differs — fork-on-conflict so a single
|
||||
* id never resolves to two distinct historical baselines (v0.2.10 Cut C
|
||||
* changed `raw_text 불변` policy → `raw_text 가변` + revision history; the
|
||||
* baseline distinction is now preserved per-id, edit history per-note). */
|
||||
id: string;
|
||||
rawText: string;
|
||||
createdAt: string;
|
||||
@@ -681,11 +684,17 @@ export class NoteRepository {
|
||||
|
||||
/**
|
||||
* Import a note from an external source (F5 export tree).
|
||||
* Conflict policy:
|
||||
* Conflict policy (fork-on-id-collision):
|
||||
* - id missing in DB → INSERT (status: 'inserted')
|
||||
* - id present + raw_text identical → no-op (status: 'skipped')
|
||||
* - id present + raw_text differs → INSERT under fresh uuidv7
|
||||
* to preserve the raw_text-immutable invariant (status: 'forked')
|
||||
* - id present + raw_text differs → INSERT under fresh uuidv7 so the same id
|
||||
* never points at two different baselines (status: 'forked'). v0.2.10 Cut C
|
||||
* relaxed the `raw_text 불변` policy → `raw_text 가변 + note_revisions 보존`,
|
||||
* but per-id baseline distinction is still required for sync determinism.
|
||||
*
|
||||
* v0.2.10 Cut C — INSERT/fork 시 동일 transaction 안에서 note_revisions 에
|
||||
* 'capture' 첫 revision INSERT (createdAt = edited_at). 미수행 시 first user
|
||||
* edit 직후 import 시점 본문이 history 에서 사라지는 회귀 (final review 발견).
|
||||
*
|
||||
* deletedAt merge (v0.2.3 #4, spec §8.2): source/dest 중 IS NOT NULL 우선
|
||||
* (삭제 보존). skip 케이스에서 source NN + dest NULL 일 때만 dest 갱신.
|
||||
@@ -736,6 +745,12 @@ export class NoteRepository {
|
||||
input.createdAt,
|
||||
input.updatedAt
|
||||
);
|
||||
this.db
|
||||
.prepare(
|
||||
`INSERT INTO note_revisions (note_id, raw_text, edited_at, edited_by)
|
||||
VALUES (?, ?, ?, 'capture')`
|
||||
)
|
||||
.run(finalId, input.rawText, input.createdAt);
|
||||
if (input.tags.length > 0) {
|
||||
const getOrInsertTag = this.db.prepare(
|
||||
`INSERT INTO tags(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET name=name RETURNING id`
|
||||
|
||||
Reference in New Issue
Block a user