Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

62 impl post apis for organization team submodules #63

Merged
merged 5 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example 쭉 만든건 예시용으로 이번에 만든건가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 매번 복사하기도 귀찮고 템플릿으로 만들면 좋을 것 같아서요

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Controller } from "@nestjs/common";

import { ExampleService } from "../service/example.service";

@Controller()
export class ExampleController {
constructor(private readonly exampleService: ExampleService) {}
}
14 changes: 14 additions & 0 deletions packages/api/src/feature/_example/example.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Module } from "@nestjs/common";

import { DrizzleModule } from "src/drizzle/drizzle.module";
import { ExampleService } from "./service/example.service";
import { ExampleController } from "./controller/example.controller";
import { ExampleRepository } from "./repository/example.repository";

@Module({
imports: [DrizzleModule],
controllers: [ExampleController],
providers: [ExampleService, ExampleRepository],
exports: [],
})
export class ExampleModule {}
11 changes: 11 additions & 0 deletions packages/api/src/feature/_example/repository/example.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Injectable, Inject } from "@nestjs/common";

import { MySql2Database } from "drizzle-orm/mysql2";
import { DrizzleAsyncProvider } from "src/drizzle/drizzle.provider";

@Injectable()
export class ExampleRepository {
constructor(
@Inject(DrizzleAsyncProvider) private readonly db: MySql2Database,
) {}
}
7 changes: 7 additions & 0 deletions packages/api/src/feature/_example/service/example.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Injectable } from "@nestjs/common";
import { ExampleRepository } from "../repository/example.repository";

@Injectable()
export class ExampleService {
constructor(private readonly exampleRepository: ExampleRepository) {}
}
12 changes: 10 additions & 2 deletions packages/api/src/feature/organization/organization.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Module } from "@nestjs/common";
import { Module, forwardRef } from "@nestjs/common";

import { DrizzleModule } from "src/drizzle/drizzle.module";
import { SemesterModule } from "src/feature/semester/semester.module";
Expand All @@ -7,9 +7,17 @@ import { OrganizationService } from "./service/organization.service";
import { OrganizationController } from "./controller/organization.controller";
import { OrganizationPublicService } from "./service/organization.public.service";
import { OrganizationRepository } from "./repository/organization.repository";
/* eslint-disable import/no-cycle */
import { TeamModule } from "./team/team.module";
/* eslint-disable import/no-cycle */
Comment on lines +10 to +12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이게 위아랫줄이 다 필요했던가..?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 순환참조를 막으려고 일단 한줄에만 걸었어요


@Module({
imports: [DrizzleModule, SemesterModule, UserModule],
imports: [
DrizzleModule,
SemesterModule,
UserModule,
forwardRef(() => TeamModule),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 이거 하마랑 어제 논의했던 내용인데 알아서 잘 썼군
혹시 모듈 설계 순환참조 생겨도 이렇게 한 이유 있나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어쨌든 organization 하위 모듈에서 상위모듈 꺼가 필요해서 발생하는 일이라 순환참조해도 괜찮지 않을까 싶었슴다

],
controllers: [OrganizationController],
providers: [
OrganizationService,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Injectable, Inject } from "@nestjs/common";
import logger from "@sparcs-students/api/common/util/logger";

import {
ApiOrg002RequestBody,
Expand All @@ -23,8 +22,6 @@ import {
OrganizationPresidentT,
UserT,
UserStudentT,
TeamT,
Team,
OrganizationMember,
OrganizationManager,
OrganizationMemberT,
Expand Down Expand Up @@ -122,11 +119,6 @@ export class OrganizationRepository {
}));
}

async getTeamById(id: number): Promise<TeamT[]> {
const res = await this.db.select().from(Team).where(eq(Team.id, id));
return res;
}

async ckOrganizationBeforeCreate(
body: ApiOrg002RequestBody,
): Promise<number> {
Expand Down Expand Up @@ -274,7 +266,6 @@ export class OrganizationRepository {
)
.orderBy(desc(OrganizationMember.createdAt))
.limit(1);
logger.info(res);
if (res.length === 0) {
return 0;
}
Expand Down Expand Up @@ -347,4 +338,51 @@ export class OrganizationRepository {
const res = await this.ckOrganizationManagerBeforeCreate(body);
return res;
}

async selectOrganizationMember(target: Partial<OrganizationMemberT>) {
const { id, userId, startTerm, endTerm, organizationId } = target;
let query = this.db.select().from(OrganizationMember).$dynamic();

const whereConditions = [];

if (id) {
whereConditions.push(eq(OrganizationMember.id, id));
}

if (userId) {
whereConditions.push(eq(OrganizationMember.userId, userId));
}

if (startTerm) {
whereConditions.push(
or(
gte(OrganizationMember.endTerm, startTerm),
isNull(OrganizationMember.endTerm),
),
);
}

if (endTerm) {
whereConditions.push(lte(OrganizationMember.startTerm, endTerm));
}

if (organizationId) {
whereConditions.push(
eq(OrganizationMember.organizationId, organizationId),
);
}

// 삭제된 항목 제외
whereConditions.push(isNull(OrganizationMember.deletedAt));

// 조건이 하나라도 있으면 AND로 묶어서 처리
if (whereConditions.length > 0) {
query = query.where(and(...whereConditions));
}

// 쿼리 실행
const res = await query.execute();

return res;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
Injectable,
NotFoundException,
} from "@nestjs/common";
import { OrganizationT, TeamT } from "src/drizzle/schema";
import { OrganizationMemberT, OrganizationT } from "src/drizzle/schema";
import { SemesterPublicService } from "src/feature/semester/semester.public.service";

import {
Expand Down Expand Up @@ -79,20 +79,52 @@ export class OrganizationPublicService {
}

/**
* @param teamId
* @returns TeamT id에 해당하는 TeamT 객체를 리턴합니다.
* @description 해당 id의 Team이 없으면 404 exception을 throw 합니다.
* @param userId, organizationId, startTerm, endTerm
* @returns TeamMemeberT 해당 학기 해당 단체에 해당하는 TeamMemberT 객체를 리턴합니다.
* @description 해당 시기에 해당하는 OrganizationMember가 없으면 404 exception을 throw 합니다.
*/
async getTeamById(teamId: number): Promise<TeamT> {
const res = await this.organizationRepository.getTeamById(teamId);
async getOrganizationMemberByUserAndOrgAndDate(
userId: number,
organizationId: number,
startTerm: Date,
endTerm: Date,
): Promise<OrganizationMemberT> {
const res = await this.organizationRepository.selectOrganizationMember({
userId,
startTerm,
endTerm,
organizationId,
});
if (res.length === 0) {
throw new NotFoundException(`Team with ID ${teamId} not found.`);
throw new NotFoundException(
`OrganizationMember with userId ${userId} not found.`,
);
} else if (res.length > 1) {
throw new HttpException(
`Unreachable: Team with ID ${teamId} has multiple records.`,
`Unreachable: OrganizationMember with userId ${userId} has multiple records.`,
HttpStatus.INTERNAL_SERVER_ERROR,
);
}
return res[0];
}

/**
* @param userId, organizationId, semesterId
* @returns TeamMemeberT 해당 학기 해당 단체에 해당하는 TeamMemberT 객체를 리턴합니다.
* @description 해당 시기에 해당하는 OrganizationMember가 없으면 404 exception을 throw 합니다.
*/
async getOrganizationMemberByUserAndOrgAndSemester(
userId: number,
semesterId: number,
organizationId: number,
): Promise<OrganizationMemberT> {
const { startTerm, endTerm } =
await this.semesterPublicService.getSemesterById(semesterId);
return this.getOrganizationMemberByUserAndOrgAndDate(
userId,
organizationId,
startTerm,
endTerm,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Body, Controller, Post, UsePipes } from "@nestjs/common";
import {
ApiOrg007RequestBody,
ApiOrg007RequestUrl,
ApiOrg007ResponseCreated,
ApiOrg008RequestBody,
ApiOrg008RequestUrl,
ApiOrg008ResponseCreated,
ApiOrg009RequestBody,
ApiOrg009RequestUrl,
ApiOrg009ResponseCreated,
apiOrg007,
apiOrg008,
apiOrg009,
Comment on lines +3 to +14
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 확실히 깔끔하다

} from "@sparcs-students/interface/api/organization/index";
import { ZodPipe } from "@sparcs-students/api/common/pipes/zod-pipe";

import { TeamService } from "../service/team.service";

@Controller()
export class TeamController {
constructor(private readonly teamService: TeamService) {}

@Post(ApiOrg007RequestUrl)
@UsePipes(new ZodPipe(apiOrg007))
async postTeam(
@Body() body: ApiOrg007RequestBody,
): Promise<ApiOrg007ResponseCreated> {
return this.teamService.postTeam(body);
}

@Post(ApiOrg008RequestUrl)
@UsePipes(new ZodPipe(apiOrg008))
async postTeamMember(
@Body() body: ApiOrg008RequestBody,
): Promise<ApiOrg008ResponseCreated> {
return this.teamService.postTeamMember(body);
}

@Post(ApiOrg009RequestUrl)
@UsePipes(new ZodPipe(apiOrg009))
async postTeamLeader(
@Body() body: ApiOrg009RequestBody,
): Promise<ApiOrg009ResponseCreated> {
return this.teamService.postTeamLeader(body);
}
}
Loading