Skip to content

Commit

Permalink
ibrahimalmalki/doo-106-change-all-apis-to-add-the-id-pk-to-the-docume…
Browse files Browse the repository at this point in the history
…nt-after (#65)

Created new "Image" table. Added IDs, createdAt, and updatedAt to all fields
  • Loading branch information
Eebro authored Feb 17, 2024
1 parent 42b9cd7 commit 7431765
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 32 deletions.
25 changes: 25 additions & 0 deletions node/src/api/board/board.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
findBoardById,
updateBoard,
deleteBoard,
findBoardsByCollaboratorId,
} from '../../models/board';
import { HTTP_STATUS } from '../../constants';

Expand Down Expand Up @@ -64,6 +65,30 @@ export const handleFindBoardById = async (req: Request, res: Response) => {
}
};

// Function to get boards associated with a collaborator
export const handleGetCollaboratorBoards = async (
req: Request,
res: Response,
) => {
try {
const collaboratorId = req.body.collaboratorId;
if (!collaboratorId) {
return res
.status(HTTP_STATUS.ERROR)
.json({ error: 'No collaborator ID provided' });
}

const boards = await findBoardsByCollaboratorId(collaboratorId);

return res.status(HTTP_STATUS.SUCCESS).json({ boards });
} catch (error) {
console.error('Error getting collaborator boards:', error);
res
.status(HTTP_STATUS.INTERNAL_SERVER_ERROR)
.json({ error: 'Failed to get collaborator boards' });
}
};

// Update board
export const handleUpdateBoard = async (req: Request, res: Response) => {
try {
Expand Down
4 changes: 4 additions & 0 deletions node/src/api/board/board.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
handleCreateBoard,
handleDeleteBoard,
handleFindBoardById,
handleGetCollaboratorBoards,
handleUpdateBoard,
} from './board.controller';

Expand All @@ -20,6 +21,9 @@ router.post('/createBoard', handleCreateBoard);
// GET board by ID
router.get('/getBoard', handleFindBoardById);

// GET board by ID
router.get('/getCollaboratorsBoard', handleGetCollaboratorBoards);

// PUT update a board
router.put('/updateBoard', handleUpdateBoard);

Expand Down
57 changes: 57 additions & 0 deletions node/src/api/image/image.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Response, Request } from 'express';
import { createImage, findImageById } from '../../models/image';
import { HTTP_STATUS } from '../../constants';

/**
* Firebase API controllers, logic for endpoint routes.
* @author Ibrahim Almalki
*/

// TODO: JSDOC

// Create image
export const handleCreateImage = async (req: Request, res: Response) => {
try {
const { imageEncoded } = req.body;
const image = await createImage(imageEncoded);

res.status(HTTP_STATUS.SUCCESS).json({ image });
} catch (error) {
console.error('Error creating image:', error);
res
.status(HTTP_STATUS.INTERNAL_SERVER_ERROR)
.json({ error: 'Failed to create image' });
}
};

const validateId = (id: string, res: Response): id is string => {
if (id === undefined) {
res.status(HTTP_STATUS.ERROR).json({ error: 'NO ID PROVIDED' });
return false;
}
return true;
};

const notFoundError = (res: Response) =>
res.status(HTTP_STATUS.ERROR).json({ error: 'image not found' });

// Get image
export const handleFindImageById = async (req: Request, res: Response) => {
try {
const imageId = req.body.id; // The comment ID parameter is in the body.
if (!validateId(imageId, res)) return;

const image = await findImageById(imageId as string);

if (image) {
res.status(HTTP_STATUS.SUCCESS).json({ image });
} else {
return notFoundError(res);
}
} catch (error) {
console.error('Error finding image by ID:', error);
res
.status(HTTP_STATUS.INTERNAL_SERVER_ERROR)
.json({ error: 'Failed to find image' });
}
};
18 changes: 18 additions & 0 deletions node/src/api/image/image.route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import express from 'express';
import { handleCreateImage, handleFindImageById } from './image.controller';

/**
* Defines image routes.
* @authors Ibrahim Almalki
*/

// The express router
const router = express.Router();

// POST create a new Image
router.post('/createImage', handleCreateImage);

// GET Image by ID
router.get('/getImage', handleFindImageById);

export default router;
2 changes: 2 additions & 0 deletions node/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import boardRoutes from './api/board/board.route';
import authRoutes from './api/auth/auth.route';
import sfuRoutes from './api/sfu/sfu.route';
import tenancyRoutes from './api/tenancy/tenancy.route';
import imageRoutes from './api/image/image.route';

const mainLogger = new Logger('MainModule', LOG_LEVEL);
const port = 3005;
Expand All @@ -40,6 +41,7 @@ app.use('/board', boardRoutes);
app.use('/auth', authRoutes);
app.use('/sfu', sfuRoutes);
app.use('/tenancy', tenancyRoutes);
app.use('/image', imageRoutes);

server.listen(port, () => {
mainLogger.info(`Example app listening on port ${port}.`);
Expand Down
46 changes: 36 additions & 10 deletions node/src/models/board.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { DocumentFields } from 'fastfire/dist/types';
import { Collaborator } from './collaborator';
import {
FastFire,
FastFireCollection,
FastFireField,
FastFireDocument,
} from 'fastfire';
import { generateRandId } from '../utils/misc';

/**
* Defines Board class.
Expand All @@ -15,6 +15,8 @@ import {
//TODO: add createdAt and updatedAt
@FastFireCollection('Board')
export class Board extends FastFireDocument<Board> {
@FastFireField({ required: true })
uid!: string;
@FastFireField({ required: true })
serialized!: string;
@FastFireField({ required: true })
Expand All @@ -24,7 +26,11 @@ export class Board extends FastFireDocument<Board> {
@FastFireField({ required: true })
shareUrl!: string;
@FastFireField({ required: true })
collaborators!: Collaborator[];
collaborators!: string[]; // Array of collaborator IDs
@FastFireField({ required: true })
createdAt!: Date;
@FastFireField({ required: true })
updatedAt!: Date;
}

// Function to create a board
Expand All @@ -33,15 +39,25 @@ export async function createBoard(
title: string,
tags: string[],
shareUrl: string,
collaborators: Collaborator[],
collaborators: string[],
) {
return FastFire.create(Board, {
serialized,
title,
tags,
shareUrl,
collaborators,
});
const uid = generateRandId();
const createdAt = new Date();
const updatedAt = new Date();
return FastFire.create(
Board,
{
uid,
serialized,
title,
tags,
shareUrl,
collaborators,
createdAt,
updatedAt,
},
uid,
);
}

// Function to find a board by ID
Expand All @@ -53,6 +69,7 @@ export const updateBoard = async (
board: Board,
updatedFields: Partial<DocumentFields<Board>>,
) => {
updatedFields.updatedAt = new Date();
const { fastFireOptions: _fastFireOptions, id: _id, ...boardFields } = board;
const updatedBoard = { ...boardFields, ...updatedFields };
await board.update(updatedBoard);
Expand All @@ -61,3 +78,12 @@ export const updateBoard = async (

// Function to delete a board
export const deleteBoard = async (board: Board) => await board.delete();

export const findBoardsByCollaboratorId = async (collaboratorId: string) => {
return await FastFire.where(
Board,
'collaborators',
'array-contains',
collaboratorId,
).get();
};
34 changes: 27 additions & 7 deletions node/src/models/collaborator.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { DocumentFields } from 'fastfire/dist/types';
import { User } from './user';
import {
FastFire,
FastFireCollection,
FastFireField,
FastFireDocument,
} from 'fastfire';
import { generateRandId } from '../utils/misc';

/**
* Defines collaborator class.
Expand All @@ -16,18 +16,37 @@ import {
//TODO: change permissionLevel to an enum
@FastFireCollection('Collaborator')
export class Collaborator extends FastFireDocument<Collaborator> {
@FastFireField({ required: true })
uid!: string;
@FastFireField({ required: true })
permissionLevel!: string;
@FastFireField({ required: true })
user!: User;
user!: string;
@FastFireField({ required: true })
createdAt!: Date;
@FastFireField({ required: true })
updatedAt!: Date;
}

// Function to create a collaborator
export async function createCollaborator(permissionLevel: string, user: User) {
return await FastFire.create(Collaborator, {
permissionLevel,
user,
});
export async function createCollaborator(
permissionLevel: string,
user: string,
) {
const uid = generateRandId();
const createdAt = new Date();
const updatedAt = new Date();
return await FastFire.create(
Collaborator,
{
uid,
permissionLevel,
user,
createdAt,
updatedAt,
},
uid,
);
}

// Function to find a collaborator by ID
Expand All @@ -39,6 +58,7 @@ export const updateCollaborator = async (
collaborator: Collaborator,
updatedFields: Partial<DocumentFields<Collaborator>>,
) => {
updatedFields.updatedAt = new Date();
const {
fastFireOptions: _fastFireOptions,
id: _id,
Expand Down
31 changes: 24 additions & 7 deletions node/src/models/comment.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { DocumentFields } from 'fastfire/dist/types';
import { Collaborator } from './collaborator';
import {
FastFire,
FastFireCollection,
FastFireField,
FastFireDocument,
} from 'fastfire';
import { generateRandId } from '../utils/misc';

/**
* Defines comment class.
Expand All @@ -15,18 +15,34 @@ import {
//TODO: add createdAt and updatedAt
@FastFireCollection('Comment')
export class Comment extends FastFireDocument<Comment> {
@FastFireField({ required: true })
uid!: string;
@FastFireField({ required: true })
text!: string;
@FastFireField({ required: true })
collaborator!: Collaborator;
collaborator!: string; // Collaborator ID
@FastFireField({ required: true })
createdAt!: Date;
@FastFireField({ required: true })
updatedAt!: Date;
}

// Function to create a comment
export async function createComment(text: string, collaborator: Collaborator) {
return await FastFire.create(Comment, {
text,
collaborator,
});
export async function createComment(text: string, collaborator: string) {
const uid = generateRandId();
const createdAt = new Date();
const updatedAt = new Date();
return await FastFire.create(
Comment,
{
uid,
text,
collaborator,
createdAt,
updatedAt,
},
uid,
);
}

// Function to find a comment by ID
Expand All @@ -38,6 +54,7 @@ export const updateComment = async (
comment: Comment,
updatedFields: Partial<DocumentFields<Comment>>,
) => {
updatedFields.updatedAt = new Date();
const {
fastFireOptions: _fastFireOptions,
id: _id,
Expand Down
Loading

0 comments on commit 7431765

Please sign in to comment.