docs: clarify rollout (no feature flag system) and sheet/dialog approach

This commit is contained in:
Grok
2026-06-17 13:14:42 -06:00
parent ddf82a0c66
commit 6545c2e0d4
@@ -356,6 +356,15 @@ Editorial-meets-field. Fraunces for numbers, prices, and the few serif headlines
- `StickyActionBar` — pending badge, conflict state - `StickyActionBar` — pending badge, conflict state
- `OfflineBanner` — appears on `offline` event, hidden on `online` - `OfflineBanner` — appears on `offline` event, hidden on `online`
- `StatusPill` — every status × every color combination renders the right aria-label - `StatusPill` — every status × every color combination renders the right aria-label
- `MoreSheet` — opens via More button, traps focus, closes on Escape and backdrop click, restores focus on close
**UI primitives:** No dialog/sheet library (vaul, radix, headlessui) is currently in the project. `MoreSheet` and the various bottom sheets (filter, status changer, stock stepper) use the native `<dialog>` element with `showModal()` + the View Transitions API for open/close animation. This is a deliberate choice to keep the bundle small for the PWA. The native `<dialog>` is well-supported in Safari 15.4+, Chrome 37+, and Firefox 98+ — all versions we target.
**Pull-to-refresh:** Custom implementation using pointer events on a sentinel element at the top of each list. We avoid adding a third-party pull-to-refresh library to keep the bundle small. The custom implementation is ~80 lines, respects `overscroll-behavior: contain`, and falls back to no-op if the user has indicated motion sensitivity.
**Tap-to-call / tap-to-email:** Implemented with explicit `tel:` and `mailto:` URL schemes on `<a>` tags (not buttons that call `window.location`). This ensures the OS handles the routing (e.g., FaceTime prompts on iOS, Gmail/Outlook chooser on Android) and is accessible to screen readers out of the box.
**Color contrast test exclusions:** `text-faint` is the only token below WCAG AAA (it's 5.3:1, passing AA only). The test in `src/lib/__tests__/design-tokens.test.ts` will assert AAA (7:1) for every token combination *except* `text-faint`, which is tested at AA (4.5:1). This is documented in the test file as an intentional exception.
### E2E (Playwright) ### E2E (Playwright)
@@ -455,18 +464,18 @@ New spec: `tests/mobile-admin/offline-queue.spec.ts`
- `src/app/layout.tsx` (PWA meta tags, viewport.fit, themeColor) - `src/app/layout.tsx` (PWA meta tags, viewport.fit, themeColor)
- `src/components/Providers.tsx` (call `registerServiceWorker()`) - `src/components/Providers.tsx` (call `registerServiceWorker()`)
- `src/app/admin/layout.tsx` (mount `PWAInstallPrompt` + `OfflineBanner`, swap sidebar for `AdminShell`) - `src/app/admin/layout.tsx` (mount `PWAInstallPrompt` + `OfflineBanner`, swap sidebar for `AdminShell`)
- `src/app/admin/page.tsx` (Dashboard card layout) - `src/app/admin/v2/page.tsx` (Dashboard card layout — new v2 route)
- `src/app/admin/orders/page.tsx` (CardList) - `src/app/admin/v2/orders/page.tsx` (CardList — new v2 route)
- `src/app/admin/orders/[id]/page.tsx` (card layout + StickyActionBar + offline-queue integration) - `src/app/admin/v2/orders/[id]/page.tsx` (card layout + StickyActionBar + offline-queue integration — new v2 route)
- `src/app/admin/stops/page.tsx` (time-grouped card list) - `src/app/admin/v2/stops/page.tsx` (time-grouped card list — new v2 route)
- `src/app/admin/products/page.tsx` (image-forward card list) - `src/app/admin/v2/products/page.tsx` (image-forward card list — new v2 route)
- `src/app/globals.css` (new type scale, color tokens, spacing) - `next.config.ts` (cache headers for static assets; cutover redirects in PRs 6 and 8)
- `src/styles/admin-design-system.css` (admin-specific tokens)
- `next.config.ts` (cache headers for static assets)
- `playwright.config.ts` (add `mobile-admin` project at iPhone 13 viewport) - `playwright.config.ts` (add `mobile-admin` project at iPhone 13 viewport)
- `src/lib/pwa.ts` (small fixes: `load` listener guard, dev-only logging) - `src/lib/pwa.ts` (small fixes: `load` listener guard, dev-only logging)
- `src/app/page.tsx` (favicon ref fix) - `src/app/page.tsx` (favicon ref fix)
Note: the v1 admin pages (`src/app/admin/page.tsx`, `src/app/admin/orders/page.tsx`, etc.) are **not** modified by PRs 15. They continue to serve the existing desktop layout until the cutover PRs redirect their routes to v2. After cutover, the v1 files are deleted in a follow-up commit.
--- ---
## Open questions (deferred) ## Open questions (deferred)
@@ -489,14 +498,25 @@ New spec: `tests/mobile-admin/offline-queue.spec.ts`
## Rollout plan ## Rollout plan
> **Note on feature flags:** The project has a `src/lib/feature-flags.ts` system, but it's for **brand-scoped add-on features** (Harvest Reach, Square Sync, etc.), not for app-wide UI rollouts. There is no general-purpose feature flag system in this codebase. We will use a **route-based dual-deployment** strategy for rollout:
>
> - PRs 12 (design system + PWA scaffolding) are non-breaking; they add the new infrastructure without changing existing routes.
> - PRs 35 (Orders, Stops, Products) ship the new mobile-first versions at **`/admin/v2/orders`**, **`/admin/v2/stops`**, **`/admin/v2/products`**, and **`/admin/v2/orders/[id]`** initially. The old `/admin/orders` etc. routes continue to work unchanged. Internal team dogfoods at `/admin/v2/*` for 12 weeks.
> - PR 6 cuts over: a redirect in `next.config.ts` sends `/admin/orders*` → `/admin/v2/orders*`, etc. The old routes are removed in a follow-up commit.
> - PR 7 (Dashboard at `/admin/v2`) follows the same pattern.
>
> This avoids the need to introduce a feature flag system, which would be a separate piece of work.
1. **PR 1 — Design system + admin shell** — type scale, color tokens, AdminShell, MobileTabBar, MoreSheet, offline queue + sync. No page changes yet. Lighthouse PWA gate added. 1. **PR 1 — Design system + admin shell** — type scale, color tokens, AdminShell, MobileTabBar, MoreSheet, offline queue + sync. No page changes yet. Lighthouse PWA gate added.
2. **PR 2 — PWA manifest + SW + icons + offline page** — PWA installable, splash, themed status bar. All tests pass. 2. **PR 2 — PWA manifest + SW + icons + offline page** — PWA installable, splash, themed status bar. All tests pass.
3. **PR 3 — Orders (list + detail)** — first page on the new design language. Validates the components in real use. 3. **PR 3 — Orders v2 (list + detail)** at `/admin/v2/orders/*` — first page on the new design language. Validates the components in real use.
4. **PR 4 — Stops** 4. **PR 4 — Stops v2** at `/admin/v2/stops`
5. **PR 5 — Products** 5. **PR 5 — Products v2** at `/admin/v2/products`
6. **PR 6 — Dashboard** (depends on the new `get_dashboard_summary` RPC migration) 6. **PR 6 — Cutover Orders + Stops + Products** — redirects in `next.config.ts`; old routes removed in a follow-up commit
7. **PR 7 — Dashboard v2** at `/admin/v2` (depends on the new `get_dashboard_summary` RPC migration)
8. **PR 8 — Dashboard cutover** — redirect `/admin``/admin/v2`; remove old dashboard
Each PR is independently shippable behind a feature flag (`ADMIN_MOBILE_V2`) so we can dogfood it internally before cutting over. The desktop layout is never affected until the flag is on for everyone. Each PR is independently shippable and reversible. The desktop layout is never affected until cutover PRs land.
--- ---