Commit graph

340 commits

Author SHA1 Message Date
1979463d05 docs(phase-5): evolve PROJECT.md after phase completion 2026-05-03 20:29:11 -04:00
62668ce8df docs(phase-5): complete phase execution 2026-05-03 20:28:51 -04:00
a7759e3029 test(05): persist human verification items as UAT 2026-05-03 20:02:36 -04:00
3b582ace53 docs(05-02): complete finance page restyle plan summary
- Finance page rewritten to Phase 5 visual contract (FIN-01, FIN-02)
- 4 KpiCardMobile tiles, 2 shadcn Collapsibles, stacked revenue list
- All 23 locked decisions (D-01 through D-23) delivered
- Phase 5 complete: both plans committed and summarized
2026-05-03 19:58:15 -04:00
a9a5a987f4 feat(05-02): rewrite mobile finance page to Phase 5 visual contract
- Replace AR Hero gradient + standalone Revenue YTD with 4 KpiCardMobile tiles (2x2 grid)
- Drop bar chart; add monthly-revenue stacked list (D-09 / DASH-04 precedent)
- Add shadcn Collapsible for Open Invoices and Recent Payments (D-15, D-16)
- Aging row uses locked amber/orange/destructive palette (D-08)
- Top AR by Customer rendered as stacked list with proportion bars (D-07)
- toast.success + toast.error on sync outcomes (D-17, D-18)
- FinanceSkeleton on initial load; destructive retry card on error (D-17, D-18)
- D-19 empty state when total_ar===0 and open_invoices.length===0
- D-23: no page H1; header controls row with aria-labels (D-14)
- No font-medium, no font-bold, no raw red/yellow/green Tailwind classes
2026-05-03 19:56:36 -04:00
1ce80371d1 docs(05-01): complete FinanceRow + FinanceSkeleton plan
- FinanceRow: 2-line stacked row with amountTone variants (D-06)
- FinanceSkeleton: initial-load placeholder matching full page layout (D-17)
- Both components type-check clean, no files outside components/mobile/ modified
2026-05-03 19:53:14 -04:00
5f7fc29e67 feat(05-01): create FinanceSkeleton component
- Initial-load placeholder for /mobile/finance (D-17)
- 2x2 KPI grid (h-20) + 3-cell aging row (h-16) + 2x list-row blocks (3 rows each)
- Uses Skeleton primitive from components/ui/skeleton
- Locked spacing tokens: px-4 py-4, space-y-6, gap-3, gap-2, space-y-3
- No props, no Card wrapper, no custom animation per UI-SPEC
2026-05-03 19:52:25 -04:00
180ab517e6 feat(05-01): create FinanceRow component
- 2-line stacked row for invoice and payment lists (D-06)
- Exports FinanceRow + FinanceRowProps per UI-SPEC contract
- Supports amountTone destructive/positive/default variants
- No priority stripe, no interactive handlers (read-only per D-22)
- Phase comment block per Phase 3/4 convention
2026-05-03 19:52:02 -04:00
a0ccd14044 docs(05): create phase plan 2026-05-03 19:48:15 -04:00
6a4a55cb9c docs(05): UI design contract 2026-05-03 19:41:38 -04:00
91987ccaa1 docs(05): UI design contract for finance restyle
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 19:32:54 -04:00
cdfa527ebd docs(05): capture phase context 2026-05-03 19:29:54 -04:00
322900dafe docs(phase-4): evolve PROJECT.md after phase completion 2026-05-03 19:28:03 -04:00
5206d8d2ef docs(phase-4): complete phase execution 2026-05-03 19:27:45 -04:00
5b6a8ff5d5 test(04): persist human verification items as UAT 2026-05-03 18:17:18 -04:00
5d87455e49 feat(04-02): rewrite mobile tickets list page with URL-synced filters, priority stripes, and IntersectionObserver infinite scroll
Cherry-picked from 04-02 worktree (b27db7d, 4ba89a0). The full worktree merge
included unrelated regressions of phase 2/3 work — only the intended changes
(app/mobile/tickets/page.tsx + SUMMARY.md) were kept.

- Suspense wrapper for useSearchParams (Next.js 16 requirement)
- URL-synced filter state via router.replace
- TicketFilterStrip wired with controlled props
- Priority-stripe rows (border-l-4 with red/orange/amber/slate)
- IntersectionObserver infinite scroll + Load more fallback
- toast.error() in load catch blocks per D-21
- Empty states per D-20
2026-05-03 18:12:00 -04:00
422ea2bd0e chore: merge executor worktree (04-03) 2026-05-03 18:04:35 -04:00
bbcb04fe3b docs(04-01): complete cursor-pagination API and filter components plan summary 2026-05-03 18:03:14 -04:00
9e10d654ad feat(04-01): add TicketRowSkeleton and TicketFilterStrip presentational components
TicketRowSkeleton (D-21):
- border-l-4 border-muted stripe + 3 Skeleton lines matching ticket row layout
- 5 instances rendered during initial load

TicketFilterStrip (D-01 through D-04):
- Sticky top-0 container with always-visible search input
- Collapsible panel with status chips (Open/In Progress/Waiting), priority chips
  (Critical/High/Medium/Low), queue Select, and mine Switch
- Controlled component — URL sync is parent's responsibility (D-05)
- Active filter count badge in Filters button
- Clear all button appears only when isFiltered (D-04)
- Exports TicketFilterValue and QueueOption interfaces for Plan 02 import
2026-05-03 18:02:13 -04:00
9658640c04 fix(04-01): restore phase 2/3 work lost by worktree soft-reset
The soft reset to 77073ba inadvertently staged deletions of all phase 2
and 3 artifacts. This commit restores them from their source commits so
subsequent task commits build on the complete prior-phase foundation:
- components/mobile/{BottomNav,HeaderBar,KpiCardMobile,MoreDrawer,NeedsAttentionStrip,WorkerStatusRow}
- app/mobile/layout.tsx, dashboard/page.tsx, analyzer/page.tsx
- app/api/mobile/dashboard/route.ts
- All .planning/** files from phases 01-04
- CLAUDE.md, app/layout.tsx, app/styles/brand.css, public/manifest.json
2026-05-03 18:01:14 -04:00
6268d1fe37 feat(04-01): rewrite /api/mobile/tickets with cursor pagination and exported interfaces
- Replace page/offset pagination with opaque base64 cursor (last_activity_date, id)
- Export MobileTicket and MobileTicketListResponse interfaces for Plan 02 import
- Add requireAuth() gate (T-04-03: legacy route lacked auth)
- Server-side limit cap at 25 rows (D-11, T-04-04)
- Default status filter [1,8,7] when no status param supplied (matches legacy t.status != 5)
- Preserve getMobileCompanyFilter() helper verbatim
- Support status/priority arrays, queue, mine, and search filters
- Cursor seek predicate: (last_activity_date, id) < (cursor) for stable keyset order
2026-05-03 17:59:54 -04:00
2ce26da290 docs(04-03): complete detail header reskin plan summary 2026-05-03 17:59:34 -04:00
b1ff8660d4 feat(04-03): reskin /mobile/tickets/[id] in-page header per D-18
- Add ExternalLink to lucide-react imports
- Replace legacy 'Back' button with three-slot header bar:
  back chevron + 'Tickets' label (router.back()), breadcrumb
  'Tickets / #{ticket_number}', ExternalLink icon to /analyzer/ticket/{id}
- rel='noopener noreferrer' + target='_blank' on external link (T-04-11)
- Detail body (badges, title, stats grid, description, timeline) unchanged per D-19
2026-05-03 17:58:51 -04:00
77073bac97 docs(04): create phase plan 2026-05-03 17:53:50 -04:00
bf780790d5 docs(04): UI design contract 2026-05-03 17:45:42 -04:00
16bc4aa5c9 docs(04): UI design contract for tickets-restyle phase
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 17:40:16 -04:00
83f326c3d1 docs(state): record phase 4 context session 2026-05-03 17:37:10 -04:00
28b5845ee8 docs(04): capture phase context 2026-05-03 17:37:05 -04:00
05a3d44045 docs(phase-3): evolve PROJECT.md after phase completion 2026-05-03 17:09:34 -04:00
7374b94db5 docs(phase-3): complete phase execution 2026-05-03 17:09:13 -04:00
dc8696900b test(03): persist human verification items as UAT 2026-05-03 16:57:42 -04:00
45c8a5d4f5 docs(03-02): complete mobile dashboard page assembly plan summary
- 118-line replacement of app/mobile/dashboard/page.tsx
- DASH-01..04 all satisfied; zero recharts; type-check clean
2026-05-03 16:54:11 -04:00
52562503c0 feat(03-02): replace mobile dashboard page with 3-section layout
- Drop legacy recharts/chart sections, priority breakdown, SLA bars, queue list, recent activity
- Add 2x2 KPI grid (DASH-01), Needs Attention horizontal strip (DASH-02), Worker/backup status row (DASH-03)
- Wire KpiCardMobile, NeedsAttentionStrip, WorkerStatusRow against /api/mobile/dashboard
- Inline error state with Retry button, spinner while loading, refresh button in H1 row
- Zero recharts imports (DASH-04); 118 lines
2026-05-03 16:53:35 -04:00
464c02a7f4 docs(03-01): complete dashboard API + components plan summary 2026-05-03 16:51:30 -04:00
bfe9549d02 feat(03-01): add KpiCardMobile, NeedsAttentionStrip, WorkerStatusRow components
- KpiCardMobile: phone-sized KPI card with label/value/caption; tone='attention' adds destructive left border
- NeedsAttentionStrip: horizontal-scroll strip of compact attention cards; renders null when items=[]
- WorkerStatusRow: 3-cell status row with emerald/amber/destructive status dots, each linking to desktop admin
- All three are pure presentational client components; no fetch, no recharts, no new state libraries
2026-05-03 16:50:35 -04:00
24e20c7ae7 feat(03-01): rewrite /api/mobile/dashboard to return kpis/needsAttention/workers shape
- Exports MobileDashboardResponse, KpiResponse, AttentionResponse, WorkerResponse interfaces
- Single Promise.all with 6 parameterless queries (KPI, failed backups, stalled workflows, analyzer, RMM, backup success)
- Ticket KPIs exclude out-of-scope companies via company_scope filter
- SLA breaches tone='attention' when value > 0
- Worker status rules: down if fail_1h>0 and in_flight=0, warn if fail_1h>0, otherwise ok
- Backup status: ok >= 95%, warn >= 80%, down otherwise
2026-05-03 16:49:49 -04:00
e5e444b36d docs(03): recover plan files and ROADMAP.md after planner worktree-base bug
The planner agent's commit (d597415) was created from a worktree branch
based on master rather than the current feature branch HEAD. The soft-reset
safety check staged a deletion of ROADMAP.md (which exists in the feature
branch but not master), and that deletion was bundled into the agent's
commit. The plan files themselves were never added to the index.

Recovery: stage the on-disk ROADMAP.md (with the planner's Phase 3 updates)
plus the two new PLAN.md files, and commit them cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 16:31:56 -04:00
170800fb43 docs(phase-03): record planning complete in state 2026-05-03 16:31:00 -04:00
d597415a2f docs(03): create phase plan 2026-05-03 16:28:27 -04:00
7455d1171a docs(phase-02): evolve PROJECT.md after phase completion 2026-05-03 16:17:25 -04:00
53b453d5af docs(phase-02): complete phase execution 2026-05-03 16:16:56 -04:00
8b33dd7955 test(02): persist human verification items as UAT 2026-05-03 16:16:53 -04:00
cc8a584f3f docs(02-02): complete mobile shell wiring plan
- SUMMARY.md: layout rewrite + nav/page.tsx deletion, all 15 phase requirements closed
- STATE.md: decisions, metrics, session recorded
- ROADMAP.md: Phase 02 marked Complete (2/2 plans done)
- REQUIREMENTS.md: SHELL-01, SHELL-05, DRAWER-06 marked complete
2026-05-03 16:12:25 -04:00
2af73955ae feat(02-02): delete app/mobile/nav/page.tsx (DRAWER-06)
- Standalone nav page replaced by MoreDrawer Sheet component
- Visiting /mobile/nav now returns Next.js 404 per DRAWER-06 spec
- No redirect needed — URL was never bookmarked-worthy
2026-05-03 16:09:51 -04:00
7a095fbe53 feat(02-02): rewrite mobile layout to wire HeaderBar + BottomNav + MoreDrawer
- Replace legacy 3-tab layout with new shell components from Plan 01
- Single useState(drawerOpen) shared between avatar and More button triggers
- SHELL-05: main content padded pb-[calc(theme(spacing.16)+env(safe-area-inset-bottom))]
- max-w-lg mx-auto container, no legacy /mobile/nav reference
2026-05-03 16:09:35 -04:00
bb5b62af86 feat(02-01): add /mobile/analyzer placeholder so Analyzer tab does not 404
- Minimal server component with coming soon card
- No data fetching — Phase 6 (ANL-01..06) owns the real implementation
- Sparkles icon consistent with BottomNav tab icon
- Resolves NAV-02: Analyzer tab in bottom nav has a valid route
2026-05-03 16:08:00 -04:00
01943a6dc9 feat(02-01): create BottomNav component with 4 tabs + More button
- Fixed bottom bar with border-t bg-background pb-safe
- 4 tabs: Dashboard, Tickets, Finance, Analyzer linked to /mobile/* routes
- Active state via pathname.startsWith(href), text-primary when active
- More cell triggers onMoreClick prop (parent controls drawer state)
- max-w-lg mx-auto gutter alignment, h-16 (64px) touch targets
- Icons: LayoutDashboard, Ticket, DollarSign, Sparkles, Menu
- Implements SHELL-06, NAV-01..03, DRAWER-01 requirements
2026-05-03 16:08:00 -04:00
05611cd80e feat(02-01): create HeaderBar component with brand, Bell placeholder, avatar trigger
- Sticky header with bg-background/95 backdrop-blur and border-b
- WulfMark + Pulse wordmark linked to /mobile/dashboard
- Bell icon placeholder (aria-label=Notifications, empty onClick per SHELL-03)
- Avatar circle (h-7 w-7) triggers drawer via onAvatarClick prop
- pt-safe applied for notch/dynamic-island clearance (PWA-04)
- Implements SHELL-02..04 requirements
2026-05-03 16:08:00 -04:00
2ef843766d feat(02-01): create MoreDrawer component with Sheet, 3 sections, sign out
- shadcn Sheet side=right with controlled open/onOpenChange props
- Section 1: Mobile sections (Engagement in-shell route)
- Section 2: Full site links with ExternalLink hints (Quotes, Config Items, Backup Status, Ticket Digest, Admin/Sync)
- Section 3: Account — user initials display + sign out via Better Auth
- Implements DRAWER-01..05 requirements
2026-05-03 16:07:47 -04:00
08467494bf docs(02-01): complete plan 02-01 shell components summary
- HeaderBar, BottomNav, MoreDrawer, analyzer placeholder created
- TypeScript and Next.js build both pass (273 routes)
- Requirements SHELL-02..04, SHELL-06, NAV-01..03, DRAWER-01..05 addressed
2026-05-03 16:05:11 -04:00