Skip to content

Outhere mobile app, every prototype screen, on Supabase - #4

Merged
EmotiveImpact merged 121 commits into
mainfrom
claude/mobile-app-build-nhob8r
Oct 16, 2026
Merged

EmotiveImpact merged 121 commits into
mainfrom
claude/mobile-app-build-nhob8r

Conversation

@EmotiveImpact

@EmotiveImpact EmotiveImpact commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Requested by Edem · project thread

Before: the app ran entirely on the phone with simulated players. It had no database, used the older green look, and covered only part of the prototype.

After: the mobile app has every screen of prototype demo v29 that a phone app can show, in the approved dark midnight design, on a real Supabase schema that every Outhere app shares. Rings mean membership. A blue dot means out now and a red dot means just stopped. In the stories row the ring shows the story instead: bright blue until watched, thin grey after. Without Supabase settings, the app still runs on local demo data.

This PR sits on top of #6.

What's in the app.

  • Getting started: a launch screen, then onboarding for anyone in the UK: email code, Apple or Google sign in, username, goal, city or town, crew and motion. There are under 18 rules.
  • Home: the stories row and the outside now carousel.
  • Move: live runs and walks with routes, splits, the climb chart, history, sharing and safety. A live race shows lanes against your rival.
  • Outside: the arena, challenges, drops with checkout and orders, events with tickets, QR check-in and who's going, and news.
  • Battles: all six modes, the season and fair play review.
  • Swipe: picks, challengers, the reveal and mystery challengers, all over 18 only.
  • Cities: city v city, call-ups, rising places, the hex map and countdowns. Smaller towns play for their region until they reach 100 active.
  • Crew: club chat, the feed, calendar, run clubs, founding and claiming, the club league and friendlies.
  • Stories: Pro and Black post.
  • Profile and money: membership (Pro £5.99 a month or £59.99 a year, Black £12.99 a month or £129.99 a year), wallet, friends, badges, emotes and settings.

Finish and the lush layer.

  • Every area was restyled on a shared Skia finish kit (components/ui, FINISH.md) and checked side by side against the prototype.
  • Skia shaders (components/ui/shaders): a brushed sheen on the Black card, aurora skies, shimmering live tug bars, liquid step rings and bars, foil on badges and emotes, and city lights on the night side of the globe. Live canvases pause off screen, in the background and under reduce motion.
  • Feel: a named haptics vocabulary (services/haptics.js) wired into countdowns, swipes, results, holds and checkout, plus rolling digit numbers and lift on press.
  • Real 3D (components/three, three.js through react-three/fiber): the race lobby globe, loaded on demand with the Skia globe as the fallback. A 3D coin was tried and dropped; the wallet keeps its coin image.
  • /lush (Settings › The lush layer) shows all of it on one page.

Screen audit. All 189 demo screens were checked in a browser. 174 are built: 122 match, 22 have small differences, and for 30 the app has the newer version of the screen. The 15 not built need native targets: the Apple Watch, the home-screen widget, and the lock screen and Live Activity. The full list is in the project files (outhere-mobile-build/screen-audit.md).

How. supabase/ holds 25 migrations, the seed and DB tests that run on plain Postgres. Anything that moves XP, OUT, tiers or results goes through a database function, and pg_cron settles battles, fixtures and friendlies. Story photos live on Cloudflare R2 behind the story-media Edge Function. scripts/build_setup_sql.py writes one SQL Editor file: it wipes the database, then runs every migration, the seed and the migration history, in one transaction. apps/mobile/src/data/source.js picks remote.js (Supabase) or engine.js (local).

Checks. The Mobile and Database workflows pass. Locally, every DB test passes on a fresh build and on a wiped-and-rebuilt one. Jest passes 106 of 106 tests, tsc is clean, and the web export works.

Known gaps.

  • The typing indicator is local only.
  • There are no direct messages.
  • Cards can't be saved as images; Save copies the result line instead.
  • The ticket doesn't brighten the screen.
  • The text size setting doesn't change text size yet.
  • Garmin and Strava say coming soon.
  • Home's drop slide still lists drops in pounds.

Still to do on the hosted project (bpquinogyvlgjtpppktc).

  • Edem runs the setup file.
  • Deploy story-media.
  • Edem sets the R2 and Vault secrets and turns on the Apple and Google sign-in providers.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV

- Make apps/mobile the only app: remove the old Emergent frontend/ app
  and generated root files (model.patch, test_result.md, move_events.js,
  Task.zip, empty test dirs)
- Remove the Anything (create.xyz) runtime from apps/mobile: global fetch
  override, launcher menu, remote error reporting, sandbox messaging,
  unused auth/upload helpers and the @anythingai/app dependency
- Fix step sync posting 0 steps every 30s (stale closure) and use the
  local calendar day
- Only show DEV BYPASS in development builds; a failed signup no longer
  onboards a local-only account
- Wait for the persisted user store before routing, so onboarded users
  aren't sent back to /welcome
- Remove the committed Mapbox token; route planning falls back to OSRM
- App identity: OutHere name, outhere scheme, com.outhere.app bundle ID,
  real permission strings; stop committing the generated ios/ project
- Use Apple Maps on iOS (Google Maps needs an SDK and key we don't ship)
- Install react-native-calendars from npm instead of a GitHub tarball
- Backend: installable requirements.txt, correct .env.example, tests
  moved to backend/tests
- Docs: add Docs/ROADMAP.md and point docs at apps/mobile

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZUVp63ghHjfkQMuinHMsq
The app now runs entirely on the phone until a server stack is chosen.
engine.js owns state in AsyncStorage, simulates seeded players and applies
the XP, OUT, streak, battle, crew, event, drop and reward rules. hooks.js
wraps it in React Query; components/ui is the shared design kit. The root
layout gates on the stored profile and syncs the pedometer into the engine.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZUVp63ghHjfkQMuinHMsq
Home, Outside (arena, events, drops, news), Move, Crew and Profile, plus
detail routes for battles, events, drops, news, crews and players, and new
membership, rewards, notifications and settings screens. All mock data,
/api fetches and dead buttons are gone. Removes the old API client, user
and club stores, and the unused Mapbox and RevenueCat packages so the app
runs in Expo Go.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZUVp63ghHjfkQMuinHMsq
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZUVp63ghHjfkQMuinHMsq
Springy presses, entrance motion, count-up numbers, skeleton loading,
toasts for every action, shared sheets, and Cover artwork with bundled
photography so nothing renders as a grey box. Reworked heroes and layouts
on Home, Outside, Move, Crew, Profile and every detail screen.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZUVp63ghHjfkQMuinHMsq
Green is kept for the primary action, progress, the live dot and the
active tab. Glows, gradients, borders and nested boxes are gone, type
carries the hierarchy, and every screen has more room to breathe.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZUVp63ghHjfkQMuinHMsq
… 600

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZUVp63ghHjfkQMuinHMsq
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZUVp63ghHjfkQMuinHMsq
Seven migrations cover people, places, run clubs, events, steps and runs,
the out-now dot, the XP and OUT ledger, battles in six modes, challenges,
the city and club leagues, feed, stories, club chat, notifications,
safety, subscriptions, the club fund, Outhere Locals and drops. Every
table has RLS and anything that moves XP, OUT, tiers or results goes
through a SECURITY DEFINER function.

supabase/tests/run.sh applies them to plain Postgres and checks the
rules; CI runs it on every change under supabase/.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
@EmotiveImpact EmotiveImpact self-assigned this Oct 15, 2026
The app now follows the approved concept demo: dark midnight colours,
Barlow Condensed headlines with Inter copy, surfaces lit from above,
blue gradient buttons and a floating tab bar in Edem's order (Home,
Move, Outside, Crew, Profile) whose active tab glows.

Every photo wears its membership ring (Free grey, Pro blue glow, Black
gunmetal with a travelling light) and the out-now dot (blue while out,
red once stopped). In a 1v1 you are blue and the rival is red.

Home is rebuilt to fit one screen: greeting with the PRO or BLACK mark,
friends row, two-tone headline, goal dial, three quick buttons and the
auto-sliding outside now carousel. Arena, Challenges (streak flame and
month calendar, now a tab inside Outside), Crew and Profile get photo
heroes, and Move's start panel ends in a Touch grass button. The seeded
world uses the bundled Outhere photography instead of remote stock.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
- data/source.js picks the Supabase adapter (data/remote.js) when
  EXPO_PUBLIC_SUPABASE_URL is set, the local engine otherwise
- remote.js maps profiles, steps, wallet, people, dots, leaderboards,
  challenges, battles, clubs, chat, runs, events, drops and
  notifications onto the schema's tables and functions
- onboarding asks for an email code first in Supabase mode
- event check-in takes the organiser's code
- new finish_onboarding function pays the welcome bonus once

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
…ghtly purge

- In the Home stories row the ring now shows the story alone: bright
  blue until watched, then thin grey. Membership rings stay everywhere
  else; dots unchanged.
- stories gain an audience (public, followers, club) and saved_at for
  highlights; RLS and the storage read policy follow the story row, so
  signed URLs only work for people allowed to see it.
- purge-stories edge function, scheduled nightly by pg_cron, removes
  expired unsaved stories through the Storage API.
- services/media.js keeps story files behind one small interface and
  resizes photos to 1080px WebP before upload.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
… step, mobile CI

Story photos upload straight to R2 through presigned links from the
story-media Edge Function, which also signs views against the story's
audience and purges expired stories each night. Adds the full screen
story viewer with emotes, posting for Pro and Black, the logo and slide
to start Welcome, a daily goal step, new app icons and a mobile workflow.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV

Copy link
Copy Markdown
Owner Author

CI on this PR is red, but no job has actually run. Every job (check, functions, migrations) finishes in about 2 seconds with no steps, no log and no output, on this commit and on all earlier ones. That pattern is GitHub refusing to start Actions runners for the account, usually because of a billing or spending limit, rather than a failure in the code.

The same checks pass locally on 31a924c: database rules and RLS tests, regenerated types with no diff, tsc, 12 jest tests, web export in both modes, deno check on story-media and the 4 R2 signing tests.

To fix it, check Settings, Billing and plans (Actions usage and spending limit) on the EmotiveImpact account. Once runners start, a push or a re-run will show the real result, and I'll fix anything that comes up.


Generated by Claude Code

Moves the website thread's apps/site/db/website.sql into supabase/ as a
migration, with its tests, so one schema serves every app. The tables
have RLS on and no grants; the site reaches them only through four
anon-callable functions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
EmotiveImpact pushed a commit that referenced this pull request Oct 15, 2026
The waitlist, club claims and Black requests now live in
supabase/migrations/20261015100900_website.sql (PR #4), so drop
apps/site/db and the website's own database CI job, and point the
docs there.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A3KTjkLAXTgUTh3vXAChDA
…led blind trial, ghost, last one standing, hold the route

Database: ready_battle, submit_battle_result scored from a saved run, mode-aware
settling, battle_entry_count to stop the entries policy recursing. Each DB test
file now runs in its own copy of the database.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
… going official, fixtures settling, club v club friendlies

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
Find a run club (near me, tonight, beginners), club runs with RSVP by pace
group and check-in, founding clubs and their road to official, claiming a
club with Instagram, Strava or video call proof, the club league table and
weekly derby fixture, and friendlies: challenge a club or a mystery club in
five modes, members vote, captains accept. Works on the local engine and on
Supabase.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
outhere-site Ready Ready Preview Oct 16, 2026 10:50am UTC

…oad function

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
…app in

The phone app is now the @outhere/mobile workspace package. Its npm
overrides and patch-package patches moved to pnpm-workspace.yaml (two stale
RevenueCat patches dropped), its package-lock.json is gone, CI installs with
pnpm, and it takes counted steps and the reserved slugs from packages/core.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
@EmotiveImpact
EmotiveImpact changed the base branch from claude/project-thread-jn157m to claude/web-app-build-nig9rl October 15, 2026 13:12
…s, staff actions

One new migration (20261015101300_web_gaps.sql) with tests:
- profiles.public_profile with a profile_cards view for the public basics
- clubs.tags, filters and join_policy; club_members.pace_group;
  club_join_requests with decide_join_request; join_club returns
  joined or requested
- rename_club with reserved slugs copied from packages/core rules.ts
- club_message_reactions, club_channel_reads, read_channel, club_unread,
  club_channels.description
- borough_week_steps view
- staff RPCs verify_club, review_steps, remove_from_squad, set_reveal_held,
  each writing audit_log; seasons.reveal_held holds settle_due_fixtures
- badges and member_badges, seeded, awarded by award_badge from triggers
- notifications.actor_id, events.activity, battles.stake_note, 120 hour
  battles, and respond_battle telling the challenger on decline

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
claude and others added 25 commits October 16, 2026 06:02
Serves the Expo web export as a single page app, with canvaskit.wasm sent
as application/wasm and long cache headers on hashed files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
…card lifts

Haptics gains a vocabulary of thirteen named moments (tap, select, beat, go,
swipe, commit, win, lose, levelUp, holdTick, holdDone, slideEnd, warn), each a
composed pattern from one table that also draws the waveform in the demo, all
silent on the web and in the simulator. GlowButton takes a haptic prop, the
countdowns beat and go, swipe, hold to finish, slide to start, off route, GPS
lost, stakes, drop claims and results all fire their moment.

Rolling.jsx adds RollingNumber (every digit a wheel on a spring, staggered
from the right, separators still, reduce motion jumps), CountUp on the kit's
expo ease, and Lift, the spring from a card into its page. Applied to the
wallet and profile OUT balances, live battle scores, the home step count, the
run summary distance, the battle results and the blind reveal, and the club
and drop cards.

The Feel section of the lush layer demos all three.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
Five runtime effects on a Reanimated clock, each a wrapper that measures,
falls back to plain views until Skia is ready and pauses when it cannot be
seen (background, another screen on top, scrolled away, reduced motion):

- Sheen: brushed metal with a light that sweeps across every six seconds.
  The Black membership card is now drawn with it (BlackCard) on the plan
  picker, compare plans and Welcome to Black, and the profile's card row.
- Aurora: soft ribbons of light on a near-black sky, behind the welcome
  hero, the city call-up and Welcome to Black.
- Shimmer: the live tug of war with a heat ripple and a hot core (TugBar
  live), on the live battle and the live club fixture. Meter gains liquid;
  the Home step ring and the manage membership OUT bar fill as a liquid.
- Foil: holographic foil masked to the object, on badges and emotes.
- City lights: the race globe's night side, with twinkling cities, a soft
  terminator and a thin atmosphere; CityLights draws a planet on its own.

The lush layer's Shaders section shows each one at its real size.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
…rter labels

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
three.js and react-three/fiber (exact versions, React 19 and RN 0.81) behind
components/three, loaded on demand so screens that never ask pay nothing.
Globe3D: a night Earth with shader-drawn land dots from the coastline table,
city lights as one Points, a thin fresnel atmosphere, pins and a glowing
arc with sparks; drag to turn. Coin3D: a thick brushed steel coin with the
mark embossed, lit by a painted studio environment, with a spring flip.
The race lobby and the wallet balance card swap them in once 3D is ready
and keep their Skia and image versions until then. The lush page's 3D tab
shows both plus a status card with the frame cost on this device.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
A CountUp changes its value every 70ms, and a layout entering animation that
restarts on every render left new columns stuck below the line until the
count finished. Each column now slides in from below and out upwards on its
own shared values, with columns that have just gone kept for 200ms to leave.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
The 3D OUT coin was turned down. The wallet goes back to its coin image,
the 3D tab on /lush shows only the globe and the status card, and the
coin scene is removed. The frame cost card says when the figures come
from a software renderer rather than a GPU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
The race lobby draws a three.js globe once 3D has loaded and keeps the
Skia globe until then; the Skia clock still pauses off screen. The pin
cards now keep their names and cities clear of the screen edge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
Bars, the tug bar and the step ring are now Skia paths painted by a
shader, with two blurred copies underneath, on canvases that bleed past
the track, so the edges are antialiased and the glow fades out into the
card instead of stopping at a box or a circle. The white caps, sparks
and flow bands are tinted with the tone. The foil is a cool
iridescence on the highlights with a glint and a blurred blue bloom
behind the object. The aurora has curtains with fine rays and its sky
feathers into whatever holds it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
Edem found the bar and badge bloom too feathered and blurry. The bar
bloom is narrower and fainter, the head glow and tug spark smaller,
the light washes tighter, and the badge bloom only comes off the lit
parts at about half the strength.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
Edem found the bars too blurry and missed the white. Each bar now has a
sharp white specular line, a slanted white glint that runs its length,
and on the tug bar white comets stream to a white-hot core where the two
sides meet. The aurora goes back to the original ribbons, which Edem
preferred.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
Each look draws the whole bar from one shader over a capsule distance
field, on a canvas that bleeds past the bar, so the edge is antialiased
and the glow falls away smoothly. Meter, TugBar, LiquidBar and Shimmer
take a look prop; without one they draw as before. The lush demo shows
the three side by side so Edem can choose.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
Edem picked neon. The core is now steady and smooth (no flicker in its
width), the halo is even with a gentle breath, the tip is a clean round
light and the meeting point is a white-hot dot with one thin flare. The
step ring is drawn the same way from an arc distance field. The old
bar, tug and ring drawings are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV
Constants for the pack (slots, pose sets, credit rules, runner choice and
scan steps), the fighterPhoto helper that picks pack picture, own photo or a
runner silhouette, and the bundled silhouettes and sample pictures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
The versus split now matches the approved mock: light edge tints, a red
glow on the rival's side, a seam that fades with the photos, a centred VS
with its bloom, and names with blue and red bars (VersusName). Every place
that fell back to the stock fighter now uses fighterPhoto: pack picture,
then own photo, then a silhouette from the runner choice. The live battle
and the profile show a Make your pack pill until a pack exists; results
show the win or respect pose. Your runner (Man, Woman, Rather not say) is
asked in onboarding and in Settings, Your profile.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
…ew, poses

Built to the approved mock as a bank style ID check: a four step bar,
consent with one tick, three simple rules, then a live front camera scan
that captures looking ahead, left and right on its own while the ring
fills. Verified shows before any credits are spent. The pictures land one
by one, the review puts each in its place with a re-roll, and the poses
screen shows Black's locked poses. Free members see what the pack is and
how to get it; under 18s stop at the door. Settings gets a Fighter Pack row.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
Runner choice on profiles, the avatar_credits ledger with join grants on
the ring moving up and a monthly top-up (pg_cron), consent and scan
records, packs and pictures with refunds for failures, pose picks with
the Pro and Black rules, and fighter_of / profiles.fighter /
profile_cards.fighter / fighter_cards so player reads get the pictures.
RPCs: pack_state, pack_credits, record_pack_consent, start_pack,
reroll_pack_slot, set_pack_pose, delete_pack. Types regenerated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
… cleanup

Actions selfie-url, verify, generate, webhook, delete and cleanup. Selfies go
to the private bucket and are removed within 24 hours; pictures land in the
public bucket. The fal webhook is checked by ED25519 signature and an optional
token. R2 gains head and put.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
makePack runs credits, consent, the scan, making, re-rolls and pose picks on
the phone; makeRemotePack does the same over the RPCs and avatar-pack.
setRunner, and runner, runnerFigure and fighter on the profile and every
player view. usePackState and usePackCredits hooks, and a pack upload helper.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
The scan now takes each shot on a timer, so reduced motion still holds
every angle. The local pack uses the portrait sample for the profile and
swipe pictures, the profile slab frames a pack background lower down, the
pack door shows an error with a retry instead of loading forever, and the
runner segment fits.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
Fighter Pack: AI pictures of members across the game
@EmotiveImpact
EmotiveImpact changed the base branch from claude/web-app-build-nig9rl to main October 16, 2026 10:40
@EmotiveImpact
EmotiveImpact marked this pull request as ready for review October 16, 2026 10:40
Regenerates pnpm-lock.yaml with pnpm rather than by hand.

With the phone app in the workspace, the flat node_modules hoists React
19.1.0 (React Native's) to the root while react-dom 19.3.1 sits beside it,
so the web apps loaded two Reacts: the website's prerender failed, the
member app's server pages returned 500 and Outhere HQ rendered blank. Each
web app now dedupes React, and the server builds bundle it, so react-dom
always uses the app's own copy.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015oE2zAkm15foN26zFA3prv
@EmotiveImpact
EmotiveImpact merged commit d5f2028 into main Oct 16, 2026
10 checks passed

This branch was successfully deployed

1 active deployment
Preview — 4e0c2a8d Deployed Oct 16, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants