40 lines
8.9 KiB
Markdown
40 lines
8.9 KiB
Markdown
# Botanica M5–M11 implementation notes
|
||
|
||
## Initial audit
|
||
Existing pure packages: genetics/rules resolve and breed versioned genomes; renderer composes original SVG primitives. Fastify uses PostgreSQL transactions and tracked SQL migrations; plants and breeding_events already carry owner IDs. React has laboratory, breeding, collection, lineage inspectors and image/JSON exports. Compose exposes only web on port 8155, including LAN access for the configured Cloudflare tunnel. Existing .env is preserved.
|
||
|
||
Implementation batches: M5–M7 accounts/scoping, greenhouse and integer economy; M8–M10 progression, paid breeding and bounded worker reconciliation; M11 game presentation and one final regression/integration/browser smoke. Existing sandbox rows remain owned by their original demo UUID and become explicitly read-only examples. Designed laboratory plants remain usable studies but are excluded from game sale/breeding rewards. No database reset or volume deletion.
|
||
|
||
## Shipped implementation
|
||
|
||
- **M5**: username/password registration/login, Argon2id, opaque hashed sessions (30 days), CSRF/origin checks, bounded process-local auth throttling, logout and five one-use recovery codes. Account creation atomically grants 120 coins, three starter seeds and a four-slot house. Owned reads/mutations use the authenticated player ID.
|
||
- **M6–M7**: greenhouse home with original SVG pots/plants, responsive rail/bottom navigation and persistent HUD. Seed inventory, server-priced purchases, confirmed specimen sale, favorites/protection and a signed integer coin ledger. Receipt keys make monetary requests replay-safe. Harvest yields a plant plus one recycled starter seed; coins come from sales and distinct discovery/quest rewards.
|
||
- **M8**: persisted UTC growth (20-second first crop, then 120/300/720 seconds), 12 handcrafted one-time goals, XP-derived levels, slot expansions, lamp, irrigation, second greenhouse and three real research unlocks. Lamp reduces remaining and future growth by 10%; irrigation reduces gardener intervals from 120 to 96 seconds.
|
||
- **M9**: existing engine wrapped in paid level-3 breeding (75 coins), with two distinct owned mature game plants, immutable parent lineage and replayed stored outcomes. Instant offspring reuses the original engine; no extra breeding timer or invented probability display. Discovery uniqueness uses the resolved species/catalog/phenotype signature, not a rarity roll.
|
||
- **M10**: hire/assign gardeners and breeders, default paused. Policies repeat_crop, repeat_cross and researched target_trait use real seeds/coins/parents. Targets protect matching offspring without changing odds. A player-row lock serializes reconciliation and manual spending; chronological event simulation is capped at 100 intervals/24 hours per calculation. Persisted cursors retain surplus time. Blocked intervals advance without rewards; new resource purchases cannot fuel historical pending work. Per-worker logs reconcile to the combined report. Auto-sale starts off, only considers newly harvested Common duplicates and excludes favorites, protected plants, first discoveries and the last specimen of a species. Breeders keep all offspring.
|
||
- **M11**: forest/parchment/gold shell, tactile growing slots, live countdown, discovery reveal, next-goal tracker, explained locks, account/reduced-motion preferences, compact mobile navigation and persistent offline summary. Existing laboratory, renderer atlas, owned collection filters, inspectors, provenance and JSON/SVG/PNG exports remain. `/examples` and reference detail routes retain the old archive read-only, including genomes, ancestry and exports; pagination includes legacy records beyond the 100 demos.
|
||
|
||
## Migration and environment
|
||
|
||
`0003_game_foundation.sql` is additive for account/game data. It replaces only the breeding request uniqueness constraint with owner+request uniqueness. No existing plant IDs, genomes, versions, owners or ancestry are migrated away. Existing sandbox rows keep their original owner, which has no account password. Designed studies in real accounts remain separate from salable/breedable game plants. PostgreSQL volumes were retained throughout.
|
||
|
||
The existing `.env` was not edited. `HOST_PORT=8155` and `PUBLIC_DOMAIN=http://localhost` remain. Optional `PUBLIC_ORIGINS` is passed through Compose; its explicit defaults include local, configured LAN and public HTTPS origins. See DEPLOYMENT.md for Vite/other deployments. No additional secret or service is required. Argon2 is the only new runtime dependency.
|
||
|
||
## Verification to date
|
||
|
||
- Full workspace typecheck passed; production npm build passed; Docker's server/web production builds also compile the delivered changes.
|
||
- `npm run test`: 16 existing domain/API checks passed, 16 artwork source files verified. The 13 database cases are intentionally skipped there without TEST_DATABASE_URL.
|
||
- Isolated `compose.test.yaml`: all 13 real PostgreSQL cases passed (eight existing persistence/rollback/pagination checks and five focused game cases). Game cases cover accounts/recovery/CSRF/isolation, simultaneous spend/sale/harvest, paid idempotent inheritance, and concurrent one-hour gardener/breeder reconciliation plus a capped two-day backlog. Late-game tests use explicit isolated fixtures, not hours of simulated manual leveling.
|
||
- Initial database acceptance found a UUID/text inference error in signup's welcome ledger row; explicit casts fixed it. Argon2/recovery test has a local 20-second timeout to tolerate concurrent Docker load. The final integration run passes all assertions.
|
||
- `docker compose config --quiet`, `docker compose up --build -d`, `docker compose ps` and proxied localhost health passed. Only web publishes 0.0.0.0:8155; API/DB remain private.
|
||
- Before/after migration checks match all **103** pre-existing plants, including owner, genome, visual seed, generation and parents (checksum `09972afb73a3b3b0fc187ec59182be9f`). Evidence: artifacts/m11/legacy-baseline.json and legacy-after-migration.json.
|
||
- `scripts/verify-game.cjs` passed all 13 browser checks: real registration/recovery-code display, live countdown, harvest/discovery, favorite protection, confirmed sale, quest claims, seed/slot purchases, paid inherited breeding and reload-persisted child favorite; advanced lab, renderer atlas and all 103 legacy references; late-game upgrades/research/worker assignment and replay-safe one-hour catch-up; logout/login; unauthenticated denial; and actual public HTTPS login through Cloudflare with Secure/HttpOnly/SameSite=Lax cookies. All nine gameplay routes have zero horizontal overflow at both 360px and 1440px, with reduced motion and no JavaScript page errors.
|
||
- Browser late-game setup is explicitly scoped to its newly registered QA UUID: level 10, a ledger-recorded 20,000-coin grant and worker cursors shifted back one hour. Early plant/harvest/sale/quest/purchase/breeding used real timers/resources without shortcuts. QA workers were paused afterward. No credentials or recovery codes are written to artifacts.
|
||
- Acceptance fixed signup SQL parameter typing, controlled-checkbox feedback and client/server harvest-boundary races. Harvest now waits for confirmed server readiness while countdowns remain smooth. Short explicit accessible select names avoid including every option in the control name. Cryptographically secure request-ID fallback was exercised with randomUUID deliberately unavailable, supporting the configured plain-HTTP LAN origin. Visual review led to an explicit row layout for the compact mobile HUD; final CSS/copy changes were rebuilt and checked separately.
|
||
- Evidence: artifacts/m11/browser-report.json, desktop/mobile greenhouse and breeding/worker screenshots. Both desktop and mobile visuals were inspected. There is no separate lint script in this repository; TypeScript, Prettier formatting, builds and the existing tests were used.
|
||
|
||
## Practical limits
|
||
|
||
One fictional species is inherited from M0–M4; no additional species or hybrid rules were invented. Workers calculate on relevant authenticated requests/15-second state refresh, without a daemon. Large backlogs require subsequent bounded batches. Throttle counters are local to the single API process and reset on restart; no distributed limiter is claimed. Recovery codes are shown once and consumable; rotation/self-service account deletion and sound are not implemented. Registration does not require email. No paid currency, runtime generation services, trackers or multiplayer were added.
|
||
|
||
Final follow-up: the rebuilt 360px HUD measures 103px tall, with coin/seed/player groups on the same row and zero overflow (artifacts/m11/mobile-final.json and greenhouse-mobile-final.png). Public HTTPS health returns connected JSON. A final SQL audit confirms the legacy checksum still matches, no player has negative coins, every player's balance equals their signed ledger total, and no QA worker remains enabled (artifacts/m11/final-data-check.json). Only temporary test Compose containers/network were removed; the application remains running. All M5–M11 gates are complete.
|