11import personRepo from '../../repos/personRepo.js' ;
22import { BadRequest , NotFound } from '../../helpers/problem.js' ;
3+ import config from '../../../config/config.js' ;
34
45async function getParadigms ( req , res ) {
56 //get the search query from the query params
6- const { search } = req . query ;
7+ const { search, limit = 50 , offset = 0 } = req . query ;
78 if ( ! search ) {
89 throw new BadRequest ( req , res , 'Search query is required' ) ;
910 }
11+ if ( limit > 100 ) {
12+ throw new BadRequest ( req , res , 'Limit cannot exceed 100' ) ;
13+ }
1014
1115 const paradigms = await personRepo . personSearch ( search , {
1216 excludeBanned : true ,
1317 excludeUnconfirmedEmail : true ,
1418 hasValidParadigm : true ,
1519 hasJudged : true ,
16- limit : 50 ,
20+ limit,
21+ offset,
1722 include : {
18- judges : {
23+ Judges : {
1924 fields : [ 'id' ] ,
2025 include : {
2126 school : {
@@ -25,7 +30,6 @@ async function getParadigms(req, res) {
2530 } ,
2631 } ,
2732 } ) ;
28-
2933 const results = paradigms . map ( p => {
3034 const nameParts = [ p . firstName , p . middleName , p . lastName ] . filter ( Boolean ) ;
3135 // Get all schools from Judges
@@ -52,30 +56,188 @@ async function getParadigms(req, res) {
5256 } ) ;
5357 res . json ( results ) ;
5458} ;
59+
60+ //NOTE, I also hate this and will fix it, I was just seeing if it would work well. it didn't. RCT
5561async function getParadigmByPersonId ( req , res ) {
5662 const { personId } = req . params ;
5763 if ( ! personId ) {
5864 throw new BadRequest ( req , res , 'Person ID is required' ) ;
5965 }
6066
67+ const certInclude = {
68+ PersonQuizzes : {
69+ isValid : true ,
70+ fields : [ 'id' , 'updatedAt' ] ,
71+ include : {
72+ Quiz : {
73+ fields : [ 'id' , 'label' , 'description' , 'badgeDescription' , 'badge' , 'badgeLink' ] ,
74+ } ,
75+ } ,
76+ } ,
77+ } ;
78+ const sectionRecordInclude = {
79+ Section : {
80+ required : true ,
81+ fields : [ 'id' ] ,
82+ include : {
83+ Round : {
84+ required : true ,
85+ publicPrimaryResults : true ,
86+ fields : [ 'id' , 'name' , 'label' ] ,
87+ include : {
88+ Event : {
89+ fields : [ 'id' , 'abbr' ] ,
90+ settings : [ 'aff_label' , 'neg_label' ] ,
91+ } ,
92+ } ,
93+ } ,
94+ Ballots : {
95+ fields : [ 'id' , 'judgeId' , 'side' ] ,
96+ include : {
97+ Scores : {
98+ winloss : true ,
99+ fields : [ 'id' , 'tag' , 'value' ] ,
100+ } ,
101+ Entry : {
102+ fields : [ 'id' , 'code' ] ,
103+ } ,
104+ } ,
105+ } ,
106+ } ,
107+ } ,
108+ } ;
109+
61110 const person = await personRepo . getPerson ( personId , {
62111 excludeBanned : true ,
63112 excludeUnconfirmedEmail : true ,
64113 hasValidParadigm : true ,
65- settings : [ 'paradigm' , 'paradigm_timestamp' ] ,
114+ settings : [ 'paradigm' ] ,
115+ include : {
116+ ...certInclude ,
117+ Judges : {
118+ fields : [ 'id' ] ,
119+ include : {
120+ Category : {
121+ required : true ,
122+ fields : [ 'id' ] ,
123+ include : {
124+ Tourn : {
125+ required : true ,
126+ fields : [ 'id' , 'name' , 'start' , 'hidden' ] ,
127+ } ,
128+ } ,
129+ } ,
130+ Ballots : {
131+ fields : [ 'id' , 'side' ] ,
132+ winnerBallot : true ,
133+ include : {
134+ ...sectionRecordInclude ,
135+ Scores : {
136+ winloss : true ,
137+ fields : [ 'id' , 'tag' , 'value' ] ,
138+ } ,
139+ } ,
140+ } ,
141+ } ,
142+ } ,
143+ } ,
66144 } ) ;
67-
68145 if ( ! person ) {
69146 return NotFound ( req , res , 'Person not found or does not have a valid paradigm' ) ;
70147 }
148+ // Build record array: one element per ballot on each judge
149+ const record = [ ] ;
150+
151+ for ( const judge of person . Judges || [ ] ) {
152+ for ( const judgeBallot of judge . Ballots || [ ] ) {
153+ // Skip non winner ballots
154+
155+ const section = judgeBallot . Section ;
156+ if ( ! section ) continue ;
157+ let affLabel = section . Round ?. Event ?. settings ?. aff_label || 'Aff' ;
158+ let negLabel = section . Round ?. Event ?. settings ?. neg_label || 'Neg' ;
159+
160+ let affTeam = null ;
161+ let negTeam = null ;
162+
163+ let affWins = 0 ;
164+ let negWins = 0 ;
165+
166+ let judgeVote = null ;
167+
168+ for ( const ballot of section . Ballots || [ ] ) {
169+ const entryName = ballot . Entry ?. code ;
170+ // Identify entries (will repeat, but safe)
171+ if ( ballot . side == 1 && ! affTeam ) {
172+ affTeam = entryName ;
173+ }
174+
175+ if ( ballot . side == 2 && ! negTeam ) {
176+ negTeam = entryName ;
177+ }
178+ const winScore = ballot . Scores ?. find (
179+ s => s . tag === 'winloss'
180+ ) ;
181+
182+ // Count panel votes
183+ if ( winScore ?. value === 1 ) {
184+ if ( ballot . side == 1 ) affWins ++ ;
185+ if ( ballot . side == 2 ) negWins ++ ;
186+ }
187+
188+ // Detect THIS judge's vote
189+ if (
190+ ballot . judgeId === judge . id &&
191+ winScore ?. value === 1
192+ ) {
193+ judgeVote = ballot . side == 1 ? affLabel : negLabel ;
194+ }
195+ }
196+
197+ // Determine panel majority winner
198+ let panelVote = null ;
199+
200+ if ( affWins > negWins ) panelVote = affLabel ;
201+ else if ( negWins > affWins ) panelVote = negLabel ;
202+ else panelVote = 'Tie' ; // optional handling
203+
204+ let roundLabel = section ?. Round ?. label ;
205+ if ( ! roundLabel && section ?. Round ?. name ) {
206+ roundLabel = `R${ section . Round . name } ` ;
207+ }
208+ record . push ( {
209+ tournName : judge . Category ?. Tourn ?. name || 'Unknown Tournament' ,
210+ roundDate : judge . Category ?. Tourn ?. start || null ,
211+ roundLabel,
212+ eventAbbr : section ?. Round ?. Event ?. abbr || null ,
213+ affTeam,
214+ affLabel,
215+ negTeam,
216+ negLabel,
217+ vote : judgeVote , // this judge's vote
218+ panelVote, // overall result
219+ record : `${ affWins } -${ negWins } ` , // optional
220+ } ) ;
221+ }
222+ }
71223 res . json ( {
72224 id : person . id ,
73225 name : [ person . firstName , person . middleName , person . lastName ] . filter ( Boolean ) . join ( ' ' ) ,
74- lastReviewed : person . settings [ 'paradigm_timestamp' ] || null ,
226+ lastReviewed : person . settingsTimestamps [ 'paradigm' ] ?. updatedAt || null ,
75227 paradigm : person . settings [ 'paradigm' ] || null ,
76-
228+ record,
229+ certifications : person . PersonQuizzes ?. map ( pq => ( {
230+ title : pq . Quiz ?. label ,
231+ description : pq . Quiz ?. description ,
232+ updatedAt : pq . updatedAt ,
233+ badge : {
234+ altText : pq . Quiz ?. badgeDescription || null ,
235+ imageUrl : ( pq . Quiz ?. id && pq . Quiz ?. badge ) ? `${ config . S3_URL } /badges/${ pq . Quiz . id } /${ pq . Quiz . badge } `
236+ : null ,
237+ link : pq . Quiz ?. badgeLink || null ,
238+ } ,
239+ } ) ) ,
77240 } ) ;
78-
79241} ;
80242
81243export default {
0 commit comments