FantasyWiki Documentation
Docs are grouped by concept, not by component. Every doc carries YAML frontmatter (title, type, tags, related) and ends with a ## Related list, so the tree reads as a graph: the inline [text](./path.md) links are the edges, and they stay clickable wherever the file is read.
Map of content
domain/, the model of the system
What the game is: rules, entities, and vocabulary. No code structure here.
| Doc | What it answers |
|---|---|
| Scoring & Economy System | How points, prices, and settlement work (canonical) |
| League Lifecycle | Active / ended / closed / left, and why nothing is ever deleted |
| Chemistry Links | What a Chemistry Link is and what it scores |
| Lineup Rules | Formation, bench, and the no-contract-is-lost invariant |
| League Visibility | Public vs private leagues, who may join, and who may invite |
| Wikipedia Language Editions | Which editions can host a league, and the measured Language Scale Factor |
| League Season | When a season starts, how long it may run, and why |
| Article Availability | Free Agent / Owned by Viewer / Owned by Other, and action eligibility |
| Standings and Podium | How a league is ranked, what rank movement means, and when a podium is shown |
| What Are Model Entities | Why model/ holds normalized, framework-free entities |
| Shared DTO Package | Why dto/ aggregates and nests for the wire |
| FantaWiki Requirements | Original GDD v5.5, partly superseded, see the ADRs |
architecture/, how the code is put together
Seams, layers, and modules. The rules they implement live in domain/.
| Doc | What it answers |
|---|---|
| Backend Architecture | Routes → Services → Repositories layering |
| DDD Building Blocks | Which DDD archetype each concept became, and the perimeter the model sets |
| Persistence Targets | D1 or MongoDB, how one is chosen, and what replaces SQL atomicity |
| Auth Modes | Why username/password exists in one build and is absent from the deployed one |
| Sessions and Sign-in Doors | One session cookie, three doors that mint it, and the guards that read it |
| Nightly Scoring Pipeline | How the nightly batch scores every team, end to end |
| Contract Settlement | The nightly Workflow that renews or settles every contract that came due |
| Backend Error Constants | Typed errors instead of string matching |
| Frontend Query Keys | One module owns every TanStack Query key |
| DTO Dressing Pattern | How FE/BE each "dress" domain data |
| Chemistry Links Rendering | computeChemistryLinks + the SVG overlay |
| Lineup Editing | The DraftLineup seam and its pure mutations |
| Article Ownership Resolution | buildArticleDetail + the async team-context seam |
| Market List | How a Top Read Snapshot becomes a priced, owner-annotated shelf |
| Notifications | What writes an in-box message, and what it never does |
| Problem Reports | How /report files a GitHub issue, and what it never publishes |
| Article Genie LLM Integration | The Workers AI seam, turn protocol, and quota handling |
| Frontend Localisation | Two catalogues, one schema, and what is deliberately untranslated |
| Wikimedia Client Architecture | Composition root and capability modules |
| Wikimedia Client Behavior Extension | How to add a capability |
| Wikimedia Client Terminology | Naming and hierarchy rules |
development/, working on the code
| Doc | What it answers |
|---|---|
| Local Development Setup | Env files, MSW, Wrangler |
| Running FantasyWiki in Docker | ./gradlew noGenie with no credentials to obtain, and the three other combinations |
| Backend Testing | The test tiers, which layer each may name, and how to seed |
| Frontend Testing | What the browser suite is for, and the two constraints that bite |
| API Naming Rules | URL, identity, request-body and versioning conventions |
| NPM Script Naming | Why formatfix, not format:fix |
| Development Process | Branches, commits, the master ruleset, and why the process is this size |
| Release Process | How a version is computed from the commits, and what it names |
| AI Assistance | Which AI tools and skills were used, for what, and under which constraints |
deployment/, shipping it
| Doc | What it answers |
|---|---|
| Deploy Strategy | Branch → environment policy |
| Dev Branch Deployment | What the dev QA environment is for |
| Setup QA Deploy | One-time QA/D1 setup |
adr/, architectural decision records
Numbered, immutable decisions with their reasoning. When an ADR and any other doc disagree, the ADR wins.
0001 Base Scoring Model · 0002 Language Scale Factor · 0003 Closed Trading Economy · 0004 Scoring Engine Platform · 0005 Contract Pricing · 0006 Article Genie · 0007 Derived Team Credits · 0008 League Invitation Codes · 0009 AGPL-3.0 Licence
The published site
Everything below docs/ except agents/ is mirrored to https://fantasywiki.github.io/FantasyWiki/, alongside an authored orientation layer that exists only there: architecture and data-flow diagrams, a coverage board, and an interactive graph of this documentation tree. The site is a view of this directory, the source of truth stays here.
One directory is deliberately not on that map: agents/. It holds machine-read metadata, the issue tracker, the triage labels, the domain-context layout, the working agreements for this site and for the HTTP contract, which skills load at fixed paths, so do not move or rename anything in it. It is indexed by AGENTS.md, not here, and it is not published: a link into it from a published page resolves to GitHub.
Before adding a page or a diagram, read Documentation Site; before adding a route, OpenAPI Spec.
Repo-root documents
These stay at the root because they are entry points, not reference material:
CONTEXT.md: the canonical domain glossary. Start here for vocabulary.PRODUCT.md: product vision and tone.DESIGN.md: brand and UI tone.AGENTS.md: agent instructions, whichCLAUDE.mdimports.AI-DECLARATION.md: how AI was used to build the project, machine-readable.SECURITY.md: how to report a vulnerability, privately.
Conventions
File naming
kebab-case.md, all lowercase. No underscores, no capitals, no spaces, including in acronyms (shared-dto-package.md, never What_are_DTO.md).
ADRs are the one exception in shape, not in case: they are prefixed with a zero-padded number, NNNN-kebab-title.md (e.g. 0003-closed-trading-economy.md).
Frontmatter
Every doc starts with:
---
title: Human Readable Title
type: domain | architecture | development | deployment | adr | index
tags: [lowercase, kebab-case]
---Metadata only, no links here. GitHub renders frontmatter as an escaped table, so a link written in it can never be clickable. Links go in the body.
Linking, one mechanism, both surfaces
Every link is a relative markdown link in the body, e.g. [Lineup Rules](../domain/lineup-rules.md). That single form is clickable on GitHub, survives the mirror onto the published site, and is what the graph is built from, so the graph and the rendered docs can never disagree.
Do not use [[wikilinks]], and do not put links in frontmatter, neither renders as a link on GitHub.
Every doc ends with a ## Related section listing its neighbours. That section is the graph: it is what makes the edges visible to a human reading on GitHub and to a crawler following links.
Prefer linking over restating. A domain rule is stated once, in domain/, and referenced everywhere else.
Images
Documentation and README media live in docs/assets/, never in frontend/public/, which ships in the deployed SPA bundle (a demo GIF there would be served to every player). Name by what it shows: formation-chemistry.gif, market.png.
Where does a new doc go?
Ask what the doc would have to change for: if a game rule changed, it is domain/. If a refactor changed it, it is architecture/. Docs that would answer "yes" to both should be split in two and cross-linked, that is how chemistry, lineups, and article ownership are handled.
