13 Commits
Author SHA1 Message Date
botsu ac990d9adc [verified] fix: serialize TCG discovery claims 2026-08-08 21:25:01 +02:00
botsu 5a48ba98c3 [verified] chore: prepare macOS Codex development 2026-08-08 21:13:30 +02:00
botsu ed3f934b61 feat: expand BOTSU creative rooms and apps 2026-08-08 20:31:07 +02:00
botsu 4c136b0f09 feat: add drawing rooms and Godot workspace support 2026-08-08 15:08:11 +02:00
botsu 8494c18fa9 feat(openstreetmap): shared map with realtime viewport sync via presence.map.viewport 2026-08-06 23:09:07 +02:00
botsu f42134e1d0 feat(tcg): Botsu Emoji TCG MVP — boosters, collection, graveyard
Backend (apps/presence-api):
- tcg-config: centralized rarity/price/shiny config, daily reset Europe/Paris
- tcg-index-catalog: idempotent Emoji Kitchen sticker indexer (23139 combos)
- tcg-catalog-store: in-memory catalog with path-traversal guard
- tcg-card-store: card instances, discoveries (unique constraint), daily tracking
- tcg-booster-store: daily/paid/admin boosters, per-user mutex, replay protection
- tcg-economy-log: JSONL audit log
- cookie-store: added debitCookies/creditCookies (atomic, no negative balance)
- server.ts: 11 HTTP routes (/tcg/images, /tcg/booster/*, /tcg/collection, etc.)
- 47 backend tests (concurrence, atomicity, path traversal, admin auth)

Protocol (packages/protocol):
- tcg.ts: shared types + strict parsers (rarity, burn, pagination)

Frontend (apps/client):
- tcg-controller: client API controller (Matrix OpenID auth)
- BotsuTcgPage: 3 tabs (Booster, Collection, Cimetière) with filters/pagination
- catalog.ts: emoji-tcg app registered
- Router.tsx + paths.ts: /botsu/tcg/ route
- BotsuNav: nav entry with Smile icon

Docs:
- docs/emoji-tcg-licence.md: Emoji Kitchen attribution and licence note

Config: EMOJI_KITCHEN_ROOT, DAILY_BOOSTER_SIZE=3, BOOSTER_PRICE=1000,
SHINY_RATE=0.01, RARITY_* (sum=1 validated at startup), BURN_REWARD=50

Tests: 106 backend + 98 frontend + 46 protocol = 250 pass
2026-08-06 03:50:14 +02:00
botsu d07dc35c03 fix(presence-api): tolerate corrupt cookie JSON instead of crashing the process
An interrupted atomic write can leave a player file truncated (0 bytes).
JSON.parse of such a file threw SyntaxError, which was unhandled and
crashed the whole presence process (cursors/Yjs/cookies all share it),
putting the canary into a crash loop.

Add tryReadJsonFile() that treats ENOENT and invalid JSON the same way
(as absent) and route readPlayerRecord, getLeaderboard and
sumAllBalances through it. A corrupt file is rebuilt on next access.

Add a regression test covering a truncated player file.
2026-08-06 02:23:34 +02:00
botsu 16eb0647ce fix(documents): collaborative cursors visible with user names
- Fix awareness state: setLocalState({ user: cursorUser }) so the default
  y-prosemirror cursorBuilder reads state.user correctly
- Custom cursorBuilder: span.botsu-collab-cursor with inline borderColor,
  div.botsu-collab-cursor-label with explicit color (no color:transparent
  inheritance issue)
- CSS: caret 2px solid, label absolute below caret, 0.625rem, opacity 0.85
- Unwrap state.user ?? state in builder for robustness
2026-08-05 22:00:58 +02:00
botsu 511b37d5a8 feat(documents): bridge shared pages with Yjs 2026-08-04 17:20:51 +02:00
botsu 74eeaa1a5a feat: add shared BOTSU documents and cookie counter
Add authenticated document objects persisted on the BOTSU drive, opaque shared references for local drafts, and websocket document snapshots/patches.

Add synchronized cookie counter API/client slice and keep the canary UI icon updates covered by BOTSU tests.
2026-08-04 16:49:41 +02:00
botsu b272c5b765 [verified] add BOTSU start page and shared canvas 2026-08-03 23:04:04 +02:00
botsu 7726614aa0 [verified] feat: add shared presence cursors 2026-08-03 18:54:37 +02:00
botsu ad31385a1b [verified] feat: add BOTSU presence 2026-08-03 17:51:29 +02:00