Coverage for src/app/modules/cards/services.py: 100%
57 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-24 08:34 +0000
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-24 08:34 +0000
1import logging
3from app.modules.cards.repository import CardRepository
4from app.modules.cards.schemas import CardCreate
6logger = logging.getLogger(__name__)
9class CardService:
10 def __init__(self, repo: CardRepository):
11 self.repo = repo
13 def create_card(self, data: CardCreate):
14 logger.debug(
15 "create_card called: deck_id=%s front_present=%s back_present=%s",
16 data.deck_id,
17 bool(data.front),
18 bool(data.back),
19 )
20 # business rule example (simple but real)
21 if not data.front or not data.back:
22 logger.warning(
23 "create_card validation failed: missing front/back: deck_id=%s", data.deck_id
24 )
25 raise ValueError("Card must have front and back")
27 try:
28 card = self.repo.create(
29 front=data.front.strip(),
30 back=data.back.strip(),
31 deck_id=data.deck_id,
32 )
33 logger.info("Card created: id=%s deck_id=%s", getattr(card, "id", None), data.deck_id)
34 return card
35 except Exception:
36 logger.exception(
37 "Error creating card for deck_id=%s front=%s", data.deck_id, data.front
38 )
39 raise
41 def get_card(self, card_id: int):
42 logger.debug("get_card called: card_id=%s", card_id)
43 try:
44 card = self.repo.get(card_id)
45 except Exception:
46 logger.exception("Failed to fetch card_id=%s", card_id)
47 raise
49 if not card:
50 logger.info("Card not found: card_id=%s", card_id)
51 raise ValueError("Card not found")
53 logger.debug("Card fetched: card_id=%s", card_id)
54 return card
56 def get_cards_for_deck(self, deck_id: int):
57 logger.debug("get_cards_for_deck called: deck_id=%s", deck_id)
58 try:
59 cards = self.repo.list_by_deck(deck_id)
60 logger.info("Fetched %s cards for deck_id=%s", len(cards), deck_id)
61 return cards
62 except Exception:
63 logger.exception("Failed to list cards for deck_id=%s", deck_id)
64 raise
66 def delete_card(self, card_id: int):
67 logger.debug("delete_card called: card_id=%s", card_id)
68 try:
69 card = self.repo.get(card_id)
70 except Exception:
71 logger.exception("Failed to fetch card before delete: card_id=%s", card_id)
72 raise
74 if not card:
75 logger.info("Attempted to delete non-existent card: card_id=%s", card_id)
76 raise ValueError("Card not found")
78 try:
79 self.repo.delete(card_id)
80 logger.info("Deleted card: card_id=%s", card_id)
81 return {"status": "deleted"}
82 except Exception:
83 logger.exception("Failed to delete card_id=%s", card_id)
84 raise