3.4 KiB
3.4 KiB
Plan: Rename Cascade + Duplicate Check
Features
- After renaming a person/project/company, update all @mentions in existing text
- On rename: prevent duplicate names of the same type
Affected Files
| File | Change |
|---|---|
client/src/lib/utils/mentionReplace.ts |
NEW — renameMentions(text, oldName, newName, type) |
client/src/lib/db/repositories.ts |
ADD renameMentionCascade(oldName, newName, type) |
client/src/lib/components/ContextHeader.svelte |
UPDATE saveEdit() — duplicate check + cascade; add warning UI |
New File: mentionReplace.ts
Pure function, no Dexie dependency.
export function renameMentions(
text: string,
oldName: string,
newName: string,
type: 'person' | 'project' | 'company'
): string
Regex patterns to replace:
| Type | Unquoted | Quoted |
|---|---|---|
| person | @OldName |
@"Old Name" |
| project | @P:OldName / @p:OldName |
@P:"Old Name" |
| company | @F:OldName / @f:OldName |
@F:"Old Name" |
| assignment (person only) | -> OldName |
n/a (not supported by extractors) |
Replacement: use quoteMention-logic — add quotes if newName contains spaces.
Boundary condition: match must end at [\w"] boundary to avoid partial matches (e.g. @Alice must not match @AliceBob).
renameMentionCascade in repositories.ts
Run in a single Dexie transaction (rw on historyEntries, topics, contexts, ratings).
Fields to scan:
| Table | Field | Notes |
|---|---|---|
historyEntries |
text |
Primary mention location |
topics |
title |
Inline mentions possible |
contexts |
meta.notes |
PersonMeta / ProjectMeta / CompanyMeta only |
ratings |
comment |
Optional, may have @mentions |
ratings |
personName |
Structured field, person rename only (exact match) |
For each changed record: increment version, update updatedAt.
Pattern to follow: renameTitleInLinks() already exists in repositories.ts (line ~541).
ContextHeader.svelte — saveEdit() changes
1. trimmed = nameInput.trim()
2. if trimmed === editableName() → return (no-op)
3. if type is person/project/company:
- check contextNameExists(fullName(trimmed), type)
- if exists AND id !== context.id → show duplicate warning, revert, return
4. oldName = editableName()
5. await upsertContext({ id, name: fullName(trimmed) })
6. if type is person/project/company:
- await renameMentionCascade(oldName, trimmed, type)
Add duplicateWarning state + small error message below input.
Sequencing
mentionReplace.ts— implement + manual regex testsrepositories.ts— addrenameMentionCascadeContextHeader.svelte— wire up
Open Questions
-> Namewith spaces:extractors.tsarrow pattern only matches[\w]+. If renamed from single-word to multi-word, arrow assignments break silently. Extend extractors to support-> "First Last", or accept as edge case?EventMeta.participants: Plainstring[], not mention syntax. Update on person rename?- Case-only rename (Alice → ALICE):
contextNameExistsis case-insensitive — will incorrectly block. Need to exclude self from duplicate check. - Performance: Full table scan (no text index). Acceptable for local-first small datasets — add a comment.
- Sync conflicts: Cascade causes many
version++. Last-write-wins acceptable, or need special marker?