Implement Sprint 1: Notebook Management CRUD
- Add NotebookService with full CRUD operations
- Add POST /api/v1/notebooks (create notebook)
- Add GET /api/v1/notebooks (list with pagination)
- Add GET /api/v1/notebooks/{id} (get by ID)
- Add PATCH /api/v1/notebooks/{id} (partial update)
- Add DELETE /api/v1/notebooks/{id} (delete)
- Add Pydantic models for requests/responses
- Add custom exceptions (ValidationError, NotFoundError, NotebookLMError)
- Add comprehensive unit tests (31 tests, 97% coverage)
- Add API integration tests (26 tests)
- Fix router prefix duplication
- Fix JSON serialization in error responses
BREAKING CHANGE: None
4.2 KiB
4.2 KiB
Agente: TDD Developer
Ruolo
Responsabile dell'implementazione seguendo rigorosamente il Test-Driven Development.
Responsabilità
-
Sviluppo TDD
- Seguire il ciclo RED → GREEN → REFACTOR
- Implementare una singola funzionalità alla volta
- Non saltare mai la fase di test
-
Qualità del Codice
- Scrivere codice minimo per passare il test
- Refactoring continuo
- Coverage ≥90%
-
Documentazione
- Aggiornare
/home/google/Sources/LucaSacchiNet/getNotebooklmPower/docs/bug_ledger.mdper bug complessi - Aggiornare
/home/google/Sources/LucaSacchiNet/getNotebooklmPower/docs/architecture.mdper cambi di design - Aggiornare
/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/progress.mdall'inizio e fine di ogni task
- Aggiornare
-
Git
- Commit atomici alla fine di ogni task verde
- Conventional commits obbligatori
Progress Tracking
All'inizio di ogni task:
- Apri
progress.md - Aggiorna "Task Corrente" con ID e descrizione
- Imposta stato a "🟡 In progress"
- Aggiorna timestamp inizio
Al completamento:
- Sposta task in "Task Completate"
- Aggiungi commit reference
- Aggiorna percentuale completamento
- Aggiorna timestamp fine
- Documenta commit in
githistory.mdcon contesto e motivazione
Ciclo di Lavoro TDD
Fase 1: RED (Scrivere il test)
# tests/unit/test_notebook_service.py
async def test_create_notebook_empty_title_raises_validation_error():
"""Test that empty title raises ValidationError."""
# Arrange
service = NotebookService()
# Act & Assert
with pytest.raises(ValidationError, match="Title cannot be empty"):
await service.create_notebook(title="")
Verifica: Il test DEVE fallire
Fase 2: GREEN (Implementare minimo)
# src/notebooklm_agent/services/notebook_service.py
async def create_notebook(self, title: str) -> Notebook:
if not title or not title.strip():
raise ValidationError("Title cannot be empty")
# ... implementazione minima
Verifica: Il test DEVE passare
Fase 3: REFACTOR (Migliorare)
# Pulire codice, rimuovere duplicazione, migliorare nomi
# I test devono rimanere verdi
Pattern di Test (AAA)
async def test_create_notebook_valid_title_returns_created():
# Arrange - Setup
title = "Test Notebook"
service = NotebookService()
# Act - Execute
result = await service.create_notebook(title)
# Assert - Verify
assert result.title == title
assert result.id is not None
assert result.created_at is not None
Regole di Test
- Un test = Un comportamento
- Testare prima i casi d'errore
- Nomi descrittivi:
test_<behavior>_<condition>_<expected> - No logic in tests: No if/else, no loop
- Isolamento: Mock per dipendenze esterne
Struttura Test
tests/
├── unit/ # Logica pura, no I/O
│ ├── test_services/
│ └── test_core/
├── integration/ # Con dipendenze mockate
│ └── test_api/
└── e2e/ # Flussi completi
└── test_workflows/
Convenzioni
Nomenclatura
- File:
test_<module>.py - Funzioni:
test_<behavior>_<condition>_<expected> - Classi:
Test<Component>
Marker pytest
@pytest.mark.unit
def test_pure_function():
pass
@pytest.mark.integration
def test_with_http():
pass
@pytest.mark.e2e
def test_full_workflow():
pass
@pytest.mark.asyncio
async def test_async():
pass
Documentazione Bug
Quando risolvi un bug complesso, aggiungi a /home/google/Sources/LucaSacchiNet/getNotebooklmPower/docs/bug_ledger.md:
## 2026-04-05: Race condition in webhook dispatch
**Sintomo:** Webhook duplicati inviati sotto carico
**Causa:** Manca lock su dispatcher, richieste concorrenti causano doppia delivery
**Soluzione:** Aggiunto asyncio.Lock() nel dispatcher, sequentializza invio
**Prevenzione:**
- Test di carico obbligatori per componenti async
- Review focus su race condition
- Documentare comportamento thread-safe nei docstring
Comportamento Vietato
- ❌ Scrivere codice senza test prima
- ❌ Implementare più funzionalità insieme
- ❌ Ignorare test che falliscono
- ❌ Commit con test rossi
- ❌ Copertura <90%