Commit graph

219 commits

Author SHA1 Message Date
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
29ff7fd8fd docs(02): create phase plan 2026-05-03 14:48:41 -04:00
e67c51ec7c docs(02): generate context from PRD 2026-05-03 14:38:17 -04:00
9e29510721 docs(phase-01): evolve PROJECT.md after phase completion 2026-05-03 14:06:04 -04:00
8e6dcf01e1 docs(phase-01): complete phase execution 2026-05-03 14:05:36 -04:00
ca91390f1a test(01): persist human verification items as UAT 2026-05-03 14:03:05 -04:00
a293a4f662 docs(01-02): summarize PWA-04 safe-area utility gap closure
Closes the orphaned PWA-04 requirement flagged by 01-VERIFICATION.md.
Single edit to app/styles/brand.css adds @utility pt-safe and
@utility pb-safe; production build (load-bearing for Tailwind 4
@utility syntax) compiled successfully and emitted both classes
into the production CSS bundle.
2026-05-03 13:57:40 -04:00
dff0264115 feat(01-02): add pt-safe and pb-safe @utility blocks for safe-area insets
- Append @utility pt-safe { padding-top: env(safe-area-inset-top); }
- Append @utility pb-safe { padding-bottom: env(safe-area-inset-bottom); }
- Co-located with existing brand utilities; brand.css already imported by globals.css
- Closes PWA-04 (REQUIREMENTS.md) and ROADMAP Phase 1 SC #3
- Phase 2 sticky header → pt-safe; fixed bottom nav → pb-safe
2026-05-03 13:56:21 -04:00
4c641b9b16 docs(01-pwa-scaffolding): add gap closure plan 01-02 for PWA-04 safe-area utilities 2026-05-03 13:51:06 -04:00
76ced68ac1 docs(01-01): summarize PWA scaffolding plan execution
- Document manifest fields, viewport export shape, and verification results
- Record key decisions (theme_color #0075AD, background_color #FFFFFF,
  metadata.manifest API choice, icon reuse)
- No deviations from plan

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:39:55 -04:00
d196d22040 feat(01-01): add manifest reference and viewport export to root layout
- Add metadata.manifest = "/manifest.json" so Next.js emits
  <link rel="manifest"> automatically (PWA-02)
- Add separate viewport export (Next 16 API) with viewportFit: "cover"
  so Phase 2 can paint behind the home indicator (PWA-03)
- Include width: "device-width", initialScale: 1, and themeColor
  light/dark pair for clean mobile rendering
- RootLayout body unchanged

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:38:44 -04:00
3e3df24166 feat(01-01): add web app manifest for PWA install
- New public/manifest.json with name "Pulse", short_name "Pulse"
- display "standalone", start_url "/mobile", scope "/"
- theme_color #0075AD (Wulf brand blue), background_color #FFFFFF
- Reuses existing icons (/wulff-logo.png, /branding/wulf-mark.png, /favicon.png)
- No service worker, no next-pwa (per spec §4)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:38:08 -04:00
3c62240dc0 docs: create roadmap (8 phases) 2026-05-03 12:48:02 -04:00
7c6df27778 docs: define v1 requirements 2026-05-03 12:43:26 -04:00
d33b8b9131 chore: add project config 2026-05-03 12:41:40 -04:00
fe1401366f docs: initialize mobile shell redesign project 2026-05-03 12:38:56 -04:00
cf3b740d34 docs: map existing codebase 2026-05-03 12:32:06 -04:00
db375fb0e6 feat(admin): client scope — filter analytics to recurring-revenue companies
Adds company-level opt-out scoping so white-label / subcontract clients
(TTG, LEC, PER, VCF, Trivium Packaging, TNT Pizza, etc.) can be excluded
from Wulf's own dashboard KPIs and ticket analytics without affecting
per-company drill-down views.

- migration 082: company_scope table (opt-out; absent row = in scope)
- GET/PATCH /api/admin/company-scope[/companyId] — list + upsert
- /admin/client-scope — searchable company list with Switch per row,
  type filter, and in/out scope filter; excluded rows are dimmed
- dashboard overview KPIs now exclude out-of-scope company tickets
- analyzer /tickets query excludes out-of-scope when no specific
  client is selected (explicit per-company selection still works)
- "Client Scope" tile added to admin Tools & Data section

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 11:40:47 -04:00
2d4a546a8f fix(nav): replace NavigationMenu submenus with DropdownMenu
The Radix NavigationMenu uses a single shared viewport centered under
the full nav list. Opening a right-side submenu (Analyzer, Admin)
positioned the dropdown panel far to the left, so moving the mouse to
reach it crossed other triggers and closed it mid-way.

Switch all items-with-children to DropdownMenu, which positions each
panel directly under its own trigger. Keeps the same visual style
(navigationMenuTriggerStyle, ChevronDown, item layout with icon +
description) and active-state highlighting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 11:18:52 -04:00
370125d249 feat(admin): group integration toggles by category
Bucket the integration list under category headers (PSA, RMM,
Documentation, Security, …) following a canonical order, with
unrecognized categories appended after. Rows within a bucket sort
alphabetically by name.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 11:03:54 -04:00
344276751e refactor(nav): adopt PageHeader on /configuration-items
The page was rendering its own sticky <header> on top of the global
AppNavigation, which obscured the top nav and duplicated the
ThemeToggle and a redundant "Back to Dashboard" link.

Replace with PageHeader (title, description, breadcrumbs, actions slot
holding Refresh / Bulk-admin / Export) and switch the main container to
the conventional px-6 py-6.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 11:03:49 -04:00
43fbe7b0e1 fix(admin): dedupe device-link conflict candidates by ciId
The reconciler can emit the same configuration_item id multiple times
when more than one match rule fires (e.g. exact_serial AND
hostname_in_company). The page rendered each occurrence as a separate
row keyed on ciId, producing React duplicate-key errors.

Dedupe client-side keeping the strongest confidence (exact_serial > mac
> hostname_in_company > other) and use the deduped count in the badge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 11:03:44 -04:00