Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e647bc7811 | ||
|
|
bf7c969629 |
@@ -91,7 +91,7 @@ CREATE TABLE Review (
|
|||||||
song_id INTEGER NOT NULL, -- Foreign Key -> Song.id
|
song_id INTEGER NOT NULL, -- Foreign Key -> Song.id
|
||||||
score_song INTEGER NOT NULL, -- Score (1-100) for song quality
|
score_song INTEGER NOT NULL, -- Score (1-100) for song quality
|
||||||
score_show INTEGER NOT NULL, -- Score (1-100) for the stage show
|
score_show INTEGER NOT NULL, -- Score (1-100) for the stage show
|
||||||
score_wardrobe INTEGER NOT NULL, -- Score (1-100) for wardrobe/costumes
|
score_costume INTEGER NOT NULL, -- Score (1-100) for wardrobe/costumes
|
||||||
text_review VARCHAR, -- Optional textual comments (nullable)
|
text_review VARCHAR, -- Optional textual comments (nullable)
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the review was created
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the review was created
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the review was last modified
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the review was last modified
|
||||||
@@ -102,7 +102,7 @@ CREATE TABLE Review (
|
|||||||
-- Ensure scores are within the valid range (1-100)
|
-- Ensure scores are within the valid range (1-100)
|
||||||
CHECK (score_song >= 1 AND score_song <= 100),
|
CHECK (score_song >= 1 AND score_song <= 100),
|
||||||
CHECK (score_show >= 1 AND score_show <= 100),
|
CHECK (score_show >= 1 AND score_show <= 100),
|
||||||
CHECK (score_wardrobe >= 1 AND score_wardrobe <= 100),
|
CHECK (score_costume >= 1 AND score_costume <= 100),
|
||||||
|
|
||||||
-- Ensure each user can only submit one review per song
|
-- Ensure each user can only submit one review per song
|
||||||
UNIQUE (user_id, song_id)
|
UNIQUE (user_id, song_id)
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewBase(BaseModel):
|
||||||
|
song_id: int = Field(description="ID of the song", examples=[1])
|
||||||
|
user_id: int = Field(description="ID of the user", examples=[1])
|
||||||
|
score_song: int = Field(
|
||||||
|
gt=0, le=100, description="Score given by the user", examples=[1]
|
||||||
|
)
|
||||||
|
score_show: int = Field(
|
||||||
|
gt=0, le=100, description="Score given by the user", examples=[1]
|
||||||
|
)
|
||||||
|
score_costume: int = Field(
|
||||||
|
gt=0, le=100, description="Score given by the user", examples=[1]
|
||||||
|
)
|
||||||
|
text_review: str | None = Field(
|
||||||
|
default=None, description="Comment given by the user", examples=["comment"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewIn(ReviewBase):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewSearch(BaseModel):
|
||||||
|
song_id: int = Field(description="ID of the song", examples=[1])
|
||||||
|
user_id: int = Field(description="ID of the user", examples=[1])
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewOut(ReviewBase):
|
||||||
|
created_at: datetime = Field(
|
||||||
|
default_factory=datetime.now,
|
||||||
|
description="Creation timestamp",
|
||||||
|
examples=["2025-01-01T00:00:00.000Z"],
|
||||||
|
)
|
||||||
|
updated_at: datetime = Field(
|
||||||
|
default_factory=datetime.now,
|
||||||
|
description="Last update timestamp",
|
||||||
|
examples=["2025-01-01T00:00:00.000Z"],
|
||||||
|
)
|
||||||
+66
-2
@@ -1,3 +1,67 @@
|
|||||||
from fastapi import APIRouter
|
from fastapi import APIRouter, HTTPException
|
||||||
|
|
||||||
router = APIRouter(prefix="/songs", tags=["songs"])
|
from models.review import ReviewOut, ReviewSearch, ReviewIn
|
||||||
|
from lib.db import get_connection
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/reviews", tags=["reviews"])
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/all", response_model=list[ReviewOut])
|
||||||
|
async def list_reviews():
|
||||||
|
with get_connection() as conn:
|
||||||
|
reviews = conn.execute("SELECT * FROM Review").fetchdf()
|
||||||
|
if reviews.empty:
|
||||||
|
raise HTTPException(status_code=404, detail="Reviews not found")
|
||||||
|
return reviews.to_dict(orient="records")
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/", response_model=ReviewOut)
|
||||||
|
async def get_review(review_id: ReviewSearch):
|
||||||
|
with get_connection() as conn:
|
||||||
|
review = conn.execute(
|
||||||
|
"SELECT * FROM Review WHERE song_id = ? AND user_id = ?",
|
||||||
|
(review_id.song_id, review_id.user_id),
|
||||||
|
).fetchdf()
|
||||||
|
if review.empty:
|
||||||
|
raise HTTPException(status_code=404, detail="Review not found")
|
||||||
|
return review.to_dict(orient="records")[0]
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/", response_model=ReviewOut)
|
||||||
|
async def create_review(review: ReviewIn):
|
||||||
|
with get_connection() as conn:
|
||||||
|
review = conn.execute(
|
||||||
|
"INSERT INTO Review (user_id, song_id, score_song, score_show, score_costume, text_review) VALUES (?, ?, ?, ?, ?, ?)",
|
||||||
|
(
|
||||||
|
review.user_id,
|
||||||
|
review.song_id,
|
||||||
|
review.score_song,
|
||||||
|
review.score_show,
|
||||||
|
review.score_costume,
|
||||||
|
review.text_review,
|
||||||
|
),
|
||||||
|
).fetchdf()
|
||||||
|
if review.empty:
|
||||||
|
raise HTTPException(status_code=404, detail="Review not found")
|
||||||
|
return review.to_dict(orient="records")[0]
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/", response_model=ReviewOut)
|
||||||
|
async def update_review(review: ReviewIn):
|
||||||
|
with get_connection() as conn:
|
||||||
|
review = conn.execute(
|
||||||
|
"UPDATE Review SET user_id = ?, song_id = ?, score_song = ?, score_show = ?, score_costume = ?, text_review = ? WHERE song_id = ? AND user_id = ?",
|
||||||
|
(
|
||||||
|
review.user_id,
|
||||||
|
review.song_id,
|
||||||
|
review.score_song,
|
||||||
|
review.score_show,
|
||||||
|
review.score_costume,
|
||||||
|
review.text_review,
|
||||||
|
review.song_id,
|
||||||
|
review.user_id,
|
||||||
|
),
|
||||||
|
).fetchdf()
|
||||||
|
if review.empty:
|
||||||
|
raise HTTPException(status_code=404, detail="Review not found")
|
||||||
|
return review.to_dict(orient="records")[0]
|
||||||
|
|||||||
Reference in New Issue
Block a user