Skip to content

Commit

Permalink
Implement an endpoint to delete notes
Browse files Browse the repository at this point in the history
  • Loading branch information
Dlurak committed Apr 11, 2024
1 parent 8a6e8cf commit e21b60d
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 4 deletions.
3 changes: 3 additions & 0 deletions dbschema/default.esdl
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ module default {
default := EditScope.Self;
};

creator: User {
on target delete allow;
};
multi updates: Change {
on target delete allow;
on source delete delete target;
Expand Down
12 changes: 12 additions & 0 deletions dbschema/migrations/00020.edgeql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE MIGRATION m17fqphiq6jr5unbqqolhaopjqdcgklmjowirlpgkejf2qsqocypsq
ONTO m1mzn3ehkgkjrnujdwfxjhe5optsk3cmyqkdagwev6vq2p5a4xxbsa
{
ALTER TYPE default::Note {
CREATE LINK creator: default::User {
ON TARGET DELETE ALLOW;
};
ALTER PROPERTY editScope {
SET REQUIRED USING (default::EditScope.Self);
};
};
};
1 change: 1 addition & 0 deletions src/routes/notes/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const createNote = new Elysia()
})),
editScope: body.editScope,

creator: userByUsername(auth.username),
updates: e.insert(e.Change, { user: userByUsername(auth.username) }),
});
const result = await promiseResult(() => query.run(client));
Expand Down
64 changes: 64 additions & 0 deletions src/routes/notes/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import e from "@edgedb";
import { DATABASE_DELETE_FAILED, UNAUTHORIZED } from "constants/responses";
import Elysia from "elysia";
import { HttpStatusCode } from "elysia-http-status-code";
import { client } from "index";
import { auth } from "plugins/auth";
import { promiseResult } from "utils/errors";
import { responseBuilder } from "utils/response";

export const deleteNote = new Elysia()
.use(auth)
.use(HttpStatusCode())
.delete("/:id", async ({ auth, set, httpStatus, params }) => {
if (!auth.isAuthorized) {
set.status = httpStatus.HTTP_401_UNAUTHORIZED;
return UNAUTHORIZED;
}

const deletionQuery = e.delete(e.Note, (n) => {
const selfFilter = e.op(
e.op(n.editScope, "=", e.cast(e.EditScope, "Self")),
"and",
e.op(n.creator.username, "=", auth.username),
);
const classFilter = e.op(
e.op(n.editScope, "=", e.cast(e.EditScope, "Class")),
"and",
e.op(auth.username, "in", n.class.students.username),
);
const schoolFilter = e.op(
e.op(n.editScope, "=", e.cast(e.EditScope, "School")),
"and",
e.op(auth.username, "in", n.class.school.classes.students.username),
);

const editScopeFilter = e.op(
e.op(selfFilter, "or", classFilter),
"or",
schoolFilter,
);

const paramId = e.cast(e.uuid, params.id);
const idFilter = e.op(n.id, "=", paramId);

return { filter_single: e.op(editScopeFilter, "and", idFilter) };
});
const result = await promiseResult(() => deletionQuery.run(client));

if (result.isError) {
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_DELETE_FAILED;
}
if (!result.data) {
set.status = httpStatus.HTTP_404_NOT_FOUND;
return responseBuilder("error", {
error: "This note doesn't exist or you don't have rights to delete it",
});
}

return responseBuilder("success", {
message: "Successfully deleted note",
data: null,
});
});
2 changes: 2 additions & 0 deletions src/routes/notes/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import Elysia from "elysia";
import { createNote } from "./create";
import { deleteNote } from "./delete";
import { listNotes } from "./list";

export const noteRouter = new Elysia({ prefix: "/notes" })
.use(createNote)
.use(deleteNote)
.use(listNotes);
13 changes: 9 additions & 4 deletions src/routes/notes/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,27 @@ export const listNotes = new Elysia()
id: true,
};
});
const result = await promiseResult(() =>
dbQuery(query.limit, query.offset).run(client),
);
const result = await promiseResult(async () => {
const [notes, count] = await Promise.all([
dbQuery(query.limit, query.offset).run(client),
e.count(dbQuery(-1, 0)).run(client),
]);
return { notes, count };
});

if (result.isError) {
set.status = httpStatus.HTTP_500_INTERNAL_SERVER_ERROR;
return DATABASE_READ_FAILED;
}

const formatted = result.data.map((i) =>
const formatted = result.data.notes.map((i) =>
replaceDateDeep(i, normalDateToCustom),
);

return responseBuilder("success", {
message: "Successfully retrieved data",
data: {
totalCount: result.data.count,
notes: formatted,
},
});
Expand Down

0 comments on commit e21b60d

Please sign in to comment.