ReviewOS

stacks/bench-review

epic: ship bench-review as a native iOS app (craft + stx)

#79
Open glennmichael123 opened this 9 days ago ·
9 days ago

What this is

Tracking issue for shipping bench-review as a native iOS app, following the pattern the wildloop sibling app already uses (stacks @stacksjs/mobile + craft-native).

It is not a rewrite. ./buddy build:ios generates an Xcode project whose app is a native shell loading this same STX site — one set of views, one set of routes, one deploy. Which server it loads is fixed at build time, with a bundled copy of the site as an offline fallback: if the server is unreachable (deploy, dropped connection, no signal) the app serves its own pages and returns to the server once it answers.

Already landed

  • chore(deps): upgrade stacks to 0.70.380 and add @stacksjs/mobile — @stacksjs/mobile first exists at 0.70.375, so the stacks pin had to move off 0.70.190. craft-native is pinned through overrides because @stacksjs/actions otherwise nests craft-native@0.0.55, whose exports map has no ./ios subpath, and the builder's own import('craft-native/ios') resolves to that nested copy and fails.
  • feat(mobile): add the iOS app config, icon, and ignore the generated project — config/mobile.ts, a 1024² alpha-free icon rendered from public/images/logos/logo.svg, and an ignore rule for the generated project.
  • feat(mobile): ship a lean offline bundle instead of all 3,593 pre-rendered pages — see below.

Current state: ** BUILD SUCCEEDED ** against the iPhone 17 Pro simulator SDK, producing a 13 MB .app.

The offline-bundle finding, since it shapes the rest

Pointing the offline copy at dist/ produced a 443 MB app — dist/ pre-renders a page per entity (290 MB of judges, 143 MB of courthouses, 121 KB × 3,593 pages). That fails App Store cellular download limits outright.

Those pages buy nothing offline: the API is unreachable then too, and bench renders entity content client-side from API data, so a bundled judges/1803.html shows the same empty state as the shared judges/_shell/* that is kept. scripts/build-offline-bundle.ts strips the per-entity trees:

beforeafter
bundle430 MB10.5 MB (−97.6%)
pages3,59345
.app443 MB13 MB

It fails above an 80 MB ceiling, so a future per-entity route missing from ENTITY_TREES surfaces as a build error rather than a quietly enormous app.

What is left

Filed separately, linked below:

  • #80 — universal links are entitled but no apple-app-site-association is served
  • #81 — no end-to-end tests for the native app (navigation, deep links, offline cold start)
  • #82 — no physical-device build path; everything so far is Simulator-only
  • #83 — courthouse tab routes have no shared shell, so they 404 offline
  • #84 — App Store submission readiness (privacy manifest gaps, Connect answers, UGC review notes)
  • #85 — benchreview.org is not deployed (blocks #80 and #82)

Adjacent, not mobile-specific but surfaced by this work: #86 (25 of 33 declared foreign keys missing from the live schema).

Android is deliberately out of scope for now; config/mobile.ts has an android section available when wanted.

Reference

~/Documents/Stacks/wildloop — same framework, mobile already shipped. Its scripts/run-mobile-e2e.ts (509 lines), scripts/run-ios-device.ts (276), scripts/generate-mobile-associations.ts (58) and .maestro/flows/ are the templates for the items above.

Sign in to comment on this issue.