Skip to content

Commit a550e65

Browse files
authored
Merge branch 'main' into ashley/update-swagger-search
2 parents 11b03d6 + 661312e commit a550e65

39 files changed

Lines changed: 806 additions & 129 deletions

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ FROM node:20-bullseye
22
RUN mkdir -p /usr/src/app
33
WORKDIR /usr/src/app
44
COPY . .
5+
RUN rm -rf node_modules
56
RUN npm install --force
67
CMD npm run db:migrate && npm run start

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ alter user postgres with superuser;
3636
create database "resell-dev";
3737
```
3838

39+
Use the \l command to see if the "resell-dev" is owned by user postgres. If
40+
instead it is owned by another root user, drop the database via:
41+
```bash
42+
drop database "resell-dev";
43+
```
44+
and login to psql via
45+
```bash
46+
psql postgres postgres
47+
```
48+
. Then, create the database again, and it should be owned by user postgres.
49+
50+
3951
## Connecting to DB
4052

4153
In order to connect to the database, follow these steps:
@@ -63,6 +75,32 @@ To create/update the database objects, run:
6375
npm run db:migrate
6476
```
6577

78+
## Migration debugging last resort
79+
80+
If you are encountering migrations errors, use this as a last resort
81+
1. Log into psql and run
82+
```bash
83+
drop database "resell-dev"
84+
```
85+
WARNING: This will delete all data in your database as well. Make sure you do not have any important data in your database.
86+
87+
2. Create the database again via.
88+
```bash
89+
create database "resell-dev"
90+
```
91+
92+
3. Delete all of the migration files in the "migrations" folder
93+
94+
4. Create a new migration file titled "init" via.
95+
```bash
96+
npm run db:migrate:generate init
97+
```
98+
99+
5. Run the migration
100+
```bash
101+
npm run db:migrate
102+
```
103+
66104
## Seeding Data for Development Environment
67105

68106
This project includes a mechanism for seeding consistent data for the development environment using TypeORM and typeorm-seeding. The seeders generate users, posts, feedback, reviews, reports, and requests, ensuring all developers work with the same data set.

ormconfig.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module.exports = {
1111
'src/models/*.ts',
1212
],
1313
synchronize: false,
14+
migrationsRun: true,
1415
// namingStrategy: new SnakeNamingStrategy(),
1516
migrations: [
1617
'src/migrations/*.ts',

src/api/controllers/AuthToken.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1-
import { Body, Get, JsonController } from 'routing-controllers';
1+
import { Body, Get, JsonController, Post } from 'routing-controllers';
22
import { getAuth } from "firebase-admin/auth";
3-
import { AuthTokenResponse, FcmTokenRequest } from '../../types';
3+
import { AuthTokenResponse, emailAndPass, FcmTokenRequest, UIDResponse } from '../../types';
44

55
@JsonController('authToken/')
66
export class AuthTokenController {
77

8+
@Post('create/') async createAccount(@Body() info:emailAndPass): Promise<UIDResponse>{
9+
const userCredential = await getAuth().createUser({
10+
email: info.email,
11+
password: info.password
12+
});
13+
14+
// Firebase automatically generates a UID for this user!
15+
const uid = userCredential.uid;
16+
console.log("New user's UID:", uid);
17+
return {uid:uid}
18+
}
19+
820
@Get() async authorize(@Body() fcmToken: FcmTokenRequest): Promise<AuthTokenResponse> {
921
try {
1022
const customToken = await getAuth().createCustomToken(fcmToken.token);

src/api/controllers/ChatController.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Body, CurrentUser, ForbiddenError, JsonController, Params, Post } from 'routing-controllers';
22
import { getFirestore } from 'firebase-admin/firestore';
33
import { ChatParam, ChatReadParam } from '../validators/GenericRequests';
4-
import { CreateChatMessage,CreateAvailabilityChat, CreateProposalChat, RespondProposalChat, MessageResponse, AvailabilityResponse, ProposalResponse, ChatReadResponse } from '../../types';
4+
import { CreateChatMessage,CreateAvailabilityChat, CreateProposalChat, RespondProposalChat, MessageResponse, AvailabilityResponse, ProposalResponse, ChatReadResponse, CancelProposalResponse } from '../../types';
55
import { UserModel } from '../../models/UserModel';
66

77
const db = getFirestore();
@@ -39,6 +39,10 @@ export const updateFirestore = async (
3939
lastMessage: lastMessage,
4040
})
4141
}
42+
43+
await chatsRef.doc(chatId).update({
44+
updatedAt: new Date(),
45+
})
4246

4347
}
4448
}
@@ -155,6 +159,30 @@ export class ChatController {
155159
return message;
156160
}
157161

162+
@Post('proposal/cancel/:id')
163+
async cancelProposal(@CurrentUser() user: UserModel,@Params() params: ChatParam,@Body() chatBody: CreateProposalChat): Promise<CancelProposalResponse>{
164+
const chatId = params.id;
165+
const doc = await chatsRef.doc(chatId).get();
166+
const now = new Date();
167+
const message = {
168+
"type": "proposal",
169+
"senderID": chatBody.senderId,
170+
"timestamp": now,
171+
"cancellation": true,
172+
"startDate":chatBody.startDate,
173+
"endDate":chatBody.endDate,
174+
}
175+
if (doc.exists){
176+
const userCheck = await checkUsers(chatId,user.firebaseUid);
177+
if (!userCheck){
178+
throw new ForbiddenError("This user is not part of this chat");
179+
}
180+
181+
}
182+
updateFirestore(chatId,doc.exists,chatBody,message,chatsRef,"");
183+
return message;
184+
}
185+
158186

159187
@Post(':chatId/message/:messageId')
160188
async markAsRead(@CurrentUser() user: UserModel,@Params() params: ChatReadParam): Promise<ChatReadResponse>{
@@ -177,12 +205,11 @@ export class ChatController {
177205
read: true
178206
});
179207

180-
await chatsRef.doc(chatId).update({
181-
updatedAt: new Date(),
182-
})
183208
}
184209
return {"read":true}
185210
}
211+
212+
186213

187214
}
188215

src/api/controllers/NotifController.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ export class NotifController {
1616
return this.notifService.getRecentNotifications(user.firebaseUid);
1717
}
1818

19+
@Get('new')
20+
async getUnread(@CurrentUser() user: UserModel) {
21+
return this.notifService.getUnreadNotifications(user.firebaseUid);
22+
}
23+
24+
@Get('last7days')
25+
getLast7Days(@CurrentUser() user: UserModel) {
26+
return this.notifService.getNotificationsLast7Days(user.firebaseUid);
27+
}
28+
29+
@Get('last30days')
30+
getLast30Days(@CurrentUser() user: UserModel) {
31+
return this.notifService.getNotificationsLast30Days(user.firebaseUid);
32+
}
33+
1934
@Post()
2035
async sendNotif(@Body() findTokensRequest: FindTokensRequest) {
2136
return this.notifService.sendNotifs(findTokensRequest);
@@ -30,4 +45,9 @@ export class NotifController {
3045
async sendRequestMatchNotif(@Body() matchRequest: RequestMatchNotificationRequest) {
3146
return this.notifService.sendRequestMatchNotification(matchRequest);
3247
}
48+
49+
@Delete('id/:id')
50+
async deleteNotification(@CurrentUser() user: UserModel, @Params() params: { id: string }) {
51+
return this.notifService.deleteNotification(user.firebaseUid, params.id);
52+
}
3353
}

src/api/controllers/PostController.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
FilterPostsRequest,
1010
FilterPostsByPriceRequest,
1111
FilterPostsByConditionRequest,
12+
FilterPostsUnifiedRequest,
1213
GetPostResponse,
1314
GetPostsResponse,
1415
GetSearchedPostsRequest,
@@ -87,6 +88,14 @@ export class PostController {
8788
return { posts: await this.postService.filterByCondition(user, filterPostsByConditionRequest) };
8889
}
8990

91+
@Post('filter/')
92+
async filterPosts(
93+
@CurrentUser() user: UserModel,
94+
@Body() filterPostsUnifiedRequest: FilterPostsUnifiedRequest
95+
): Promise<GetPostsResponse> {
96+
return { posts: await this.postService.filterPostsUnified(user, filterPostsUnifiedRequest) };
97+
}
98+
9099
@Get('archive/')
91100
async getArchivedPosts(@CurrentUser() user: UserModel): Promise<GetPostsResponse> {
92101
return { posts: await this.postService.getArchivedPosts(user) };

src/api/validators/GenericRequests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export class EmailParam {
88
}
99

1010
export class UuidParam {
11-
@IsUUID()
11+
@IsString()
1212
id: Uuid;
1313
}
1414

src/app.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ import { ReportService } from './services/ReportService';
4343
import { ReportRepository } from './repositories/ReportRepository';
4444
import { reportToString } from './utils/Requests';
4545
import { CurrentUserChecker } from 'routing-controllers/types/CurrentUserChecker';
46+
// import { getLoadedModel } from './utils/SentenceEncoder';
4647

48+
dotenv.config();
49+
50+
// TODO: Figure out how to load the model when running app.ts
51+
// export const encoder = await getLoadedModel();
4752

4853
async function main() {
4954
routingUseContainer(Container);

src/migrations/1709163288115-init.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,4 @@ export class init1709163288115 implements MigrationInterface {
6363
await queryRunner.query(`DROP TABLE "Request"`);
6464
}
6565

66-
}
66+
}

0 commit comments

Comments
 (0)