add notes routes
This commit is contained in:
79
src/note/note.controller.ts
Normal file
79
src/note/note.controller.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { FastifyReply, FastifyRequest } from "fastify";
|
||||||
|
import { createNote, deleteNote, listNotes, updateNote } from "./note.service";
|
||||||
|
import { CreateNoteInput } from "./note.schema";
|
||||||
|
|
||||||
|
export async function createNoteHandler(
|
||||||
|
req: FastifyRequest,
|
||||||
|
res: FastifyReply
|
||||||
|
) {
|
||||||
|
const { resourceId } = req.params as { resourceId: string };
|
||||||
|
const input = req.body as CreateNoteInput;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const note = await createNote(input, resourceId, req.user);
|
||||||
|
return res.code(201).send(note);
|
||||||
|
} catch (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listNotesHandler(req: FastifyRequest, res: FastifyReply) {
|
||||||
|
const { resourceId } = req.params as { resourceId: string };
|
||||||
|
|
||||||
|
try {
|
||||||
|
const notes = await listNotes(resourceId, req.user.tenantId);
|
||||||
|
return res.code(200).send({ notes: notes });
|
||||||
|
} catch (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateNoteHandler(
|
||||||
|
req: FastifyRequest,
|
||||||
|
res: FastifyReply
|
||||||
|
) {
|
||||||
|
const { resourceId, noteId } = req.params as {
|
||||||
|
resourceId: string;
|
||||||
|
noteId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const input = req.body as CreateNoteInput;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const updatedNote = await updateNote(
|
||||||
|
input,
|
||||||
|
resourceId,
|
||||||
|
noteId,
|
||||||
|
req.user.tenantId
|
||||||
|
);
|
||||||
|
if (!updateNote) return res.code(404).send({ error: "resource not found" });
|
||||||
|
|
||||||
|
return res.code(200).send(updatedNote);
|
||||||
|
} catch (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteNoteHandler(
|
||||||
|
req: FastifyRequest,
|
||||||
|
res: FastifyReply
|
||||||
|
) {
|
||||||
|
const { resourceId, noteId } = req.params as {
|
||||||
|
resourceId: string;
|
||||||
|
noteId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const deleteResult = await deleteNote(
|
||||||
|
resourceId,
|
||||||
|
noteId,
|
||||||
|
req.user.tenantId
|
||||||
|
);
|
||||||
|
if (deleteResult.deletedCount == 0)
|
||||||
|
return res.code(404).send({ error: "resource not found" });
|
||||||
|
|
||||||
|
return res.code(204).send();
|
||||||
|
} catch (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
79
src/note/note.route.ts
Normal file
79
src/note/note.route.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { FastifyInstance } from "fastify";
|
||||||
|
import {
|
||||||
|
createNoteHandler,
|
||||||
|
listNotesHandler,
|
||||||
|
deleteNoteHandler,
|
||||||
|
updateNoteHandler,
|
||||||
|
} from "./note.controller";
|
||||||
|
import { Claim } from "../utils/claims";
|
||||||
|
|
||||||
|
export async function noteRoutes(
|
||||||
|
fastify: FastifyInstance,
|
||||||
|
claims: { read: Claim; write: Claim; delete: Claim }
|
||||||
|
) {
|
||||||
|
fastify.post(
|
||||||
|
"/:resourceId/notes",
|
||||||
|
{
|
||||||
|
schema: {
|
||||||
|
params: {
|
||||||
|
type: "object",
|
||||||
|
properties: { resourceId: { type: "string" } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config: { requiredClaims: [claims.write] },
|
||||||
|
preHandler: [fastify.authorize],
|
||||||
|
},
|
||||||
|
createNoteHandler
|
||||||
|
);
|
||||||
|
|
||||||
|
fastify.get(
|
||||||
|
"/:resourceId/notes",
|
||||||
|
{
|
||||||
|
schema: {
|
||||||
|
params: {
|
||||||
|
type: "object",
|
||||||
|
properties: { resourceId: { type: "string" } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config: { requiredClaims: [claims.read] },
|
||||||
|
preHandler: [fastify.authorize],
|
||||||
|
},
|
||||||
|
listNotesHandler
|
||||||
|
);
|
||||||
|
|
||||||
|
fastify.patch(
|
||||||
|
"/:resourceId/notes/:noteId",
|
||||||
|
{
|
||||||
|
schema: {
|
||||||
|
params: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
resourceId: { type: "string" },
|
||||||
|
noteId: { type: "string" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config: { requiredClaims: [claims.write] },
|
||||||
|
preHandler: [fastify.authorize],
|
||||||
|
},
|
||||||
|
updateNoteHandler
|
||||||
|
);
|
||||||
|
|
||||||
|
fastify.delete(
|
||||||
|
"/:resourceId/notes/:noteId",
|
||||||
|
{
|
||||||
|
schema: {
|
||||||
|
params: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
resourceId: { type: "string" },
|
||||||
|
noteId: { type: "string" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config: { requiredClaims: [claims.write] },
|
||||||
|
preHandler: [fastify.authorize],
|
||||||
|
},
|
||||||
|
deleteNoteHandler
|
||||||
|
);
|
||||||
|
}
|
||||||
43
src/note/note.schema.ts
Normal file
43
src/note/note.schema.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { buildJsonSchemas } from "fastify-zod";
|
||||||
|
import mongoose from "mongoose";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const noteSchema = new mongoose.Schema({
|
||||||
|
tenantId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
pid: {
|
||||||
|
type: String,
|
||||||
|
unique: true,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
resourceId: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
createdAt: Date,
|
||||||
|
createdBy: {
|
||||||
|
type: mongoose.Types.ObjectId,
|
||||||
|
ref: "user",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const noteModel = mongoose.model("note", noteSchema);
|
||||||
|
|
||||||
|
const createNoteInput = z.object({
|
||||||
|
content: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type CreateNoteInput = z.infer<typeof createNoteInput>;
|
||||||
|
|
||||||
|
export const { schemas: noteSchemas, $ref: $note } = buildJsonSchemas(
|
||||||
|
{
|
||||||
|
createNoteInput,
|
||||||
|
},
|
||||||
|
{ $id: "note" }
|
||||||
|
);
|
||||||
83
src/note/note.service.ts
Normal file
83
src/note/note.service.ts
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
import { AuthenticatedUser } from "../auth";
|
||||||
|
import { generateId } from "../utils/id";
|
||||||
|
import { CreateNoteInput, noteModel } from "./note.schema";
|
||||||
|
|
||||||
|
export async function createNote(
|
||||||
|
input: CreateNoteInput,
|
||||||
|
resourceId: string,
|
||||||
|
user: AuthenticatedUser
|
||||||
|
) {
|
||||||
|
return await noteModel.create({
|
||||||
|
tenantId: user.tenantId,
|
||||||
|
pid: generateId(),
|
||||||
|
resourceId: resourceId,
|
||||||
|
content: input.content,
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdBy: user.userId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateNote(
|
||||||
|
input: CreateNoteInput,
|
||||||
|
resourceId: string,
|
||||||
|
noteId: string,
|
||||||
|
tenantId: string
|
||||||
|
) {
|
||||||
|
return await noteModel.findOneAndUpdate(
|
||||||
|
{
|
||||||
|
$and: [
|
||||||
|
{ pid: noteId },
|
||||||
|
{ tenantId: tenantId },
|
||||||
|
{ resourceId: resourceId },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ ...input },
|
||||||
|
{ new: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function listNotes(resourceId: string, tenantId: string) {
|
||||||
|
return await noteModel.aggregate([
|
||||||
|
{
|
||||||
|
$match: { $and: [{ resourceId: resourceId }, { tenantId: tenantId }] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$lookup: {
|
||||||
|
from: "users",
|
||||||
|
localField: "createdBy",
|
||||||
|
foreignField: "_id",
|
||||||
|
as: "user",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$project: {
|
||||||
|
_id: 1,
|
||||||
|
pid: 1,
|
||||||
|
resourceId: 1,
|
||||||
|
content: 1,
|
||||||
|
createdAt: 1,
|
||||||
|
createdBy: {
|
||||||
|
$let: {
|
||||||
|
vars: { user: { $arrayElemAt: ["$user", 0] } },
|
||||||
|
in: {
|
||||||
|
_id: "$$user._id",
|
||||||
|
pid: "$$user.pid",
|
||||||
|
name: "$$user.name",
|
||||||
|
avatar: "$$user.avatar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteNote(
|
||||||
|
resourceId: string,
|
||||||
|
noteId: string,
|
||||||
|
tenantId: string
|
||||||
|
) {
|
||||||
|
return await noteModel.deleteOne({
|
||||||
|
$and: [{ pid: noteId }, { tenantId: tenantId }, { resourceId: resourceId }],
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -10,6 +10,12 @@ import {
|
|||||||
} from "./permit.controller";
|
} from "./permit.controller";
|
||||||
import { $permit } from "./permit.schema";
|
import { $permit } from "./permit.schema";
|
||||||
import { hideFields } from "../auth";
|
import { hideFields } from "../auth";
|
||||||
|
import {
|
||||||
|
createNoteHandler,
|
||||||
|
deleteNoteHandler,
|
||||||
|
listNotesHandler,
|
||||||
|
} from "../note/note.controller";
|
||||||
|
import { noteRoutes } from "../note/note.route";
|
||||||
|
|
||||||
export async function permitRoutes(fastify: FastifyInstance) {
|
export async function permitRoutes(fastify: FastifyInstance) {
|
||||||
fastify.post(
|
fastify.post(
|
||||||
@@ -111,5 +117,11 @@ export async function permitRoutes(fastify: FastifyInstance) {
|
|||||||
getUniqueFieldValuesPermit
|
getUniqueFieldValuesPermit
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await noteRoutes(fastify, {
|
||||||
|
read: "permit:read",
|
||||||
|
write: "permit:write",
|
||||||
|
delete: "permit:delete",
|
||||||
|
});
|
||||||
|
|
||||||
fastify.addHook("onSend", hideFields("permits"));
|
fastify.addHook("onSend", hideFields("permits"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
updateRtsHandler,
|
updateRtsHandler,
|
||||||
} from "./rts.controller";
|
} from "./rts.controller";
|
||||||
import { hideFields } from "../auth";
|
import { hideFields } from "../auth";
|
||||||
|
import { noteRoutes } from "../note/note.route";
|
||||||
|
|
||||||
export async function rtsRoutes(fastify: FastifyInstance) {
|
export async function rtsRoutes(fastify: FastifyInstance) {
|
||||||
fastify.post(
|
fastify.post(
|
||||||
@@ -94,5 +95,11 @@ export async function rtsRoutes(fastify: FastifyInstance) {
|
|||||||
newFilesHandler
|
newFilesHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await noteRoutes(fastify, {
|
||||||
|
read: "rts:read",
|
||||||
|
write: "rts:write",
|
||||||
|
delete: "rts:delete",
|
||||||
|
});
|
||||||
|
|
||||||
fastify.addHook("onSend", hideFields("rts"));
|
fastify.addHook("onSend", hideFields("rts"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { authRoutes } from "./auth/auth.route";
|
|||||||
import { rtsSchemas } from "./rts/rts.schema";
|
import { rtsSchemas } from "./rts/rts.schema";
|
||||||
import { taskSchemas } from "./task/task.schema";
|
import { taskSchemas } from "./task/task.schema";
|
||||||
import { notificationSchemas } from "./notification/notification.schema";
|
import { notificationSchemas } from "./notification/notification.schema";
|
||||||
|
import { noteSchemas } from "./note/note.schema";
|
||||||
|
|
||||||
const app = fastify({ logger: true });
|
const app = fastify({ logger: true });
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ for (const schema of [
|
|||||||
...rtsSchemas,
|
...rtsSchemas,
|
||||||
...taskSchemas,
|
...taskSchemas,
|
||||||
...notificationSchemas,
|
...notificationSchemas,
|
||||||
|
...noteSchemas,
|
||||||
]) {
|
]) {
|
||||||
app.addSchema(schema);
|
app.addSchema(schema);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
listTaskHandler,
|
listTaskHandler,
|
||||||
updateTaskHandler,
|
updateTaskHandler,
|
||||||
} from "./task.controller";
|
} from "./task.controller";
|
||||||
|
import { noteRoutes } from "../note/note.route";
|
||||||
|
|
||||||
export async function taskRoutes(fastify: FastifyInstance) {
|
export async function taskRoutes(fastify: FastifyInstance) {
|
||||||
fastify.post(
|
fastify.post(
|
||||||
@@ -79,4 +80,10 @@ export async function taskRoutes(fastify: FastifyInstance) {
|
|||||||
},
|
},
|
||||||
deleteTaskHandler
|
deleteTaskHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await noteRoutes(fastify, {
|
||||||
|
read: "task:read",
|
||||||
|
write: "task:write",
|
||||||
|
delete: "task:delete",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user