feat: complete MENTORING round config form (§A)

Surfaces every MentoringConfigSchema field on the round Config tab:

- Adds "Mentoring Request Window" card with mentoringRequestDeadlineDays
  numeric input (1-90 days, default 14) and passThroughIfNoRequest toggle
  (default ON; OFF holds projects PENDING until manual mentor assignment).
- Adds inline help-text for the Eligibility dropdown explaining each
  option's effect on auto-PASS behavior.
- Hides the General Settings card on MENTORING rounds (it only renders
  Advancement Targets, which don't apply to a pass-through round).
- Relaxes the Launch Readiness "File requirements set" gate for MENTORING
  rounds without filePromotionEnabled + a target window — file requirements
  only matter when files will be promoted to a downstream submission window.

Spec: docs/superpowers/specs/2026-04-28-mentor-round-readiness-design.md §A
Plan: docs/superpowers/plans/2026-04-28-pr3-mentoring-config-completeness.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt
2026-04-28 14:25:23 +02:00
parent 2e7b545a1b
commit 16156111a6
3 changed files with 90 additions and 2 deletions

View File

@@ -0,0 +1,39 @@
# PR 3 — MENTORING Round Config Completeness (§A)
> **For agentic workers:** Use superpowers:executing-plans for inline execution.
**Goal:** Surface every `MentoringConfigSchema` field on the round Config tab; hide the empty General Settings card on MENTORING rounds; relax the "File requirements set" Launch Readiness gate when no file promotion is configured.
**Architecture:** UI-only changes. No schema, no API. Three files touched.
**Spec:** `docs/superpowers/specs/2026-04-28-mentor-round-readiness-design.md` §A.
## File map
| File | Action | Why |
|------|--------|-----|
| `src/components/admin/rounds/config/mentoring-config.tsx` | Modify | Add `mentoringRequestDeadlineDays` numeric input + `passThroughIfNoRequest` toggle; add help-text to Eligibility |
| `src/app/(admin)/admin/rounds/[roundId]/page.tsx` | Modify | Hide General Settings card when `round.roundType === 'MENTORING'`; relax File-requirements readiness gate for MENTORING rounds without file promotion configured |
## Tasks
### Task 1: Add the two missing inputs to `mentoring-config.tsx`
- [ ] **Step 1: Patch the file** — append a new "Mentoring Request Window" card BETWEEN the existing two cards, and add help-text to Eligibility. Code in execution.
- [ ] **Step 2: Typecheck**`npm run typecheck`. Expect 0 errors.
### Task 2: Hide General Settings card + relax readiness on MENTORING rounds
- [ ] **Step 1: Patch `(admin)/admin/rounds/[roundId]/page.tsx`** — wrap the General Settings card in `{!isMentoring && (...)}` and extend the file-requirements bypass condition.
- [ ] **Step 2: Typecheck + build** — confirm clean.
### Task 3: Smoke + commit
- [ ] **Step 1: `npm run build`** — confirm clean.
- [ ] **Step 2: Commit** — message references §A.
## Out of scope
Form unit tests (heavy render setup; existing config-save mutation already verified by other PRs). Manual smoke covers the UI work.

View File

@@ -514,6 +514,7 @@ export default function RoundDetailPage() {
const isFiltering = round?.roundType === 'FILTERING'
const isEvaluation = round?.roundType === 'EVALUATION'
const isMentoring = round?.roundType === 'MENTORING'
const hasJury = ['EVALUATION', 'LIVE_FINAL', 'DELIBERATION'].includes(round?.roundType ?? '')
const hasAwards = roundAwards.length > 0
const isSimpleAdvance = ['INTAKE', 'SUBMISSION', 'MENTORING'].includes(round?.roundType ?? '')
@@ -589,7 +590,8 @@ export default function RoundDetailPage() {
action: undefined as Route | undefined,
actionLabel: undefined as string | undefined,
},
...((isEvaluation && !(config.requireDocumentUpload as boolean))
...((isEvaluation && !(config.requireDocumentUpload as boolean)) ||
(isMentoring && !(config.filePromotionEnabled as boolean) && !config.promotionTargetWindowId)
? []
: [{
label: 'File requirements set',
@@ -2198,7 +2200,8 @@ export default function RoundDetailPage() {
</CardContent>
</Card>
{/* General Round Settings */}
{/* General Round Settings — hidden on MENTORING rounds (no advancement targets apply) */}
{!isMentoring && (
<Card>
<CardHeader className="border-b">
<ConfigSectionHeader
@@ -2321,6 +2324,7 @@ export default function RoundDetailPage() {
)}
</CardContent>
</Card>
)}
{/* Round-type-specific config */}
<RoundConfigForm

View File

@@ -40,6 +40,11 @@ export function MentoringConfig({ config, onChange }: MentoringConfigProps) {
<SelectItem value="admin_selected">Admin Selected</SelectItem>
</SelectContent>
</Select>
<ul className="text-xs text-muted-foreground space-y-1 mt-2">
<li><strong>All Advancing Projects</strong> every project that enters this round is paired with a mentor.</li>
<li><strong>Requested Only</strong> only projects that explicitly request mentoring participate (default).</li>
<li><strong>Admin Selected</strong> admin manually picks which projects get a mentor.</li>
</ul>
</div>
<div className="flex items-center justify-between">
@@ -56,6 +61,46 @@ export function MentoringConfig({ config, onChange }: MentoringConfigProps) {
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-base">Mentoring Request Window</CardTitle>
<CardDescription>How long teams have to request a mentor, and what happens to non-requesters</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="mentoringRequestDeadlineDays">Request deadline (days from round opening)</Label>
<p className="text-xs text-muted-foreground">After this many days, teams can no longer submit a mentoring request. Default: 14.</p>
<Input
id="mentoringRequestDeadlineDays"
type="number"
min={1}
max={90}
className="w-32"
value={(config.mentoringRequestDeadlineDays as number) ?? 14}
onChange={(e) => {
const v = parseInt(e.target.value, 10)
if (!Number.isNaN(v) && v >= 1 && v <= 90) update('mentoringRequestDeadlineDays', v)
}}
/>
</div>
<div className="flex items-center justify-between">
<div>
<Label htmlFor="passThroughIfNoRequest">Auto-pass non-requesters</Label>
<p className="text-xs text-muted-foreground">
When ON, projects that don&apos;t request mentoring auto-PASS to the next round (default).
When OFF, all projects are held in PENDING until the admin decides useful when mentoring is mandatory.
</p>
</div>
<Switch
id="passThroughIfNoRequest"
checked={(config.passThroughIfNoRequest as boolean | undefined) ?? true}
onCheckedChange={(v) => update('passThroughIfNoRequest', v)}
/>
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-base">Communication & Files</CardTitle>