Skip to content

Commit d94110c

Browse files
committed
adapt to code comments
1 parent 3f3822b commit d94110c

4 files changed

Lines changed: 28 additions & 54 deletions

File tree

backend/app/core/database.py

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import logging
44
from importlib import import_module
5-
from typing import Tuple
65

76
from sqlalchemy import create_engine, inspect, text
87
from sqlalchemy.orm import declarative_base, sessionmaker
@@ -21,53 +20,9 @@
2120
SESSION_LOCAL = sessionmaker(autocommit=False, autoflush=False, bind=engine)
2221

2322

24-
def _timestamp_sql(dialect_name: str) -> Tuple[str, str]:
25-
"""Return dialect-specific SQL fragments for timestamp columns."""
26-
27-
if dialect_name == "postgresql":
28-
return "TIMESTAMPTZ", "NOW()"
29-
if dialect_name == "sqlite":
30-
return "TIMESTAMP", "CURRENT_TIMESTAMP"
31-
return "TIMESTAMP", "CURRENT_TIMESTAMP"
32-
33-
34-
def _migrate_legacy_users_table() -> None:
35-
"""Rename and backfill the legacy ``users`` table if it exists."""
36-
37-
with engine.begin() as connection:
38-
inspector = inspect(connection)
39-
existing_tables = set(inspector.get_table_names())
40-
if "user" in existing_tables or "users" not in existing_tables:
41-
return
42-
43-
logger.info("🚚 Migrating legacy users table to new schema...")
44-
connection.execute(text('ALTER TABLE "users" RENAME TO "user"'))
45-
46-
inspector = inspect(connection)
47-
columns = {column["name"] for column in inspector.get_columns("user")}
48-
49-
if "id" in columns:
50-
connection.execute(text('ALTER TABLE "user" RENAME COLUMN id TO user_id'))
51-
52-
if "created_at" not in columns:
53-
column_type, default_expr = _timestamp_sql(connection.dialect.name)
54-
connection.execute(
55-
text(
56-
f'ALTER TABLE "user" ADD COLUMN created_at {column_type} DEFAULT {default_expr}'
57-
)
58-
)
59-
connection.execute(
60-
text(f'UPDATE "user" SET created_at = {default_expr} WHERE created_at IS NULL')
61-
)
62-
63-
logger.info("✅ Legacy users table migrated.")
64-
65-
6623
def init_db() -> None:
6724
"""Automatically create or update tables based on SQLAlchemy models."""
6825

69-
_migrate_legacy_users_table()
70-
7126
for module in (
7227
"app.models.user",
7328
"app.models.project",

backend/app/models/project_paper.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,40 @@ class ProjectPaper(Base):
1414
"""Associative entity connecting projects with papers."""
1515

1616
__tablename__ = "project_paper"
17-
__table_args__ = (UniqueConstraint("project_id", "paper_id", name="uq_project_paper"),)
1817

19-
project_paper_id: Mapped[int] = mapped_column(BigInteger, primary_key=True, index=True)
18+
# Ensure a paper can only be linked once to the same project.
19+
__table_args__ = (
20+
UniqueConstraint(
21+
"project_id",
22+
"paper_id",
23+
name="uq_project_paper_project_id_paper_id",
24+
),
25+
)
26+
27+
project_paper_id: Mapped[int] = mapped_column(
28+
BigInteger, primary_key=True, index=True
29+
)
30+
2031
project_id: Mapped[int] = mapped_column(
2132
BigInteger, ForeignKey("project.project_id"), nullable=False, index=True
2233
)
34+
2335
paper_id: Mapped[int] = mapped_column(
2436
BigInteger, ForeignKey("paper.paper_id"), nullable=False, index=True
2537
)
38+
2639
added_at: Mapped[datetime] = mapped_column(
27-
DateTime(timezone=True), nullable=False, server_default=func.now()
40+
DateTime(timezone=True),
41+
nullable=False,
42+
server_default=func.now(),
2843
)
2944

30-
project: Mapped["Project"] = relationship("Project", back_populates="project_papers")
31-
paper: Mapped["Paper"] = relationship("Paper", back_populates="project_links")
45+
project: Mapped["Project"] = relationship(
46+
"Project", back_populates="project_papers"
47+
)
48+
paper: Mapped["Paper"] = relationship(
49+
"Paper", back_populates="project_links"
50+
)
3251

3352

3453
if TYPE_CHECKING:

backend/app/routes/auth_routes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
status_code=status.HTTP_200_OK,
1515
summary="Authenticate a user and return JWT tokens"
1616
)
17-
def login(request: LoginRequest, db: Session = Depends(get_db)):
17+
def login(request: LoginRequest, db: Session = Depends(get_db)) -> LoginResponse:
1818
"""Authenticate a user and return access plus refresh tokens."""
1919

2020
user, access_token, refresh_token = AuthService.login(db, request.username)
@@ -32,7 +32,7 @@ def login(request: LoginRequest, db: Session = Depends(get_db)):
3232
status_code=status.HTTP_200_OK,
3333
summary="Generate a new access token using a refresh token"
3434
)
35-
def refresh_access_token(request: RefreshRequest):
35+
def refresh_access_token(request: RefreshRequest) -> RefreshResponse:
3636
"""Validate a refresh token and return a new access token."""
3737

3838
new_access_token = AuthService.refresh(request.refresh_token)

backend/app/routes/user_routes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
status_code=status.HTTP_201_CREATED,
1616
summary="Create a new user"
1717
)
18-
def create_user(request: UserCreate, db: Session = Depends(get_db)):
18+
def create_user(request: UserCreate, db: Session = Depends(get_db)) -> UserResponse:
1919
"""Create a new user."""
2020

2121
user = UserService.create_user(db, request.username)
@@ -31,7 +31,7 @@ def create_user(request: UserCreate, db: Session = Depends(get_db)):
3131
def get_current_user_profile(
3232
current_username: str = Depends(get_current_user),
3333
db: Session = Depends(get_db),
34-
):
34+
) -> UserResponse:
3535
"""Return the authenticated user's profile."""
3636

3737
user = UserService.get_user_by_username(db, current_username)

0 commit comments

Comments
 (0)