Skip to content

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.

DocWhat it answers
Scoring & Economy SystemHow points, prices, and settlement work (canonical)
League LifecycleActive / ended / closed / left, and why nothing is ever deleted
Chemistry LinksWhat a Chemistry Link is and what it scores
Lineup RulesFormation, bench, and the no-contract-is-lost invariant
League VisibilityPublic vs private leagues, who may join, and who may invite
Wikipedia Language EditionsWhich editions can host a league, and the measured Language Scale Factor
League SeasonWhen a season starts, how long it may run, and why
Article AvailabilityFree Agent / Owned by Viewer / Owned by Other, and action eligibility
Standings and PodiumHow a league is ranked, what rank movement means, and when a podium is shown
What Are Model EntitiesWhy model/ holds normalized, framework-free entities
Shared DTO PackageWhy dto/ aggregates and nests for the wire
FantaWiki RequirementsOriginal 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/.

DocWhat it answers
Backend ArchitectureRoutes → Services → Repositories layering
DDD Building BlocksWhich DDD archetype each concept became, and the perimeter the model sets
Persistence TargetsD1 or MongoDB, how one is chosen, and what replaces SQL atomicity
Auth ModesWhy username/password exists in one build and is absent from the deployed one
Sessions and Sign-in DoorsOne session cookie, three doors that mint it, and the guards that read it
Nightly Scoring PipelineHow the nightly batch scores every team, end to end
Contract SettlementThe nightly Workflow that renews or settles every contract that came due
Backend Error ConstantsTyped errors instead of string matching
Frontend Query KeysOne module owns every TanStack Query key
DTO Dressing PatternHow FE/BE each "dress" domain data
Chemistry Links RenderingcomputeChemistryLinks + the SVG overlay
Lineup EditingThe DraftLineup seam and its pure mutations
Article Ownership ResolutionbuildArticleDetail + the async team-context seam
Market ListHow a Top Read Snapshot becomes a priced, owner-annotated shelf
NotificationsWhat writes an in-box message, and what it never does
Problem ReportsHow /report files a GitHub issue, and what it never publishes
Article Genie LLM IntegrationThe Workers AI seam, turn protocol, and quota handling
Frontend LocalisationTwo catalogues, one schema, and what is deliberately untranslated
Wikimedia Client ArchitectureComposition root and capability modules
Wikimedia Client Behavior ExtensionHow to add a capability
Wikimedia Client TerminologyNaming and hierarchy rules

development/, working on the code ​

DocWhat it answers
Local Development SetupEnv files, MSW, Wrangler
Running FantasyWiki in Docker./gradlew noGenie with no credentials to obtain, and the three other combinations
Backend TestingThe test tiers, which layer each may name, and how to seed
Frontend TestingWhat the browser suite is for, and the two constraints that bite
API Naming RulesURL, identity, request-body and versioning conventions
NPM Script NamingWhy formatfix, not format:fix
Development ProcessBranches, commits, the master ruleset, and why the process is this size
Release ProcessHow a version is computed from the commits, and what it names
AI AssistanceWhich AI tools and skills were used, for what, and under which constraints

deployment/, shipping it ​

DocWhat it answers
Deploy StrategyBranch → environment policy
Dev Branch DeploymentWhat the dev QA environment is for
Setup QA DeployOne-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:

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:

yaml
---
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.

Built from the repository's own documentation. Source on GitHub.