Repository navigation
Outhere mobile app, every prototype screen, on Supabase - #4
Conversation
- 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
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
|
CI on this PR is red, but no job has actually run. Every job ( The same checks pass locally on 31a924c: database rules and RLS tests, regenerated types with no diff, 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
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
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…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
…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
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
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
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.
Finish and the lush layer.
components/ui,FINISH.md) and checked side by side against the prototype.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.services/haptics.js) wired into countdowns, swipes, results, holds and checkout, plus rolling digit numbers and lift on press.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 thestory-mediaEdge Function.scripts/build_setup_sql.pywrites 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.jspicksremote.js(Supabase) orengine.js(local).Checks. The
MobileandDatabaseworkflows 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.
Still to do on the hosted project (bpquinogyvlgjtpppktc).
story-media.🤖 Generated with Claude Code
https://claude.ai/code/session_01GuNoar5FSdqFXBKo7d7CmV