Skip to content

Commit 9cdc478

Browse files
authored
Merge pull request #165 from cuappdev/charles/availability
Charles/availability
2 parents b771ef6 + 33e7213 commit 9cdc478

29 files changed

Lines changed: 1208 additions & 398 deletions

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ package-lock.json
66
yarn.lock
77
*.DS_Store
88
*.pem
9-
dumps/
10-
firebase-admin-service-account.json
9+
firebase-admin-service-account.json
10+
# Firebase secrets
11+
secrets/

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,19 @@
4848
"@tensorflow-models/universal-sentence-encoder": "^1.3.3",
4949
"@tensorflow/tfjs": "^4.2.0",
5050
"@tensorflow/tfjs-node": "^4.22.0",
51-
"body-parser": "^2.2.2",
51+
"@types/node-cron": "^3.0.11",
52+
"body-parser": "^1.19.1",
5253
"class-transformer": "^0.5.1",
53-
"class-validator": "^0.14.3",
54+
"class-validator": "^0.14.0",
5455
"cors": "^2.8.6",
5556
"dotenv": "^10.0.0",
5657
"express": "^4.22.1",
5758
"faker": "^5.5.3",
5859
"firebase-admin": "^13.1.0",
59-
"multer": "^2.0.2",
60+
"google-auth-library": "^7.14.0",
61+
"math.js": "^1.1.46",
62+
"multer": "1.4.5-lts.1",
63+
"node-cron": "^4.2.1",
6064
"node-fetch": "^2.6.1",
6165
"pg": "^8.7.1",
6266
"pgvector": "^0.2.0",
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import { Body, CurrentUser, Get, JsonController, Param, Post } from 'routing-controllers';
2+
import { UserModel } from '../../models/UserModel';
3+
import { AvailabilityService } from '../../services/AvailabilityService';
4+
import {
5+
UpdateAvailabilityRequest,
6+
GetAvailabilityResponse,
7+
UserAvailabilityResponse
8+
} from '../../types';
9+
10+
@JsonController('availability/')
11+
export class AvailabilityController {
12+
private availabilityService: AvailabilityService;
13+
14+
constructor(availabilityService: AvailabilityService) {
15+
this.availabilityService = availabilityService;
16+
}
17+
18+
/**
19+
* Get availability for the current user
20+
* Creates empty availability if user doesn't have one yet
21+
* GET /availability/
22+
*/
23+
@Get()
24+
async getMyAvailability(
25+
@CurrentUser() user: UserModel
26+
): Promise<GetAvailabilityResponse> {
27+
const availability = await this.availabilityService.getAvailabilityByUserId(
28+
user.firebaseUid
29+
);
30+
31+
return {
32+
availability: this.toResponse(availability)
33+
};
34+
}
35+
36+
/**
37+
* Get availability for a specific user by their userId
38+
* Creates empty availability if user doesn't have one yet
39+
* GET /availability/user/:userId
40+
*/
41+
@Get('user/:userId')
42+
async getAvailabilityByUserId(
43+
@Param('userId') userId: string
44+
): Promise<GetAvailabilityResponse> {
45+
const availability = await this.availabilityService.getAvailabilityByUserId(userId);
46+
47+
return {
48+
availability: this.toResponse(availability)
49+
};
50+
}
51+
52+
/**
53+
* Update availability for specific days
54+
* Only the days included in the request are updated - other days remain unchanged
55+
* Send an empty array for a day to clear that day's availability
56+
*
57+
* POST /availability/update/
58+
*
59+
* Example request body:
60+
* {
61+
* "schedule": {
62+
* "2026-01-23": [
63+
* { "startDate": "2026-01-23T16:00:00Z", "endDate": "2026-01-23T18:00:00Z" }
64+
* ],
65+
* "2026-01-24": [] // clears this day
66+
* }
67+
* }
68+
*/
69+
@Post('update/')
70+
async updateAvailability(
71+
@CurrentUser() user: UserModel,
72+
@Body() request: UpdateAvailabilityRequest
73+
): Promise<GetAvailabilityResponse> {
74+
// Convert string dates to Date objects for each day
75+
const scheduleUpdates: Record<string, { startDate: Date; endDate: Date }[]> = {};
76+
77+
for (const [day, slots] of Object.entries(request.schedule)) {
78+
scheduleUpdates[day] = slots.map(slot => ({
79+
startDate: new Date(slot.startDate),
80+
endDate: new Date(slot.endDate)
81+
}));
82+
}
83+
84+
const availability = await this.availabilityService.updateAvailability(
85+
user.firebaseUid,
86+
scheduleUpdates
87+
);
88+
89+
return {
90+
availability: this.toResponse(availability)
91+
};
92+
}
93+
94+
/**
95+
* Helper to convert internal type to response type
96+
*/
97+
private toResponse(availability: any): UserAvailabilityResponse {
98+
// Convert schedule to response format
99+
const scheduleResponse: Record<string, { startDate: Date; endDate: Date }[]> = {};
100+
101+
for (const [day, slots] of Object.entries(availability.schedule)) {
102+
scheduleResponse[day] = (slots as any[]).map((slot: any) => ({
103+
startDate: slot.startDate,
104+
endDate: slot.endDate
105+
}));
106+
}
107+
108+
return {
109+
id: availability.id,
110+
userId: availability.userId,
111+
schedule: scheduleResponse,
112+
updatedAt: availability.updatedAt
113+
};
114+
}
115+
}

0 commit comments

Comments
 (0)