wulf-pulse/.planning/phases/04-tickets-restyle/04-03-SUMMARY.md

4.3 KiB


phase: 04 plan: 03 subsystem: mobile-tickets-detail tags: [mobile, tickets, header, navigation, accessibility] dependency_graph: requires: [] provides: [ticket-detail-header-D18] affects: [app/mobile/tickets/[id]/page.tsx] tech_stack: added: [] patterns: [three-slot-header, external-link-with-noopener] key_files: modified: - app/mobile/tickets/[id]/page.tsx decisions:

  • Desktop URL chosen as /analyzer/ticket/{id} (in-app, stays in auth boundary; UI-SPEC permits either Autotask direct URL or analyzer URL)
  • rel="noopener noreferrer" added per T-04-11 threat mitigation (reverse tabnabbing defense-in-depth, even on same-origin)
  • -mx-4 px-4 technique extends header band to parent div's edges so border-b runs full-width under the new header bar metrics: duration_minutes: 5 completed_date: "2026-05-03" tasks_completed: 1 files_changed: 1

Phase 4 Plan 3: Detail Page In-Page Header Reskin Summary

One-liner: Three-slot in-page header on /mobile/tickets/[id] — back chevron + breadcrumb + external-link icon — replacing the legacy Back button per D-18.


What Changed

Exact Lines Modified in app/mobile/tickets/[id]/page.tsx

Import line (line 7): Added ExternalLink to the named lucide-react import, alphabetically between Eye and Mail. All existing imports retained.

Header bar (lines ~240-264, replacing ~240-242): The legacy single-line back button:

<button onClick={() => router.back()} className="flex items-center gap-1 text-sm text-muted-foreground mb-3 hover:text-foreground">
  <ArrowLeft className="w-4 h-4" /> Back
</button>

Was replaced with the D-18 three-slot header bar (25 lines). The replacement lives inside the existing <div className="px-4 pt-4 pb-3 border-b"> parent — that wrapper was NOT changed. The new inner div uses -mx-4 px-4 to extend to the parent's edges so its border-b runs full-width as a visual separator between the new header and the body below.


Desktop URL Choice

/analyzer/ticket/{id} was used as the desktop link target.

Rationale: The analyzer ticket view (/analyzer/ticket/{id}) is the canonical in-app desktop view of a ticket in this codebase. It stays within the auth boundary (same domain, same session cookie), so the user lands on a fully functional desktop page rather than being redirected to an external system. The UI-SPEC permits either the Autotask direct URL or the analyzer URL — the analyzer URL is preferred per the plan's spec note.


D-19 Body Untouched — Confirmation

The following sections were preserved verbatim (not modified):

Section Preserved
Badges row (flex items-start gap-2 mb-2 — priority + ticket# + status pills) Yes
<h1 className="text-base font-bold leading-snug"> ticket title Yes
Metadata icons row (Briefcase / User / Clock) Yes
3-card stats grid (Notes / Time entries / Hours logged) Yes
Description Collapsible block (AlignLeft icon, raw/formatted toggle) Yes
Timeline section (filter toggles, TimelineCard list) Yes
TimelineCard component definition Yes
loading and error states Yes
Helper functions: fmtDate, fmtHours, renderContent, relTime Yes (note: relTime is not in this file — lives in the list page; all helpers in this file preserved)
Constant maps: STATUS_LABEL, PRIORITY_LABEL, PRIORITY_COLOR Yes

Parallel Execution

This plan (04-03) ran in parallel with 04-01 and 04-02 in wave 1. There is no shared file conflict — 04-03 only touches app/mobile/tickets/[id]/page.tsx, while 04-01 touches app/api/mobile/tickets/route.ts and 04-02 touches app/mobile/tickets/page.tsx. No merge conflicts expected.


Deviations from Plan

None — plan executed exactly as written.


Known Stubs

None. The header bar is fully wired: router.back() for navigation, ticket.ticket_number for breadcrumb text, ticket.id for the external link href. No placeholder values.


Threat Flags

No new threat surface beyond what was declared in the plan's threat model (T-04-11, T-04-12). T-04-11 mitigation (rel="noopener noreferrer") is implemented.


Self-Check

Checking created file and commit:

  • app/mobile/tickets/[id]/page.tsx — FOUND
  • Commit b1ff866 — FOUND
  • 04-03-SUMMARY.md — FOUND

Self-Check: PASSED