Skip to content

Commit

Permalink
feat: add service session users
Browse files Browse the repository at this point in the history
  • Loading branch information
SebassNoob committed Nov 28, 2023
1 parent 38c9e76 commit 859c090
Show file tree
Hide file tree
Showing 5 changed files with 454 additions and 36 deletions.
121 changes: 89 additions & 32 deletions interapp-backend/api/models/service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { HTTPError, HTTPErrorCode } from '@utils/errors';
import appDataSource from '@utils/init_datasource';
import { Service, ServiceSession, ServiceSessionUser, User } from '@db/entities';
import { AttendanceStatus } from '@db/entities';
import { UserModel } from './user';

export class ServiceModel {
public static async createService(service: Omit<Service, 'service_id'>) {
Expand All @@ -17,19 +17,7 @@ export class ServiceModel {
newService.start_time = service.start_time;
newService.end_time = service.end_time;

const service_ic = await appDataSource.manager
.createQueryBuilder()
.select('user')
.from(User, 'user')
.where('username = :username', { username: service.service_ic_username })
.getOne();
if (!service_ic) {
throw new HTTPError(
'Service IC not found',
`Service IC with username ${service.service_ic_username} does not exist`,
HTTPErrorCode.NOT_FOUND_ERROR,
);
}
const service_ic = await UserModel.getUser(service.service_ic_username);
newService.service_ic = service_ic;
newService.service_ic_username = service.service_ic_username;
try {
Expand Down Expand Up @@ -61,19 +49,7 @@ export class ServiceModel {
return service;
}
public static async updateService(service: Service) {
const service_ic = await appDataSource.manager
.createQueryBuilder()
.select('user')
.from(User, 'user')
.where('username = :username', { username: service.service_ic_username })
.getOne();
if (!service_ic) {
throw new HTTPError(
'Service IC not found',
`Service IC with username ${service.service_ic_username} does not exist`,
HTTPErrorCode.NOT_FOUND_ERROR,
);
}
const service_ic = await UserModel.getUser(service.service_ic_username);
service.service_ic = service_ic;
service.service_ic_username = service.service_ic_username;
try {
Expand Down Expand Up @@ -146,14 +122,95 @@ export class ServiceModel {
await appDataSource.manager.delete(ServiceSession, { service_session_id });
}

public static async createServiceSessionUser(user_session: ServiceSessionUser) {}
public static async createServiceSessionUser(user_session: ServiceSessionUser) {
const session = new ServiceSessionUser();
session.service_session_id = user_session.service_session_id;
session.username = user_session.username;
session.ad_hoc = user_session.ad_hoc;
session.attended = user_session.attended;
session.is_ic = user_session.is_ic;
session.service_session = await this.getServiceSession(user_session.service_session_id);
session.user = await UserModel.getUser(user_session.username);
try {
await appDataSource.manager.insert(ServiceSessionUser, session);
} catch (e) {
throw new HTTPError(
'Service session user already exists',
`Service session user with service_session_id ${user_session.service_session_id} and username ${user_session.username} already exists`,
HTTPErrorCode.CONFLICT_ERROR,
);
}
return session;
}
public static async createServiceSessionUsers(user_sessions: ServiceSessionUser[]) {
const sessions = [];
for (const user_session of user_sessions) {
const session = new ServiceSessionUser();
session.service_session_id = user_session.service_session_id;
session.username = user_session.username;
session.ad_hoc = user_session.ad_hoc;
session.attended = user_session.attended;
session.is_ic = user_session.is_ic;
session.service_session = await this.getServiceSession(user_session.service_session_id);
session.user = await UserModel.getUser(user_session.username);
sessions.push(session);
}
try {
await appDataSource.manager.insert(ServiceSessionUser, sessions);
} catch (e) {
throw new HTTPError(
'DB error',
`Error inserting service session users: ${String(e)}`,
HTTPErrorCode.INTERNAL_SERVER_ERROR,
);
}
return sessions;
}
public static async getServiceSessionUser(service_session_id: number, username: string) {
throw new HTTPError('Not implemented', '', HTTPErrorCode.NOT_IMPLEMENTED_ERROR);
const res = await appDataSource.manager
.createQueryBuilder()
.select('service_session_user')
.from(ServiceSessionUser, 'service_session_user')
.where('service_session_id = :service_session_id', { service_session_id })
.andWhere('username = :username', { username })
.getOne();
if (!res) {
throw new HTTPError(
'Service session user not found',
`Service session user with service_session_id ${service_session_id} and username ${username} does not exist`,
HTTPErrorCode.NOT_FOUND_ERROR,
);
}
return res;
}
public static async updateServiceSessionUser(service_session_id: number, username: string) {
throw new HTTPError('Not implemented', '', HTTPErrorCode.NOT_IMPLEMENTED_ERROR);
public static async getServiceSessionUsers(service_session_id: number) {
const res = await appDataSource.manager
.createQueryBuilder()
.select('service_session_user')
.from(ServiceSessionUser, 'service_session_user')
.where('service_session_id = :service_session_id', { service_session_id })
.getMany();
return res;
}
public static async updateServiceSessionUser(new_service_session_user: ServiceSessionUser) {
try {
await appDataSource.manager.update(
ServiceSessionUser,
{
service_session_id: new_service_session_user.service_session_id,
username: new_service_session_user.username,
},
new_service_session_user,
);
} catch (e) {
throw new HTTPError('DB error', String(e), HTTPErrorCode.BAD_REQUEST_ERROR);
}
return await this.getServiceSessionUser(
new_service_session_user.service_session_id,
new_service_session_user.username,
);
}
public static async deleteServiceSessionUser(service_session_id: number, username: string) {
throw new HTTPError('Not implemented', '', HTTPErrorCode.NOT_IMPLEMENTED_ERROR);
await appDataSource.manager.delete(ServiceSessionUser, { service_session_id, username });
}
}
16 changes: 16 additions & 0 deletions interapp-backend/api/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,22 @@ interface EmailOptions extends Mail.Options {
}

export class UserModel {
public static async getUser(username: string) {
const user = await appDataSource.manager
.createQueryBuilder()
.select(['user'])
.from(User, 'user')
.where('user.username = :username', { username: username })
.getOne();
if (!user) {
throw new HTTPError(
'User not found',
`The user with username ${username} was not found in the database`,
HTTPErrorCode.NOT_FOUND_ERROR,
);
}
return user;
}
public static async changePassword(username: string, oldPassword: string, newPassword: string) {
const user = await appDataSource.manager
.createQueryBuilder()
Expand Down
117 changes: 117 additions & 0 deletions interapp-backend/api/routes/endpoints/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { validateRequiredFields, verifyJWT, verifyRequiredRole } from '../middle
import { ServiceModel } from '@models/service';
import { HTTPError, HTTPErrorCode } from '@utils/errors';
import { Permissions } from '@utils/permissions';
import { AttendanceStatus } from '@db/entities';

const serviceRouter = Router();

Expand Down Expand Up @@ -202,4 +203,120 @@ serviceRouter.delete(
res.status(204).send();
},
);

serviceRouter.post(
'/session_user',
validateRequiredFields(['service_session_id', 'username', 'ad_hoc', 'attended', 'is_ic']),
verifyJWT,
verifyRequiredRole(Permissions.SERVICE_IC),
async (req, res) => {
if (!(req.body.attended in AttendanceStatus)) {
throw new HTTPError(
'Invalid field type',
`attended must be one of ${Object.values(AttendanceStatus)}`,
HTTPErrorCode.BAD_REQUEST_ERROR,
);
}
await ServiceModel.createServiceSessionUser(req.body);
res.status(204).send();
},
);

serviceRouter.post(
'/session_user_bulk',
validateRequiredFields(['service_session_id', 'users']),
verifyJWT,
verifyRequiredRole(Permissions.SERVICE_IC),
async (req, res) => {
if (!Array.isArray(req.body.users)) {
throw new HTTPError(
'Invalid field type',
'users must be an array of users',
HTTPErrorCode.BAD_REQUEST_ERROR,
);
}
// validate users
for (const user of req.body.users) {
if (
!(
'username' in user &&
'ad_hoc' in user &&
'attended' in user &&
'is_ic' in user &&
user.attended in AttendanceStatus
)
) {
throw new HTTPError(
'Invalid field type',
'users must be a valid array of users',
HTTPErrorCode.BAD_REQUEST_ERROR,
);
}
}
for (const entry of req.body.users) {
entry.service_session_id = req.body.service_session_id;
}
await ServiceModel.createServiceSessionUsers(req.body.users);
res.status(204).send();
},
);

serviceRouter.get(
'/session_user',
validateRequiredFields(['service_session_id', 'username']),
async (req, res) => {
const session_user = await ServiceModel.getServiceSessionUser(
Number(req.query.service_session_id),
String(req.query.username),
);
res.status(200).send(session_user);
},
);

serviceRouter.get(
'/session_user_bulk',
validateRequiredFields(['service_session_id']),
async (req, res) => {
const session_users = await ServiceModel.getServiceSessionUsers(
Number(req.query.service_session_id),
);
res.status(200).send(session_users);
},
);

serviceRouter.patch(
'/session_user',
validateRequiredFields(['service_session_id', 'username'], ['ad_hoc', 'attended', 'is_ic']),
verifyJWT,
verifyRequiredRole(Permissions.SERVICE_IC),
async (req, res) => {
if (req.body.attended && !(req.body.attended in AttendanceStatus)) {
throw new HTTPError(
'Invalid field type',
`attended must be one of ${Object.values(AttendanceStatus)}`,
HTTPErrorCode.BAD_REQUEST_ERROR,
);
}
const session_user = await ServiceModel.getServiceSessionUser(
Number(req.body.service_session_id),
String(req.body.username),
);
const updated = await ServiceModel.updateServiceSessionUser({ ...session_user, ...req.body });
res.status(200).send(updated);
},
);

serviceRouter.delete(
'/session_user',
validateRequiredFields(['service_session_id', 'username']),
verifyJWT,
verifyRequiredRole(Permissions.SERVICE_IC),
async (req, res) => {
await ServiceModel.deleteServiceSessionUser(
Number(req.body.service_session_id),
String(req.body.username),
);
res.status(204).send();
},
);
export default serviceRouter;
2 changes: 0 additions & 2 deletions interapp-backend/api/routes/endpoints/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ userRouter.patch(
);

userRouter.get('/userservices', validateRequiredFields(['username']), async (req, res) => {
console.log(req.params.username);

const services = await UserModel.getAllServicesByUser(req.query.username as string);
res.status(200).send(services);
});
Expand Down
Loading

0 comments on commit 859c090

Please sign in to comment.