skara-brae-common/docs/openup/requirements/supplementary-specifications.md
Jan-Peter von Hunnius 4798f55660 docs(openup): move WI-2 OpenUP work set verbatim from skara-brae-server
All OpenUP artifacts are versioned in skara-brae-common under docs/openup/
per the 2026-10-03 decision reversal in design-wi-2-architecture-cleanup.md
(supersedes the earlier in-server-docs decision). Verbatim move, no content
changes: analysis-design/, requirements/, test/ (6 files).
2026-10-03 17:17:44 +02:00

51 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Skara Brae — Supplementary Specifications
Version 1.0 (WI-2, 2026-10-03) · OpenUP artifact: `requirements/supplementary-specifications.md`
Non-functional requirements and constraints for the server MVP. Facts cite code where they are implemented; assumptions are marked.
## 1. Performance / Scalability
- **NFR-01 (in-memory state):** all game state (users, characters, shop stock) is held in process memory behind `tokio::sync::RwLock` (`crates/sb-api/src/routes/mod.rs:33–42`). Single-process deployment; persistence is write-through to SQLite, reads never hit the DB.
- **NFR-02 (lazy regeneration):** resource regeneration is computed on every character access from elapsed wall-clock time (`apply_regen`, character.rs:105–122) — no timers, no background ticks. Intervals: energy 180 s, nerve 300 s, HP 300 s (5% max HP per tick).
- **NFR-03 (client polling):** clients poll character state to observe regeneration; the assumed UI refresh cadence is ~15 s *(assumption carried from project planning; server-side behavior is poll-frequency-independent by design NFR-02)*.
- **NFR-04 (static catalogue):** items, enemies, zones, spells, and crit tables are compiled in via `include_str!` from `skara-brae-common` JSON and parsed once behind `LazyLock`; catalogue reads are lock-free after first access.
## 2. Reliability / Correctness
- **NFR-05 (deterministic domain logic):** all domain randomness is injected `StdRng` (WI-1); identical seeds produce identical outcomes. Request paths construct RNG only at `request_rng()`.
- **NFR-06 (persistence best-effort):** persistence failures are logged (`tracing::error`) and do not fail the request; in-memory state remains authoritative for the process lifetime.
- **NFR-07 (referential data integrity):** zone encounter tables must reference existing enemy ids and loot drops must reference existing item ids; violations are detected at first use (WI-2: `DomainError::UnknownEncounterEnemy` → 500 instead of a panic).
## 3. Quality Gates (per-commit acceptance)
- **NFR-08:** `cargo fmt --check` clean (fmt baseline established by WI-2).
- **NFR-09:** `cargo clippy --all-targets -- -D warnings` clean — zero-warning policy.
- **NFR-10:** `cargo test --workspace` fully green (45 sb-core tests at WI-2 start; suite only grows).
- **NFR-11 (WI-2-specific):** behavior-identical refactor — JSON field names/order, HTTP status codes, game semantics, and RNG draw order unchanged.
- **NFR-12:** no `unwrap()`/`expect()` on request paths outside the documented keep-with-reason invariants in the design-note §6 ledger (covers sb-api, sb-core, sb-db mutex poisoning, sb-auth time/entropy invariants).
## 4. Data
- **NFR-13 (shared data source):** all game content lives in the `skara-brae-common` repo as language-neutral JSON under `data/` — single source of truth consumed at build time by server (`include_str!` + serde) and client. Server must not duplicate or transform these definitions in code.
- **NFR-14 (persistence format):** optional SQLite via `SB_DB_PATH` (rusqlite; users, characters, shop stock with `next_character_id`). Absent the variable the server runs purely in-memory with seeded `admin`/`player` accounts.
- **NFR-15 (numeric headroom):** stats are `i64` (BIGINT) — “exponential growth, tiered display” is a product commitment; no narrowing conversions to smaller integers in new code.
## 5. Security
- **NFR-16:** passwords hashed with argon2; verification constant-time via the crate.
- **NFR-17:** JWT (HS256, `jsonwebtoken`), 24 h expiry; all game routes behind auth middleware; cross-user access requires the `admin` role (403 otherwise).
- **NFR-18:** no secrets in code; JWT secret and admin/player seed passwords come from environment/configuration.
## 6. Constraints
- **CON-01:** Rust, edition **2024**; workspace crates `sb-api` / `sb-core` / `sb-db` / `sb-auth` / `sb-shared` + external sibling `sb-common` (absolute path dependency; submodule migration planned).
- **CON-02:** HTTP framework **Axum 0.8** (ws + macros features), tokio, tower stack (CORS/trace/compression-gzip).
- **CON-03:** `rand 0.9`; domain functions take `rng: &mut impl Rng`; handlers obtain RNG only from `request_rng()` (WI-1 rule).
- **CON-04:** Error handling: `thiserror 2` in-domain; **no new error/framework dependencies**; one domain error enum (`sb_core::error::DomainError`) with a single central HTTP status mapping in sb-api.
- **CON-05:** Clean Architecture dependency rule: sb-core has zero knowledge of HTTP/axum/serde_json/tokio/tracing/sb-db; ports (domain traits) would live in sb-core, adapters outward.
- **CON-06:** OpenUP work products are versioned in the **skara-brae-common repo** under `docs/openup/` — one canonical project-docs home (decision reversed 2026-10-03 from the earlier skara-brae-server `docs/openup/` plan). The drafted WI-2 artifacts move there verbatim (coder, session 2); WI-1 artifacts at the old project-top folder migrate there as well. `roadmap.md` stays at the project-top folder per the earlier PM decision.
## 7. Usability / API
- **NFR-19:** REST JSON API; field names and order are a wire contract — refactors must preserve them byte-for-byte. The current API emits JSON object keys in **lexicographic order** (serde_json resolves without `preserve_order`; `json!` uses BTreeMap-backed maps), and the typed-response structs of WI-2 declare fields in that order to stay byte-identical.
- **NFR-20:** meaningful HTTP status codes: 400 malformed input, 401 auth failure, 403 foreign/non-permitted resource, 404 unknown resource, 409 name conflict, 410 shop stock exhausted, 422 game-rule violation (resources/requirements), 500 internal.