mirror of
https://github.com/hex248/sprint.git
synced 2026-02-08 02:33:01 +00:00
Organisation and OrganisationMember routes
This commit is contained in:
@@ -23,6 +23,16 @@ const main = async () => {
|
||||
"/issues/:projectBlob": withCors(withAuth(routes.issuesInProject)),
|
||||
"/issues/all": withCors(withAuth(routes.issues)),
|
||||
|
||||
"/organisation/create": withCors(withAuth(routes.organisationCreate)),
|
||||
"/organisation/by-id": withCors(withAuth(routes.organisationById)),
|
||||
"/organisation/by-user": withCors(withAuth(routes.organisationByUser)),
|
||||
"/organisation/update": withCors(withAuth(routes.organisationUpdate)),
|
||||
"/organisation/delete": withCors(withAuth(routes.organisationDelete)),
|
||||
"/organisation/add-member": withCors(withAuth(routes.organisationAddMember)),
|
||||
"/organisation/members": withCors(withAuth(routes.organisationMembers)),
|
||||
"/organisation/remove-member": withCors(withAuth(routes.organisationRemoveMember)),
|
||||
"/organisation/update-member-role": withCors(withAuth(routes.organisationUpdateMemberRole)),
|
||||
|
||||
"/project/create": withCors(withAuth(routes.projectCreate)),
|
||||
"/project/update": withCors(withAuth(routes.projectUpdate)),
|
||||
"/project/delete": withCors(withAuth(routes.projectDelete)),
|
||||
|
||||
@@ -6,6 +6,15 @@ import issueDelete from "./issue/delete";
|
||||
import issueUpdate from "./issue/update";
|
||||
import issuesInProject from "./issues/[projectBlob]";
|
||||
import issues from "./issues/all";
|
||||
import organisationAddMember from "./organisation/add-member";
|
||||
import organisationById from "./organisation/by-id";
|
||||
import organisationByUser from "./organisation/by-user";
|
||||
import organisationCreate from "./organisation/create";
|
||||
import organisationDelete from "./organisation/delete";
|
||||
import organisationMembers from "./organisation/members";
|
||||
import organisationRemoveMember from "./organisation/remove-member";
|
||||
import organisationUpdate from "./organisation/update";
|
||||
import organisationUpdateMemberRole from "./organisation/update-member-role";
|
||||
import projectsAll from "./project/all";
|
||||
import projectsByCreator from "./project/by-creator";
|
||||
import projectCreate from "./project/create";
|
||||
@@ -22,6 +31,16 @@ export const routes = {
|
||||
issuesInProject,
|
||||
issues,
|
||||
|
||||
organisationCreate,
|
||||
organisationById,
|
||||
organisationByUser,
|
||||
organisationUpdate,
|
||||
organisationDelete,
|
||||
organisationAddMember,
|
||||
organisationMembers,
|
||||
organisationRemoveMember,
|
||||
organisationUpdateMemberRole,
|
||||
|
||||
projectCreate,
|
||||
projectUpdate,
|
||||
projectDelete,
|
||||
|
||||
38
packages/backend/src/routes/organisation/add-member.ts
Normal file
38
packages/backend/src/routes/organisation/add-member.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { BunRequest } from "bun";
|
||||
import { createOrganisationMember, getOrganisationById, getUserById } from "../../db/queries";
|
||||
|
||||
// /organisation/add-member?organisationId=1&userId=2&role=member
|
||||
export default async function organisationAddMember(req: BunRequest) {
|
||||
const url = new URL(req.url);
|
||||
const organisationId = url.searchParams.get("organisationId");
|
||||
const userId = url.searchParams.get("userId");
|
||||
const role = url.searchParams.get("role") || "member";
|
||||
|
||||
if (!organisationId || !userId) {
|
||||
return new Response(
|
||||
`missing parameters: ${!organisationId ? "organisationId " : ""}${!userId ? "userId" : ""}`,
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const orgIdNumber = Number(organisationId);
|
||||
const userIdNumber = Number(userId);
|
||||
|
||||
if (!Number.isInteger(orgIdNumber) || !Number.isInteger(userIdNumber)) {
|
||||
return new Response("organisationId and userId must be integers", { status: 400 });
|
||||
}
|
||||
|
||||
const organisation = await getOrganisationById(orgIdNumber);
|
||||
if (!organisation) {
|
||||
return new Response(`organisation with id ${organisationId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
const user = await getUserById(userIdNumber);
|
||||
if (!user) {
|
||||
return new Response(`user with id ${userId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
const member = await createOrganisationMember(orgIdNumber, userIdNumber, role);
|
||||
|
||||
return Response.json(member);
|
||||
}
|
||||
24
packages/backend/src/routes/organisation/by-id.ts
Normal file
24
packages/backend/src/routes/organisation/by-id.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { BunRequest } from "bun";
|
||||
import { getOrganisationById } from "../../db/queries";
|
||||
|
||||
// /organisation/by-id?id=1
|
||||
export default async function organisationById(req: BunRequest) {
|
||||
const url = new URL(req.url);
|
||||
const id = url.searchParams.get("id");
|
||||
|
||||
if (!id) {
|
||||
return new Response("organisation id is required", { status: 400 });
|
||||
}
|
||||
|
||||
const organisationId = Number(id);
|
||||
if (!Number.isInteger(organisationId)) {
|
||||
return new Response("organisation id must be an integer", { status: 400 });
|
||||
}
|
||||
|
||||
const organisation = await getOrganisationById(organisationId);
|
||||
if (!organisation) {
|
||||
return new Response(`organisation with id ${id} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
return Response.json(organisation);
|
||||
}
|
||||
26
packages/backend/src/routes/organisation/by-user.ts
Normal file
26
packages/backend/src/routes/organisation/by-user.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { BunRequest } from "bun";
|
||||
import { getOrganisationsByUserId, getUserById } from "../../db/queries";
|
||||
|
||||
// /organisation/by-user?userId=1
|
||||
export default async function organisationsByUser(req: BunRequest) {
|
||||
const url = new URL(req.url);
|
||||
const userId = url.searchParams.get("userId");
|
||||
|
||||
if (!userId) {
|
||||
return new Response("userId is required", { status: 400 });
|
||||
}
|
||||
|
||||
const userIdNumber = Number(userId);
|
||||
if (!Number.isInteger(userIdNumber)) {
|
||||
return new Response("userId must be an integer", { status: 400 });
|
||||
}
|
||||
|
||||
const user = await getUserById(userIdNumber);
|
||||
if (!user) {
|
||||
return new Response(`user with id ${userId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
const organisations = await getOrganisationsByUserId(user.id);
|
||||
|
||||
return Response.json(organisations);
|
||||
}
|
||||
23
packages/backend/src/routes/organisation/create.ts
Normal file
23
packages/backend/src/routes/organisation/create.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import type { BunRequest } from "bun";
|
||||
import { createOrganisation } from "../../db/queries";
|
||||
|
||||
// /organisation/create?name=Org%20Name&slug=org-name&description=Optional%20description
|
||||
export default async function organisationCreate(req: BunRequest) {
|
||||
const url = new URL(req.url);
|
||||
const name = url.searchParams.get("name");
|
||||
const slug = url.searchParams.get("slug");
|
||||
const description = url.searchParams.get("description") || undefined;
|
||||
|
||||
if (!name || !slug) {
|
||||
return new Response(`missing parameters: ${!name ? "name " : ""}${!slug ? "slug" : ""}`, {
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
// Check if organisation with slug already exists
|
||||
// TODO: Add this check when we have a getOrganisationBySlug function
|
||||
|
||||
const organisation = await createOrganisation(name, slug, description);
|
||||
|
||||
return Response.json(organisation);
|
||||
}
|
||||
26
packages/backend/src/routes/organisation/delete.ts
Normal file
26
packages/backend/src/routes/organisation/delete.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { BunRequest } from "bun";
|
||||
import { deleteOrganisation, getOrganisationById } from "../../db/queries";
|
||||
|
||||
// /organisation/delete?id=1
|
||||
export default async function organisationDelete(req: BunRequest) {
|
||||
const url = new URL(req.url);
|
||||
const id = url.searchParams.get("id");
|
||||
|
||||
if (!id) {
|
||||
return new Response("organisation id is required", { status: 400 });
|
||||
}
|
||||
|
||||
const organisationId = Number(id);
|
||||
if (!Number.isInteger(organisationId)) {
|
||||
return new Response("organisation id must be an integer", { status: 400 });
|
||||
}
|
||||
|
||||
const organisation = await getOrganisationById(organisationId);
|
||||
if (!organisation) {
|
||||
return new Response(`organisation with id ${id} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
await deleteOrganisation(organisationId);
|
||||
|
||||
return Response.json({ success: true });
|
||||
}
|
||||
26
packages/backend/src/routes/organisation/members.ts
Normal file
26
packages/backend/src/routes/organisation/members.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { BunRequest } from "bun";
|
||||
import { getOrganisationById, getOrganisationMembers } from "../../db/queries";
|
||||
|
||||
// /organisation/members?organisationId=1
|
||||
export default async function organisationMembers(req: BunRequest) {
|
||||
const url = new URL(req.url);
|
||||
const organisationId = url.searchParams.get("organisationId");
|
||||
|
||||
if (!organisationId) {
|
||||
return new Response("organisationId is required", { status: 400 });
|
||||
}
|
||||
|
||||
const orgIdNumber = Number(organisationId);
|
||||
if (!Number.isInteger(orgIdNumber)) {
|
||||
return new Response("organisationId must be an integer", { status: 400 });
|
||||
}
|
||||
|
||||
const organisation = await getOrganisationById(orgIdNumber);
|
||||
if (!organisation) {
|
||||
return new Response(`organisation with id ${organisationId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
const members = await getOrganisationMembers(orgIdNumber);
|
||||
|
||||
return Response.json(members);
|
||||
}
|
||||
37
packages/backend/src/routes/organisation/remove-member.ts
Normal file
37
packages/backend/src/routes/organisation/remove-member.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import type { BunRequest } from "bun";
|
||||
import { getOrganisationById, getUserById, removeOrganisationMember } from "../../db/queries";
|
||||
|
||||
// /organisation/remove-member?organisationId=1&userId=2
|
||||
export default async function organisationRemoveMember(req: BunRequest) {
|
||||
const url = new URL(req.url);
|
||||
const organisationId = url.searchParams.get("organisationId");
|
||||
const userId = url.searchParams.get("userId");
|
||||
|
||||
if (!organisationId || !userId) {
|
||||
return new Response(
|
||||
`missing parameters: ${!organisationId ? "organisationId " : ""}${!userId ? "userId" : ""}`,
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const orgIdNumber = Number(organisationId);
|
||||
const userIdNumber = Number(userId);
|
||||
|
||||
if (!Number.isInteger(orgIdNumber) || !Number.isInteger(userIdNumber)) {
|
||||
return new Response("organisationId and userId must be integers", { status: 400 });
|
||||
}
|
||||
|
||||
const organisation = await getOrganisationById(orgIdNumber);
|
||||
if (!organisation) {
|
||||
return new Response(`organisation with id ${organisationId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
const user = await getUserById(userIdNumber);
|
||||
if (!user) {
|
||||
return new Response(`user with id ${userId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
await removeOrganisationMember(orgIdNumber, userIdNumber);
|
||||
|
||||
return Response.json({ success: true });
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { BunRequest } from "bun";
|
||||
import { getOrganisationById, getUserById, updateOrganisationMemberRole } from "../../db/queries";
|
||||
|
||||
// /organisation/update-member-role?organisationId=1&userId=2&role=admin
|
||||
export default async function organisationUpdateMemberRole(req: BunRequest) {
|
||||
const url = new URL(req.url);
|
||||
const organisationId = url.searchParams.get("organisationId");
|
||||
const userId = url.searchParams.get("userId");
|
||||
const role = url.searchParams.get("role");
|
||||
|
||||
if (!organisationId || !userId || !role) {
|
||||
return new Response(
|
||||
`missing parameters: ${!organisationId ? "organisationId " : ""}${!userId ? "userId " : ""}${!role ? "role" : ""}`,
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
const orgIdNumber = Number(organisationId);
|
||||
const userIdNumber = Number(userId);
|
||||
|
||||
if (!Number.isInteger(orgIdNumber) || !Number.isInteger(userIdNumber)) {
|
||||
return new Response("organisationId and userId must be integers", { status: 400 });
|
||||
}
|
||||
|
||||
const organisation = await getOrganisationById(orgIdNumber);
|
||||
if (!organisation) {
|
||||
return new Response(`organisation with id ${organisationId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
const user = await getUserById(userIdNumber);
|
||||
if (!user) {
|
||||
return new Response(`user with id ${userId} not found`, { status: 404 });
|
||||
}
|
||||
|
||||
const member = await updateOrganisationMemberRole(orgIdNumber, userIdNumber, role);
|
||||
|
||||
return Response.json(member);
|
||||
}
|
||||
39
packages/backend/src/routes/organisation/update.ts
Normal file
39
packages/backend/src/routes/organisation/update.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { BunRequest } from "bun";
|
||||
import { getOrganisationById, updateOrganisation } from "../../db/queries";
|
||||
|
||||
// /organisation/update?id=1&name=New%20Name&description=New%20Description&slug=new-slug
|
||||
export default async function organisationUpdate(req: BunRequest) {
|
||||
const url = new URL(req.url);
|
||||
const id = url.searchParams.get("id");
|
||||
const name = url.searchParams.get("name") || undefined;
|
||||
const description = url.searchParams.get("description") || undefined;
|
||||
const slug = url.searchParams.get("slug") || undefined;
|
||||
|
||||
if (!id) {
|
||||
return new Response("organisation id is required", { status: 400 });
|
||||
}
|
||||
|
||||
const organisationId = Number(id);
|
||||
if (!Number.isInteger(organisationId)) {
|
||||
return new Response("organisation id must be an integer", { status: 400 });
|
||||
}
|
||||
|
||||
const existingOrganisation = await getOrganisationById(organisationId);
|
||||
if (!existingOrganisation) {
|
||||
return new Response(`organisation with id ${id} does not exist`, { status: 404 });
|
||||
}
|
||||
|
||||
if (!name && !description && !slug) {
|
||||
return new Response("at least one of name, description, or slug must be provided", {
|
||||
status: 400,
|
||||
});
|
||||
}
|
||||
|
||||
const organisation = await updateOrganisation(organisationId, {
|
||||
name,
|
||||
description,
|
||||
slug,
|
||||
});
|
||||
|
||||
return Response.json(organisation);
|
||||
}
|
||||
Reference in New Issue
Block a user