English | 简体中文
A couples' interactive flying-chess (Ludo-style) game + platform skeleton. Same-screen local play + online room battles, with zone-based task cards, lucky/trap nodes, tiered penalties, and endgame scoring. Installable PWA ("Add to Home Screen").
Architecture in
docs/technology/, deployment indocs/deploy.md.
- Flying Chess Gameplay: Roll dice, take off, send opponents' pieces home. Board logic is defined once in
shared/game.ts, shared by frontend and server, with the server as the source of truth. - Zone-based Task Cards: Interaction tasks grouped by intimacy zone (see
web/src/data/taskset.ts); landing on a tile triggers the task for that zone. - Lucky / Trap Nodes: Special board tiles that trigger rewards/penalties or piece displacement (see
docs/technology/260801-积分与幸运陷阱节点.md). - Tiered Penalties: Penalty tasks are graded by difficulty (
feat/实现惩罚任务分级别). - Endgame Scoring: Both players' scores are settled at the end and stored in
Game.scoreA / scoreB. - Online Battles: Create rooms / lobby matchmaking, real-time sync, game locks, and automatic cleanup of empty rooms (Socket.IO).
- Account System: Registration / login, JWT (access + refresh, httpOnly cookie), partner pairing.
- Daily Home:
Homedaily-life revamp + site theme styling (dark / light dual theme). - Match History: List + detail review.
- PWA:
manifest.webmanifest+ Service Worker, installable offline.
| Layer | Tech |
|---|---|
Frontend web/ |
Vue 3 · Vite · Pinia · Vue Router · Vant · SCSS · Socket.IO-client · canvas-confetti |
Backend server/ |
Node · Express · Prisma · SQLite · Socket.IO · JWT · Zod · argon2 · nanoid |
Shared shared/ |
Board & game rules (board.ts / game.ts); frontend imports via vite alias, backend via tsconfig paths as @shared |
| Deploy | Docker Compose · nginx · exposed via airise-gateway (same origin) |
.
├── web/ Frontend SPA (Vue 3 + Vite)
├── server/ Backend: core platform spine (auth/media/http/db) + game module (online battles)
│ └── prisma/ Multi-file schema: core.auth / core.media / game / main
├── shared/ Shared board & rules, consumed by both frontend and backend
├── docker/ nginx.conf for the frontend container (static SPA leaf)
├── design/ High-fidelity design mockups (YYMMDD-slug)
└── docs/
├── deploy.md
└── technology/ Technical design docs
The backend is layered as a "core platform spine + business modules": core/ (auth / media / http / db / config / errors) provides cross-cutting capabilities, while modules/game/ is the first business module (blueprint / engine / rooms / socket / presence / rest).
In production, the service is exposed via a unified gateway airise-gateway (dedicated 80/443 + TLS); this service does not publish host ports:
https://dailylife.airise.site ─► airise-gateway ─┬─ /api /socket /storage → dailylife-server:8787
└─ / → dailylife-web (SPA)
- Gateway-side routing:
airise-gateway/conf.d/dailylife.airise.site.conf - This service's containers join the shared network
airise-web(the gateway reverse-proxies by container name).
Deploy on the server (gateway and airise-web network already set up):
cp .env.example .env # set JWT_ACCESS_SECRET / JWT_REFRESH_SECRET
docker compose up -d --build
docker exec airise-gateway nginx -s reload # reload the gateway to pick up the new site conf
# open https://dailylife.airise.siteOption A · Docker hot-reload (both frontend and backend, no gateway):
docker compose -f docker-compose.dev.yml up
# frontend http://localhost:5173, backend :8787; source changes hot-reloadOption B · Native npm (start separately):
# Backend
cd server && cp .env.example .env # set JWT_* secrets
npm install && npm run db:push # initialize SQLite (dev.db)
npm run dev # tsx watch, listens on :8787
# Frontend (separate terminal)
cd web && npm install && npm run dev # vite, listens on :5173vite.config.ts configures a dev proxy: /api, /socket(ws), /storage → http://localhost:8787. The browser only sees :5173 (same origin), so cookies work naturally.
Type checking / build:
cd server && npm run typecheck # tsc --noEmit
cd web && npx vue-tsc --noEmit && npm run build # outputs web/distCommon commands:
docker compose logs -f # tail logs
docker compose down # stop (keep data volumes)
docker compose down -v # stop and wipe SQLite / uploadsBoth frontend and backend images use the repository root as the build context (they need to copy
shared/too — see the note at the top of each Dockerfile).
The server stores only "task indices" (zone + taskIndex). Explicit task text never touches the server (not in DB, logs, or backups). The PWA is self-distributed. See docs/deploy.md §7 for details.
