chore: check in pending work — queue preferences, QBO AR diagnostics, mobile engagement fixes, ops scripts
Bundles several in-progress efforts that were sitting uncommitted: - User queue-preferences (migration 087, API route, popover component) - QBO invoice soft-delete (migration 088) and AR diagnostics route - Dashboard/mobile engagement route and page adjustments - Docker Compose log-rotation config - One-off ticket/RMM investigation scripts (scripts/) - Planning docs: phase verification/pattern notes, mobile shell design spec - .gitignore: exclude local scratch financial/inventory data and Claude Code worktree/local-settings runtime state (never meant for version control) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6RuWdiUiXrPK6FLBHjtpY
This commit is contained in:
parent
b638189cb0
commit
672f17b7f9
35 changed files with 2801 additions and 92 deletions
221
docs/superpowers/specs/2026-05-03-mobile-shell-design.md
Normal file
221
docs/superpowers/specs/2026-05-03-mobile-shell-design.md
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
# Mobile Shell Redesign — Design Spec
|
||||
|
||||
**Date:** 2026-05-03
|
||||
**Scope:** `/mobile/*` shell, navigation, and per-page layouts on Pulse.
|
||||
|
||||
## 1. Goal & audience
|
||||
|
||||
Pulse's mobile shell exists for **managers on the go** — quick status checks,
|
||||
triage decisions, and read-only awareness. It is not a full replacement for the
|
||||
desktop app; pages where mobile editing isn't justified should link out to the
|
||||
desktop equivalent.
|
||||
|
||||
Success means a manager can:
|
||||
|
||||
- See the state of the business at a glance (Dashboard).
|
||||
- Triage and inspect tickets (Tickets).
|
||||
- Read AR / invoice / payment status (Finance).
|
||||
- Skim recent AI ticket analyses (Analyzer).
|
||||
- Reach Engagement and sign-out without clutter on the primary nav.
|
||||
|
||||
## 2. Approach
|
||||
|
||||
**Rebuild `/mobile` in place.** Keep all existing `/mobile/*` route paths
|
||||
(`/mobile/dashboard`, `/mobile/tickets`, `/mobile/tickets/[id]`,
|
||||
`/mobile/finance`). Replace `/mobile/layout.tsx`, the four page files, and
|
||||
delete `/mobile/nav` (its content moves into a Sheet drawer — see §3).
|
||||
|
||||
No new top-level routes. No parallel `/mobile-v2` directory. The existing pages
|
||||
stay their canonical URLs throughout the redesign.
|
||||
|
||||
## 3. Navigation
|
||||
|
||||
### 3.1 Bottom tab bar (primary)
|
||||
|
||||
Four tabs, equal-width, fixed to the bottom of the viewport:
|
||||
|
||||
| Tab | Icon (lucide) | Route |
|
||||
|------------|-------------------|---------------------|
|
||||
| Dashboard | `LayoutDashboard` | `/mobile/dashboard` |
|
||||
| Tickets | `Ticket` | `/mobile/tickets` |
|
||||
| Finance | `DollarSign` | `/mobile/finance` |
|
||||
| Analyzer | `Sparkles` | `/mobile/analyzer` |
|
||||
|
||||
Active state: `text-primary`; inactive: `text-muted-foreground`. Active
|
||||
detection via `pathname.startsWith(href)`.
|
||||
|
||||
### 3.2 "More" Sheet drawer (secondary)
|
||||
|
||||
A fifth control on the bottom bar — `Menu` icon labelled **More** — opens a
|
||||
shadcn `Sheet` (side="right", or "bottom" on phones; pick one and stay
|
||||
consistent). The drawer **replaces the standalone `/mobile/nav` page entirely**.
|
||||
|
||||
Drawer contents, top to bottom:
|
||||
|
||||
1. **Mobile sections** — Engagement (`/mobile/engagement`, see §6.5).
|
||||
2. **Full site** — link list to desktop pages that have no mobile view yet
|
||||
(Quotes, Configuration Items, Backup Status, Ticket Digest, Admin / Sync).
|
||||
Each link uses the `ExternalLink` icon hint to signal "leaves mobile shell".
|
||||
3. **Account** — current user (avatar + email, read-only), then **Sign out**
|
||||
(calls `signOut()` then `router.push('/auth/sign-in')`).
|
||||
|
||||
Delete `app/mobile/nav/page.tsx` after the drawer is in place.
|
||||
|
||||
## 4. PWA setup
|
||||
|
||||
- `public/manifest.json` — name "Pulse", short_name "Pulse", `display: "standalone"`,
|
||||
`start_url: "/mobile"`, theme/background colors matching the dark and light
|
||||
shells. Reference it from `app/layout.tsx` via `<link rel="manifest">`.
|
||||
- `viewport` meta in `app/layout.tsx` (or root metadata): include
|
||||
`viewport-fit=cover` so the shell can paint behind the home indicator.
|
||||
- **Safe-area insets** — both the sticky header and the bottom tab bar add
|
||||
`env(safe-area-inset-top)` / `env(safe-area-inset-bottom)` padding. Use
|
||||
Tailwind arbitrary values (`pt-[env(safe-area-inset-top)]`,
|
||||
`pb-[env(safe-area-inset-bottom)]`) or a small utility class.
|
||||
- **No service worker, no offline mode** in this iteration. Don't ship
|
||||
`next-pwa` or a custom SW — deferred until a clear offline use-case lands.
|
||||
- **Tablet** — `md:max-w-2xl mx-auto` wrapper is noted as a follow-up but is
|
||||
**not** part of this spec's deliverable. Keep the current `max-w-lg`.
|
||||
|
||||
## 5. Shell (`app/mobile/layout.tsx`)
|
||||
|
||||
### 5.1 Header
|
||||
|
||||
Sticky top, `bg-background/95 backdrop-blur`, bottom border. Three slots:
|
||||
|
||||
- **Left:** Wulf mark (existing logo asset) + "Pulse" wordmark, linked to
|
||||
`/mobile/dashboard`. Use the actual brand mark, not the text-only fallback.
|
||||
- **Right (in order):**
|
||||
- `Bell` icon button — **placeholder only**, no menu, no badge logic. Wire
|
||||
to `aria-label="Notifications"` and an empty `onClick` so it's
|
||||
keyboard-accessible. A future phase will turn this into a real list.
|
||||
- Compact user avatar (`Avatar` from shadcn, size `h-7 w-7`). On tap,
|
||||
opens the More drawer (so the avatar is the entry point alongside the
|
||||
bottom-bar More button).
|
||||
|
||||
No page title in the header — pages render their own H1 in the content area.
|
||||
|
||||
### 5.2 Content area
|
||||
|
||||
`<main>` between header and bottom nav, scrollable. Add bottom padding equal to
|
||||
the bottom-nav height + safe-area inset so content doesn't hide under the bar.
|
||||
|
||||
### 5.3 Bottom nav
|
||||
|
||||
Fixed, full-width, `border-t bg-background`. Wraps in `max-w-lg mx-auto` so
|
||||
content and nav share the same gutter. Five cells: 4 tabs (§3.1) + More (§3.2).
|
||||
|
||||
## 6. Pages
|
||||
|
||||
### 6.1 Dashboard (`/mobile/dashboard`)
|
||||
|
||||
Sections, top to bottom:
|
||||
|
||||
1. **2×2 KPI grid** — four primary metric cards. KPIs to choose from the
|
||||
desktop dashboard's hero stats; final selection during build, but the layout
|
||||
is fixed at 2×2 on phone widths.
|
||||
2. **"Needs Attention" strip** — horizontal scroll of compact cards
|
||||
surfacing items that require manager action (overdue tickets, failed
|
||||
backups, stalled workflows). Each card opens its detail view directly.
|
||||
3. **Backup / worker status** — compact status row showing the analyzer
|
||||
worker, RMM worker, and backup-success-rate at a glance. Read-only; tap
|
||||
opens the desktop admin page.
|
||||
|
||||
No charts on the mobile Dashboard in this iteration — recharts on small widths
|
||||
isn't earning its weight.
|
||||
|
||||
### 6.2 Tickets (`/mobile/tickets`)
|
||||
|
||||
- **Collapsible filter strip** at top (`Collapsible` from shadcn, default
|
||||
collapsed). When expanded: status, priority, queue, assigned-to-me toggle.
|
||||
Filter state syncs to the URL query string so deep-linking works.
|
||||
- **Priority-bar rows** — list rows have a left-edge color stripe by priority
|
||||
(Critical/High/Medium/Low → red/orange/amber/slate). Body shows ticket #,
|
||||
title, company, age, assignee. Single-tap opens detail.
|
||||
- **Infinite scroll** — replace the current pagination with cursor-based
|
||||
infinite scroll. Fetch in pages of ~25; trigger next page when the last row
|
||||
enters the viewport (IntersectionObserver). Keep a "Load more" fallback button
|
||||
for accessibility.
|
||||
- **Detail page** — keep `/mobile/tickets/[id]/page.tsx` largely as-is; only
|
||||
reskin the header to match the new shell (Wulf mark, breadcrumb back).
|
||||
|
||||
### 6.3 Finance (`/mobile/finance`)
|
||||
|
||||
Restyle of the existing page only. No new data, no new sections. Adopt the new
|
||||
Card and typography scale, fix any spacing that breaks on small phones. If a
|
||||
section currently relies on a wide table, swap it for a stacked list on mobile.
|
||||
|
||||
### 6.4 Analyzer (`/mobile/analyzer`) — NEW
|
||||
|
||||
**Read-only feed of recent AI ticket analyses.**
|
||||
|
||||
- List view: most-recent-first stream of analyses. Each row shows ticket #,
|
||||
title, the analyzer's one-line summary, confidence badge, and a stage
|
||||
indicator (Triage → Analyze → Deep Review). Tap opens a mobile summary view.
|
||||
- Mobile summary view: renders **Summary**, **Next Step**, **Next Step
|
||||
Rationale** (all already produced by the analyzer pipeline). Includes a "View
|
||||
full analysis" link out to the desktop analyzer page.
|
||||
- No editing, no re-run, no prompt tuning on mobile.
|
||||
- Source data: existing `analyzer_analyses` rows via a new
|
||||
`/api/mobile/analyzer/feed` endpoint (or reuse an existing list endpoint if
|
||||
one already returns the right shape).
|
||||
|
||||
### 6.5 Engagement (`/mobile/engagement`) — NEW, accessed via More drawer
|
||||
|
||||
Engagement gets a **real mobile refactor**, not a thin adaptation. The desktop
|
||||
page (`app/engagement/page.tsx`, ~1300 lines) and profile page
|
||||
(`app/engagement/profile/page.tsx`, ~650 lines) both rely on wide tables, dense
|
||||
charts, and modal patterns that don't translate to phone widths. Build the
|
||||
mobile views from the same data sources but with phone-first layouts.
|
||||
|
||||
**Overview (`/mobile/engagement`):**
|
||||
|
||||
- Period selector chip row (today / 7d / 30d) — sticky just below the page H1.
|
||||
- Summary cards stacked single-column (active users, total Graph hours, total
|
||||
Autotask hours, hours-per-active-user). No 4-up grid; reading numbers across
|
||||
a 4-up row on a phone is a non-starter.
|
||||
- Per-employee list as stacked rows (avatar / initials, name, role, hours
|
||||
bar). Sortable via a small control above the list (sort by hours, name,
|
||||
utilization). Search input above the list.
|
||||
- Charts: replace the desktop's wide bar/line charts with one compact "hours
|
||||
trend" sparkline at the top of the list, period-scoped. No multi-series
|
||||
chart on mobile in this iteration.
|
||||
|
||||
**User profile (`/mobile/engagement/profile?userId=...` or
|
||||
`/mobile/engagement/[userId]`):**
|
||||
|
||||
- Reuses the existing profile data endpoints. Layout is single-column:
|
||||
identity header → period selector → key metrics (compact) → activity
|
||||
breakdown list → recent items.
|
||||
- This **replaces** the desktop user-detail modal pattern on mobile —
|
||||
tapping a row navigates to a real page, not a modal, so the shell's back
|
||||
gesture works correctly.
|
||||
- Pick exactly one of the two route shapes above during build (prefer the
|
||||
`[userId]` segment form for shareable URLs); don't ship both.
|
||||
|
||||
Engagement is **not** on the bottom bar — it lives in the More drawer because
|
||||
managers don't check it as often as the four primary surfaces.
|
||||
|
||||
## 7. Out of scope (explicit non-goals)
|
||||
|
||||
- Service worker, offline cache, push notifications.
|
||||
- Tablet breakpoint (md:max-w-2xl) — noted, deferred.
|
||||
- Real notification list behind the bell.
|
||||
- Mobile editing on Engagement (user detail) or Analyzer (re-run, prompt edits).
|
||||
- Charts / recharts on mobile Dashboard.
|
||||
- Replacing or restyling the desktop pages reachable from the More drawer.
|
||||
|
||||
## 8. Build order
|
||||
|
||||
1. PWA scaffolding — `manifest.json`, viewport meta, safe-area utility.
|
||||
2. New `app/mobile/layout.tsx` — header, More drawer (Sheet), 5-cell bottom nav.
|
||||
Delete `app/mobile/nav/page.tsx` in the same change.
|
||||
3. Dashboard restyle (2×2 grid, Needs Attention, status row).
|
||||
4. Tickets restyle (filter Collapsible, priority-bar rows, infinite scroll).
|
||||
Detail page header reskin only.
|
||||
5. Finance restyle.
|
||||
6. Analyzer page + `/api/mobile/analyzer/feed` endpoint.
|
||||
7. Engagement Overview (`/mobile/engagement`) — phone-first layout from existing data sources.
|
||||
8. Engagement user profile (`/mobile/engagement/[userId]`) — replaces the desktop modal pattern with a real mobile page.
|
||||
|
||||
Each step ships independently — no big-bang merge.
|
||||
Loading…
Add table
Add a link
Reference in a new issue