Skip to content

Commit 217ceab

Browse files
authored
feat: preregistration api (#89)
* pre registration api를 구현했습니다. * pre_registration 테이블이 추가가 안되어있어 마이그레이션 파일을 추가했습니다.
1 parent aa96a4b commit 217ceab

9 files changed

Lines changed: 269 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .views import v3_router as router
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from wacruit.src.apps.common.exceptions import WacruitException
2+
3+
4+
class PreRegistNotActiveException(WacruitException):
5+
def __init__(self):
6+
super().__init__(status_code=404, detail="활성화된 사전 알림이 존재하지 않습니다.")
7+
8+
9+
class PreRegistNotExistException(WacruitException):
10+
def __init__(self):
11+
super().__init__(status_code=404, detail="해당하는 사전 알림이 존재하지 않습니다.")
12+
13+
14+
class PreRegistAlreadyExistException(WacruitException):
15+
def __init__(self):
16+
super().__init__(status_code=409, detail="활성화된 사전 알림이 이미 존재합니다.")
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from fastapi import Depends
2+
from sqlalchemy import delete
3+
from sqlalchemy import select
4+
from sqlalchemy import true
5+
from sqlalchemy.orm import Session
6+
7+
from wacruit.src.apps.pre_registration.models import PreRegistration
8+
from wacruit.src.database.connection import get_db_session
9+
from wacruit.src.database.connection import Transaction
10+
11+
12+
class PreRegistrationRepository:
13+
def __init__(
14+
self,
15+
session: Session = Depends(get_db_session),
16+
transaction: Transaction = Depends(),
17+
) -> None:
18+
self.session = session
19+
self.transaction = transaction
20+
21+
def get_pre_registration_by_id(
22+
self, pre_registration_id: int
23+
) -> PreRegistration | None:
24+
query = select(PreRegistration).where(PreRegistration.id == pre_registration_id)
25+
return self.session.execute(query).scalar_one_or_none()
26+
27+
def get_active_pre_registration(self) -> PreRegistration | None:
28+
query = select(PreRegistration).where(PreRegistration.is_active == true())
29+
return self.session.execute(query).scalar_one_or_none()
30+
31+
def get_pre_registration(self) -> list[PreRegistration]:
32+
return list(self.session.execute(select(PreRegistration)).scalars())
33+
34+
def create_pre_registration(
35+
self, pre_registration: PreRegistration
36+
) -> PreRegistration:
37+
with self.transaction:
38+
self.session.add(pre_registration)
39+
return pre_registration
40+
41+
def update_pre_registration(
42+
self, pre_registration: PreRegistration
43+
) -> PreRegistration:
44+
with self.transaction:
45+
self.session.merge(pre_registration)
46+
return pre_registration
47+
48+
def delete_pre_registration(self, pre_registration_id: int) -> None:
49+
self.session.execute(
50+
delete(PreRegistration).where(PreRegistration.id == pre_registration_id)
51+
)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from pydantic import BaseModel
2+
3+
4+
class CreatePreRegistrationRequest(BaseModel):
5+
url: str
6+
generation: str
7+
is_active: bool
8+
9+
10+
class UpdatePreRegistrationRequest(BaseModel):
11+
url: str | None = None
12+
generation: str | None = None
13+
is_active: bool | None = None
14+
15+
16+
class PreRegistrationResponse(BaseModel):
17+
id: int
18+
url: str
19+
generation: str
20+
is_active: bool
21+
22+
class Config:
23+
orm_mode = True
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from typing import Annotated
2+
3+
from fastapi import Depends
4+
5+
from wacruit.src.apps.pre_registration.exceptions import PreRegistAlreadyExistException
6+
from wacruit.src.apps.pre_registration.exceptions import PreRegistNotActiveException
7+
from wacruit.src.apps.pre_registration.exceptions import PreRegistNotExistException
8+
from wacruit.src.apps.pre_registration.models import PreRegistration
9+
from wacruit.src.apps.pre_registration.repositories import PreRegistrationRepository
10+
from wacruit.src.apps.pre_registration.schemas import CreatePreRegistrationRequest
11+
from wacruit.src.apps.pre_registration.schemas import UpdatePreRegistrationRequest
12+
13+
14+
class PreRegistrationService:
15+
def __init__(
16+
self,
17+
pre_registration_repository: Annotated[PreRegistrationRepository, Depends()],
18+
):
19+
self.pre_registration_repository = pre_registration_repository
20+
21+
def check_active_pre_registration(self) -> bool:
22+
pre_registration = (
23+
self.pre_registration_repository.get_active_pre_registration()
24+
)
25+
if pre_registration is None:
26+
return False
27+
return True
28+
29+
def get_active_pre_registration(self) -> PreRegistration:
30+
pre_registration = (
31+
self.pre_registration_repository.get_active_pre_registration()
32+
)
33+
if pre_registration is None:
34+
raise PreRegistNotActiveException
35+
return pre_registration
36+
37+
def get_pre_registration(self) -> list[PreRegistration]:
38+
pre_registration_list = self.pre_registration_repository.get_pre_registration()
39+
return pre_registration_list
40+
41+
def create_pre_registration(
42+
self, req: CreatePreRegistrationRequest
43+
) -> PreRegistration:
44+
if req.is_active and (self.check_active_pre_registration()):
45+
raise PreRegistAlreadyExistException
46+
to_create = PreRegistration(
47+
url=req.url, generation=req.generation, is_active=req.is_active
48+
)
49+
pre_registration = self.pre_registration_repository.create_pre_registration(
50+
to_create
51+
)
52+
return pre_registration
53+
54+
def update_pre_registration(
55+
self, pre_registration_id: int, req: UpdatePreRegistrationRequest
56+
) -> PreRegistration:
57+
pre_registration = self.pre_registration_repository.get_pre_registration_by_id(
58+
pre_registration_id
59+
)
60+
if pre_registration is None:
61+
raise PreRegistNotExistException
62+
if req.is_active and (self.check_active_pre_registration()):
63+
raise PreRegistAlreadyExistException
64+
65+
for key, value in req.dict(exclude_none=True).items():
66+
setattr(pre_registration, key, value)
67+
return self.pre_registration_repository.update_pre_registration(
68+
pre_registration
69+
)
70+
71+
def delete_pre_registration(self, pre_registration_id: int) -> None:
72+
pre_registration = self.pre_registration_repository.get_pre_registration_by_id(
73+
pre_registration_id
74+
)
75+
if pre_registration is None:
76+
raise PreRegistNotExistException
77+
self.pre_registration_repository.delete_pre_registration(pre_registration_id)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from http import HTTPStatus
2+
from typing import Annotated
3+
4+
from fastapi import APIRouter
5+
from fastapi import Depends
6+
7+
from wacruit.src.apps.common.schemas import ListResponse
8+
from wacruit.src.apps.pre_registration.models import PreRegistration
9+
from wacruit.src.apps.pre_registration.schemas import CreatePreRegistrationRequest
10+
from wacruit.src.apps.pre_registration.schemas import PreRegistrationResponse
11+
from wacruit.src.apps.pre_registration.schemas import UpdatePreRegistrationRequest
12+
from wacruit.src.apps.pre_registration.services import PreRegistrationService
13+
from wacruit.src.apps.user.dependencies import AdminUser
14+
15+
v3_router = APIRouter(prefix="/v3/pre-registration", tags=["preregistration"])
16+
17+
18+
@v3_router.get("/active", status_code=HTTPStatus.OK)
19+
def get_active_pre_registration(
20+
pre_registration_service: Annotated[PreRegistrationService, Depends()]
21+
) -> PreRegistrationResponse:
22+
pre_registration = pre_registration_service.get_active_pre_registration()
23+
return PreRegistrationResponse.from_orm(pre_registration)
24+
25+
26+
@v3_router.get("", status_code=HTTPStatus.OK)
27+
def get_pre_registration(
28+
admin_user: AdminUser,
29+
pre_registration_service: Annotated[PreRegistrationService, Depends()],
30+
) -> ListResponse[PreRegistrationResponse]:
31+
pre_registration_list = pre_registration_service.get_pre_registration()
32+
return ListResponse(
33+
items=[PreRegistrationResponse.from_orm(item) for item in pre_registration_list]
34+
)
35+
36+
37+
@v3_router.post("", status_code=HTTPStatus.CREATED)
38+
def create_pre_registration(
39+
admin_user: AdminUser,
40+
request: CreatePreRegistrationRequest,
41+
pre_registration_service: Annotated[PreRegistrationService, Depends()],
42+
) -> PreRegistrationResponse:
43+
res = pre_registration_service.create_pre_registration(request)
44+
return PreRegistrationResponse.from_orm(res)
45+
46+
47+
@v3_router.patch("/{pre_registration_id}", status_code=HTTPStatus.OK)
48+
def update_pre_registration(
49+
admin_user: AdminUser,
50+
request: UpdatePreRegistrationRequest,
51+
pre_registration_id: int,
52+
pre_registration_service: Annotated[PreRegistrationService, Depends()],
53+
) -> PreRegistrationResponse:
54+
res = pre_registration_service.update_pre_registration(pre_registration_id, request)
55+
return PreRegistrationResponse.from_orm(res)
56+
57+
58+
@v3_router.delete("/{pre_registration_id}", status_code=HTTPStatus.NO_CONTENT)
59+
def delete_pre_registration(
60+
admin_user: AdminUser,
61+
pre_registration_id: int,
62+
pre_registration_service: Annotated[PreRegistrationService, Depends()],
63+
) -> None:
64+
pre_registration_service.delete_pre_registration(pre_registration_id)

wacruit/src/apps/router.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from wacruit.src.apps import history
77
from wacruit.src.apps import member
88
from wacruit.src.apps import portfolio
9+
from wacruit.src.apps import pre_registration
910
from wacruit.src.apps import problem
1011
from wacruit.src.apps import project
1112
from wacruit.src.apps import recruiting
@@ -35,3 +36,4 @@
3536
api_router.include_router(review.router)
3637
api_router.include_router(faq.router)
3738
api_router.include_router(timeline.router)
39+
api_router.include_router(pre_registration.router)

wacruit/src/database/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
import wacruit.src.apps.faq.models # isort: skip
1414
import wacruit.src.apps.history.models # isort: skip
1515
import wacruit.src.apps.timeline.models # isort: skip
16+
import wacruit.src.apps.pre_registration.models # isort: skip
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""add pre_registration table
2+
3+
Revision ID: 9dd2ff558a82
4+
Revises: c9b5e993e78b
5+
Create Date: 2025-07-18 21:04:38.078619
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
# revision identifiers, used by Alembic.
12+
revision = "9dd2ff558a82"
13+
down_revision = "c9b5e993e78b"
14+
branch_labels = None
15+
depends_on = None
16+
17+
18+
def upgrade() -> None:
19+
# ### commands auto generated by Alembic - please adjust! ###
20+
op.create_table(
21+
"pre_registration",
22+
sa.Column("id", sa.Integer(), nullable=False),
23+
sa.Column("url", sa.String(length=255), nullable=False),
24+
sa.Column("generation", sa.String(length=30), nullable=False),
25+
sa.Column("is_active", sa.Boolean(), nullable=False),
26+
sa.PrimaryKeyConstraint("id"),
27+
)
28+
# ### end Alembic commands ###
29+
30+
31+
def downgrade() -> None:
32+
# ### commands auto generated by Alembic - please adjust! ###
33+
op.drop_table("pre_registration")
34+
# ### end Alembic commands ###

0 commit comments

Comments
 (0)