Skip to content

Commit 223f1e5

Browse files
committed
wip: update Officer models
1 parent ab736be commit 223f1e5

File tree

4 files changed

+41
-40
lines changed

4 files changed

+41
-40
lines changed

src/officers/constants.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from enum import StrEnum
22

3-
OFFICER_POSITION_MAX_LENGTH = 128
3+
# OFFICER FIELD CONSTRAINTS
4+
OFFICER_POSITION_MAX = 128
5+
OFFICER_LEGAL_NAME_MAX = 128
46

57
class OfficerPositionEnum(StrEnum):
68
PRESIDENT = "president"

src/officers/models.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
from datetime import datetime
1+
from datetime import date
22

3-
from pydantic import BaseModel
3+
from pydantic import BaseModel, Field
44

5-
from officers.constants import OfficerPositionEnum
5+
from officers.constants import OFFICER_LEGAL_NAME_MAX, OfficerPositionEnum
66

77

8-
class BaseOfficerModel(BaseModel):
8+
class OfficerBaseModel(BaseModel):
99
# TODO (#71): compute this using SFU's API & remove from being uploaded
10-
legal_name: str
10+
legal_name: str = Field(..., max_length=OFFICER_LEGAL_NAME_MAX)
1111
position: OfficerPositionEnum
12-
start_date: datetime
13-
end_date: str | None = None
12+
start_date: date
13+
end_date: date | None = None
1414

15-
class PublicOfficerResponse(BaseOfficerModel):
15+
class PublicOfficerResponse(OfficerBaseModel):
1616
"""
1717
Response when fetching public officer data
1818
"""
@@ -33,17 +33,17 @@ class PrivateOfficerResponse(PublicOfficerResponse):
3333
github_username: str | None = None
3434
google_drive_email: str | None = None
3535

36-
class OfficerTermCreate(BaseOfficerModel):
37-
"""
38-
Create a new Officer term
39-
"""
36+
class OfficerTermBaseModel(BaseModel):
4037
computing_id: str
41-
42-
class OfficerTermUpdate(BaseModel):
43-
"""
44-
Update an Officer Term
45-
"""
46-
legal_name: str | None = None
47-
position: OfficerPositionEnum | None = None
48-
start_date: datetime | None = None
49-
end_date: datetime | None = None
38+
position: OfficerPositionEnum
39+
start_date: date
40+
41+
class OfficerTermResponse(OfficerTermBaseModel):
42+
id: int
43+
end_date: date | None = None
44+
favourite_course_0: str | None = None
45+
favourite_course_1: str | None = None
46+
favourite_pl_0: str | None = None
47+
favourite_pl_1: str | None = None
48+
biography: str | None = None
49+
photo_url: str | None = None

src/officers/tables.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from datetime import datetime
3+
from datetime import date, datetime
44

55
from sqlalchemy import (
66
Date,
@@ -20,7 +20,7 @@
2020
GITHUB_USERNAME_LEN,
2121
)
2222
from database import Base
23-
from officers.constants import OFFICER_POSITION_MAX_LENGTH, OfficerPositionEnum
23+
from officers.constants import OFFICER_LEGAL_NAME_MAX, OFFICER_POSITION_MAX, OfficerPositionEnum
2424

2525

2626
# A row represents an assignment of a person to a position.
@@ -36,10 +36,10 @@ class OfficerTerm(Base):
3636
nullable=False,
3737
)
3838

39-
position: Mapped[OfficerPositionEnum] = mapped_column(String(OFFICER_POSITION_MAX_LENGTH), nullable=False)
40-
start_date: Mapped[datetime] = mapped_column(Date, nullable=False)
39+
position: Mapped[OfficerPositionEnum] = mapped_column(String(OFFICER_POSITION_MAX), nullable=False)
40+
start_date: Mapped[date] = mapped_column(Date, nullable=False)
4141
# end_date is only not-specified for positions that don't have a length (ie. webmaster)
42-
end_date: Mapped[datetime] = mapped_column(Date, nullable=True)
42+
end_date: Mapped[date] = mapped_column(Date, nullable=True)
4343

4444
nickname: Mapped[str] = mapped_column(String(128), nullable=True)
4545
favourite_course_0: Mapped[str] = mapped_column(String(64), nullable=True)
@@ -113,7 +113,7 @@ class OfficerInfo(Base):
113113
)
114114

115115
# TODO (#71): we'll need to use SFU's API to get the legal name for users
116-
legal_name: Mapped[str] = mapped_column(String(128), nullable=False) # some people have long names, you never know
116+
legal_name: Mapped[str] = mapped_column(String(OFFICER_LEGAL_NAME_MAX), nullable=False) # some people have long names, you never know
117117
phone_number: Mapped[str] = mapped_column(String(24), nullable=True)
118118

119119
# TODO (#99): add unique constraints to discord_id (stops users from stealing the username of someone else)

src/officers/urls.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import database
66
import officers.crud
77
import utils
8-
from officers.models import PrivateOfficerResponse, PublicOfficerResponse
8+
from officers.models import OfficerTermResponse, PrivateOfficerResponse, PublicOfficerResponse
99
from officers.tables import OfficerInfo, OfficerTerm
1010
from officers.types import InitialOfficerInfo, OfficerInfoUpload, OfficerTermUpload
1111
from permission.types import OfficerPrivateInfo, WebsiteAdmin
@@ -82,23 +82,22 @@ async def all_officers(
8282
raise HTTPException(status_code=401, detail="only website admins can view all executive terms that have not started yet")
8383

8484
all_officers = await officers.crud.all_officers(db_session, has_private_access, include_future_terms)
85-
if has_private_access:
86-
return JSONResponse([
87-
PrivateOfficerResponse.model_validate(officer_data)
88-
for officer_data in all_officers
89-
])
90-
else:
91-
return JSONResponse([
92-
PublicOfficerResponse.model_validate(officer_data)
93-
for officer_data in all_officers
94-
])
85+
return JSONResponse([
86+
officer_data.serializable_dict()
87+
for officer_data in all_officers
88+
])
9589

9690
@router.get(
9791
"/terms/{computing_id}",
9892
description="""
9993
Get term info for an executive. All term info is public for all past or active terms.
10094
Future terms can only be accessed by website admins.
10195
""",
96+
response_model=list[OfficerTermResponse],
97+
responses={
98+
401: { "description": "not authorized to view private info", "model": DetailModel }
99+
},
100+
operation_id="get_all_officers"
102101
)
103102
async def get_officer_terms(
104103
request: Request,
@@ -118,7 +117,7 @@ async def get_officer_terms(
118117
include_future_terms
119118
)
120119
return JSONResponse([
121-
term.serializable_dict() for term in officer_terms
120+
OfficerTermResponse.model_validate(term) for term in officer_terms
122121
])
123122

124123
@router.get(

0 commit comments

Comments
 (0)