Skip to content

feat(raids): raid planning — group planner per raid team + personal availability#160

Merged
VortexUK merged 1 commit into
mainfrom
feature/raid-planning
Jul 11, 2026
Merged

feat(raids): raid planning — group planner per raid team + personal availability#160
VortexUK merged 1 commit into
mainfrom
feature/raid-planning

Conversation

@VortexUK

Copy link
Copy Markdown
Owner

Summary

The Raid Planning feature: officers curate a raid roster and drag characters into a 4-group × 6-slot layout per raid team, with automatic availability overlays from each player's personal calendar. Lives inside each team's (now collapsible) section on the guild Raids tab. Visible to members of that guild only.

Planner (per raid team)

  • Roster designations (officers): any guild member → Raider / Raid Alt via a filterable "Manage raiders" panel. Clearing a role cascades the character out of every team layout.
  • Groups: 4 × 6 grid + Sitout strip + Unassigned bench. Class-coloured chips (colour/archetype/subclass all data-driven from /api/classes).
  • Drag & drop: chips between slots (occupied slot ⇒ swap), to sitout/bench; drag a group header onto another group to swap whole groups. Click-to-place fallback for mobile/keyboard.
  • Date-aware: a date picker (defaults to the team's next raid night) overlays availability — AFK characters grey out with a badge.
  • Warnings: per-group missing priest / bard / enchanter; "X is AFK on this date"; "Player has N characters in the raid" (via approved claims).
  • Officers autosave (debounced, Saving…/Saved chips). Members get a sandbox — full drag freedom, nothing persists, reset chip. Non-members: 403 and the planner doesn't render.

Personal availability (home page)

"My Raid Availability" — renders only when one of the viewer's claimed characters is on a raid roster, and starts collapsed. 3-month calendar, click to cycle Available → Tentative → AFK (untouched = available), debounced save. Raiders with no schedule are simply always available.

Data model

Three new users.db tables (no migration needed): guild-scoped raid_roster_roles, team-scoped raid_placements (keyed by team_index — schedule saves regenerate team ids; the schedule PUT prunes layouts for removed teams), and user_availability (absent row = available). Two new AsyncStoreBase domains registered in ALL_STORES.

Tests

23 backend (member/officer/anonymous permission matrix, placement structural validation, availability window + status whitelist, role-clear cascade, team prune, claims-driven overlay) + 16 planner-logic vitest (swap semantics incl. bench/sitout displacement, warnings, ISO-weekday next-raid-date, dirty-check). Full suite: 1550 pytest, tsc/vitest/build clean. UI reviewed locally by the maintainer.

🤖 Generated with Claude Code

…vailability

Officer-curated raid rosters with a drag-and-drop group planner embedded
in each raid team's section of the guild Raids tab, plus a personal
3-month availability calendar on the home page.

Backend:
- Three new users.db tables (CREATE IF NOT EXISTS, no migration):
  raid_roster_roles (guild-scoped raider/raid_alt designations),
  raid_placements (per-team 4x6 layout keyed by team_index — schedule
  saves regenerate team ids, and the schedule PUT prunes layouts for
  removed teams), user_availability (per-user per-day; only non-default
  days stored so absent = available).
- RaidPlanningStore + AvailabilityStore (AsyncStoreBase domains, in
  ALL_STORES, facade-exempt like favorites/raid_schedule). Clearing a
  character's role cascades their placements out of every team.
- raid_planning router: GET planner payload (guild-members only — an
  approved claim on a character in the guild; officers flagged), officer
  PUTs for roles (canonical casing resolved from the roster) and
  placements (full-replace with structural validation: groups 1-4,
  slots 0-5, no double booking, group xor sitout, rostered chars only),
  GET/PUT /me/availability (92-day window, status whitelist).
- Availability overlay: char → player via approved claims; player → day
  status; player display names for the duplicate-player warning.

Frontend:
- Raid team sections are collapsible (single team starts expanded).
- RaidPlanner per team: class-coloured chips, drag & drop between
  slots/sitout/bench with occupied-slot swap and whole-group swap via
  header drag, click-to-place fallback, date picker defaulting to the
  team's next raid night, AFK grey-out, per-group priest/bard/enchanter
  warnings (data-driven from /api/classes archetype+subclass), AFK and
  duplicate-player callouts. Officers autosave (debounced) with status
  chips + a Manage Raiders panel; members get a local sandbox with a
  reset chip; non-members see nothing (403 → render null).
- Home page: "My Raid Availability" renders only when a claimed
  character is rostered anywhere, starts collapsed; 3-month click-to-
  cycle calendar (Available → Tentative → AFK), debounced save.

Tests: 23 backend (permission matrix incl. non-member 403, placement
validation, availability window/status, role-clear cascade, prune,
overlay via real claims) + 16 frontend logic tests (move/swap
semantics, warnings, next-raid-date, dirty check). 1550 pytest green,
tsc/vitest/build clean. User-reviewed locally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@VortexUK
VortexUK merged commit e1566a2 into main Jul 11, 2026
6 checks passed
@VortexUK
VortexUK deleted the feature/raid-planning branch July 11, 2026 17:11
VortexUK added a commit that referenced this pull request Jul 11, 2026
…aiders search/rank filter (#161)

Two follow-ups to #160:

- A site admin who is ALSO a member of the guild can edit the raid plan
  like an officer (roles + placements). Admin alone is not enough — the
  planner belongs to the guild. The GET payload's is_officer flag
  reflects it so the UI enables autosave. Tests cover both the
  admin+member happy path and the admin-non-member 403.
- Manage Raiders scales to large guilds: the roster payload now carries
  each member's guild rank (name + id), and the panel gains a rank
  dropdown (ordered by rank id) alongside the renamed search box.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant