Skip to content
8 changes: 4 additions & 4 deletions database-diagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ erDiagram
string contactPersonEmail
boolean isInternational
}
SCHOOL_SEMESTER_ASSISTANT{
SCHOOL_ASSIGNMENTS{
int school FK
int semester FK
int user FK
Expand All @@ -122,9 +122,9 @@ erDiagram
SEMESTER }|--|| VEKTOR_DEPARTMENT : department
SCHOOL }|--|| VEKTOR_DEPARTMENT : department
SEMESTER }o--|| ASSISTENT_APPLICATION : admissionPeriod
SCHOOL_SEMESTER_ASSISTANT ||--o{ SCHOOL : schoolSemesterAssistant
SCHOOL_SEMESTER_ASSISTANT ||--o{ SEMESTER : schoolSemesterAssistant
SCHOOL_SEMESTER_ASSISTANT ||--o{ USER : shcoolSemesterAssistant
SCHOOL_ASSIGNMENTS ||--o{ SCHOOL : schoolAssignments
SCHOOL_ASSIGNMENTS ||--o{ SEMESTER : schoolAssignments
SCHOOL_ASSIGNMENTS ||--o{ USER : schoolAssignments
TEAM_SEMESTER_USER ||--o{ TEAM : teamSemesterUser
TEAM_SEMESTER_USER ||--o{ SEMESTER : teamSemesterUser
TEAM_SEMESTER_USER ||--o{ USER : teamSemesterUser
Expand Down
37 changes: 26 additions & 11 deletions db/tables/applications.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { mainSchema } from "@/db/tables/schema";
import { relations } from "drizzle-orm";
import { date, integer, serial, text } from "drizzle-orm/pg-core";
import {
boolean,
date,
integer,
primaryKey,
serial,
text,
} from "drizzle-orm/pg-core";

import { teamsTable } from "@/db/tables/teams";
import { fieldsOfStudyTable } from "./fields-of-study";
Expand Down Expand Up @@ -42,16 +49,24 @@ export const applicationsRelations = relations(
}),
);

export const teamApplicationsTable = mainSchema.table("teamApplications", {
id: integer("id")
.primaryKey()
.references(() => applicationsTable.id),
teamId: integer("teamId")
.notNull()
.references(() => teamsTable.id),
motivationText: text("motivationText").notNull(),
biography: text("biography").notNull(),
});
export const teamApplicationsTable = mainSchema.table(
"teamApplications",
{
id: serial("id"),
applicationParentId: integer("applicationParentId").references(
() => applicationsTable.id,
),
teamId: integer("teamId")
.notNull()
.references(() => teamsTable.id),
motivationText: text("motivationText"),
biography: text("biography"),
teamInterest: boolean("teamInterest").notNull(),
},
(table) => ({
primaryKey: primaryKey({ columns: [table.id, table.applicationParentId] }),
}),
);

export const teamApplicationsRelations = relations(
teamApplicationsTable,
Expand Down
42 changes: 42 additions & 0 deletions db/tables/school-assignments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { relations } from "drizzle-orm";
import { integer, primaryKey } from "drizzle-orm/pg-core";
import { mainSchema } from "./schema";
import { schoolsTable } from "./schools";
import { semestersTable } from "./semesters";
import { assistantUsersTable } from "./users";

export const schoolAssignmentsTable = mainSchema.table(
"schoolAssignments",
{
schoolId: integer("schoolId").references(() => schoolsTable.id),
semesterId: integer("semesterId")
.references(() => semestersTable.id)
.notNull(),
assistantUserId: integer("userId")
.references(() => assistantUsersTable.id)
.notNull(),
},
(table) => ({
pk: primaryKey({
columns: [table.semesterId, table.assistantUserId],
}),
}),
);

export const schoolAssignmentsRelations = relations(
schoolAssignmentsTable,
({ one }) => ({
school: one(schoolsTable, {
fields: [schoolAssignmentsTable.schoolId],
references: [schoolsTable.id],
}),
semester: one(semestersTable, {
fields: [schoolAssignmentsTable.semesterId],
references: [semestersTable.id],
}),
assistantUser: one(assistantUsersTable, {
fields: [schoolAssignmentsTable.assistantUserId],
references: [assistantUsersTable.id],
}),
}),
);
33 changes: 0 additions & 33 deletions db/tables/school-semester-assistant.ts

This file was deleted.

4 changes: 2 additions & 2 deletions db/tables/schools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { relations } from "drizzle-orm";
import { boolean, integer, serial, text } from "drizzle-orm/pg-core";
import { departmentsTable } from "./departments";
import { mainSchema } from "./schema";
import { schoolSemesterAssistantsTable } from "./school-semester-assistant";
import { schoolAssignmentsTable } from "./school-assignments";

export const schoolsTable = mainSchema.table("schools", {
id: serial("id").primaryKey(),
Expand All @@ -19,5 +19,5 @@ export const schoolsRelations = relations(schoolsTable, ({ one, many }) => ({
fields: [schoolsTable.departmentId],
references: [departmentsTable.id],
}),
semesterAssistants: many(schoolSemesterAssistantsTable),
semesterAssistants: many(schoolAssignmentsTable),
}));
4 changes: 2 additions & 2 deletions db/tables/semesters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from "drizzle-orm/pg-core";
import { departmentsTable } from "./departments";
import { mainSchema } from "./schema";
import { schoolSemesterAssistantsTable } from "./school-semester-assistant";
import { schoolAssignmentsTable } from "./school-assignments";
import { teamSemesterUsersTable } from "./team-semester-user";

export const semestersTable = mainSchema.table("semesters", {
Expand Down Expand Up @@ -41,7 +41,7 @@ export const semestersRelations = relations(
fields: [semestersTable.id],
references: [semestersTable.lastSemesterId],
}),
schoolAssistants: many(schoolSemesterAssistantsTable),
schoolAssistants: many(schoolAssignmentsTable),
teamUsers: many(teamSemesterUsersTable),
}),
);
4 changes: 2 additions & 2 deletions db/tables/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { integer, serial, text } from "drizzle-orm/pg-core";
import { expensesTable } from "@/db/tables/expenses";
import { fieldsOfStudyTable } from "@/db/tables/fields-of-study";
import { teamsTable } from "@/db/tables/teams";
import { schoolSemesterAssistantsTable } from "./school-semester-assistant";
import { schoolAssignmentsTable } from "./school-assignments";
import { teamSemesterUsersTable } from "./team-semester-user";

export const usersTable = mainSchema.table("users", {
Expand Down Expand Up @@ -65,6 +65,6 @@ export const assistantUsersRelation = relations(
fields: [assistantUsersTable.id],
references: [usersTable.id],
}),
schoolSemesters: many(schoolSemesterAssistantsTable),
schoolSemesters: many(schoolAssignmentsTable),
}),
);
57 changes: 49 additions & 8 deletions src/db-access/applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ import {
applicationsTable,
teamApplicationsTable,
} from "@/db/tables/applications";
import type { OrmResult } from "@/src/error/orm-error";
import { type OrmResult, ormError } from "@/src/error/orm-error";
import type {
NewApplication,
NewTeamApplication,
NewTeamInterestApplication,
} from "@/src/request-handling/applications";
import type { QueryParameters } from "@/src/request-handling/common";
import type {
ApplicationKey,
TeamApplication,
TeamKey,
} from "@/src/response-handling/applications";
import { eq, inArray } from "drizzle-orm";
import { and, eq, inArray } from "drizzle-orm";
import { newDatabaseTransaction } from "./common";

export const selectTeamApplications = async (
Expand All @@ -24,6 +25,7 @@ export const selectTeamApplications = async (
const teamApplications = await tx
.select({
id: applicationsTable.id,
applicationParentId: teamApplicationsTable.applicationParentId,
teamId: teamApplicationsTable.teamId,
firstName: applicationsTable.firstName,
lastName: applicationsTable.lastName,
Expand All @@ -34,12 +36,13 @@ export const selectTeamApplications = async (
phonenumber: applicationsTable.phonenumber,
motivationText: teamApplicationsTable.motivationText,
biography: teamApplicationsTable.biography,
teamInterest: teamApplicationsTable.teamInterest,
submitDate: applicationsTable.submitDate,
})
.from(teamApplicationsTable)
.innerJoin(
applicationsTable,
eq(teamApplicationsTable.id, applicationsTable.id),
eq(teamApplicationsTable.applicationParentId, applicationsTable.id),
)
.limit(parameters.limit)
.offset(parameters.offset);
Expand All @@ -56,6 +59,7 @@ export const selectTeamApplicationsByTeamId = async (
const selectResult = await tx
.select({
id: applicationsTable.id,
applicationParentId: teamApplicationsTable.applicationParentId,
teamId: teamApplicationsTable.teamId,
firstName: applicationsTable.firstName,
lastName: applicationsTable.lastName,
Expand All @@ -66,13 +70,14 @@ export const selectTeamApplicationsByTeamId = async (
phonenumber: applicationsTable.phonenumber,
motivationText: teamApplicationsTable.motivationText,
biography: teamApplicationsTable.biography,
teamInterest: teamApplicationsTable.teamInterest,
submitDate: applicationsTable.submitDate,
})
.from(teamApplicationsTable)
.where(inArray(teamApplicationsTable.id, teamId))
.innerJoin(
applicationsTable,
eq(teamApplicationsTable.id, applicationsTable.id),
eq(teamApplicationsTable.applicationParentId, applicationsTable.id),
)
.limit(parameters.limit)
.offset(parameters.offset);
Expand All @@ -83,11 +88,13 @@ export const selectTeamApplicationsByTeamId = async (

export const selectTeamApplicationsById = async (
applicationIds: ApplicationKey[],
teamApplicationIds: number[],
): Promise<OrmResult<TeamApplication[]>> => {
return await newDatabaseTransaction(database, async (tx) => {
const selectResult = await tx
.select({
id: applicationsTable.id,
id: teamApplicationsTable.id,
applicationParentId: teamApplicationsTable.applicationParentId,
teamId: teamApplicationsTable.teamId,
firstName: applicationsTable.firstName,
lastName: applicationsTable.lastName,
Expand All @@ -98,13 +105,19 @@ export const selectTeamApplicationsById = async (
phonenumber: applicationsTable.phonenumber,
motivationText: teamApplicationsTable.motivationText,
biography: teamApplicationsTable.biography,
teamInterest: teamApplicationsTable.teamInterest,
submitDate: applicationsTable.submitDate,
})
.from(teamApplicationsTable)
.where(inArray(teamApplicationsTable.id, applicationIds))
.where(
and(
inArray(teamApplicationsTable.applicationParentId, applicationIds),
inArray(teamApplicationsTable.id, teamApplicationIds),
),
)
.innerJoin(
applicationsTable,
eq(teamApplicationsTable.id, applicationsTable.id),
eq(teamApplicationsTable.applicationParentId, applicationsTable.id),
);

return selectResult;
Expand Down Expand Up @@ -132,10 +145,11 @@ export async function insertTeamApplication(
const newTeamApplicationResult = await tx
.insert(teamApplicationsTable)
.values({
id: newApplicationId,
applicationParentId: newApplicationId,
teamId: teamApplication.teamId,
motivationText: teamApplication.motivationText,
biography: teamApplication.biography,
teamInterest: teamApplication.teamInterest,
})
.returning();

Expand All @@ -145,3 +159,30 @@ export async function insertTeamApplication(
};
});
}

export async function createTeamApplicationFromAssistantApplication(
teamInterestApplication: NewTeamInterestApplication,
): Promise<OrmResult<TeamApplication[]>> {
return await newDatabaseTransaction(database, async (tx) => {
const newTeamApplicationResult = await tx
.insert(teamApplicationsTable)
.values({
applicationParentId: teamInterestApplication.applicationParentId,
teamId: teamInterestApplication.teamId,
motivationText: teamInterestApplication.motivationText,
biography: teamInterestApplication.biography,
teamInterest: true,
})
.returning();

const teamApplicationResult = await selectTeamApplicationsById(
[teamInterestApplication.applicationParentId],
[newTeamApplicationResult[0].id],
);
if (!teamApplicationResult.success) {
throw ormError("Transaction failed", teamApplicationResult.error);
}

return teamApplicationResult.data;
});
}
8 changes: 8 additions & 0 deletions src/request-handling/applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,16 @@ export const assistantApplicationToInsertParser = assistantApplicationParser
.readonly(),
);

export const teamInterestParser = z.object({
applicationParentId: serialIdParser,
teamId: teamApplicationParser.shape.teamId,
biography: teamApplicationParser.shape.biography.nullable(),
motivationText: teamApplicationParser.shape.motivationText.nullable(),
});

export type NewApplication = z.infer<typeof applicationToInsertParser>;
export type NewTeamApplication = z.infer<typeof teamApplicationToInsertParser>;
export type NewAssistantApplication = z.infer<
typeof assistantApplicationToInsertParser
>;
export type NewTeamInterestApplication = z.infer<typeof teamInterestParser>;
5 changes: 4 additions & 1 deletion src/response-handling/applications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ export const teamApplicationSelectSchema = createSelectSchema(
.readonly();

export type TeamApplication = z.infer<typeof teamApplicationSelectSchema>;
export type TeamApplicationKey = TeamApplication["id"];
export type TeamApplicationKey = {
id: TeamApplication["id"];
applicationParentId: TeamApplication["applicationParentId"];
};
export type TeamKey = TeamApplication["teamId"];
Loading