Platform polish: bulk invite, file requirements, filtering redesign, UX fixes

- F1: Set seed jury/mentors/observers to NONE status (not invited), remove passwords
- F2: Add bulk invite UI with checkbox selection and floating toolbar
- F3: Add getProjectRequirements backend query + requirement slots on project detail
- F4: Redesign filtering section: AI criteria textarea, "What AI sees" card,
  field-aware eligibility rules with human-readable previews
- F5: Auto-redirect to pipeline detail when only one pipeline exists
- F6: Make project names clickable in pipeline intake panel
- F7: Fix pipeline creation error: edition context fallback + .min(1) validation
- Pipeline wizard sections: add isActive locking, info tooltips, UX improvements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 23:45:21 +01:00
parent 451b483880
commit 70cfad7d46
28 changed files with 1312 additions and 200 deletions

View File

@@ -419,12 +419,20 @@ export async function getSmartSuggestions(options: {
const suggestions: AssignmentScore[] = []
for (const user of users) {
// Skip users at AI max (they won't appear in suggestions)
const currentCount = user._count.assignments
// Skip users at AI max (they won't appear in suggestions)
if (currentCount >= aiMaxPerJudge) {
continue
}
// Per-juror hard block: skip entirely if at personal maxAssignments limit
if (user.maxAssignments !== null && user.maxAssignments !== undefined) {
if (currentCount >= user.maxAssignments) {
continue
}
}
for (const project of projects) {
// Skip if already assigned
const pairKey = `${user.id}:${project.id}`
@@ -621,6 +629,13 @@ export async function getMentorSuggestionsForProject(
continue
}
// Per-mentor hard block: skip entirely if at personal maxAssignments limit
if (mentor.maxAssignments !== null && mentor.maxAssignments !== undefined) {
if (mentor._count.mentorAssignments >= mentor.maxAssignments) {
continue
}
}
const { score: tagScore, matchingTags } = calculateTagOverlapScore(
mentor.expertiseTags,
projectTags