From ccf04c50a34355ad7a28e51dd5b88d61e627b838 Mon Sep 17 00:00:00 2001 From: Trillium Smith Date: Wed, 20 May 2026 13:36:26 -0700 Subject: [PATCH 1/2] fix: add missing ref options to Mongoose schema fields --- backend/models/checkIn.model.js | 4 +-- backend/models/event.model.js | 4 +-- backend/models/project.model.js | 37 ++++++++++++----------- backend/models/projectTeamMember.model.js | 4 +-- backend/models/recurringEvent.model.js | 2 +- backend/models/user.model.js | 2 +- 6 files changed, 27 insertions(+), 26 deletions(-) diff --git a/backend/models/checkIn.model.js b/backend/models/checkIn.model.js index e4a068657..1ed4c6bf4 100644 --- a/backend/models/checkIn.model.js +++ b/backend/models/checkIn.model.js @@ -3,8 +3,8 @@ const mongoose = require("mongoose"); mongoose.Promise = global.Promise; const checkInSchema = mongoose.Schema({ - userId: { type: String }, - eventId: { type: String }, + userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + eventId: { type: mongoose.Schema.Types.ObjectId, ref: 'Event' }, checkedIn: { type: Boolean, default: true }, createdDate: { type: Date, default: Date.now }, }); diff --git a/backend/models/event.model.js b/backend/models/event.model.js index 25aa9fe0c..35b1189a4 100644 --- a/backend/models/event.model.js +++ b/backend/models/event.model.js @@ -25,10 +25,10 @@ const eventSchema = mongoose.Schema({ checkInReady: { type: Boolean, default: false }, // is the event open for check-ins? videoConferenceLink: { type: String }, // can be same or different from project owner: { - ownerId: { type: Number } // id of user who created event + ownerId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' } // id of user who created event }, recurringEventLink: { // only populated if this event was created from a RecurringEvent - recurringEventId: { type: String } + recurringEventId: { type: mongoose.Schema.Types.ObjectId, ref: 'RecurringEvent' } } }); diff --git a/backend/models/project.model.js b/backend/models/project.model.js index e345b2c4f..7c5c3c5d6 100644 --- a/backend/models/project.model.js +++ b/backend/models/project.model.js @@ -16,24 +16,25 @@ Idea for the future: programmingLanguages, numberGithubContributions (pull these */ const projectSchema = mongoose.Schema({ - name: { type: String }, - description: { type: String }, - githubIdentifier: { type: String }, - projectStatus: { type: String }, // Active, Completed, or Paused - location: { type: String }, // DTLA, Westside, South LA, or Remote (hacknight) - //teamMembers: { type: String }, // commented since we should be able to get this from Project Team Members table - createdDate: { type: Date, default: Date.now }, // date/time project was created - completedDate: { type: Date }, // only if Status = Completed, date/time completed - githubUrl: { type: String }, // link to main repo - slackUrl: { type: String }, // link to Slack channel - googleDriveUrl: { type: String }, - googleDriveId: { type: String }, - hflaWebsiteUrl: { type: String }, - videoConferenceLink: { type: String }, - lookingDescription: { type: String }, // narrative on what the project is looking for - recruitingCategories: [{ type: String }], // same as global Skills picklist - partners: [{ type: String }], // any third-party partners on the project, e.g. City of LA - managedByUsers: [{ type: String }] // Which users may manage this project. + name: { type: String, trim: true }, + description: { type: String, trim: true }, + githubIdentifier: { type: String, trim: true }, + projectStatus: { type: String }, // Active, Completed, or Paused + location: { type: String, trim: true }, // DTLA, Westside, South LA, or Remote (hacknight) + //teamMembers: { type: String }, // commented since we should be able to get this from Project Team Members table + createdDate: { type: Date, default: Date.now }, // date/time project was created + completedDate: { type: Date }, // only if Status = Completed, date/time completed + githubUrl: { type: String, trim: true }, // link to main repo + slackUrl: { type: String, trim: true }, // link to Slack channel + googleDriveUrl: { type: String, trim: true }, + googleDriveId: { type: String }, + hflaWebsiteUrl: { type: String, trim: true }, + videoConferenceLink: { type: String }, + lookingDescription: { type: String }, // narrative on what the project is looking for + recruitingCategories: [{ type: String }], // same as global Skills picklist + partners: [{ type: String }], // any third-party partners on the project, e.g. City of LA + managedByUsers: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }], // Which users may manage this project. + onboardOffboardVisible: { type: Boolean, default: true }, // Whether onboarding/offboarding forms are visible on the project page }); projectSchema.methods.serialize = function() { diff --git a/backend/models/projectTeamMember.model.js b/backend/models/projectTeamMember.model.js index d6586cf55..aecacdc91 100644 --- a/backend/models/projectTeamMember.model.js +++ b/backend/models/projectTeamMember.model.js @@ -15,8 +15,8 @@ Idea for the future: numberGithubContributions (pull this from github?) */ const projectTeamMemberSchema = mongoose.Schema({ - userId: { type: String }, // id of the user - projectId: { type: String }, // id of the project + userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, // id of the user + projectId: { type: mongoose.Schema.Types.ObjectId, ref: 'Project' }, // id of the project teamMemberStatus: { type: String }, // Active or Inactive vrmsProjectAdmin: { type: Boolean }, // does this team member have admin rights to the project in VRMS? roleOnProject: { type: String }, // Developer, Project Manager, UX, Data Science diff --git a/backend/models/recurringEvent.model.js b/backend/models/recurringEvent.model.js index 54073343e..de6fde68d 100644 --- a/backend/models/recurringEvent.model.js +++ b/backend/models/recurringEvent.model.js @@ -26,7 +26,7 @@ const recurringEventSchema = mongoose.Schema({ checkInReady: { type: Boolean, default: false }, // is the event open for check-ins? videoConferenceLink: { type: String }, // can be same or different from project owner: { - ownerId: { type: String, default: '123456' } // id of user who created event + ownerId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' } // id of user who created event } }); diff --git a/backend/models/user.model.js b/backend/models/user.model.js index 0534d6107..33cd64004 100644 --- a/backend/models/user.model.js +++ b/backend/models/user.model.js @@ -33,7 +33,7 @@ const userSchema = mongoose.Schema({ isHflaGithubMember: { type: Boolean }, // pull from API once github handle in place? githubPublic2FA: { type: Boolean }, // does the user have 2FA enabled on their github and membership set to public? availability: { type: String }, // availability to meet outside of hacknight times; string for now, more structured in future - managedProjects: [{ type: String}] // Which projects managed by user. + managedProjects: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Project' }], // Which projects managed by user. //currentProject: { type: String } // no longer need this as we can get it from Project Team Member table // password: { type: String, required: true } }); From 9536ef50bda229440392b20fc856f9f29c73ec9b Mon Sep 17 00:00:00 2001 From: Trillium Smith Date: Mon, 12 Oct 2026 18:49:49 -0700 Subject: [PATCH 2/2] test(user): use ObjectId for managedProjects now that the field is a ref --- backend/models/user.test.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/models/user.test.js b/backend/models/user.test.js index 5e8a43e4c..7d8eddb19 100644 --- a/backend/models/user.test.js +++ b/backend/models/user.test.js @@ -1,7 +1,7 @@ -import { describe, it, expect, vi, beforeAll, beforeEach, afterAll, afterEach, test } from 'vitest'; import mongoose from 'mongoose'; -import { User } from './user.model.js'; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, test, vi } from 'vitest'; import { setupIntegrationDB } from '../setup-test.js'; +import { User } from './user.model.js'; setupIntegrationDB('user-model'); @@ -69,7 +69,7 @@ describe('User Model - Serialization', () => { isHflaGithubMember: true, githubPublic2FA: false, availability: 'Evenings', - managedProjects: ['ProjectGamma'], + managedProjects: [new mongoose.Types.ObjectId()], isActive: true, createdDate: new Date(2023, 0, 15), }; @@ -93,7 +93,9 @@ describe('User Model - Serialization', () => { expect(serializedUser.isHflaGithubMember).toBe(userData.isHflaGithubMember); expect(serializedUser.githubPublic2FA).toBe(userData.githubPublic2FA); expect(serializedUser.availability).toBe(userData.availability); - expect([...serializedUser.managedProjects]).toEqual(userData.managedProjects); + expect(serializedUser.managedProjects.map(String)).toEqual( + userData.managedProjects.map(String), + ); expect(serializedUser.isActive).toBe(userData.isActive); }); });