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).
9.1 KiB
Skara Brae — Analysis & Design Model (text form)
Version 1.0 (WI-2, 2026-10-03) · OpenUP artifact: analysis-design/uc-realization-mapping.md
This is the content the EA model will carry once the modeling pipeline exists. The EA repository itself (.eapx, keyfob-station style) is planned for a later work item — EA is a human-gated interactive tool; this document is the authoritative source any future EA builder script generates from.
1. Model structure (planned EA packages)
Model: Skara Brae
├── Requirements
│ ├── Vision (from requirements/vision.md)
│ ├── Use Case Model
│ │ ├── Actors: Player, Administrator, Guest
│ │ └── Use Cases UC-01 … UC-12 (from requirements/use-case-model.md;
│ │ scenarios as Basic Path / Alternate / Exception with per-step Actor)
│ └── Supplementary Specifications (from requirements/supplementary-specifications.md)
└── Analysis-Design
├── Architecture Overview (crate/layer diagram, dependency rule)
└── UC-01 Realization … UC-12 Realization (one package per UC: analysis classes,
design elements, realization table below)
2. UC realization mapping (analysis classes → design elements)
Legend — Analysis class (OpenUP stereotype): «controller», «entity», «boundary». Design element: crate::module::item (Rust). "WI-2" marks elements introduced or re-homed by this work item; everything else exists at 899fde8.
| UC | Analysis class | Stereotype | Design element | Notes |
|---|---|---|---|---|
| UC-01 Register | AccountRegistry | controller | sb-api::routes::{register, seed_users} |
argon2 hash via sb-auth::hash; JWT via sb-auth::jwt |
| UserAccount | entity | sb-shared::user::User, Role |
persisted via sb-db::Database |
|
| AuthBoundary | boundary | POST /api/auth/register, AuthResponse |
||
| UC-02 Authenticate | Authenticator | controller | sb-api::routes::login, sb-auth::{hash::verify_password, jwt::create_token} |
|
| TokenService | boundary | POST /api/auth/login, AuthResponse, middleware::auth::auth_middleware |
middleware guards all UC-03…12 | |
| UC-03 Manage Characters | CharacterFactory | controller | sb-core::character::create_character |
takes injected rng (WI-1) |
| Character | entity | sb-shared::character::Character (+ Race, Class, CharacterStats) |
||
| CharacterCatalog | boundary | GET/POST /api/users/{id}/characters, GET /api/characters/{id} |
store: AppState.characters |
|
| ResourceRegenerator | entity | sb-core::character::apply_regen (+ regen constants — WI-2 names them) |
included sub-flow | |
| UC-04 Browse Catalogue | CatalogueBrowser | boundary | GET /api/{races,classes,items,enemies,adventures}; response types sb-shared::responses |
data from sb-common JSON via sb-core::{character::RACES/CLASSES, data, items} |
| GameData | entity | sb-core::data::{EnemyDef, ZoneDef, EncounterEntry, LootDrop}, items::load_all_items |
||
| UC-05 Train Stat | TrainingService | controller | sb-core::services::train_stat |
error type DomainError (WI-2) |
| TrainingGrounds | entity | sb-core::character::TRAINING_GROUNDS, training_cost (+ cost constants WI-2) |
||
| GymBoundary | boundary | GET/POST /api/characters/{id}/gym, GymResponse, TrainStatResponse |
||
| UC-06 Manage Equipment | EquipmentService | controller | sb-core::services::{equip_item, unequip_item} |
DomainError (WI-2) |
| Equipment/Inventory | entity | Character.equipment / .inventory, sb-shared::item::Item |
||
| EquipmentBoundary | boundary | POST /api/characters/{id}/{equip,unequip} |
||
| UC-07 Trade at Shop | ShopService | controller | sb-api::routes::{shop_action, buy_item, sell_item} (handler-side; extraction candidate, design note Q3) |
prices: sb-core::items::{item_price, item_sell_price} |
| ShopStock | entity | AppState.shop_stock |
persisted via sb-db |
|
| ShopBoundary | boundary | GET/POST /api/characters/{id}/shop, ShopResponse, ShopActionResponse |
||
| UC-08 Run Adventure | AdventureService | controller | sb-core::adventure::run_adventure (new, WI-2) + services::pick_enemy → Result (WI-2) |
takes injected rng; DomainError (WI-2) |
| CombatEngine | entity | sb-core::combat::{resolve_combat_full, resolve_attack, crit tables, open_ended_roll} + combat constants (WI-2) |
||
| Combatant | entity | sb-core::combat::CombatStats |
built from Character/EnemyDef | |
| SpellEffect / BardSong | entity | sb-core::combat::SpellEffect, sb-core::spells, sb-core::songs |
||
| AdventureBoundary | boundary | GET /api/characters/{id}/adventure; AdventureRunResponse (new, WI-2), sb-shared::responses::CombatLog |
||
| UC-09 Heal at Temple | HealingService | controller | sb-api::routes::heal_character (handler-side; extraction candidate, Q3) |
|
| TempleBoundary | boundary | POST /api/characters/{id}/heal; HealResponse (new, WI-2) |
||
| UC-10 Practice Bard Song | SongService | controller | sb-api::routes::set_song; sb-core::songs::available_songs |
|
| BardSong | entity | sb-core::songs::BARD_SONGS, Character.active_song |
||
| SongBoundary | boundary | GET/POST /api/characters/{id}/songs, SongsResponse, SetSongResponse |
||
| UC-11 Study Magic | MagicService | controller | sb-api::routes::{get_spells, learn_spell_level}; sb-core::spells::{spells_for_class, spell_learn_cost, max_spell_points, caster_spell_level (WI-2)} |
|
| Spell | entity | sb-core::spells::SpellDef, Character.{known_spells, active_spell, spell_points} |
||
| MagicBoundary | boundary | GET/POST /api/characters/{id}/spells; SpellbookResponse, LearnSpellResponse (new, WI-2) |
||
| UC-12 Level Up | ReviewBoard | controller | sb-core::character::level_up |
DomainError (WI-2) |
| Progression | entity | sb-core::character::{xp_for_level, level_up_cost, MAX_LEVEL} (+ curve constants WI-2) |
||
| ReviewBoundary | boundary | POST /api/characters/{id}/level-up, LevelUpResponse |
Cross-cutting design elements (WI-2): sb-core::error::DomainError + sb-api::routes::domain_status (status mapping table, design note §4.1) realize the error paths of UC-05/06/08/12; sb-core::constants realizes NFR "no magic numbers"; sb-api::routes::responses realizes NFR-19 (wire-format freeze).
Dependency rule check (Clean Architecture): all controllers/entities above live in sb-core/sb-shared (domain side, no HTTP imports); all boundaries live in sb-api; the single current violations (ShopService, HealingService, parts of MagicService in sb-api) are recorded as debt with a follow-up question — the model must not paper over them (stale docs are defects).
3. Research summary — keyfob-station EA pipeline (reference)
Source: read-only clone http://192.168.1.10:3000/jan/keyfob-station.git (inspected 2026-10-03; no modifications).
- Model file:
docs/openup/model/keyfob-station.eapx(MS Access database — the EA native format; EABase-derived). Never hand-edited. - Structure: Model →
Requirementspackage →Use Case Modelpackage containingActorandUseCaseelements; scenario lists are stored on each use case as named scenarios of type Basic Path / Alternate / Exception, each with ordered steps carrying a per-step Actor tag and notes. AnAnalysis-Designpackage holds oneUC-N Realizationpackage per use case (realization diagrams + design elements). - Builders are surgical scripts:
scripts/add-*.ps1(PowerShell driving the EA COM objectNew-Object -ComObject EA.App,$repo.OpenFile($modelPath)). Each script opens the model, adds/rebuilds exactly one package's contents, and closes it — because EA repository IDs and package rebuilds clobber manual edits, hand edits do not survive; all content lives in the scripts (scenario text is embedded as PowerShell arrays ofName/Type/Notes/Steps). This matches our standards note: model additions are surgical; builders rebuild whole packages. - Exports:
scripts/export-model-json.ps1walks the Use Case Model package and emitsexports/use-case-model.json+supplementary-requirements.json; realization diagrams are exported to PDF/PNG intodocs/openup/analysis-design/. The JSON export is the doc-machine readable form of the same content. - Windows-only: the pipeline runs on Windows (EA is a Win32 app; scripts use
.ps1+ COM). For Skara Brae, the same pattern applies when the modeling WI lands: keepdocs/openup/*.md(this file set) as the source the builder scripts embed, never the reverse.
Adoption decision for Skara Brae (updated at 1B rework): the EA model + generator pipeline is in WI-2 scope. This document (§1–2) plus requirements/use-case-model.md are the content source; the model-home recommendation, agent preparation steps, generator scripts (scripts/openup/build-model.ps1, export-model.ps1), and the human-gate checklist are specified in design-wi-2-architecture-cleanup.md §11. The .eapx interactive editing session remains human-gated; everything around it is COD-phase agent work.