Skip to content

Commit 2d817c3

Browse files
authored
Merge pull request #6 from CIAT-DAPA/develop
Implementation of cards in the bulletin preview
2 parents dc5ed80 + 7ee3851 commit 2d817c3

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

src/api/bulletins_management.py

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,43 @@
11
from fastapi import APIRouter, HTTPException, Depends, Path
2-
from typing import List
2+
from typing import List, Dict, Set
33
from bson import ObjectId
44
from services.bulletins_master_service import BulletinsMasterService
55
from services.bulletins_version_service import BulletinsVersionService
6+
from services.cards_service import CardsService
67
from acb_orm.schemas.bulletins_master_schema import BulletinsMasterCreate, BulletinsMasterUpdate, BulletinsMasterRead
78
from acb_orm.schemas.bulletins_version_schema import BulletinsVersionRead, BulletinsVersionCreate, BulletinsVersionUpdate
9+
from acb_orm.schemas.cards_schema import CardsRead
810
from acb_orm.enums.status_bulletin import StatusBulletin
911
from auth.access_utils import get_current_user, user_has_permission
10-
from schemas.response_models import BulletinWithCurrentVersion
12+
from schemas.response_models import BulletinWithCurrentVersion, BulletinWithCurrentVersionPublic
1113
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
1214

1315
router = APIRouter(prefix="/bulletins", tags=["Bulletin Management"])
1416
bulletins_master_service = BulletinsMasterService()
1517
bulletins_version_service = BulletinsVersionService()
18+
cards_service = CardsService()
1619
security = HTTPBearer()
1720

1821

22+
def extract_card_ids_from_data(data: dict) -> Set[str]:
23+
"""Recursively extract all cardId values from bulletin data."""
24+
card_ids = set()
25+
26+
sections = data.get("sections", [])
27+
for section in sections:
28+
blocks = section.get("blocks", [])
29+
for block in blocks:
30+
fields = block.get("fields", [])
31+
for field in fields:
32+
if field.get("type") == "card":
33+
values = field.get("value", [])
34+
for value_item in values:
35+
if isinstance(value_item, dict) and "cardId" in value_item:
36+
card_ids.add(value_item["cardId"])
37+
38+
return card_ids
39+
40+
1941
# --- CRUD and queries for bulletin masters ---
2042

2143
@router.post("/", response_model=BulletinsMasterRead)
@@ -132,13 +154,14 @@ def get_current_version(
132154
)
133155

134156

135-
@router.get("/{bulletin_id}/current-version-published", response_model=BulletinWithCurrentVersion)
157+
@router.get("/{bulletin_id}/current-version-published", response_model=BulletinWithCurrentVersionPublic)
136158
def get_current_version_published(
137159
bulletin_id: str = Path(..., description="ID del boletín"),
138160
):
139161
"""
140162
Public endpoint that returns the bulletin master and its current version
141163
ONLY if the bulletin status is PUBLISHED. No authentication required.
164+
Includes cards metadata for all cards referenced in the bulletin data.
142165
Returns 404 if the bulletin doesn't exist or is not published.
143166
"""
144167

@@ -147,8 +170,6 @@ def get_current_version_published(
147170
if not bulletin_master:
148171
raise HTTPException(status_code=404, detail="Bulletin not found")
149172

150-
print("Bulletin master status:", bulletin_master.status)
151-
152173
# Verify the bulletin is PUBLISHED (security check for public access)
153174
if bulletin_master.status != StatusBulletin.PUBLISHED:
154175
raise HTTPException(status_code=404, detail="Bulletin not found")
@@ -165,9 +186,28 @@ def get_current_version_published(
165186
except Exception as e:
166187
raise HTTPException(status_code=404, detail="Bulletin not found")
167188

168-
return BulletinWithCurrentVersion(
189+
# Extract all card IDs from the bulletin data
190+
card_ids = extract_card_ids_from_data(current_version.data)
191+
192+
# Fetch all cards in bulk and create a dict indexed by card ID
193+
cards_metadata: Dict[str, CardsRead] = {}
194+
if card_ids:
195+
try:
196+
# Convert set to comma-separated string for get_by_ids
197+
card_ids_str = ",".join(card_ids)
198+
cards = cards_service.get_by_ids(card_ids_str)
199+
200+
# Index cards by their ID
201+
for card in cards:
202+
cards_metadata[card.id] = card
203+
except Exception as e:
204+
# If cards fetch fails, continue without cards (graceful degradation)
205+
pass
206+
207+
return BulletinWithCurrentVersionPublic(
169208
master=bulletin_master,
170-
current_version=current_version
209+
current_version=current_version,
210+
cards_metadata=cards_metadata
171211
)
172212

173213

src/schemas/response_models.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
from typing import Dict
12
from pydantic import BaseModel
23
from acb_orm.schemas.templates_master_schema import TemplatesMasterRead
34
from acb_orm.schemas.templates_version_schema import TemplatesVersionRead
45
from acb_orm.schemas.bulletins_master_schema import BulletinsMasterRead
56
from acb_orm.schemas.bulletins_version_schema import BulletinsVersionRead
7+
from acb_orm.schemas.cards_schema import CardsRead
68

79
class TemplateWithCurrentVersion(BaseModel):
810
"""Response model for template master with its current version."""
@@ -12,4 +14,10 @@ class TemplateWithCurrentVersion(BaseModel):
1214
class BulletinWithCurrentVersion(BaseModel):
1315
"""Response model for bulletin master with its current version."""
1416
master: BulletinsMasterRead
15-
current_version: BulletinsVersionRead
17+
current_version: BulletinsVersionRead
18+
19+
class BulletinWithCurrentVersionPublic(BaseModel):
20+
"""Public response model with embedded cards metadata."""
21+
master: BulletinsMasterRead
22+
current_version: BulletinsVersionRead
23+
cards_metadata: Dict[str, CardsRead]

0 commit comments

Comments
 (0)