- analysis-design/architecture-notebook.md: Architecture Notebook work product in the keyfob docx template structure (10 sections), grounded in mapping / design note / supplementary specs; embeds the component model and all 12 realization figures - scripts/openup/export-diagram-images.ps1: read-only EA COM renderer (EA-15 findings: image API on ProjectInterface, OpenDiagram before export or blank stub, type 0 = PNG); renders reflect manual layouts - renders: requirements/use-case-overview.png, analysis-design/ uc-01..12-realization.png + component-architecture.png; embedded as figures in use-case-model.md and uc-realization-mapping.md - BUILD-CHECKLIST 6.4 documents the exporter
15 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)
└── Design (component model of the joint architecture — server
crates + skara-brae-client + skara-brae-common; §3)
Joint-model decision (2026-10-03): one EA model covers the whole product — server, client and common — because the use cases are player-facing and Requirement→realization traceability spans tiers. Client-side UC realization packages (Vue boundary elements per UC) are a future work item: no markdown source exists yet; they are NOT invented here. Today the client enters the model via the §4 component model only.
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).
2a. Analysis interactions (associations + dependencies, added 2026-10-03)
Within each realization package the analysis classes collaborate per the robustness rule
boundary ↔ controller ↔ entity (boundary never touches entity directly — exception: UC-04
has no controller, its boundary reads the static catalogue entity). Each association serves
the UC's Basic Path steps (boundary receives the actor request, controller applies the
rules, entities hold the state). Cross-cutting: the four «uses» dependencies realize the
error paths (Alternate/Exception flows) named in the cross-cutting paragraph above.
| UC | From | To | Type | Serves |
|---|---|---|---|---|
| UC-01 | AuthBoundary | AccountRegistry | Association | MSS steps 1–4 |
| UC-01 | AccountRegistry | UserAccount | Association | MSS steps 3–4 |
| UC-02 | TokenService | Authenticator | Association | MSS steps 1–3 |
| UC-03 | CharacterCatalog | CharacterFactory | Association | MSS (create) steps 1–4 |
| UC-03 | CharacterFactory | Character | Association | MSS steps 3–4 |
| UC-03 | CharacterFactory | ResourceRegenerator | Association | list/view (regen on return) |
| UC-04 | CatalogueBrowser | GameData | Association (no controller in this realization) | MSS steps 1–2 |
| UC-05 | GymBoundary | TrainingService | Association | MSS steps 1–5 |
| UC-05 | TrainingService | TrainingGrounds | Association | MSS steps 3–4 |
| UC-06 | EquipmentBoundary | EquipmentService | Association | MSS (equip) + unequip |
| UC-06 | EquipmentService | Equipment/Inventory | Association | MSS steps 2–3 |
| UC-07 | ShopBoundary | ShopService | Association | MSS (buy) + sell |
| UC-07 | ShopService | ShopStock | Association | MSS steps 3–4 |
| UC-08 | AdventureBoundary | AdventureService | Association | MSS steps 1–9 |
| UC-08 | AdventureService | CombatEngine | Association | MSS step 5 |
| UC-08 | AdventureService | Combatant | Association | MSS step 5 |
| UC-08 | AdventureService | SpellEffect / BardSong | Association | MSS steps 5, 8 |
| UC-09 | TempleBoundary | HealingService | Association | MSS steps 1–3 |
| UC-10 | SongBoundary | SongService | Association | MSS steps 1–2 + clear |
| UC-10 | SongService | BardSong | Association | MSS steps 1–2 |
| UC-11 | MagicBoundary | MagicService | Association | view + learn + activate |
| UC-11 | MagicService | Spell | Association | learn + activate steps |
| UC-12 | ReviewBoundary | ReviewBoard | Association | MSS steps 1–3 |
| UC-12 | ReviewBoard | Progression | Association | MSS step 2 |
The authoritative connector count is 24 associations (UC-01:2, UC-02:1, UC-03:3, UC-04:1, UC-05:2, UC-06:2, UC-07:2, UC-08:4 — its realization has one boundary, one controller and three entities, UC-09:1, UC-10:2, UC-11:2, UC-12:2) plus 4 cross-cutting dependencies below — 28 connectors in total.
| UC | From (controller) | To | Type | Serves |
|---|---|---|---|---|
| UC-05 | TrainingService | DomainError (Architecture Overview) | Dependency «uses» | Alternate flows (error paths) |
| UC-06 | EquipmentService | DomainError (Architecture Overview) | Dependency «uses» | Alternate flows (error paths) |
| UC-08 | AdventureService | DomainError (Architecture Overview) | Dependency «uses» | Exception (unknown enemy → 500) |
| UC-12 | ReviewBoard | DomainError (Architecture Overview) | Dependency «uses» | Alternate flows (error paths) |
3. Design component model (joint architecture, added 2026-10-03)
Package Analysis-Design / Design — components of the three repos and their dependency
rule (sources: design note §2–3, mapping §2 dependency paragraph, client repo @ 34dc02f,
common repo @ wi-2-openup-docs). Every component note carries the UCs it serves.
| Component | Kind | Notes (traceability) |
|---|---|---|
| skara-brae-client | Component (presentation tier) | Vue 3.5 SPA (TypeScript, Pinia, Vite); monolithic App.vue @ 34dc02f; JWT bearer; REST via Vite proxy to :8080. Serves UC-01…12 as the player-facing boundary. |
| sb-api | Component (boundary/adapter) | Axum routes/handlers, domain_status, responses (wire-format freeze). May import sb-core, sb-shared, sb-common, sb-db, sb-auth (design §3). Serves all UC boundaries per §2. |
| sb-auth | Component (adapter) | argon2 hashing + JWT (UC-01/02). Imports sb-shared. |
| sb-db | Component (adapter) | persistence via sb-db::Database. Imports sb-shared. |
| sb-core | Component (domain) | controllers/entities: adventure (UC-08), services (UC-05/06), character (UC-03/12), combat, spells (UC-11), songs (UC-10), data/items (UC-04). Must not reference axum/http/serde_json::json!/tokio/sb-db/sb-api (design §3). |
| sb-shared | Component (domain types) | User, Character, Item, response types. Zero HTTP imports. Entities of all UCs. |
| sb-common | Component (data) | bilingual data package: data/ JSON (items, enemies, spells, zones), rust/ crate, ts/ package, codegen/. UC-04 data source; consumed by sb-core + sb-api; future client codegen. |
Dependencies (arrows = depends on): skara-brae-client → sb-api (REST/JSON); sb-api → {sb-core, sb-shared, sb-db, sb-auth, sb-common}; sb-core → {sb-shared, sb-common}; sb-db → sb-shared; sb-auth → sb-shared. The dependency rule: inward toward sb-core/sb-shared (domain); adapters (sb-api/sb-db/sb-auth) and the client at the edge.
Figure: joint component architecture (rendered from the EA model via scripts/openup/export-diagram-images.ps1). Per-UC realization figures: uc-01-realization.png … uc-12-realization.png in this folder; they are embedded in the Architecture Notebook (§9.2).
4. 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.
