Enhancement: Court Planner + Recommendations workflow (Planner, Court Report, Herald Script, Recs Manager, notifications, pass-to-local)#490
Open
baltinerdist wants to merge 128 commits into
Conversation
Contributor
Author
|
Updated with the Court Planner grant-safety + workflow/UX implementation (commit Records integrity
Concurrency
Workflow / mobile / a11y
Ceremony polish
Verified end-to-end against a live instance (6/6 functional + 4/4 fix re-tests; all data-integrity SQL invariants at 0). Migrations: 🤖 Generated with Claude Code |
- New Court class, Court controller, and CourtAjax controller - Court detail and list templates - DB migration for court planner table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mendations - Court Planner tab added to Kingdomnew profile (visible to canManage users only): loads CourtList/UpcomingEvents from controller, inline card list with status badges and award counts, Plan a Court modal using kn-* CSS classes - Anonymous toggle on all recommendation modals (Playernew, Kingdomnew, Parknew): checkbox stores mask_giver=1 in ork_recommendations; submitter fields are nulled in PlayerAwardRecommendations for non-ORK-admin callers; ORK admins see name with (anon) label; CallerUid + CallerIsOrkAdmin wired through all three controllers and the Park/Kingdom/Player AJAX handlers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Court Planner tab on Kingdom and Park profiles (Monarch/Regent/PM access) - Court detail page: create/manage courts, add awards, reorder, track scroll/regalia status - Award recommendations: anonymous rec support, snooze functionality, rec enhancements - Print court script: two-column table layout with rec reason and recommender attribution - Fix: Court detail template path (HTTP_TEMPLATE → relative path) - Fix: Print script overlay moved to body level so print CSS selector works correctly - Fix: Authorization switch fall-through missing break for AUTH_EDIT case - Fix: Password reset email copy and expiry duration - DB migrations: snooze-to-recommendations, court-rec-enhancements Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Award row layout (Court_detail.tpl): - Replaced rigid 6-column CSS grid with 2-line flexbox layout - Line 1: bold persona + park abbreviation + note icon - Line 2: award name + rank + compact icon-only flags + tracking icons - Removed type badge (left border color already communicates title/ladder/award) - Pass-to-Local and From-Rec flags reduced to 20px circle icons with tooltips - Updated both PHP server-rendered markup and JS cpAppendAwardRow() to match Plan a New Court modal (Kingdomnew_index.tpl, Parknew_index.tpl, revised.css): - Fixed modal rendering outside overlay (missing position:fixed CSS) - Aligned field classes to match existing modal pattern (kn-acct-field, kn-modal-close-btn) - Added scoped CSS for both kingdom and park new-court modals revised.js syntax fix: - Repaired two unclosed IIFE/addEventListener blocks at end of file that prevented the court planner tab from responding to clicks DB migration (local only): - Created ork_court, ork_court_award, ork_court_award_artisan tables Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reverse-engineered PRD covering: ork_court / ork_court_award / ork_court_award_artisan tables, recommendation snooze (regnum-scoped auto-expiry), award context preservation (court_award_id + source_reason on ork_awards), anonymous recs (mask_giver wired end-to-end), planning + run-of-show + post-court workflows. Flags the parallel ork_recommendation_support vs Mask branch's ork_recommendation_seconds collision that needs resolution before either can merge. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Spreadsheet layout for the Order of Court list — sticky column header, CSS-grid rows, density toggle (Cozy / Comfortable / Compact) persisted to localStorage, sidebar collapse rail, row #'s kept in sync on reorder/add/remove. - Comprehensive dark-mode coverage on both Court_detail and Court_list: status bar, sidebar cards, modals, type chips, tracking icons, status badges, recommendation modal, expand area, autocomplete dropdowns. Inline-styled pills/buttons refactored to classes so theme overrides actually apply. - "Add from Recommendations" modal now delegates to Reports::PlayerAwardRecommendations, gaining Master-peerage cascade, custom-award carve-out, award_id cross-check, snooze awareness, age, seconds, and anon-rec masking. Modal gets 4 view filters (Open / All / Snoozed / Already Has), inline age badges, seconds count, on-another-court warning, and per-row "Already Has / Covered by Master" context. Each row collapsed from ~5 lines to 2 (header + reason). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Standalone spreadsheet-style tool (Recommendations/manage/{kingdom|park}/{id})
consolidating admin rec actions (Grant Now, Dismiss, Snooze, Add to Court) off
the inline profile tab. Reuses existing AJAX endpoints + Court Planner.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
12 bite-sized tasks: route scaffold, getRecommendationCourtMap, controller data, spreadsheet grid, expand rows, sort/filter, selection+bulk, snooze/ dismiss, Grant Now, Add to Court, inline-tab migration, dark-mode/QA pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kingdom/Park profile recs tabs: add authority-gated "Manage Recommendations" button; remove inline grant/snooze/dismiss/add-to-court controls + the now- orphan add-court overlays (kept the Enter-Awards award modals; community +1/second controls retained). revised.js handlers left inert (delegated/null- guarded). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rm absent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… table.dataTable The Park/Kingdom recommendation tables are not DataTables (no DataTable() init), so the dark-mode rules scoped to table.dataTable never matched — leaving a white thead and light :hover background, and dark text on dark bg, in dark mode. Scope to the always-present .pk-recs-table class instead. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…l bar Park rendered TWO filter rows: a legacy kn-rec-header-row (style.display filter, the functional one) and a kn-rec-filter-bar wired to a never-initialized DataTables path (pkRecDT undefined -> dead no-op). Unlike the lazy-loaded Kingdom panel, the Park recs table is NOT a DataTable, so the filter-bar's filters did nothing. Consolidate to one bar mirroring Kingdom's layout: drop the duplicate header-row filters (keep Recommend in a toolbar, fold Manage into the bar), add the Snoozed filter, and teach the style.display applyFilter the 'open' filter so 'Open Recs' actually hides already-fulfilled recs. JS change is additive and does not affect the Kingdom DataTables path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e + dead filters)
The Park recs tab never became a DataTable because (a) the DataTables library
(CSS+JS) was never loaded on the Park page (only Kingdom loads it), so the inline
init threw "Cannot read properties of undefined (reading 'ext')" on
$.fn.dataTable.ext..., and (b) that inline init had unbalanced braces (missing the
if-close and $(function(){...}) close). Both killed the whole <script>, so
pkRecDT/pkRecPrint/pkRecCsv/initEmailSpellCheck never ran and the table never got
the dataTable class — which is what broke dark mode (rules gated on table.dataTable)
and left the filter bar inert.
Fix: load the same DataTables 1.13.8 CSS+JS the Kingdom page loads, and balance the
init braces. Park now matches Kingdom (paging/search/sort, working ext.search
filters, Print/CSV). Drop the Snoozed filter button (Kingdom has none; the
ext.search doesn't handle it) and make the legacy style.display applyFilter stand
down when a recs DataTable is present so it can't fight DataTables.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…er filter labels - Manage Recommendations (<a> styled as button) was inheriting the global dark link color (#theme_container a -> cyan); override to white for .pk/.kn-manage-recs. - Shorten 'Below Recommended' -> 'Below Rec'd' and 'At or Above Recommended' -> 'At or Above Rec'd' on the filter buttons (Park + Kingdom) to save bar space. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PlayerAwardRecommendations selected recs.passed_to_local but the intermediate row object omitted it, so the PassedToLocal mapping read an undefined property and was always false — the 'passed to local' badge never showed on the Recommendations Manager, park, or player recs views despite the DB flag being set. Carry passed_to_local/_by/_at on the row object (mirrors the snoozed_* fields). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…anager Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ed-on date Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirrors the Court Planner collapse pattern: header toggle button + chevron, collapsible body (default open). Uses a chevron glyph swap (up/down) rather than CSS rotate, which did not take on the FA <i>. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…der/chrome Wrap the Manager in .rp-root + reports.css and replace the light rm-hero with the standard reports header (dark indigo bar: icon + title + scope chip + Back) and a rp-context description strip. Also drop the leftover @media(prefers-color-scheme) blocks so the grid follows the app's data-theme toggle (was tracking OS setting, causing header/grid theme mismatch). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add one shared component — rank-pill.css `.ladder-rank[data-lvl="1..10"]` — and use it on every surface that shows ladder ranks: Recommendations Manager, Park & Kingdom recs tabs, and Court planning (static + JS renders). Rank is clamped to 1..10 (min); non-ladder/0 awards render plain (no pill). Palette is a single cool spectrum (light blue -> indigo -> violet -> purple -> deep magenta), deliberately NO green and NO red so rank reads as magnitude, not an approve/reject verdict; dark-mode tuned for contrast. Also: in the Recommendations Manager, sorting by Award now subsorts by ladder rank, following the column's sort direction (data-rank + rmSort tiebreaker). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the blue->magenta spectrum with a wider cool->warm sweep so adjacent ranks are easier to distinguish: teal, sky, blue, indigo, violet, purple, magenta, rose, orange, gold. Still deliberately avoids deep green and deep red (teal/gold/orange are fine); light + dark variants tuned for contrast. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Spec for moving the Manager from load-all + client filter/sort to server-side filter/sort/paginate in 500-row (cluster) batches via infinite scroll, with eligibility aligned to the recs-tab pills (Open Recs default) and newest-first default sort. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7-task plan: grouping helper, PlayerAwardRecommendationsPage (cluster paging + SQL filters/sort, reusing existing hydration for exact flags), shared row partial, rows() endpoint, first-batch manage(), infinite-scroll client rewrite, end-to-end verification. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…$DB in controller)
…de cluster paging)
…e, not filtered count)
Adds the rows() action + rmParkMap() helper to Controller_Recommendations and the recommended_awards_page() model passthrough. The endpoint renders one 500-row batch of shared _rm_row.tpl partials as JSON. Also fixes a MariaDB correlation bug in Report::PlayerAwardRecommendationsPage's support subquery (outer alias not visible through a UNION-in-FROM derived table) that made every page return zero rows. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…+ pill eligibility
… the count SQL The page/count query approximated AlreadyHas with kacount/awcount only, so the 'Showing N of M' total read a few high (and ator a few low) for ladder recs covered by a Master peerage. Inject the GetLadderMasterMap ladder->master pairs as a derived table + correlated EXISTS so the SQL AlreadyHas matches the PHP hydration exactly. Verified park 76 open now rows==total (272==272). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the plain one-word data-tip on the snooze button with the rich .rm-passlocal-tip pattern so it can render a bold title plus description: "Snooze to Next Monarchy" / "Temporarily dismiss this recommendation until either the Monarch or Regent officer at this level changes." Snoozed state shows an Unsnooze counterpart. Right-anchored + dark-mode variant; JS swap targets the icon span so it no longer clobbers the tooltip markup. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nt Award modal; + Court/Recs polish Recommendations Manager - CSV export endpoint streaming the full filtered/sorted set (Recommendations/export) - Server-side Rank sort + sortable Rank column header - Split Park into its own column (abbreviation); Rank into its own column (pill without the "Rank" word) - Grant Award modal (replaces insta-grant — never grants without confirmation): pre-filled recipient/award/rank/note, JSON PlayerAjax grantaward endpoint, court-plan reconciliation folded in, resolves the cluster on success - Grant modal parity with the regular award modal: rank pills (green = already held), officer quick-pick chips (Monarch/Regent), "Given at" park/kingdom/event location picker Court Planner + Recs polish - Security: add_award scopes KingdomAwardId to the court's kingdom (IDOR) - grant_award atomic claim (no double-grant); reorder_awards single CASE UPDATE (no N+1) - All CourtAjax mutations moved into the class.Court lib layer (no raw $DB in the controller) - controller.Court lookups + hero heraldry routed through the lib (restores cache-buster) - Court_detail: error handling on post()/cpSaveOrder, native confirm()/alert() → in-product dialogs, batch add-from-rec no longer marks failed adds as succeeded - class.Report: expose HeldRank; class.Court do-while → while (read-after-Next fix) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Design spec for splitting grant (stage) from commit-to-record (finalize), adding a stored run-vs-plan court mode, a two-tap pre-filled grant modal, per-row undo, drag-and-drop reorder, a live multi-manager heartbeat, a prepopulate-skipped-from-last-court banner, and a complete-court modal. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GDxMDhZUEMepFQ9hMidnpJ
Six-expert review roadmap: S1 idempotent grant sink + QW1-9 + S2 mode-driven workflow + S3 responsive mobile + S5 optimistic concurrency/presence. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DXQ2YePHm59VSzozsxbNXJ
…kflow, mobile, collaboration & ceremony polish Implements the stage/finalize + grant-safety specs on top of the Court Planner. Grant safety / records integrity: - Single idempotent commit sink (Court::commitStagedAward); court-line identity is the idempotency key. Player::AddAward returns the real inserted id (findRecentAwardId date-heuristic removed); throw-safe finalize (revert-on-throw, re-runnable). - Server-side cross-path reconcile (reconcileGrantForRecommendation, exact rec id OR cluster key) so a Recs-Manager grant can't be re-granted at finalize. - update_court_status rejects 'complete' (only finalize completes a court); remove/skip/setStatus guard 'given'; update_award no longer writes lifecycle status. Concurrency / collaboration: - ork_court_award.row_version optimistic-lock token (409/stale -> non-destructive reload); full-field heartbeat reconcile (add/remove rows); presence roster + honest sync indicator; silent background poll. Workflow / UX / mobile / accessibility: - Run mode: 'Grant' vocabulary + auto-finalize on Complete; walk-on adds while published; inline un-skip. Mobile: overflow-x wrapper + stacked-card layout so Grant/Skip are reachable on a phone. a11y additive pass (aria-live, labels, contrast, tracker glyphs, dialog roles); native confirm/alert removed. - Rank-pill contrast ramp reworked to WCAG AA (uniform saturated + white text). - Functional status (inert manual dropdown removed; Cancelled -> Skipped); expanded-row highlight; hero breadcrumb tidy; flags/type instant tooltips. - Ad-hoc add split into Add Award / Add Title with typeable autocompletes grouped exactly like the player Add Award modal (new Model_Award::fetch_award_option_groups), rank pills replacing the number box. Migrations: 2026-07-11-court-stage-finalize.sql, 2026-07-12-court-grant-safety.sql. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DXQ2YePHm59VSzozsxbNXJ
baltinerdist
force-pushed
the
feature/court-planner
branch
from
July 18, 2026 20:26
748e3df to
d32dc7c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Court Planner + Recommendations workflow
A complete workflow for planning royal courts and managing award recommendations.
Court Planner
Recommendations Manager
Migrations
Seven migrations under
db-migrations/(court tables, recommendation snooze / pass-to-local columns, notification table, etc.). Apply before deploy.Notes
system/lib/ork3/(Court + Report libs); controllers stay thin.🤖 Generated with Claude Code