ForgeKitFORGEKIT

Build Log

Hearth: Copied Item Polish

June 22, 2026

Tighter dedup, honest time display, source labels, and remove — the loop is coherent. Ready for Courtney.

HearthUXData ModelBug Fix
1
duplicate detection fix
1
time ghost closed
1
new server action
2
RouteItemCard label paths

Timeline

Start
Plan review + time ghost catch
Zeb flagged scheduledTime on copied items implies today's time — plan adjusted before build
20m
Duplicate detection fix
OR(sourceRouteItemId, sourceGoogleEventId) — defensive null guard
40m
removeFromTodayRoute action
Hard delete of Hearth copy only — guard, delete, revalidate /today + /week
1h
RouteItemCard: source label + time suppression
isCopiedItem → liveScheduledTime = null, buildSourceLabel shows original day/time
1.5h
Remove button + tsc clean
Copied items: Done + Trash2 only. Native items: unchanged. tsc passes.

What shipped

addToTodayRoute: OR duplicate check — sourceRouteItemId OR sourceGoogleEventId (only when source.googleEventId exists — avoids eq(field, null) weirdness)

removeFromTodayRoute server action: fetches item, guards on sourceRouteItemId || sourceGoogleEventId, hard-deletes Hearth copy, revalidates /today and /week — Google Calendar untouched

RouteItemCard: isCopiedItem = !!(sourceRouteItemId || sourceGoogleEventId)

RouteItemCard: liveScheduledTime = isCopiedItem ? null : item.scheduledTime — copied items never render a clock time badge

RouteItemCard: buildSourceLabel() — 'From Google Calendar · Original: Sat 10:00 AM' or 'Added from Week · Original: Tue' — quiet italic text-[10px]

RouteItemCard: copied items get Done + Trash2 (destructive ghost) only — Move/Skip/Note hidden since they don't apply to a reminder-copy

RouteItemCard: removed state returns null immediately on client — no flicker waiting for revalidation

Hearth should feel like a calm route, not a calendar in a trench coat.

Zeb, plan review
Hearth: Copied Item Polish — June 22, 2026 · ForgeKit