id: 4a7fcbf3efca4cd7a12aabd5d10a2c45
parent_id: 6d3a597fcf48454b9fb0f6aaff042b88
item_type: 1
item_id: 980c3eb587294e4383474b94988f2f88
item_updated_time: 1785523646817
title_diff: "[]"
body_diff: "[{\"diffs\":[[0,\"  # \"],[-1,\"This repo — \"],[0,\"Rust\"]],\"start1\":745,\"start2\":745,\"length1\":20,\"length2\":8},{\"diffs\":[[0,\" backend\"],[1,\" (opened in RustRover)\\\n├── skara-brae-client/          # Vue 3 frontend (opened in WebStorm)\\\n└── skara-brae-common/          # Shared game data, API contract, constants\\\n```\\\n\\\n### Local Checkout Layout (IDE Wiring)\\\n\\\nThe two consumer repos live in different JetBrains IDEs (RustRover, WebStorm). Keep all three as **siblings under one parent folder** — the parent is a plain folder, **not** a git repo:\\\n\\\n```\\\n~/dev/skara-brae/                  # workspace root (plain folder, NOT a git repo)\\\n├── skara-brae-server/             # RustRover opens THIS\"],[0,\"\\\n├── ska\"]],\"start1\":753,\"start2\":753,\"length1\":16,\"length2\":561},{\"diffs\":[[0,\"ara-brae-client/\"],[1,\"   \"],[0,\"          # Vue \"]],\"start1\":1313,\"start2\":1313,\"length1\":32,\"length2\":35},{\"diffs\":[[0,\"  # \"],[-1,\"Vue 3 frontend\\\n└── \"],[1,\"WebStorm opens THIS\\\n└── skara-brae-common/             # shared — 3rd window, or \\\"Attach\\\" in either IDE\\\n```\\\n\\\n- **RustRover (server)** — path dependency in `skara-brae-server/Cargo.toml`:\\\n  ```toml\\\n  sb-common = { path = \\\"../skara-brae-common/rust\\\" }\\\n  ```\\\n  Sibling path deps resolve fine. To edit common from inside RustRover: **Settings → Project Structure → Attach** (or add `../skara-brae-common` as a content root).\\\n- **WebStorm (client)** — local file dependency in `skara-brae-client/package.json`:\\\n  ```json\\\n  \\\"@skara-brae/common\\\": \\\"file:../skara-brae-common/ts\\\"\\\n  ```\\\n  plus a Vite alias (`@common` → that path) so HMR picks up data edits. Attach the module likewise to edit it in-window.\\\n\\\n### Shared-Repo Consumption Strategy (Bilingual Package)\\\n\\\n`skara-brae-common` is a **bilingual package** whose source of truth is **language-neutral data + schema**, consumed at build time by both projects via codegen (never hand-duplicated types):\\\n\\\n```\\\nskara-brae-common/\\\n├── data/                  # language-neutral source of truth\\\n│   ├── items/ adventures/ crit-tables/ spells/ recipes/\\\n│   ├── medals/ dungeons/ tower/ expeditions/        (*.json / *.toml)\\\n│   └── schema/            # JSON Schema (entities) + openapi.yaml (API contract)\\\n├── rust/                  # thin crate the server depends on\\\n│   ├── Cargo.toml         #   name = \\\"sb-common\\\"; includes data via include_str! + serde\\\n│   └── src/lib.rs\\\n├── ts/                    # thin package the client depends on\\\n│   ├── package.json       #   name = \\\"@\"],[0,\"skar\"]],\"start1\":1340,\"start2\":1340,\"length1\":27,\"length2\":1527},{\"diffs\":[[0,\"brae\"],[-1,\"-\"],[1,\"/\"],[0,\"common\"],[-1,\"/          # Shared game data, API types, constants\\\n```\"],[1,\"\\\"; generated types + data re-exports\\\n│   └── src/index.ts\\\n└── codegen/               # data/ + schema  →  rust/ and ts/ bindings\\\n```\\\n\\\n**How sharing actually works:**\\\n- **Static game data** (`data/*.json`) is the single source of truth. Both sides consume at build time: Rust via `include_str!` + `serde`; Vue via Vite JSON import.\\\n- **API contract — server is authoritative.** Expose OpenAPI via [`utoipa`](https://docs.rs/utoipa); generate the client's TS types with `openapi-typescript` (or `orval`). So `api-types/` becomes a *generated* artifact, not hand-written in two languages.\\\n- **Entity types** — define once as JSON Schema in `data/schema/`, generate both Rust structs (`typify` / `schemars`) and TS interfaces (`json-schema-to-typescript`) from `codegen/`. Commit generated output (or generate in CI).\\\n\\\n**Two clarifications:**\\\n1. Do **not** confuse `skara-brae-common` (cross-language, this third repo) with the `sb-shared` crate in the server workspace below — `sb-shared` is a **server-internal** Rust crate (types/errors/constants) and stays inside `skara-brae-server/crates/`. Only truly cross-language artifacts go in the third repo.\\\n2. **Alternative for self-contained CI**: add `skara-brae-common` as a **git submodule** inside both (`server/common/`, `client/common/`) so `git clone --recurse-submodules` yields a complete tree. Cleaner CI, more day-to-day friction (detached HEAD, two-step updates). For solo work, start with the **sibling + path** layout above; switch to submodules only if contributors/CI demand it.\\\n\\\n**Synergy:** Because all content lives as structured data, we can **auto-generate a community game wiki** from `skara-brae-common` (Idle Fantasy does exactly this) — client tooltips and docs from one source.\"],[0,\"\\\n\\\n--\"]],\"start1\":2869,\"start2\":2869,\"length1\":70,\"length2\":1763},{\"diffs\":[[0,\"         # S\"],[1,\"erver-internal s\"],[0,\"hared types,\"]],\"start1\":8157,\"start2\":8157,\"length1\":24,\"length2\":40},{\"diffs\":[[0,\"DME.md\\\n```\\\n\\\n\"],[1,\"> Note: `sb-shared` above is the **server-internal** Rust crate. The **cross-language** shared repo is `skara-brae-common` (consumed via `sb-common = { path = \\\"../skara-brae-common/rust\\\" }`). See [Multi-Repo Structure](#multi-repo-structure) above.\\\n\\\n\"],[0,\"---\\\n\\\n## Key \"]],\"start1\":8602,\"start2\":8602,\"length1\":24,\"length2\":274},{\"diffs\":[[0,\"ared\\\" }\\\n\"],[1,\"sb-common = { path = \\\"../skara-brae-common/rust\\\" }   # cross-language game data + types\\\nutoipa = { version = \\\"5\\\", features = [\\\"axum_extras\\\"] } # OpenAPI for client codegen\\\n\"],[0,\"tracing \"]],\"start1\":9338,\"start2\":9338,\"length1\":16,\"length2\":188},{\"diffs\":[[0,\"b-shared\\\" }\\\n\"],[1,\"sb-common = { path = \\\"../skara-brae-common/rust\\\" }\\\n\"],[0,\"```\\\n\\\n### sb-\"]],\"start1\":9770,\"start2\":9770,\"length1\":24,\"length2\":75}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-07-31T18:49:42.206Z
created_time: 2026-07-31T18:49:42.206Z
is_locked: 0
type_: 13