You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two distinct "fingerprints", kept separate: publishId (the hex folder name — the un-friendly one, being killed) vs lastPublishedHash (invisible content hash for drift — kept).
Repo layout
flyers/
otevrene-hranice/ ← readable slug (display only)
v1.md ← frontmatter keeps publishId = a3f9c2e8… (true identity)
v2.md
v2-logo.png
otevrene-hranice-a3f9/ ← only on slug collision with a different flyer
Identity stays publishId in frontmatter; import matches on it, never the folder name.
Drift hash excludes version + publishedAt — serializeFlyer embeds both, so they'd always read as drifted. Hash a normalized payload (markdown + effectiveMeta + logo).
Collision check = one GET on the target slug folder: 404 → use slug; contains my publishId → same flyer, new version; contains a different publishId → append short id.
Non-atomic move (contents API is per-file): copy all versions → verify → delete old last. A mid-failure leaves harmless duplicates, never data loss; locate-logic tolerates a publishId in two folders (pick highest version, clean stragglers next run).
Version derived before the move; new folder ends contiguous v1..vN.
Goal
One "release" feature with two halves:
flyers/<12-hex-publishId>/vN.mdfolders with readable slug folders.Two distinct "fingerprints", kept separate:
publishId(the hex folder name — the un-friendly one, being killed) vslastPublishedHash(invisible content hash for drift — kept).Repo layout
publishIdin frontmatter; import matches on it, never the folder name.flyer-<publishId>.-a3f9).<hex>/folder is renamed to its slug.lastPublishedSlugon the concept row (O(1)); if missing after a DB wipe → one repo scan, then repopulate.Sidebar release status
Persist
lastPublishedHash+lastPublishedAton publish. Three states, following the existingreviewStatusbadge/stripe pattern,--ui-*chrome only:publishId == nullhash(current) == lastPublishedHashv3 · 8.7.hash(current) != lastPublishedHashv3 · změněnoVocabulary: keep "Publikovat"/"Publikováno"; drift = "změněno".
Implementation notes (seams)
version+publishedAt—serializeFlyerembeds both, so they'd always read as drifted. Hash a normalized payload (markdown + effectiveMeta + logo).v1..vN.Touches:
src/lib/githubPublish.ts,src/lib/flyerFile.ts,src/db/schema.ts(addlastPublishedHash,lastPublishedAt,lastPublishedSlug),handlePublishinEditorLayout.tsx,Sidebar.tsx.