Spaces:
Running
Running
| """Author RAG — Link Service. | |
| Business logic for smart links: buy/preview URL sync between books and links tables. | |
| """ | |
| from fastapi import HTTPException | |
| from sqlalchemy.ext.asyncio import AsyncSession | |
| from app.repositories.book_repo import BookRepository | |
| from app.repositories.link_repo import LinkRepository | |
| from app.schemas.admin import SmartLinkUpdate | |
| class LinkService: | |
| """Orchestrates smart link updates for admin books.""" | |
| def __init__(self, db: AsyncSession) -> None: | |
| self._db = db | |
| self._books = BookRepository(db) | |
| self._links = LinkRepository(db) | |
| async def update_smart_link( | |
| self, author_id: str, book_id: str, body: SmartLinkUpdate | |
| ) -> dict: | |
| """Update buy/preview URLs on book and sync to links table (R-074).""" | |
| book = await self._books.get_by_id(book_id) | |
| if not book or book.author_id != author_id: | |
| raise HTTPException(404, "Book not found") | |
| if body.buy_url is not None: | |
| book.buy_url = body.buy_url[:1000] if body.buy_url else None | |
| if body.preview_url is not None: | |
| book.preview_url = body.preview_url[:1000] if body.preview_url else None | |
| await self._links.upsert_for_book( | |
| author_id, | |
| book_id, | |
| { | |
| "purchase_url": book.buy_url, | |
| "preview_url": book.preview_url, | |
| }, | |
| ) | |
| await self._db.commit() | |
| return {"message": "Smart link updated"} | |