Build Log · June 22, 2026

Hearth: Copied Item Polish

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

  • Hearth
  • UX
  • Data Model
  • Bug Fix
duplicate detection fix
1

duplicate detection fix

time ghost closed
1

time ghost closed

new server action
1

new server action

RouteItemCard label paths
2

RouteItemCard label paths

Timeline

  1. Start

    Plan review + time ghost catch

    Zeb flagged scheduledTime on copied items implies today's time — plan adjusted before build

  2. 20m

    Duplicate detection fix

    OR(sourceRouteItemId, sourceGoogleEventId) — defensive null guard

  3. 40m

    removeFromTodayRoute action

    Hard delete of Hearth copy only — guard, delete, revalidate /today + /week

  4. 1h

    RouteItemCard: source label + time suppression

    isCopiedItem → liveScheduledTime = null, buildSourceLabel shows original day/time

  5. 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