feat(events): the minimal admin surface (Phase 3)
Three screens, an Events nav group and the six live run controls Phase 1 left
absent on purpose because nothing was in flight. An admin can now author,
publish, start and watch an event that announces things and cues a human; a
moderator can stop one that is going wrong.
Six controls, not eight. `advance` is absent because a phase today advances when
its steps go terminal — the per-step skip already does that — and Phase 5 is what
gives a phase an advance condition. Cancel takes `{ reason }`, not `{ cleanup }`,
until Phase 8's ledger exists. Every control is a compare-and-set on the status it
may act from, so a console rendered thirty seconds ago cannot act on a run that
has moved.
Fixes a defect in the Phase 2 runner: `advanceRun` drained up to
EVENT_STEPS_PER_TICK steps while only checking the run's status at the top of the
tick, so a pause pressed mid-batch did nothing for up to 24 more steps.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T6t8mrAWhZU5vnyYgZTMtL
This commit is contained in:
@@ -49,6 +49,9 @@ import EngagementTriggers from './routes/admin/views/EngagementTriggers.jsx'
|
||||
import EngagementSendLog from './routes/admin/views/EngagementSendLog.jsx'
|
||||
import EngagementSuppressions from './routes/admin/views/EngagementSuppressions.jsx'
|
||||
import EngagementRetention from './routes/admin/views/EngagementRetention.jsx'
|
||||
import EventsAdmin from './routes/admin/views/EventsAdmin.jsx'
|
||||
import EventEditor from './routes/admin/views/EventEditor.jsx'
|
||||
import EventRun from './routes/admin/views/EventRun.jsx'
|
||||
import TeamsAdmin from './routes/admin/views/TeamsAdmin.jsx'
|
||||
import AccountAdmin from './routes/admin/views/AccountAdmin.jsx'
|
||||
import Moderation from './routes/admin/views/Moderation.jsx'
|
||||
@@ -192,6 +195,18 @@ export default function App() {
|
||||
actions that publish a game-written name is applied per request
|
||||
on the server, from the caller's live role (TEAMS.md 2.9). */}
|
||||
<Route path="teams" element={<TeamsAdmin />} />
|
||||
{/* Events (EVENTS.md §I, Phase 3). Staff-wide, unlike Engagement:
|
||||
§K makes every read here `staff`, and the moderator's whole
|
||||
power over this feature is the run console — cancelling a run
|
||||
that is doing something wrong at 2am. The narrower gates are
|
||||
applied per action instead: authoring is admin+editor, publish
|
||||
and start are admin only (§N2), and each button follows the
|
||||
route it calls. `runs/:runId` is declared before `:id` so the
|
||||
literal segment is never read as a definition id. */}
|
||||
<Route path="events" element={<EventsAdmin />} />
|
||||
<Route path="events/runs/:runId" element={<EventRun />} />
|
||||
<Route path="events/new" element={<EventEditor />} />
|
||||
<Route path="events/:id" element={<EventEditor />} />
|
||||
{/* Engagement (ENGAGEMENT.md Phases 4b and 5b). Admin-only, matching the
|
||||
server: every route under /admin/engagement re-gates to `admin`
|
||||
on top of the group's staff gate, because this is the group that
|
||||
|
||||
Reference in New Issue
Block a user