Skip to content
Open
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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ COPY pyproject.toml pyproject.toml

RUN pip install poetry
RUN poetry config virtualenvs.create false
RUN poetry install --no-dev
RUN poetry install --no-root

COPY . /app

Expand Down
228 changes: 218 additions & 10 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/catalogue/models/pydantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ProductModel(BaseModel):
title: str
description: Optional[str]
short_description: Optional[constr(max_length=20)]
is_active: bool
is_active: Optional[bool] = None

class Config:
from_attributes = True
2 changes: 1 addition & 1 deletion src/common/databases/mongo_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ async def init_mongo_db():
await init_beanie(
database=client.get_database(),
document_models=[
ProductReview,
ProductReview
],
)
8 changes: 8 additions & 0 deletions src/reviews/models/mongo.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import uuid
from datetime import datetime
from typing import Optional

from beanie import Document
Expand Down Expand Up @@ -28,3 +29,10 @@ class ProductReview(Document, BaseProductReview):

class Settings:
name = 'productReviews'

class ProductAnalytics(Document):
product_id: int
timestamp: datetime

class Settings:
name = "productAnalytics"
5 changes: 4 additions & 1 deletion src/reviews/repositories.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from src.common.repository.beanie import BaseMongoRepository
from src.reviews.models.mongo import ProductReview
from src.reviews.models.mongo import ProductReview, ProductAnalytics


class ProductReviewRepository(BaseMongoRepository[ProductReview]):
__model__ = ProductReview

class ProductAnalyticsRepository(BaseMongoRepository[ProductAnalytics]):
__model__ = ProductAnalytics
24 changes: 21 additions & 3 deletions src/reviews/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from src.common.service import BaseService
from src.reviews.models.mongo import (
ProductReview,
Reply,
Reply, ProductAnalytics,
)
from src.reviews.repositories import ProductReviewRepository

from src.reviews.repositories import ProductReviewRepository, ProductAnalyticsRepository
from datetime import datetime

class ProductReviewService(BaseService):
def __init__(
Expand Down Expand Up @@ -44,3 +44,21 @@ async def add_reply(self, pk: str, reply: Reply) -> ProductReview:
review.replies.append(reply.model_dump())

return await review.save()




class ProductAnalyticsService(BaseService):
def __init__(
self,
repository: Annotated[ProductAnalyticsRepository, Depends(ProductAnalyticsRepository)],
):
super().__init__(repository=repository)

async def create_record(self, product_id: int) -> ProductAnalytics:
record = ProductAnalytics(
product_id=product_id,
timestamp=datetime.utcnow()
)
return await self.repository.create(record)

27 changes: 22 additions & 5 deletions src/reviews/views/product_reviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,25 @@
Response,
status,
)

from datetime import datetime
from src.common.exceptions.base import ObjectDoesNotExistException
from src.common.schemas.common import ErrorResponse
from src.reviews.models.mongo import (
BaseProductReview,
ProductReview,
ProductReview, ProductAnalytics,
Reply,
)
from src.reviews.routes import (
ProductReviewRoutesPrefixes,
ReviewsRoutesPrefixes,
ReviewsRoutesPrefixes
)
from src.reviews.services import ProductReviewService
from src.reviews.services import ProductReviewService, ProductAnalyticsService
from src.catalogue.services import ProductService
from src.catalogue.models.pydantic import ProductModel


router = APIRouter(prefix=ReviewsRoutesPrefixes.product_reviews)


@router.get(
ProductReviewRoutesPrefixes.root,
status_code=status.HTTP_200_OK,
Expand Down Expand Up @@ -113,3 +114,19 @@ async def add_reply_to_review(
return ErrorResponse(message=exc.message)

return response




@router.get("/catalogue/product/{pk}")
async def product_detail(
pk: int,
analytics_service: ProductAnalyticsService = Depends()
):
try:
await analytics_service.create_record(product_id=pk)
except Exception as e:
print(f"Analytics save failed: {e}")

return Response(status_code=status.HTTP_204_NO_CONTENT)