* feat: Add Terraform configuration for AWS * feat: Update data models to use string identifiers and add DynamoDB table configurations * feat: Update Terraform S3 backend configuration
181 lines
4.5 KiB
TypeScript
181 lines
4.5 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
|
import { fetchAuthSession, getCurrentUser } from "aws-amplify/auth";
|
|
|
|
export interface Project {
|
|
projectId: string;
|
|
name: string;
|
|
description?: string;
|
|
startDate?: string;
|
|
endDate?: string;
|
|
}
|
|
|
|
export enum Priority {
|
|
Urgent = "Urgent",
|
|
High = "High",
|
|
Medium = "Medium",
|
|
Low = "Low",
|
|
Backlog = "Backlog",
|
|
}
|
|
|
|
export enum Status {
|
|
ToDo = "To Do",
|
|
InProgress = "In Progress",
|
|
TestReview = "Test/Review",
|
|
Done = "Done",
|
|
}
|
|
|
|
export interface User {
|
|
userId?: string;
|
|
username: string;
|
|
email: string;
|
|
profilePictureUrl?: string;
|
|
cognitoId?: string;
|
|
teamId?: string;
|
|
}
|
|
|
|
export interface Attachment {
|
|
attachmentId: string;
|
|
fileURL: string;
|
|
fileName: string;
|
|
taskId: string;
|
|
uploadedById: string;
|
|
}
|
|
|
|
export interface Task {
|
|
taskId: string;
|
|
title: string;
|
|
description?: string;
|
|
status?: Status;
|
|
priority?: Priority;
|
|
tags?: string;
|
|
startDate?: string;
|
|
dueDate?: string;
|
|
points?: number;
|
|
projectId: string;
|
|
authorUserId?: string;
|
|
assignedUserId?: string;
|
|
|
|
author?: User;
|
|
assignee?: User;
|
|
comments?: Comment[];
|
|
attachments?: Attachment[];
|
|
}
|
|
|
|
export interface SearchResults {
|
|
tasks?: Task[];
|
|
projects?: Project[];
|
|
users?: User[];
|
|
}
|
|
|
|
export interface Team {
|
|
teamId: string;
|
|
teamName: string;
|
|
productOwnerUserId?: string;
|
|
projectManagerUserId?: string;
|
|
}
|
|
|
|
export const api = createApi({
|
|
baseQuery: fetchBaseQuery({
|
|
baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL,
|
|
prepareHeaders: async (headers) => {
|
|
const session = await fetchAuthSession();
|
|
const { accessToken } = session.tokens ?? {};
|
|
if (accessToken) {
|
|
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
}
|
|
return headers;
|
|
},
|
|
}),
|
|
reducerPath: "api",
|
|
tagTypes: ["Projects", "Tasks", "Users", "Teams"],
|
|
endpoints: (build) => ({
|
|
getAuthUser: build.query({
|
|
queryFn: async (_, _queryApi, _extraoptions, fetchWithBQ) => {
|
|
try {
|
|
const user = await getCurrentUser();
|
|
const session = await fetchAuthSession();
|
|
if (!session) throw new Error("No session found");
|
|
|
|
const { userSub } = session;
|
|
|
|
const userDetailsResponse = await fetchWithBQ(`users/${userSub}`);
|
|
const userDetails = userDetailsResponse.data as User;
|
|
|
|
return { data: { user, userSub, userDetails } };
|
|
} catch (error: any) {
|
|
return { error: error.message || "Could not fetch user data" };
|
|
}
|
|
},
|
|
}),
|
|
getProjects: build.query<Project[], void>({
|
|
query: () => "projects",
|
|
providesTags: ["Projects"],
|
|
}),
|
|
createProject: build.mutation<Project, Partial<Project>>({
|
|
query: (project) => ({
|
|
url: "projects",
|
|
method: "POST",
|
|
body: project,
|
|
}),
|
|
invalidatesTags: ["Projects"],
|
|
}),
|
|
getTasks: build.query<Task[], { projectId: number }>({
|
|
query: ({ projectId }) => `tasks?projectId=${projectId}`,
|
|
providesTags: (result) =>
|
|
result
|
|
? result.map(({ taskId }) => ({ type: "Tasks" as const, taskId }))
|
|
: [{ type: "Tasks" as const }],
|
|
}),
|
|
getTasksByUser: build.query<Task[], string>({
|
|
query: (userId) => `tasks/user/${userId}`,
|
|
providesTags: (result, error, userId) =>
|
|
result
|
|
? result.map(({ taskId }) => ({ type: "Tasks", taskId }))
|
|
: [{ type: "Tasks", taskId: userId }],
|
|
}),
|
|
createTask: build.mutation<Task, Partial<Task>>({
|
|
query: (task) => ({
|
|
url: "tasks",
|
|
method: "POST",
|
|
body: task,
|
|
}),
|
|
invalidatesTags: ["Tasks"],
|
|
}),
|
|
updateTaskStatus: build.mutation<Task, { taskId: string; status: string }>({
|
|
query: ({ taskId, status }) => ({
|
|
url: `tasks/${taskId}/status`,
|
|
method: "PATCH",
|
|
body: { status },
|
|
}),
|
|
invalidatesTags: (result, error, { taskId }) => [
|
|
{ type: "Tasks", id: taskId },
|
|
],
|
|
}),
|
|
getUsers: build.query<User[], void>({
|
|
query: () => "users",
|
|
providesTags: ["Users"],
|
|
}),
|
|
getTeams: build.query<Team[], void>({
|
|
query: () => "teams",
|
|
providesTags: ["Teams"],
|
|
}),
|
|
search: build.query<SearchResults, string>({
|
|
query: (query) => `search?query=${query}`,
|
|
}),
|
|
}),
|
|
});
|
|
|
|
export const {
|
|
useGetAuthUserQuery,
|
|
useGetProjectsQuery,
|
|
useCreateProjectMutation,
|
|
useGetTasksQuery,
|
|
useCreateTaskMutation,
|
|
useUpdateTaskStatusMutation,
|
|
useSearchQuery,
|
|
useGetUsersQuery,
|
|
useGetTeamsQuery,
|
|
useGetTasksByUserQuery,
|
|
} = api;
|