docs: add architecture and decisions documentation
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# Decisions
|
||||
|
||||
> **Scope:** The rationale behind key design decisions. For the system's
|
||||
> architecture, see [`architecture.md`](./architecture.md). For the concrete
|
||||
> build plan, see [`implementation-plan.md`](./implementation-plan.md).
|
||||
>
|
||||
> Each entry records the decision, the context, and the alternatives considered.
|
||||
> New entries are appended; existing entries are updated only to correct facts,
|
||||
> not to rewrite history.
|
||||
|
||||
## D1 — Client-only, no caching
|
||||
|
||||
**Decision:** The system runs on the client only and has no caching layer.
|
||||
|
||||
**Context:** The tool is a personal, single-user utility. There is no shared
|
||||
state to protect and no multi-instance deployment.
|
||||
|
||||
**Alternatives considered:** In-memory TTL caching; Redis-backed caching. Both
|
||||
rejected as unnecessary complexity for a single client.
|
||||
|
||||
## D2 — Separate `packages/extract` from `packages/tts`
|
||||
|
||||
**Decision:** Analysis lives in `packages/extract`; fetching lives in
|
||||
`packages/tts`. They are separate packages with a clean fetch-vs-analyze
|
||||
boundary.
|
||||
|
||||
**Context:** The user wants to analyze saves and extract objects for a future
|
||||
frontend. Keeping analysis separate lets it be reused independently of the
|
||||
fetcher.
|
||||
|
||||
**Alternatives considered:** Folding analysis into `packages/tts`. Rejected —
|
||||
couples fetch and analysis and would force the frontend to depend on the
|
||||
fetcher.
|
||||
|
||||
## D3 — Traversal lives in `packages/extract`
|
||||
|
||||
**Decision:** `traverseMod` / `markParent` move from the fetcher into
|
||||
`packages/extract`.
|
||||
|
||||
**Context:** Traversal is analysis, not fetching. `packages/tts` should be
|
||||
fetch-only.
|
||||
|
||||
**Alternatives considered:** Keeping traversal in `packages/tts`. Rejected —
|
||||
blurs the fetch/analyze boundary.
|
||||
|
||||
## D4 — `packages/extract` is isomorphic with zero runtime deps
|
||||
|
||||
**Decision:** `packages/extract` runs in browser and Node, using only `fetch`,
|
||||
`Blob`, and typed arrays. It has no external runtime dependencies.
|
||||
|
||||
**Context:** The frontend (deferred) will consume it directly, so it must be
|
||||
portable. Node 18+ provides global `fetch` and `Blob`.
|
||||
|
||||
**Alternatives considered:** Using `Buffer` and Node-only packages. Rejected —
|
||||
breaks browser use.
|
||||
|
||||
## D5 — No backend traversal endpoints
|
||||
|
||||
**Decision:** The proxy exposes search and fetch only. Traversal is not exposed
|
||||
as HTTP endpoints.
|
||||
|
||||
**Context:** The frontend will use `packages/extract` directly. Exposing
|
||||
traversal on the backend would duplicate that logic and add endpoints with no
|
||||
current consumer.
|
||||
|
||||
**Alternatives considered:** Adding `/items/:id/objects` and similar endpoints.
|
||||
Deferred until a consumer exists.
|
||||
|
||||
## D6 — Search scrapes the Workshop browse page
|
||||
|
||||
**Decision:** Search is implemented by scraping
|
||||
`steamcommunity.com/workshop/browse/?appid=286160` with `cheerio`.
|
||||
|
||||
**Context:** Steam has no official Web API for searching the Workshop; the API
|
||||
only fetches details for known IDs.
|
||||
|
||||
**Alternatives considered:** None viable — there is no official search API.
|
||||
Accepted risk: scraping is fragile and may break if Steam changes its HTML.
|
||||
|
||||
## D7 — `bson` npm package replaces the browser `BSON` global
|
||||
|
||||
**Decision:** The existing scraper's `BSON.deserialize` global is replaced with
|
||||
the `bson` npm package.
|
||||
|
||||
**Context:** The scraper was written for the browser; the proxy runs on Node.
|
||||
|
||||
**Alternatives considered:** Keeping a browser-only global. Rejected — not
|
||||
available in Node.
|
||||
|
||||
## D8 — Download output type is `Blob`
|
||||
|
||||
**Decision:** `packages/extract`'s `downloadAsset` / `downloadAll` return `Blob`.
|
||||
|
||||
**Context:** The primary consumer is a frontend that renders assets in
|
||||
`<img>` / `<object>` elements.
|
||||
|
||||
**Alternatives considered:** Raw `ArrayBuffer`. Rejected — less convenient for
|
||||
frontend rendering.
|
||||
Reference in New Issue
Block a user