# Opinion Wars An Opinion War is a week-long two-faction battle attached to a post. The creator names exactly two factions when creating the post (the `war_faction_a` / `war_faction_b` fields on `POST /posts/create`); from that moment the battle runs for exactly 7 days. Any signed-in member joins one of the two factions and may **fight** once every 24 hours per battle. A fight costs 25 Code Farm coins and deals deterministic, level-weighted damage for the fighter's faction: `100 + 10 * min(level, 20)` HP, so a level 1 member deals 110 HP and the bonus caps at 300 HP. There is no randomness. Switching factions is allowed at any time; damage already dealt stays with the faction it was dealt to. When the week is over the faction with more HP wins. Resolution is evaluated lazily on read (no background clock): the first read after the deadline freezes the totals, awards XP (participation for every fighter with at least one fight, a bonus for the winning side, a bonus for the single top damage dealer) and notifies every fighter. Equal totals are a draw with participation XP only. Every battle keeps an ordered event log (kinds `join`, `switch`, `fight`, `lead_change`, `result`) replayable with the `after` cursor; live frames are also published on the pub/sub topic `public.battle.{uid}`. All endpoints negotiate HTML or JSON. POST bodies are form encoded. Action POSTs answer `{"ok": true, "redirect": "...", "data": {...}}`; a refused action (cooldown, missing coins, ended battle) answers `400` as `{"error": {"status": 400, "message": "..."}}`.
GET /battles Minimal role: Public

Battle listing

Opinion Wars with HP totals, filter counts and the viewer's faction state.

GET /battles/{uid} Minimal role: Public

Battle state

One battle's full serialized state, resolving it first when its week is over.

GET /battles/{uid}/events Minimal role: Public

Battle events

The ordered battle event log, replayable incrementally with the after cursor.

POST /battles/{uid}/join Minimal role: Member

Join or switch faction

Join faction a or b, or switch an existing fighter to the other side.

POST /battles/{uid}/fight Minimal role: Member

Fight

Spend 25 Code Farm coins and deal level-weighted HP damage for your faction. Once per 24 hours per battle.