Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions __tests__/datalib/panels/createPanels.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
const mockTracks = {
'Best AI/ML Hack': {
name: 'Best AI/ML Hack',
domain: 'aiml',
domainDisplayName: 'Data Science or AI/ML',
},
'Most Technically Challenging Hack': {
name: 'Most Technically Challenging Hack',
domain: 'swe',
domainDisplayName: 'Software Engineering',
},
};

jest.mock('@data/tracks', () => ({
__esModule: true,
judgeVisibleTracks: {
'Best AI/ML Hack': {
name: 'Best AI/ML Hack',
domain: 'aiml',
domainDisplayName: 'Data Science or AI/ML',
},
'Most Technically Challenging Hack': {
name: 'Most Technically Challenging Hack',
domain: 'swe',
domainDisplayName: 'Software Engineering',
},
},
judgeVisibleTracks: mockTracks,
panelTracks: mockTracks,
}));

jest.mock('@utils/mongodb/mongoClient.mjs', () => ({
Expand Down
4 changes: 2 additions & 2 deletions app/(api)/_actions/logic/assignJudgesToPanels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
import { GetManyPanels } from '@datalib/panels/getPanels';
import { GetManyUsers } from '@datalib/users/getUser';
import judgeToPanelAlgorithm from '@utils/matching/judgeToPanelAlgorithm';
import { judgeVisibleTracks } from '@data/tracks';
import { panelTracks } from '@data/tracks';
import { CreateManyPanels } from '@datalib/panels/createPanels';
import { UpdatePanel } from '@datalib/panels/updatePanel';
import Panel from '@typeDefs/panel';
import { DeleteManyPanels } from '@datalib/panels/deletePanel';

async function initializeEmptyPanels() {
const panelData: Panel[] = Object.values(judgeVisibleTracks).map((track) => ({
const panelData: Panel[] = Object.values(panelTracks).map((track) => ({
track: track.name,
domain: track.domain ?? '',
user_ids: [],
Expand Down
11 changes: 11 additions & 0 deletions app/(api)/_data/test_projects_2026.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Project Title,Table Number,Submission Url,Project Status,Judging Status,Highest Step Completed,Project Created At,About The Project,"""Try it out"" Links",Video Demo Link,Opt-In Prizes,Built With,Submitter First Name,Submitter Last Name,Submitter Email,Notes,Technical Focus,Design Focus,Track #1 (Primary Track),Track #2,Track #3,Team Colleges/Universities,Additional Team Member Count,Team Member 1 First Name,Team Member 1 Last Name,Team Member 1 Email,Team Member 2 First Name,Team Member 2 Last Name,Team Member 2 Email,Team Member 3 First Name,Team Member 3 Last Name,Team Member 3 Email
AgriSense AI,1,https://hackdavis-2026.devpost.com/submissions/001-agrisense-ai,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 09:00:00,"A machine learning pipeline that classifies crop diseases from drone imagery and recommends treatments using a fine-tuned vision model.",https://agrisense.hackdavis.io,,"Best AI/ML Hack, Best Use of Gemini API, Best UI/UX Design, Best Hack for Social Justice",Python; TensorFlow; Next.js,Sandeep,Reehal,sandeep@hackdavis.io,,10,1,Most Technically Challenging Hack,Best Beginner Hack,Best Hardware Hack,University of California - Davis,1,Michelle,Yeoh,michelleyeoh@hackdavis.io,,,
EduBuddy,2,https://hackdavis-2026.devpost.com/submissions/002-edubuddy,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 09:15:00,"An interactive learning companion for first-time coders that gamifies debugging exercises with adaptive feedback.",https://edubuddy.hackdavis.io,,"Best UI/UX Design, Best Use of ElevenLabs, Best Use of Solana",React; Node.js; ElevenLabs API,Haylie,Tan,haylie@hackdavis.io,,1,7,Best Interdisciplinary Hack,Most Creative Hack,Best Hack for Social Justice,University of California - Davis,2,Afifah,Hadi,afifah@hackdavis.io,Jack,Zheng,jack@hackdavis.io
CrossDiscipline Map,3,https://hackdavis-2026.devpost.com/submissions/003-crossdiscipline-map,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 09:30:00,"A geospatial visualization tool built by a team spanning environmental science, sociology, and CS majors to map community resource deserts in Davis.",https://xdmap.hackdavis.io,,"Best Use of DAC Materials, Best use of Reconstruct, Best Use of Backboard",Next.js; MongoDB; D3.js,Alex,Marasigan,alex@hackdavis.io,,10,7,Best User Research,Best Entrepreneurship Hack,Best Statistical Model,University of California - Davis,1,Sandeep,Reehal,sandeep@hackdavis.io,,,
MoodCanvas,4,https://hackdavis-2026.devpost.com/submissions/004-moodcanvas,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 09:45:00,"A generative art web app that transforms your journaled emotions into personalized abstract paintings using color theory and procedural generation.",https://moodcanvas.hackdavis.io,,"Best Hack for Women's Center, Best Use of Vultr, Best Use of MongoDB Atlas, Most Creative Hack",p5.js; Next.js; MongoDB Atlas,Michelle,Yeoh,michelleyeoh@hackdavis.io,,1,7,Most Technically Challenging Hack,Best Beginner Hack,,University of California - Davis,0,,,,,,
BuildBot 3000,5,https://hackdavis-2026.devpost.com/submissions/005-buildbot-3000,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 10:00:00,"An autonomous sorting robot built with an M5Stack kit that uses computer vision to categorize recyclables and routes them to the correct bin via servo actuators.",https://buildbot.hackdavis.io,,"Best Domain Name from GoDaddy Registry, Best AI/ML Hack, Best Use of ElevenLabs, Best Hack for Women's Center, Best Statistical Model",C++; OpenCV; Arduino; Vultr,Haylie,Tan,haylie@hackdavis.io,,10,1,Best Hardware Hack,Best User Research,,University of California - Davis,2,Afifah,Hadi,afifah@hackdavis.io,Alex,Marasigan,alex@hackdavis.io
JusticeNet,6,https://hackdavis-2026.devpost.com/submissions/006-justicenet,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 10:15:00,"A resource hub for low-income renters facing eviction, connecting them to legal aid organizations and auto-generating demand letters using templated forms.",https://justicenet.hackdavis.io,,"Best UI/UX Design, Best Use of Backboard, Best Use of Solana, Best Entrepreneurship Hack",Next.js; Nodemailer; Figma,Jack,Zheng,jack@hackdavis.io,,10,7,Best Interdisciplinary Hack,Best Statistical Model,,University of California - Davis,1,Michelle,Yeoh,michelleyeoh@hackdavis.io,,,
UserVoice Research Tool,7,https://hackdavis-2026.devpost.com/submissions/007-uservoice,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 10:30:00,"A mixed-methods UX research platform that synthesizes interview transcripts, survey results, and heatmap data into a unified insight dashboard backed by statistical modeling.",https://uservoice.hackdavis.io,,"Best AI/ML Hack, Best Use of Gemini API, Best Use of ElevenLabs",React; Python; Pandas; Scikit-learn,Sandeep,Reehal,sandeep@hackdavis.io,,1,7,Best Hardware Hack,Best Hack for Social Justice,,University of California - Davis,3,Haylie,Tan,haylie@hackdavis.io,Jack,Zheng,jack@hackdavis.io,Afifah,Hadi,afifah@hackdavis.io
MarketMind,8,https://hackdavis-2026.devpost.com/submissions/008-marketmind,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 10:45:00,"A no-code SaaS pitch builder that walks founders through lean canvas modeling, market sizing, and auto-generates a slide deck from their inputs.",https://marketmind.hackdavis.io,,"Best Use of Solana, Best Use of Vultr, Best Use of DAC Materials, Best use of Reconstruct, Best Interdisciplinary Hack",Next.js; Tailwind CSS; Figma API,Alex,Marasigan,alex@hackdavis.io,,1,7,Best Entrepreneurship Hack,Best User Research,,University of California - Davis,1,Michelle,Yeoh,michelleyeoh@hackdavis.io,,,
VoiceBot Arena,9,https://hackdavis-2026.devpost.com/submissions/009-voicebot-arena,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 11:00:00,"A real-time multiplayer game where players command robots using voice instructions parsed by an NLP model, with hardware obstacle courses controlled over WebSockets.",https://voicebotarena.hackdavis.io,,"Best use of Reconstruct, Best Use of MongoDB Atlas, Best Use of Gemini API, Best Beginner Hack",ElevenLabs; WebSockets; Raspberry Pi; Next.js,Afifah,Hadi,afifah@hackdavis.io,,10,1,Most Technically Challenging Hack,Most Creative Hack,,University of California - Davis,2,Jack,Zheng,jack@hackdavis.io,Sandeep,Reehal,sandeep@hackdavis.io
DataStory,10,https://hackdavis-2026.devpost.com/submissions/010-datastory,Submitted (Gallery/Visible),Pending,Submit,05/03/2026 11:15:00,"A storytelling platform that helps first-time data explorers build and share visual narratives from public datasets, with AI-assisted chart recommendations.",https://datastory.hackdavis.io,,"Best Use of DAC Materials, Best Domain Name from GoDaddy Registry, Best AI/ML Hack, Best User Research, Best Hardware Hack",Python; Streamlit; OpenAI API,Haylie,Tan,haylie@hackdavis.io,,10,1,Best Beginner Hack,Best Entrepreneurship Hack,,University of California - Davis,1,Alex,Marasigan,alex@hackdavis.io,,,
9 changes: 4 additions & 5 deletions app/(api)/_datalib/panels/createPanels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ import {
} from '@utils/response/Errors';
import isBodyEmpty from '@utils/request/isBodyEmpty';
import parseAndReplace from '@utils/request/parseAndReplace';
import { judgeVisibleTracks } from '@data/tracks';
import { panelTracks } from '@data/tracks';
import type Panel from '@typeDefs/panel';

const validTracks = Object.values(judgeVisibleTracks).map(
(track) => track.name
);
const validTracks = Object.values(panelTracks).map((track) => track.name);

export const CreatePanel = async (trackName: string) => {
try {
Expand All @@ -31,9 +29,10 @@ export const CreatePanel = async (trackName: string) => {
);
}

const domain = panelTracks[trackName].domain;
const result = await db.collection('panels').insertOne({
track: trackName,
domain: judgeVisibleTracks[trackName].domain,
...(domain !== undefined && { domain }),
user_ids: [],
Comment thread
ReehalS marked this conversation as resolved.
});

Expand Down
26 changes: 26 additions & 0 deletions app/(api)/_utils/csv-ingestion/csvAlgorithm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,24 @@ export type CsvRowIssue = {
duplicateTeamNumber?: number;
};

export type CsvRowContact = {
teamNumber: number | undefined;
projectTitle: string;
contactEmails: string[];
contactNames: string[];
memberEmails: string[];
memberNames: string[];
memberColumnsFromTeamMember1: Array<{ header: string; value: string }>;
};

export type CsvValidationReport = {
totalTeamsParsed: number;
validTeams: number;
errorRows: number;
warningRows: number;
unknownTracks: string[];
issues: CsvRowIssue[];
rowContacts: CsvRowContact[];
globalWarnings?: string[];
};

Expand Down Expand Up @@ -416,6 +427,7 @@ export async function validateCsvBlob(blob: Blob): Promise<{
error: string | null;
}> {
const issues: CsvRowIssue[] = [];
const rowContacts: CsvRowContact[] = [];
const unknownTrackSet = new Set<string>();
const output: ParsedRecord[] = [];
const seenTeamNumbers = new Map<number, number>(); // teamNumber -> first rowIndex where seen
Expand Down Expand Up @@ -496,6 +508,18 @@ export async function validateCsvBlob(blob: Blob): Promise<{
}
}

rowContacts.push({
teamNumber: Number.isFinite(parsedTeamNumber)
? parsedTeamNumber
: undefined,
projectTitle,
contactEmails,
contactNames,
memberEmails,
memberNames,
memberColumnsFromTeamMember1,
});

if (
invalidTracks.length > 0 ||
missingFields.length > 0 ||
Expand Down Expand Up @@ -608,6 +632,7 @@ export async function validateCsvBlob(blob: Blob): Promise<{
warningRows,
unknownTracks: Array.from(unknownTrackSet).sort(),
issues,
rowContacts,
globalWarnings,
};

Expand All @@ -628,6 +653,7 @@ export async function validateCsvBlob(blob: Blob): Promise<{
warningRows: 0,
unknownTracks: [],
issues: [],
rowContacts: [],
globalWarnings: [],
};
return {
Expand Down
11 changes: 6 additions & 5 deletions app/(api)/_utils/matching/judgeToPanelAlgorithm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ export default async function judgeToPanelAlgorithm(
for (const panel of panels) {
if (judges.length < panelSize) return null;

judges = judges.sort(
(a, b) =>
(a.specialties?.indexOf(panel.domain ?? '') ?? 0) -
(b.specialties?.indexOf(panel.domain ?? '') ?? 0)
);
judges = judges.sort((a, b) => {
const domain = panel.domain ?? '';
const aIdx = a.specialties?.indexOf(domain) ?? -1;
const bIdx = b.specialties?.indexOf(domain) ?? -1;
return (aIdx === -1 ? Infinity : aIdx) - (bIdx === -1 ? Infinity : bIdx);
});

panel.user_ids = judges
.splice(0, panelSize)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ import arrow from 'public/hackers/project-info/arrow.svg';

const questions = [
{
text: 'PICKED 4 RELEVANT PRIZE TRACKS',
text: 'SELECTED UP TO 4 HACKDAVIS TRACKS',
color: styles.qboxGreen,
},
{
text: 'ADDED OPT-IN PRIZES IF RELEVANT (SPONSOR, NPO, OR MLH TRACKS - NO LIMIT)',
color: styles.qboxBlue,
},
{
text: 'ADDED YOUR GITHUB AND/OR FIGMA LINKS',
color: styles.qboxYellow,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ export default function FillOutDetails() {
return (
<div className={styles.container}>
<p className={styles.text}>
Fill out respective information - project overview, details, etc
Fill out respective information — project overview, details, etc. <br />
When selecting prize tracks: pick{' '}
<strong>up to 4 HackDavis tracks</strong> via{' '}
<strong>Tracks #1–#3</strong> on Devpost, and use the{' '}
<strong>Opt-in Prizes</strong> section for any{' '}
<strong>Sponsor, NPO, or MLH tracks</strong> your project qualifies for
(no limit, but keep it relevant).
</p>

<div className={styles.imageWrapper}>
Expand Down
Loading
Loading