Part of EPIC #193. Depends on #194.
Description
Add a canonicalPath: String field to the Project model (SharedModels) and its SwiftData ProjectModel. Implement a lightweight VersionedSchema migration — the new column is nullable. On first load, lazy-backfill canonicalPath via ProjectID(path:) and persist. Keep the UUID id for backward compatibility. Update ProjectRepository.addProject to deduplicate by canonicalPath rather than raw path.
Acceptance Criteria
Module / Layer
SharedModels + Persistence / Data
Complexity
Medium
Part of EPIC #193. Depends on #194.
Description
Add a
canonicalPath: Stringfield to theProjectmodel (SharedModels) and its SwiftDataProjectModel. Implement a lightweightVersionedSchemamigration — the new column is nullable. On first load, lazy-backfillcanonicalPathviaProjectID(path:)and persist. Keep theUUID idfor backward compatibility. UpdateProjectRepository.addProjectto deduplicate bycanonicalPathrather than rawpath.Acceptance Criteria
VersionedSchema.V2added with a migration path from V1ProjectRepository.addProject(url:)deduplicates viacanonicalPathcanonicalPathpopulated~/work/projand/Users/me/work/proj) inaddProjectresult in a single entryswiftlint lint --strictcleanModule / Layer
SharedModels + Persistence / Data
Complexity
Medium