Add Projects: third tab, swipe-to-file, per-project note capture

Notes gain an optional project (schema v4, additive). Projects derive
from note values like tags — no separate entity. Tab naming
(Projects/Categories) is a Settings choice applied across the UI.

Claude-Session: https://claude.ai/code/session_014esDWi42URLEC6Cj17hGQ3
This commit is contained in:
2026-07-16 18:24:11 -04:00
parent a8085865bc
commit b2f16e8600
14 changed files with 395 additions and 11 deletions
+15
View File
@@ -43,6 +43,21 @@ struct NoteMapperTests {
#expect(all.first?.tags == ["coffee", "people"])
}
@Test func upsertWritesProjectAndNoteRestoresIt() throws {
let (container, context) = try makeStore()
defer { withExtendedLifetime(container) {} }
var note = makeNote()
note.payload.project = "Kitchen Remodel"
NoteMapper.upsert(note, relativePath: note.relativePath, into: context)
let entity = try #require(NoteMapper.fetch(id: note.meta.id.stringValue, in: context))
#expect(entity.project == "Kitchen Remodel")
let restored = try #require(NoteMapper.note(from: entity))
#expect(restored.payload.project == "Kitchen Remodel")
#expect(restored.payload == note.payload)
}
@Test func entityRoundTripsBackToNote() throws {
let (container, context) = try makeStore()
defer { withExtendedLifetime(container) {} }