11from fastapi import APIRouter , HTTPException , Depends , Path
2- from typing import List
2+ from typing import List , Dict , Set
33from bson import ObjectId
44from services .bulletins_master_service import BulletinsMasterService
55from services .bulletins_version_service import BulletinsVersionService
6+ from services .cards_service import CardsService
67from acb_orm .schemas .bulletins_master_schema import BulletinsMasterCreate , BulletinsMasterUpdate , BulletinsMasterRead
78from acb_orm .schemas .bulletins_version_schema import BulletinsVersionRead , BulletinsVersionCreate , BulletinsVersionUpdate
9+ from acb_orm .schemas .cards_schema import CardsRead
810from acb_orm .enums .status_bulletin import StatusBulletin
911from 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
1113from fastapi .security import HTTPBearer , HTTPAuthorizationCredentials
1214
1315router = APIRouter (prefix = "/bulletins" , tags = ["Bulletin Management" ])
1416bulletins_master_service = BulletinsMasterService ()
1517bulletins_version_service = BulletinsVersionService ()
18+ cards_service = CardsService ()
1619security = 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 )
136158def 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
0 commit comments