Merge remote-tracking branch 'origin/feat/user-routes' into feat/user-routes

This commit is contained in:
Gabriellvl 2025-04-02 14:56:45 +02:00
commit fe5102dd19
20 changed files with 117 additions and 118 deletions

View file

@ -11,10 +11,10 @@ import {
updateClassJoinRequestStatus,
} from '../services/teachers.js';
import { requireFields } from './error-helper.js';
import {TeacherDTO} from "dwengo-1-common/src/interfaces/teacher";
import {ClassDTO} from "dwengo-1-common/src/interfaces/class";
import {StudentDTO} from "dwengo-1-common/src/interfaces/student";
import {QuestionDTO, QuestionId} from "dwengo-1-common/src/interfaces/question";
import { TeacherDTO } from 'dwengo-1-common/src/interfaces/teacher';
import { ClassDTO } from 'dwengo-1-common/src/interfaces/class';
import { StudentDTO } from 'dwengo-1-common/src/interfaces/student';
import { QuestionDTO, QuestionId } from 'dwengo-1-common/src/interfaces/question';
export async function getAllTeachersHandler(req: Request, res: Response): Promise<void> {
const full = req.query.full === 'true';

View file

@ -1,4 +1,4 @@
import {Theme} from "dwengo-1-common/src/interfaces/theme";
import { Theme } from 'dwengo-1-common/src/interfaces/theme';
export const themes: Theme[] = [
{

View file

@ -1,7 +1,7 @@
import { Question } from '../entities/questions/question.entity.js';
import { mapToStudentDTO } from './student.js';
import { QuestionDTO, QuestionId } from 'dwengo-1-common/src/interfaces/question';
import {LearningObjectIdentifier} from "../entities/content/learning-object-identifier";
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier';
function getLearningObjectIdentifier(question: Question): LearningObjectIdentifier {
return {

View file

@ -3,8 +3,7 @@ import { ClassJoinRequest, ClassJoinRequestStatus } from '../entities/classes/cl
import { getClassJoinRequestRepository } from '../data/repositories.js';
import { Student } from '../entities/users/student.entity.js';
import { Class } from '../entities/classes/class.entity.js';
import {ClassJoinRequestDTO} from "dwengo-1-common/src/interfaces/class-join-request";
import { ClassJoinRequestDTO } from 'dwengo-1-common/src/interfaces/class-join-request';
export function mapToStudentRequestDTO(request: ClassJoinRequest): ClassJoinRequestDTO {
return {

View file

@ -1,13 +1,13 @@
import { getAnswerRepository, getQuestionRepository } from '../data/repositories.js';
import {mapToQuestionDTO, mapToQuestionDTOId } from '../interfaces/question.js';
import { mapToQuestionDTO, mapToQuestionDTOId } from '../interfaces/question.js';
import { Question } from '../entities/questions/question.entity.js';
import { Answer } from '../entities/questions/answer.entity.js';
import {mapToAnswerDTO, mapToAnswerDTOId} from '../interfaces/answer.js';
import { mapToAnswerDTO, mapToAnswerDTOId } from '../interfaces/answer.js';
import { QuestionRepository } from '../data/questions/question-repository.js';
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
import { mapToStudent } from '../interfaces/student.js';
import {QuestionDTO, QuestionId} from "dwengo-1-common/src/interfaces/question";
import {AnswerDTO, AnswerId} from "dwengo-1-common/src/interfaces/answer";
import { QuestionDTO, QuestionId } from 'dwengo-1-common/src/interfaces/question';
import { AnswerDTO, AnswerId } from 'dwengo-1-common/src/interfaces/answer';
export async function getAllQuestions(id: LearningObjectIdentifier, full: boolean): Promise<QuestionDTO[] | QuestionId[]> {
const questionRepository: QuestionRepository = getQuestionRepository();

View file

@ -20,7 +20,7 @@ import { NotFoundException } from '../../src/exceptions/not-found-exception.js';
import { BadRequestException } from '../../src/exceptions/bad-request-exception.js';
import { ConflictException } from '../../src/exceptions/conflict-exception.js';
import { EntityAlreadyExistsException } from '../../src/exceptions/entity-already-exists-exception.js';
import {StudentDTO} from "dwengo-1-common/src/interfaces/student";
import { StudentDTO } from 'dwengo-1-common/src/interfaces/student';
describe('Student controllers', () => {
let req: Partial<Request>;

View file

@ -15,8 +15,7 @@ import {
import { BadRequestException } from '../../src/exceptions/bad-request-exception.js';
import { EntityAlreadyExistsException } from '../../src/exceptions/entity-already-exists-exception.js';
import { getStudentRequestsHandler } from '../../src/controllers/students.js';
import {TeacherDTO} from "dwengo-1-common/src/interfaces/teacher";
import { TeacherDTO } from 'dwengo-1-common/src/interfaces/teacher';
describe('Teacher controllers', () => {
let req: Partial<Request>;

View file

@ -1,4 +1,4 @@
import {StudentDTO} from "./student";
import { StudentDTO } from './student';
export interface ClassJoinRequestDTO {
requester: StudentDTO;

View file

@ -1,3 +1,5 @@
import type {AssignmentDTO} from "dwengo-1-common/src/interfaces/assignment";
import type { AssignmentDTO } from "dwengo-1-common/src/interfaces/assignment";
export interface AssignmentsResponse { assignments: AssignmentDTO[] } // TODO ID
export interface AssignmentsResponse {
assignments: AssignmentDTO[];
} // TODO ID

View file

@ -1,3 +1,5 @@
import type {ClassDTO} from "dwengo-1-common/src/interfaces/class";
import type { ClassDTO } from "dwengo-1-common/src/interfaces/class";
export interface ClassesResponse { classes: ClassDTO[] | string[] }
export interface ClassesResponse {
classes: ClassDTO[] | string[];
}

View file

@ -1,3 +1,5 @@
import type {GroupDTO} from "dwengo-1-common/src/interfaces/group";
import type { GroupDTO } from "dwengo-1-common/src/interfaces/group";
export interface GroupsResponse { groups: GroupDTO[] } // | TODO id
export interface GroupsResponse {
groups: GroupDTO[];
} // | TODO id

View file

@ -1,3 +1,5 @@
import type {QuestionDTO, QuestionId} from "dwengo-1-common/src/interfaces/question";
import type { QuestionDTO, QuestionId } from "dwengo-1-common/src/interfaces/question";
export interface QuestionsResponse { questions: QuestionDTO[] | QuestionId[] }
export interface QuestionsResponse {
questions: QuestionDTO[] | QuestionId[];
}

View file

@ -1,17 +1,24 @@
import { BaseController } from "@/controllers/base-controller.ts";
import type {StudentDTO} from "dwengo-1-common/src/interfaces/student";
import type {ClassesResponse} from "@/controllers/classes.ts";
import type {AssignmentsResponse} from "@/controllers/assignments.ts";
import type {GroupsResponse} from "@/controllers/groups.ts";
import type {SubmissionsResponse} from "@/controllers/submissions.ts";
import type {QuestionsResponse} from "@/controllers/questions.ts";
import type {ClassJoinRequestDTO} from "dwengo-1-common/src/interfaces/class-join-request";
export interface StudentsResponse { students: StudentDTO[] | string[] }
export interface StudentResponse { student: StudentDTO }
export interface JoinRequestsResponse { requests: ClassJoinRequestDTO[] }
export interface JoinRequestResponse { request: ClassJoinRequestDTO }
import type { StudentDTO } from "dwengo-1-common/src/interfaces/student";
import type { ClassesResponse } from "@/controllers/classes.ts";
import type { AssignmentsResponse } from "@/controllers/assignments.ts";
import type { GroupsResponse } from "@/controllers/groups.ts";
import type { SubmissionsResponse } from "@/controllers/submissions.ts";
import type { QuestionsResponse } from "@/controllers/questions.ts";
import type { ClassJoinRequestDTO } from "dwengo-1-common/src/interfaces/class-join-request";
export interface StudentsResponse {
students: StudentDTO[] | string[];
}
export interface StudentResponse {
student: StudentDTO;
}
export interface JoinRequestsResponse {
requests: ClassJoinRequestDTO[];
}
export interface JoinRequestResponse {
request: ClassJoinRequestDTO;
}
export class StudentController extends BaseController {
constructor() {

View file

@ -1,3 +1,5 @@
import {type SubmissionDTO, SubmissionDTOId} from "dwengo-1-common/src/interfaces/submission";
import { type SubmissionDTO, SubmissionDTOId } from "dwengo-1-common/src/interfaces/submission";
export interface SubmissionsResponse { submissions: SubmissionDTO[] | SubmissionDTOId[] }
export interface SubmissionsResponse {
submissions: SubmissionDTO[] | SubmissionDTOId[];
}

View file

@ -1,12 +1,15 @@
import { BaseController } from "@/controllers/base-controller.ts";
import type {JoinRequestResponse, JoinRequestsResponse, StudentsResponse} from "@/controllers/students.ts";
import type {QuestionsResponse} from "@/controllers/questions.ts";
import type {ClassesResponse} from "@/controllers/classes.ts";
import type {TeacherDTO} from "dwengo-1-common/src/interfaces/teacher";
export interface TeachersResponse { teachers: TeacherDTO[] | string[] }
export interface TeacherResponse { teacher: TeacherDTO }
import type { JoinRequestResponse, JoinRequestsResponse, StudentsResponse } from "@/controllers/students.ts";
import type { QuestionsResponse } from "@/controllers/questions.ts";
import type { ClassesResponse } from "@/controllers/classes.ts";
import type { TeacherDTO } from "dwengo-1-common/src/interfaces/teacher";
export interface TeachersResponse {
teachers: TeacherDTO[] | string[];
}
export interface TeacherResponse {
teacher: TeacherDTO;
}
export class TeacherController extends BaseController {
constructor() {
@ -45,8 +48,16 @@ export class TeacherController extends BaseController {
return this.get<JoinRequestsResponse>(`/${username}/joinRequests/${classId}`);
}
async updateStudentJoinRequest(teacherUsername: string, classId: string, studentUsername: string, accepted: boolean): Promise<JoinRequestResponse> {
return this.put<JoinRequestResponse>(`/${teacherUsername}/joinRequests/${classId}/${studentUsername}`, accepted);
async updateStudentJoinRequest(
teacherUsername: string,
classId: string,
studentUsername: string,
accepted: boolean,
): Promise<JoinRequestResponse> {
return this.put<JoinRequestResponse>(
`/${teacherUsername}/joinRequests/${classId}/${studentUsername}`,
accepted,
);
}
// GetInvitations(id: string) {return this.get<{ invitations: string[] }>(`/${id}/invitations`);}

View file

@ -1,5 +1,5 @@
import { BaseController } from "@/controllers/base-controller.ts";
import type {Theme} from "dwengo-1-common/src/interfaces/theme";
import type { Theme } from "dwengo-1-common/src/interfaces/theme";
export class ThemeController extends BaseController {
constructor() {

View file

@ -5,21 +5,21 @@ import {
type UseMutationReturnType,
useQuery,
useQueryClient,
type UseQueryReturnType
type UseQueryReturnType,
} from "@tanstack/vue-query";
import {
type JoinRequestResponse,
type JoinRequestsResponse,
StudentController,
type StudentResponse,
type StudentsResponse
type StudentsResponse,
} from "@/controllers/students.ts";
import type {ClassesResponse} from "@/controllers/classes.ts";
import type {AssignmentsResponse} from "@/controllers/assignments.ts";
import type {GroupsResponse} from "@/controllers/groups.ts";
import type {SubmissionsResponse} from "@/controllers/submissions.ts";
import type {QuestionsResponse} from "@/controllers/questions.ts";
import type {StudentDTO} from "dwengo-1-common/src/interfaces/student";
import type { ClassesResponse } from "@/controllers/classes.ts";
import type { AssignmentsResponse } from "@/controllers/assignments.ts";
import type { GroupsResponse } from "@/controllers/groups.ts";
import type { SubmissionsResponse } from "@/controllers/submissions.ts";
import type { QuestionsResponse } from "@/controllers/questions.ts";
import type { StudentDTO } from "dwengo-1-common/src/interfaces/student";
const studentController = new StudentController();
@ -52,9 +52,7 @@ export function studentJoinRequestQueryKey(username: string, classId: string): [
return ["student-join-request", username, classId];
}
export function useStudentsQuery(
full: MaybeRefOrGetter<boolean> = true
): UseQueryReturnType<StudentsResponse, Error> {
export function useStudentsQuery(full: MaybeRefOrGetter<boolean> = true): UseQueryReturnType<StudentsResponse, Error> {
return useQuery({
queryKey: computed(() => studentsQueryKey(toValue(full))),
queryFn: async () => studentController.getAll(toValue(full)),
@ -62,7 +60,7 @@ export function useStudentsQuery(
}
export function useStudentQuery(
username: MaybeRefOrGetter<string | undefined>
username: MaybeRefOrGetter<string | undefined>,
): UseQueryReturnType<StudentResponse, Error> {
return useQuery({
queryKey: computed(() => studentQueryKey(toValue(username)!)),
@ -73,7 +71,7 @@ export function useStudentQuery(
export function useStudentClassesQuery(
username: MaybeRefOrGetter<string | undefined>,
full: MaybeRefOrGetter<boolean> = true
full: MaybeRefOrGetter<boolean> = true,
): UseQueryReturnType<ClassesResponse, Error> {
return useQuery({
queryKey: computed(() => studentClassesQueryKey(toValue(username)!, toValue(full))),
@ -84,7 +82,7 @@ export function useStudentClassesQuery(
export function useStudentAssignmentsQuery(
username: MaybeRefOrGetter<string | undefined>,
full: MaybeRefOrGetter<boolean> = true
full: MaybeRefOrGetter<boolean> = true,
): UseQueryReturnType<AssignmentsResponse, Error> {
return useQuery({
queryKey: computed(() => studentAssignmentsQueryKey(toValue(username)!, toValue(full))),
@ -95,7 +93,7 @@ export function useStudentAssignmentsQuery(
export function useStudentGroupsQuery(
username: MaybeRefOrGetter<string | undefined>,
full: MaybeRefOrGetter<boolean> = true
full: MaybeRefOrGetter<boolean> = true,
): UseQueryReturnType<GroupsResponse, Error> {
return useQuery({
queryKey: computed(() => studentGroupsQueryKeys(toValue(username)!, toValue(full))),
@ -105,7 +103,7 @@ export function useStudentGroupsQuery(
}
export function useStudentSubmissionsQuery(
username: MaybeRefOrGetter<string | undefined>
username: MaybeRefOrGetter<string | undefined>,
): UseQueryReturnType<SubmissionsResponse, Error> {
return useQuery({
queryKey: computed(() => studentSubmissionsQueryKey(toValue(username)!)),
@ -116,7 +114,7 @@ export function useStudentSubmissionsQuery(
export function useStudentQuestionsQuery(
username: MaybeRefOrGetter<string | undefined>,
full: MaybeRefOrGetter<boolean> = true
full: MaybeRefOrGetter<boolean> = true,
): UseQueryReturnType<QuestionsResponse, Error> {
return useQuery({
queryKey: computed(() => studentQuestionsQueryKey(toValue(username)!, toValue(full))),
@ -126,7 +124,7 @@ export function useStudentQuestionsQuery(
}
export function useStudentJoinRequestsQuery(
username: MaybeRefOrGetter<string | undefined>
username: MaybeRefOrGetter<string | undefined>,
): UseQueryReturnType<JoinRequestsResponse, Error> {
return useQuery({
queryKey: computed(() => studentJoinRequestsQueryKey(toValue(username)!)),
@ -137,7 +135,7 @@ export function useStudentJoinRequestsQuery(
export function useStudentJoinRequestQuery(
username: MaybeRefOrGetter<string | undefined>,
classId: MaybeRefOrGetter<string | undefined>
classId: MaybeRefOrGetter<string | undefined>,
): UseQueryReturnType<JoinRequestResponse, Error> {
return useQuery({
queryKey: computed(() => studentJoinRequestQueryKey(toValue(username)!, toValue(classId)!)),
@ -146,12 +144,7 @@ export function useStudentJoinRequestQuery(
});
}
export function useCreateStudentMutation(): UseMutationReturnType<
StudentResponse,
Error,
StudentDTO,
unknown
> {
export function useCreateStudentMutation(): UseMutationReturnType<StudentResponse, Error, StudentDTO, unknown> {
const queryClient = useQueryClient();
return useMutation({
@ -162,12 +155,7 @@ export function useCreateStudentMutation(): UseMutationReturnType<
});
}
export function useDeleteStudentMutation(): UseMutationReturnType<
StudentResponse,
Error,
string,
unknown
> {
export function useDeleteStudentMutation(): UseMutationReturnType<StudentResponse, Error, string, unknown> {
const queryClient = useQueryClient();
return useMutation({
@ -190,7 +178,9 @@ export function useCreateJoinRequestMutation(): UseMutationReturnType<
return useMutation({
mutationFn: async ({ username, classId }) => studentController.createJoinRequest(username, classId),
onSuccess: async (newJoinRequest) => {
await queryClient.invalidateQueries({ queryKey: studentJoinRequestsQueryKey(newJoinRequest.request.requester) });
await queryClient.invalidateQueries({
queryKey: studentJoinRequestsQueryKey(newJoinRequest.request.requester),
});
},
});
}

View file

@ -1,18 +1,12 @@
import { computed, toValue } from "vue";
import type { MaybeRefOrGetter } from "vue";
import {
useMutation,
useQuery,
useQueryClient,
UseMutationReturnType,
UseQueryReturnType,
} from "@tanstack/vue-query";
import {TeacherController, type TeacherResponse, type TeachersResponse} from "@/controllers/teachers.ts";
import type {ClassesResponse} from "@/controllers/classes.ts";
import type {JoinRequestResponse, JoinRequestsResponse, StudentsResponse} from "@/controllers/students.ts";
import type {QuestionsResponse} from "@/controllers/questions.ts";
import type {TeacherDTO} from "dwengo-1-common/src/interfaces/teacher";
import {studentJoinRequestQueryKey, studentJoinRequestsQueryKey} from "@/queries/students.ts";
import { useMutation, useQuery, useQueryClient, UseMutationReturnType, UseQueryReturnType } from "@tanstack/vue-query";
import { TeacherController, type TeacherResponse, type TeachersResponse } from "@/controllers/teachers.ts";
import type { ClassesResponse } from "@/controllers/classes.ts";
import type { JoinRequestResponse, JoinRequestsResponse, StudentsResponse } from "@/controllers/students.ts";
import type { QuestionsResponse } from "@/controllers/questions.ts";
import type { TeacherDTO } from "dwengo-1-common/src/interfaces/teacher";
import { studentJoinRequestQueryKey, studentJoinRequestsQueryKey } from "@/queries/students.ts";
const teacherController = new TeacherController();
@ -37,10 +31,7 @@ function teacherQuestionsQueryKey(username: string, full: boolean): [string, str
return ["teacher-questions", username, full];
}
export function useTeachersQuery(
full: MaybeRefOrGetter<boolean> = false
): UseQueryReturnType<TeachersResponse, Error> {
export function useTeachersQuery(full: MaybeRefOrGetter<boolean> = false): UseQueryReturnType<TeachersResponse, Error> {
return useQuery({
queryKey: computed(() => teachersQueryKey(toValue(full))),
queryFn: async () => teacherController.getAll(toValue(full)),
@ -48,7 +39,7 @@ export function useTeachersQuery(
}
export function useTeacherQuery(
username: MaybeRefOrGetter<string | undefined>
username: MaybeRefOrGetter<string | undefined>,
): UseQueryReturnType<TeacherResponse, Error> {
return useQuery({
queryKey: computed(() => teacherQueryKey(toValue(username)!)),
@ -59,7 +50,7 @@ export function useTeacherQuery(
export function useTeacherClassesQuery(
username: MaybeRefOrGetter<string | undefined>,
full: MaybeRefOrGetter<boolean> = false
full: MaybeRefOrGetter<boolean> = false,
): UseQueryReturnType<ClassesResponse, Error> {
return useQuery({
queryKey: computed(() => teacherClassesQueryKey(toValue(username)!, toValue(full))),
@ -70,7 +61,7 @@ export function useTeacherClassesQuery(
export function useTeacherStudentsQuery(
username: MaybeRefOrGetter<string | undefined>,
full: MaybeRefOrGetter<boolean> = false
full: MaybeRefOrGetter<boolean> = false,
): UseQueryReturnType<StudentsResponse, Error> {
return useQuery({
queryKey: computed(() => teacherStudentsQueryKey(toValue(username)!, toValue(full))),
@ -81,7 +72,7 @@ export function useTeacherStudentsQuery(
export function useTeacherQuestionsQuery(
username: MaybeRefOrGetter<string | undefined>,
full: MaybeRefOrGetter<boolean> = false
full: MaybeRefOrGetter<boolean> = false,
): UseQueryReturnType<QuestionsResponse, Error> {
return useQuery({
queryKey: computed(() => teacherQuestionsQueryKey(toValue(username)!, toValue(full))),
@ -92,7 +83,7 @@ export function useTeacherQuestionsQuery(
export function useTeacherJoinRequestsQuery(
username: MaybeRefOrGetter<string | undefined>,
classId: MaybeRefOrGetter<string | undefined>
classId: MaybeRefOrGetter<string | undefined>,
): UseQueryReturnType<JoinRequestsResponse, Error> {
return useQuery({
queryKey: computed(() => JOIN_REQUESTS_QUERY_KEY(toValue(username)!, toValue(classId)!)),
@ -101,12 +92,7 @@ export function useTeacherJoinRequestsQuery(
});
}
export function useCreateTeacherMutation(): UseMutationReturnType<
TeacherResponse,
Error,
TeacherDTO,
unknown
> {
export function useCreateTeacherMutation(): UseMutationReturnType<TeacherResponse, Error, TeacherDTO, unknown> {
const queryClient = useQueryClient();
return useMutation({
@ -117,12 +103,7 @@ export function useCreateTeacherMutation(): UseMutationReturnType<
});
}
export function useDeleteTeacherMutation(): UseMutationReturnType<
TeacherResponse,
Error,
string,
unknown
> {
export function useDeleteTeacherMutation(): UseMutationReturnType<TeacherResponse, Error, string, unknown> {
const queryClient = useQueryClient();
return useMutation({

View file

@ -1,7 +1,7 @@
import {useQuery, type UseQueryReturnType} from "@tanstack/vue-query";
import { useQuery, type UseQueryReturnType } from "@tanstack/vue-query";
import { type MaybeRefOrGetter, toValue } from "vue";
import { ThemeController } from "@/controllers/themes.ts";
import type {Theme} from "dwengo-1-common/src/interfaces/theme";
import type { Theme } from "dwengo-1-common/src/interfaces/theme";
const themeController = new ThemeController();
@ -16,7 +16,9 @@ export function useThemeQuery(language: MaybeRefOrGetter<string | undefined>): U
});
}
export function useThemeHruidsQuery(themeKey: MaybeRefOrGetter<string | undefined>): UseQueryReturnType<string[], Error> {
export function useThemeHruidsQuery(
themeKey: MaybeRefOrGetter<string | undefined>,
): UseQueryReturnType<string[], Error> {
return useQuery({
queryKey: ["theme-hruids", themeKey],
queryFn: async () => themeController.getHruidsByKey(toValue(themeKey)!),

View file

@ -120,6 +120,6 @@
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true,
/* Skip type checking all .d.ts files. */
"resolveJsonModule": true,
"resolveJsonModule": true
}
}