Skip to content

Repository files navigation

Presence — Web MVP

A shared virtual home for long-distance couples. The home is a mirror for the relationship: stay attentive and it glows; go quiet and it visibly softens — plants wilt, music stops, candles go dark. No scores, no points. The home state is the feedback.

This repo is the playable web MVP (Phase 1 core loop from the PRD) plus a Node + MongoDB backend ready to grow into the full product.


Run it in 10 seconds (no setup)

Open public/index.html in any browser. That's it. The app runs fully offline using browser storage — onboard, tend the home, run rituals, watch it decay and restore.

Tip: use the demo bar at the bottom (+6h, +2d, partner, reset) to fast-forward decay and simulate your partner arriving, so you can feel weeks of the loop in seconds and experience both sides solo.

Run it as a real shared home (two people)

This is the sync mode: real accounts, a partner invite link, one shared home, and live updates between partners.

npm install
cp .env.example .env          # point MONGODB_URI at local mongod or Atlas
npm start                     # http://localhost:3000

Then flip the client to sync mode — in public/index.html:

window.PRESENCE_CONFIG = { mode: 'sync', apiBase: '/api' };

Flow: sign up → Invite my partner gives you a link → open it in a second browser/device, sign up, Join this home. Now both of you share one home — water the plant on one screen and it updates on the other, candles light when you're both connected, letters and songs cross over live.

How the sync works (no third-party realtime service needed):

  • Accounts: scrypt-hashed passwords + signed tokens (server/auth.js).
  • Live updates: Server-Sent Events per couple (/api/stream) push partner actions and presence; candles light only when both are connected.

Data model (hybrid)

Two layers, each playing to its strength:

  • Slim live-state doc (Snapshot, one per couple) — only the bounded, always-needed state: each object's health + last-restored time, the current song, streak, candle/presence, and a capped notification list. Small and fast to read/write on every interaction. Decayed on read, mutated on each ritual (server/engine-core.js).
  • Append-only history collectionsMemory, Letter, and Ritual, one document per event. They grow without bloating the live doc (no 16MB-document ceiling), are independently queryable (memory wall, anniversary video, analytics), and — because each is its own insert — don't suffer the read-modify-write race two partners would hit when sharing one blob.

The client receives the same assembled game shape either way, so the UI doesn't care which layer a field came from.

Concurrency note: history writes are race-free. The slim live-state doc is still read-modify-write; under heavy simultaneous use the final hardening step is per-object atomic updates (move object health to a GameObject collection with $inc/$max). Not needed at MVP scale.

(There's also a simpler account-less mode: 'api' that shares one demo home via /api/state — handy for quick local testing.)

Run the decay job (the PRD's pg_cron equivalent) on a schedule or once:

npm run decay                 # loops every 6h
node server/decay.js --once   # single pass

Run it as a native iOS/Android app (Expo)

There's a native shell in mobile/ that wraps this web client and adds push notifications. With your phone on the same Wi-Fi:

npm start                 # backend, in the project root (one terminal)
cd mobile && npm install && npx expo start   # second terminal

Install Expo Go on your phone and scan the QR code. Full guide: mobile/README.md.

What's implemented (vs. the PRD)

Area Status
Home renders as a warm, lit 2D scene (5 rooms) ✅ SVG/CSS (stands in for Pixi.js)
Objects: plant, fridge, record player, letterbox, candles, garden ✅ all six, 4 health states each
Decay logic (per-object rates, warmth = avg of 3) ✅ §2.3 / §5.2 faithful
Warmth → ambient light mapping (full→dormant) ✅ §2.3
Async rituals: water plant, drop song, leave letter
Sync rituals: morning coffee, cook together ✅ (simulated, single-player)
Memory wall (polaroid grid, milestone pinning) ✅ §6
Poetic notification feed ("Home, speaking") ✅ §8 copy, home's-perspective
Candle / presence mechanic ✅ partner-online toggles candles §2.4
Streak + garden day-30 unlock
Onboarding (name → date → starter theme) ✅ §9 condensed
MongoDB models matching PRD schema ✅ §2.2 (Postgres → Mongoose)
REST API + seed + decay job
Real accounts + partner invite/join ✅ sync mode
One shared home between two people ✅ server-authoritative
Live partner updates + presence ✅ SSE (Realtime stand-in) §2.4
Native iOS/Android app ✅ Expo WebView shell (mobile/)
Push notifications to partner's phone ✅ Expo Push on ritual/join §8

Not in this MVP (later phases, by design)

Supabase Realtime (we use SSE), Daily.co voice, Spotify OAuth, Remotion anniversary video, RevenueCat paywalls, and the Printful book. The engine and schema are structured so these drop in without a rewrite. See Path to the App Store.


Project layout

public/                 the playable web client (open index.html)
  index.html
  styles.css            warmth-driven lighting, sheets, animations
  js/
    engine.js           decay / warmth / rituals — pure logic, framework-free
    store.js            persistence: localStorage  OR  MongoDB API
    home.js             SVG home renderer (4 health states per object)
    ui.js               onboarding, object sheets, rituals, memory wall
    sync.js             sync mode: auth, invite/join, SSE, server rituals
    app.js              bootstrap + demo controls (chooses local vs sync)
server/                 Node + Express + MongoDB
  server.js             API + static hosting
  db.js                 mongoose connection
  auth.js               password hashing + signed tokens
  routes.js             auth, invite/join, shared home, rituals, SSE presence
  engine-core.js        server-authoritative decay/warmth/ritual logic
  models/index.js       PRD schema as Mongoose models
  decay.js              pg_cron-equivalent decay job
  seed.js               demo couple + home + objects
scripts/                verification tests (run: npm test)

Tests

npm test     # auth, engine parity, API routes, SVG render, two-partner sync

61 checks across six suites: 16 engine logic (decay rates, restoration, streak, day-30 garden unlock), 6 auth (hashing + tokens), 3 client/server rule parity, 8 API routes, 6 SVG render, and a 22-check two-partner simulation (signup → invite → join → shared rituals → live presence → letters → auth guards).


Path to the App Store / Play Store

This web app can't be submitted to the stores directly — that requires Apple and Google developer accounts, code signing, and native build/test devices. The intended route, matching the PRD:

  1. Wrap this client in Expo (React Native) via a WebView, or port the screens to React Native and keep engine.js as shared logic.
  2. Swap browser storage for Supabase/Mongo + real auth and partner invite.
  3. Add Expo push, then submit through EAS Build → App Store Connect / Play Console.

The decay/warmth engine, schema, and ritual model here are the parts you'd otherwise rebuild — they carry straight over.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages