mirror of
https://github.com/Matysh/houseplan-card
synced 2026-07-31 16:38:31 +00:00
fix v1.44.2: external review CR-1..CR-3
CR-1: the lock invariant is restated precisely (never by an accidental
tap; the door card's labeled button is the ONE sanctioned surface),
unlocking now confirms, and smoke_lock_invariant exercises all five
actuation paths (icon tap, controls[], card entities, _cardToggle,
opening card).
CR-2: attachment migration is transactional — the server COPIES files,
the config is committed with its revision check, and only then the old
folder is removed via the new houseplan/files/cleanup. A rejected save
no longer leaves the stored urls pointing at an emptied folder.
CR-3: migrate returns an exact {source: written} mapping; only confirmed
copies are rewritten, destination name collisions get a unique name
instead of silently linking a pre-existing file, and a failed migration
raises a toast instead of being swallowed.
+1 unit test (119), +1 backend test, +1 smoke (51 total); docs
same-commit
This commit is contained in:
+15
-2
@@ -1070,12 +1070,25 @@ export function roomFillModeOf(
|
||||
* server moves /files/<oldId>/ to /files/<newId>/, the urls must follow.
|
||||
*/
|
||||
export function migratePdfUrls<T extends { url: string }>(
|
||||
pdfs: T[], oldId: string, newId: string,
|
||||
pdfs: T[], oldId: string, newId: string, mapping?: Record<string, string>,
|
||||
): T[] {
|
||||
if (!oldId || !newId || oldId === newId) return pdfs;
|
||||
const from = '/files/' + oldId + '/';
|
||||
const to = '/files/' + newId + '/';
|
||||
return pdfs.map((p) => (p.url.includes(from) ? { ...p, url: p.url.split(from).join(to) } : p));
|
||||
return pdfs.map((p) => {
|
||||
if (!p.url.includes(from)) return p;
|
||||
const tail = p.url.split(from)[1] || '';
|
||||
const [name, query] = [tail.split('?')[0], tail.includes('?') ? '?' + tail.split('?')[1] : ''];
|
||||
if (mapping) {
|
||||
// review CR-3: rewrite ONLY files the server confirmed it copied, and use
|
||||
// the name it actually wrote (collisions get a unique name). A url that
|
||||
// was not copied keeps pointing at the still-existing old folder.
|
||||
const dst = mapping[decodeURIComponent(name)] ?? mapping[name];
|
||||
if (!dst) return p;
|
||||
return { ...p, url: p.url.split(from + name)[0] + to + encodeURIComponent(dst) + query };
|
||||
}
|
||||
return { ...p, url: p.url.split(from).join(to) };
|
||||
});
|
||||
}
|
||||
|
||||
// ---------------- kiosk gestures ----------------
|
||||
|
||||
Reference in New Issue
Block a user