feat(setup): T01 create project directory structure
- Create src/openrouter_monitor/ package structure - Create models/, routers/, services/, utils/ subpackages - Create tests/unit/ and tests/integration/ structure - Create alembic/, docs/, scripts/ directories - Add test_project_structure.py with 13 unit tests - All tests passing (13/13) Refs: T01
This commit is contained in:
164
.opencode/WORKFLOW.md
Normal file
164
.opencode/WORKFLOW.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# Flusso di Lavoro Obbligatorio - getNotebooklmPower
|
||||
|
||||
> **Regola fondamentale:** *Safety first, little often, double check*
|
||||
|
||||
## 1. Contesto (Prima di ogni task)
|
||||
|
||||
**OBBLIGATORIO:** Prima di implementare qualsiasi funzionalità:
|
||||
|
||||
1. **Leggi il PRD**: Leggi sempre `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/prd.md` per capire i requisiti del task corrente
|
||||
2. **Non implementare mai funzionalità non esplicitamente richieste**
|
||||
3. **Scope check**: Verifica che il task rientri nello scope definito nel PRD
|
||||
|
||||
## 2. TDD (Test-Driven Development)
|
||||
|
||||
**Ciclo RED → GREEN → REFACTOR:**
|
||||
|
||||
1. **RED**: Scrivi PRIMA il test fallimentare per la singola funzionalità
|
||||
2. **GREEN**: Scrivi il codice applicativo minimo necessario per far passare il test
|
||||
3. **REFACTOR**: Migliora il codice mantenendo i test verdi
|
||||
4. **Itera** finché la funzionalità non è completa e tutti i test passano
|
||||
|
||||
**Regole TDD:**
|
||||
- Un test per singolo comportamento
|
||||
- Testare prima i casi limite (errori, input invalidi)
|
||||
- Coverage target: ≥90%
|
||||
- Usa AAA pattern: Arrange → Act → Assert
|
||||
|
||||
## 3. Memoria e Logging
|
||||
|
||||
**Documentazione obbligatoria:**
|
||||
|
||||
| Evento | Azione | File |
|
||||
|--------|--------|------|
|
||||
| Bug complesso risolto | Descrivi il bug e la soluzione | `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/docs/bug_ledger.md` |
|
||||
| Decisione di design | Documenta il pattern scelto | `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/docs/architecture.md` |
|
||||
| Cambio architetturale | Aggiorna le scelte architetturali | `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/docs/architecture.md` |
|
||||
| Inizio task | Aggiorna progresso corrente | `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/progress.md` |
|
||||
| Fine task | Registra completamento | `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/progress.md` |
|
||||
| Blocco riscontrato | Documenta problema e soluzione | `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/progress.md` |
|
||||
|
||||
**Formato bug_ledger.md:**
|
||||
```markdown
|
||||
## YYYY-MM-DD: [Titolo Bug]
|
||||
**Sintomo:** [Descrizione sintomo]
|
||||
**Causa:** [Root cause]
|
||||
**Soluzione:** [Fix applicato]
|
||||
**Prevenzione:** [Come evitare in futuro]
|
||||
```
|
||||
|
||||
## 4. Git Flow (Commit)
|
||||
|
||||
**Alla fine di ogni task completato con test verdi:**
|
||||
|
||||
1. **Commit atomico**: Un commit per singola modifica funzionale
|
||||
2. **Conventional Commits** obbligatorio:
|
||||
```
|
||||
<type>(<scope>): <description>
|
||||
|
||||
[optional body]
|
||||
|
||||
[optional footer]
|
||||
```
|
||||
3. **Tipi ammessi:**
|
||||
- `feat:` - Nuova funzionalità
|
||||
- `fix:` - Correzione bug
|
||||
- `docs:` - Documentazione
|
||||
- `test:` - Test
|
||||
- `refactor:` - Refactoring
|
||||
- `chore:` - Manutenzione
|
||||
4. **Scope**: api, webhook, skill, notebook, source, artifact, auth, core
|
||||
5. **Documenta il commit**: Aggiorna `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/githistory.md` con contesto e spiegazione
|
||||
|
||||
**Esempi:**
|
||||
```bash
|
||||
feat(api): add notebook creation endpoint
|
||||
|
||||
- Implements POST /api/v1/notebooks
|
||||
- Validates title length (max 100 chars)
|
||||
- Returns 201 with notebook details
|
||||
|
||||
Closes #123
|
||||
```
|
||||
|
||||
**Formato githistory.md:**
|
||||
```markdown
|
||||
## 2026-04-05 14:30 - feat(api): add notebook creation endpoint
|
||||
|
||||
**Hash:** `a1b2c3d`
|
||||
**Autore:** @tdd-developer
|
||||
**Branch:** main
|
||||
|
||||
### Contesto
|
||||
Necessità di creare notebook programmaticamente via API per integrazione con altri agenti.
|
||||
|
||||
### Cosa cambia
|
||||
- Aggiunto endpoint POST /api/v1/notebooks
|
||||
- Implementata validazione titolo (max 100 chars)
|
||||
- Aggiunto test coverage 95%
|
||||
|
||||
### Perché
|
||||
Il PRD richiede CRUD operations su notebook. Questo è il primo endpoint implementato.
|
||||
|
||||
### Impatto
|
||||
- [x] Nuova feature
|
||||
- [ ] Breaking change
|
||||
- [ ] Modifica API
|
||||
|
||||
### File modificati
|
||||
- src/api/routes/notebooks.py - Nuovo endpoint
|
||||
- src/services/notebook_service.py - Logica creazione
|
||||
- tests/unit/test_notebook_service.py - Test unitari
|
||||
|
||||
### Note
|
||||
Closes #42
|
||||
```
|
||||
|
||||
## 5. Spec-Driven Development (SDD)
|
||||
|
||||
**Prima di scrivere codice, definisci le specifiche:**
|
||||
|
||||
### 5.1 Analisi Profonda
|
||||
- Fai domande mirate per chiarire dubbi architetturali o di business
|
||||
- Non procedere con specifiche vaghe
|
||||
- Verifica vincoli tecnici e dipendenze
|
||||
|
||||
### 5.2 Output Richiesti (cartella `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/`)
|
||||
|
||||
Tutto il lavoro di specifica si concretizza in questi file:
|
||||
|
||||
| File | Contenuto |
|
||||
|------|-----------|
|
||||
| `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/prd.md` | Product Requirements Document (obiettivi, user stories, requisiti tecnici) |
|
||||
| `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/architecture.md` | Scelte architetturali, stack tecnologico, diagrammi di flusso |
|
||||
| `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/kanban.md` | Scomposizione in task minimi e verificabili (regola "little often") |
|
||||
|
||||
### 5.3 Principio "Little Often"
|
||||
- Scomporre in task il più piccoli possibile
|
||||
- Ogni task deve essere verificabile in modo indipendente
|
||||
- Progresso incrementale, mai "big bang"
|
||||
|
||||
### 5.4 Rigore
|
||||
- **Sii diretto, conciso e tecnico**
|
||||
- **Se una richiesta è vaga, non inventare: chiedi di precisare**
|
||||
- Nessuna supposizione non verificata
|
||||
|
||||
## Checklist Pre-Implementazione
|
||||
|
||||
- [ ] Ho letto il PRD in `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/prd.md`
|
||||
- [ ] Ho compreso lo scope del task
|
||||
- [ ] Ho scritto il test fallimentare (RED)
|
||||
- [ ] Ho implementato il codice minimo (GREEN)
|
||||
- [ ] Ho refactoring mantenendo test verdi
|
||||
- [ ] Ho aggiornato `bug_ledger.md` se necessario
|
||||
- [ ] Ho aggiornato `architecture.md` se necessario
|
||||
- [ ] Ho creato un commit atomico con conventional commit
|
||||
|
||||
## Checklist Spec-Driven (per nuove feature)
|
||||
|
||||
- [ ] Ho analizzato in profondità i requisiti
|
||||
- [ ] Ho chiesto chiarimenti sui punti vaghi
|
||||
- [ ] Ho creato/aggiormaneto `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/prd.md`
|
||||
- [ ] Ho creato/aggiormaneto `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/architecture.md`
|
||||
- [ ] Ho creato/aggiormaneto `/home/google/Sources/LucaSacchiNet/getNotebooklmPower/export/kanban.md`
|
||||
- [ ] I task sono scomposti secondo "little often"
|
||||
175
.opencode/agents/git-manager.md
Normal file
175
.opencode/agents/git-manager.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# Agente: Git Flow Manager
|
||||
|
||||
## Ruolo
|
||||
Responsabile della gestione dei commit e del flusso Git.
|
||||
|
||||
## Responsabilità
|
||||
|
||||
1. **Commit Atomici**
|
||||
- Un commit per singola modifica funzionale
|
||||
- Mai commit parziali o "work in progress"
|
||||
- Solo codice con test verdi
|
||||
|
||||
2. **Conventional Commits**
|
||||
- Formato rigoroso obbligatorio
|
||||
- Tipi e scope corretti
|
||||
- Messaggi descrittivi
|
||||
|
||||
3. **Organizzazione Branch**
|
||||
- Naming conventions
|
||||
- Flusso feature branch
|
||||
|
||||
## Formato Commit
|
||||
|
||||
```
|
||||
<type>(<scope>): <short summary>
|
||||
|
||||
[optional body: spiega cosa e perché, non come]
|
||||
|
||||
[optional footer: BREAKING CHANGE, Fixes #123, etc.]
|
||||
```
|
||||
|
||||
### Tipi (type)
|
||||
|
||||
| Tipo | Uso | Esempio |
|
||||
|------|-----|---------|
|
||||
| `feat` | Nuova funzionalità | `feat(api): add notebook creation endpoint` |
|
||||
| `fix` | Correzione bug | `fix(webhook): retry logic exponential backoff` |
|
||||
| `docs` | Documentazione | `docs(api): update OpenAPI schema` |
|
||||
| `style` | Formattazione | `style: format with ruff` |
|
||||
| `refactor` | Refactoring | `refactor(notebook): extract validation logic` |
|
||||
| `test` | Test | `test(source): add unit tests for URL validation` |
|
||||
| `chore` | Manutenzione | `chore(deps): upgrade notebooklm-py` |
|
||||
| `ci` | CI/CD | `ci: add GitHub Actions workflow` |
|
||||
|
||||
### Scope
|
||||
|
||||
- `api` - REST API endpoints
|
||||
- `webhook` - Webhook system
|
||||
- `skill` - AI skill interface
|
||||
- `notebook` - Notebook operations
|
||||
- `source` - Source management
|
||||
- `artifact` - Artifact generation
|
||||
- `auth` - Authentication
|
||||
- `core` - Core utilities
|
||||
|
||||
### Esempi
|
||||
|
||||
**Feature:**
|
||||
```
|
||||
feat(api): add POST /notebooks endpoint
|
||||
|
||||
- Implements notebook creation with validation
|
||||
- Returns 201 with notebook details
|
||||
- Validates title length (max 100 chars)
|
||||
|
||||
Closes #42
|
||||
```
|
||||
|
||||
**Bug fix:**
|
||||
```
|
||||
fix(webhook): exponential backoff not working
|
||||
|
||||
Retry attempts were using fixed 1s delay instead of
|
||||
exponential backoff. Fixed calculation in retry.py.
|
||||
|
||||
Fixes #55
|
||||
```
|
||||
|
||||
**Test:**
|
||||
```
|
||||
test(notebook): add unit tests for create_notebook
|
||||
|
||||
- Valid title returns notebook
|
||||
- Empty title raises ValidationError
|
||||
- Long title raises ValidationError
|
||||
```
|
||||
|
||||
## Branch Naming
|
||||
|
||||
| Tipo | Pattern | Esempio |
|
||||
|------|---------|---------|
|
||||
| Feature | `feat/<description>` | `feat/notebook-crud` |
|
||||
| Bugfix | `fix/<description>` | `fix/webhook-retry` |
|
||||
| Hotfix | `hotfix/<description>` | `hotfix/auth-bypass` |
|
||||
| Release | `release/v<version>` | `release/v1.0.0` |
|
||||
|
||||
## Checklist Pre-Commit
|
||||
|
||||
- [ ] Tutti i test passano (`uv run pytest`)
|
||||
- [ ] Code quality OK (`uv run ruff check`)
|
||||
- [ ] Type checking OK (`uv run mypy`)
|
||||
- [ ] Commit atomico (una sola funzionalità)
|
||||
- [ ] Messaggio segue Conventional Commits
|
||||
- [ ] Scope appropriato
|
||||
- [ ] Body descrittivo se necessario
|
||||
|
||||
## Flusso di Lavoro
|
||||
|
||||
1. **Prepara il commit:**
|
||||
```bash
|
||||
uv run pytest # Verifica test
|
||||
uv run ruff check # Verifica linting
|
||||
uv run pre-commit run # Verifica hook
|
||||
```
|
||||
|
||||
2. **Stage file:**
|
||||
```bash
|
||||
git add <file_specifico> # Non usare git add .
|
||||
```
|
||||
|
||||
3. **Commit:**
|
||||
```bash
|
||||
git commit -m "feat(api): add notebook creation endpoint
|
||||
|
||||
- Implements POST /api/v1/notebooks
|
||||
- Validates title length
|
||||
- Returns 201 with notebook details
|
||||
|
||||
Closes #123"
|
||||
```
|
||||
|
||||
4. **Documenta in githistory.md:**
|
||||
- Aggiorna `/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/githistory.md`
|
||||
- Aggiungi entry con contesto, motivazione, impatto
|
||||
- Inserisci in cima (più recente prima)
|
||||
|
||||
## Documentazione Commit (githistory.md)
|
||||
|
||||
Ogni commit DEVE essere documentato in `/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/githistory.md`:
|
||||
|
||||
```markdown
|
||||
## YYYY-MM-DD HH:MM - type(scope): description
|
||||
|
||||
**Hash:** `commit-hash`
|
||||
**Autore:** @agent
|
||||
**Branch:** branch-name
|
||||
|
||||
### Contesto
|
||||
[Perché questo commit era necessario]
|
||||
|
||||
### Cosa cambia
|
||||
[Descrizione modifiche]
|
||||
|
||||
### Perché
|
||||
[Motivazione scelte]
|
||||
|
||||
### Impatto
|
||||
- [x] Nuova feature / Bug fix / Refactoring / etc
|
||||
|
||||
### File modificati
|
||||
- `file.py` - descrizione cambiamento
|
||||
|
||||
### Note
|
||||
[Riferimenti issue, considerazioni]
|
||||
```
|
||||
|
||||
## Comportamento Vietato
|
||||
|
||||
- ❌ Commit con test falliti
|
||||
- ❌ `git add .` (selezionare file specifici)
|
||||
- ❌ Messaggi vaghi: "fix stuff", "update", "WIP"
|
||||
- ❌ Commit multi-funzionalità
|
||||
- ❌ Push force su main
|
||||
- ❌ Commit senza scope quando applicabile
|
||||
- ❌ Mancata documentazione in `githistory.md`
|
||||
88
.opencode/agents/security-reviewer.md
Normal file
88
.opencode/agents/security-reviewer.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Agente: Security Reviewer
|
||||
|
||||
## Ruolo
|
||||
Responsabile della revisione della sicurezza e della conformità alle best practices di sicurezza.
|
||||
|
||||
## Responsabilità
|
||||
|
||||
1. **Code Security Review**
|
||||
- Revisionare codice per vulnerabilità comuni
|
||||
- Verificare gestione segreti (API key, password, token)
|
||||
- Controllare validazione input
|
||||
- Verificare protezione contro SQL injection, XSS, CSRF
|
||||
|
||||
2. **Crittografia**
|
||||
- Verificare cifratura API key (AES-256)
|
||||
- Controllare hashing password (bcrypt/Argon2)
|
||||
- Validare gestione chiavi di cifratura
|
||||
- Verificare trasmissione sicura (HTTPS)
|
||||
|
||||
3. **Autenticazione e Autorizzazione**
|
||||
- Validare implementazione JWT
|
||||
- Verificare scadenza token
|
||||
- Controllare refresh token flow
|
||||
- Validare permessi e RBAC
|
||||
|
||||
4. **Compliance**
|
||||
- Verificare conformità GDPR (dati personali)
|
||||
- Controllare logging sicuro (no leak dati sensibili)
|
||||
- Validare rate limiting
|
||||
|
||||
## Checklist Sicurezza
|
||||
|
||||
### Per Ogni Feature
|
||||
|
||||
- [ ] **Input Validation**: Tutti gli input sono validati
|
||||
- [ ] **Output Encoding**: Prevenzione XSS
|
||||
- [ ] **Authentication**: Solo utenti autenticati accedono a risorse protette
|
||||
- [ ] **Authorization**: Verifica permessi per ogni operazione
|
||||
- [ ] **Secrets Management**: Nessun segreto in codice o log
|
||||
- [ ] **Error Handling**: Errori non leakano informazioni sensibili
|
||||
- [ ] **Logging**: Log di sicurezza per operazioni critiche
|
||||
|
||||
### Critico per Questo Progetto
|
||||
|
||||
- [ ] **API Key Encryption**: Chiavi OpenRouter cifrate con AES-256
|
||||
- [ ] **Password Hashing**: bcrypt con salt appropriato
|
||||
- [ ] **JWT Security**: Secret key forte, scadenza breve
|
||||
- [ ] **Rate Limiting**: Protezione brute force e DoS
|
||||
- [ ] **SQL Injection**: Query sempre parameterizzate
|
||||
- [ ] **CSRF Protection**: Token CSRF per form web
|
||||
|
||||
## Output
|
||||
|
||||
Quando trovi problemi di sicurezza, crea:
|
||||
|
||||
```markdown
|
||||
## Security Review: [Feature/Componente]
|
||||
|
||||
**Data:** YYYY-MM-DD
|
||||
**Revisore:** @security-reviewer
|
||||
|
||||
### Vulnerabilità Trovate
|
||||
|
||||
#### [ID-001] SQL Injection in endpoint X
|
||||
- **Livello:** 🔴 Critico / 🟡 Medio / 🟢 Basso
|
||||
- **File:** `src/path/to/file.py:line`
|
||||
- **Problema:** Descrizione
|
||||
- **Fix:** Soluzione proposta
|
||||
|
||||
### Raccomandazioni
|
||||
|
||||
1. [Raccomandazione specifica]
|
||||
|
||||
### Checklist Completata
|
||||
|
||||
- [x] Input validation
|
||||
- [x] Output encoding
|
||||
- ...
|
||||
```
|
||||
|
||||
Salva in: `/home/google/Sources/LucaSacchiNet/openrouter-watcher/docs/security_reviews/[feature].md`
|
||||
|
||||
## Comportamento Vietato
|
||||
|
||||
- ❌ Approvare codice con vulnerabilità critiche
|
||||
- ❌ Ignorare best practices di cifratura
|
||||
- ❌ Permettere logging di dati sensibili
|
||||
- ❌ Saltare review per "piccole modifiche"
|
||||
73
.opencode/agents/spec-architect.md
Normal file
73
.opencode/agents/spec-architect.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Agente: Spec-Driven Lead
|
||||
|
||||
## Ruolo
|
||||
Responsabile della definizione delle specifiche e dell'architettura prima dell'implementazione.
|
||||
|
||||
## Responsabilità
|
||||
|
||||
1. **Analisi dei Requisiti**
|
||||
- Leggere e comprendere il PRD (`/home/google/Sources/LucaSacchiNet/openrouter-watcher/prd.md`)
|
||||
- Fare domande mirate per chiarire ambiguità
|
||||
- Non procedere se i requisiti sono vaghi
|
||||
|
||||
2. **Definizione Specifiche**
|
||||
- Creare/aggiornare `/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/prd.md` con:
|
||||
- Obiettivi chiari e misurabili
|
||||
- User stories (formato: "Come [ruolo], voglio [obiettivo], per [beneficio]")
|
||||
- Requisiti tecnici specifici
|
||||
- Criteri di accettazione
|
||||
|
||||
3. **Architettura**
|
||||
- Creare/aggiornare `/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/architecture.md` con:
|
||||
- Scelte architetturali
|
||||
- Stack tecnologico
|
||||
- Diagrammi di flusso
|
||||
- Interfacce e contratti API
|
||||
|
||||
4. **Pianificazione**
|
||||
- Creare/aggiornare `/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/kanban.md` con:
|
||||
- Scomposizione in task minimi
|
||||
- Dipendenze tra task
|
||||
- Stima complessità
|
||||
- Regola "little often": task verificabili in <2 ore
|
||||
|
||||
## Principi Guida
|
||||
|
||||
- **Rigore**: Essere diretti, concisi, tecnici
|
||||
- **Nessuna Supposizione**: Se qualcosa è vago, chiedere
|
||||
- **Little Often**: Task piccoli, progresso incrementale
|
||||
- **Output Definiti**: Solo i 3 file in /export/ sono l'output valido
|
||||
|
||||
## Domande da Fare (Checklist)
|
||||
|
||||
Prima di iniziare:
|
||||
- [ ] Qual è il problema che stiamo risolvendo?
|
||||
- [ ] Chi sono gli utenti finali?
|
||||
- [ ] Quali sono i vincoli tecnici?
|
||||
- [ ] Ci sono dipendenze da altri componenti?
|
||||
- [ ] Qual è il criterio di successo?
|
||||
- [ ] Quali sono i casi limite/errori da gestire?
|
||||
|
||||
## Output Attesi
|
||||
|
||||
```
|
||||
/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/
|
||||
├── prd.md # Requisiti prodotto
|
||||
├── architecture.md # Architettura sistema
|
||||
├── kanban.md # Task breakdown
|
||||
└── progress.md # Tracciamento progresso
|
||||
```
|
||||
|
||||
## Progress Tracking
|
||||
|
||||
Quando crei una nuova feature/specifica:
|
||||
1. Inizializza `progress.md` con la feature corrente
|
||||
2. Imposta stato a "🔴 Pianificazione"
|
||||
3. Aggiorna metriche e task pianificate
|
||||
|
||||
## Comportamento Vietato
|
||||
|
||||
- ❌ Inventare requisiti non espliciti
|
||||
- ❌ Procedere senza specifiche chiare
|
||||
- ❌ Creare task troppo grandi
|
||||
- ❌ Ignorare vincoli tecnici
|
||||
163
.opencode/agents/tdd-developer.md
Normal file
163
.opencode/agents/tdd-developer.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# Agente: TDD Developer
|
||||
|
||||
## Ruolo
|
||||
Responsabile dell'implementazione seguendo rigorosamente il Test-Driven Development.
|
||||
|
||||
## Responsabilità
|
||||
|
||||
1. **Sviluppo TDD**
|
||||
- Seguire il ciclo RED → GREEN → REFACTOR
|
||||
- Implementare una singola funzionalità alla volta
|
||||
- Non saltare mai la fase di test
|
||||
|
||||
2. **Qualità del Codice**
|
||||
- Scrivere codice minimo per passare il test
|
||||
- Refactoring continuo
|
||||
- Coverage ≥90%
|
||||
|
||||
3. **Documentazione**
|
||||
- Aggiornare `/home/google/Sources/LucaSacchiNet/openrouter-watcher/docs/bug_ledger.md` per bug complessi
|
||||
- Aggiornare `/home/google/Sources/LucaSacchiNet/openrouter-watcher/docs/architecture.md` per cambi di design
|
||||
- Aggiornare `/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/progress.md` all'inizio e fine di ogni task
|
||||
|
||||
4. **Git**
|
||||
- Commit atomici alla fine di ogni task verde
|
||||
- Conventional commits obbligatori
|
||||
|
||||
## Progress Tracking
|
||||
|
||||
All'inizio di ogni task:
|
||||
1. Apri `progress.md`
|
||||
2. Aggiorna "Task Corrente" con ID e descrizione
|
||||
3. Imposta stato a "🟡 In progress"
|
||||
4. Aggiorna timestamp inizio
|
||||
|
||||
Al completamento:
|
||||
1. Sposta task in "Task Completate"
|
||||
2. Aggiungi commit reference
|
||||
3. Aggiorna percentuale completamento
|
||||
4. Aggiorna timestamp fine
|
||||
5. Documenta commit in `githistory.md` con contesto e motivazione
|
||||
|
||||
## Ciclo di Lavoro TDD
|
||||
|
||||
### Fase 1: RED (Scrivere il test)
|
||||
```python
|
||||
# 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)
|
||||
```python
|
||||
# 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)
|
||||
```python
|
||||
# Pulire codice, rimuovere duplicazione, migliorare nomi
|
||||
# I test devono rimanere verdi
|
||||
```
|
||||
|
||||
## Pattern di Test (AAA)
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
1. **Un test = Un comportamento**
|
||||
2. **Testare prima i casi d'errore**
|
||||
3. **Nomi descrittivi**: `test_<behavior>_<condition>_<expected>`
|
||||
4. **No logic in tests**: No if/else, no loop
|
||||
5. **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
|
||||
```python
|
||||
@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/openrouter-watcher/docs/bug_ledger.md`:
|
||||
|
||||
```markdown
|
||||
## 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%
|
||||
29
.opencode/opencode.json
Normal file
29
.opencode/opencode.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"sequential-thinking": {
|
||||
"type": "local",
|
||||
"command": [
|
||||
"npx",
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-sequential-thinking"
|
||||
]
|
||||
},
|
||||
"context7": {
|
||||
"type": "local",
|
||||
"command": [
|
||||
"npx",
|
||||
"-y",
|
||||
"@context7/mcp-server"
|
||||
]
|
||||
},
|
||||
"universal-skills": {
|
||||
"type": "local",
|
||||
"command": [
|
||||
"npx",
|
||||
"-y",
|
||||
"github:jacob-bd/universal-skills-manager"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
221
.opencode/skills/project-guidelines/SKILL.md
Normal file
221
.opencode/skills/project-guidelines/SKILL.md
Normal file
@@ -0,0 +1,221 @@
|
||||
---
|
||||
name: project-guidelines
|
||||
description: Linee guida per lo sviluppo del progetto. Usa questa skill per comprendere l'architettura, le convenzioni di codice e il workflow di sviluppo.
|
||||
---
|
||||
|
||||
# Project Guidelines - [NOME PROGETTO]
|
||||
|
||||
> ⚠️ **NOTA**: Personalizza questo file con il nome e la descrizione del tuo progetto!
|
||||
|
||||
## Panoramica del Progetto
|
||||
|
||||
**[NOME PROGETTO]** è [breve descrizione del progetto - da personalizzare].
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Leggere Prima
|
||||
1. **Workflow**: `.opencode/WORKFLOW.md` - Flusso di lavoro obbligatorio
|
||||
2. **PRD**: `prd.md` - Requisiti prodotto
|
||||
3. **AGENTS.md**: Linee guida generali del progetto (se esiste)
|
||||
|
||||
### Agenti Disponibili (in `.opencode/agents/`)
|
||||
|
||||
| Agente | Ruolo | Quando Usare |
|
||||
|--------|-------|--------------|
|
||||
| `@spec-architect` | Definisce specifiche e architettura | Prima di nuove feature |
|
||||
| `@tdd-developer` | Implementazione TDD | Durante sviluppo |
|
||||
| `@git-manager` | Gestione commit Git | A fine task |
|
||||
|
||||
## Flusso di Lavoro (OBBLIGATORIO)
|
||||
|
||||
### Per Nuove Feature
|
||||
|
||||
```
|
||||
1. @spec-architect → Legge PRD, definisce specifiche
|
||||
↓
|
||||
Crea/aggiorna:
|
||||
- /export/prd.md
|
||||
- /export/architecture.md
|
||||
- /export/kanban.md
|
||||
↓
|
||||
2. @tdd-developer → Implementa seguendo TDD
|
||||
↓
|
||||
RED → GREEN → REFACTOR
|
||||
↓
|
||||
3. @git-manager → Commit atomico
|
||||
↓
|
||||
Conventional Commit
|
||||
```
|
||||
|
||||
### Per Bug Fix
|
||||
|
||||
```
|
||||
1. Leggi bug_ledger.md per pattern simili
|
||||
2. Scrivi test che riproduce il bug
|
||||
3. Implementa fix
|
||||
4. Aggiorna bug_ledger.md
|
||||
5. Commit con tipo "fix:"
|
||||
```
|
||||
|
||||
## Regole Fondamentali
|
||||
|
||||
### 1. TDD (Test-Driven Development)
|
||||
- **RED**: Scrivi test fallimentare PRIMA
|
||||
- **GREEN**: Scrivi codice minimo per passare
|
||||
- **REFACTOR**: Migliora mantenendo test verdi
|
||||
|
||||
### 2. Spec-Driven
|
||||
- Leggi sempre `prd.md` prima di implementare
|
||||
- Non implementare funzionalità non richieste
|
||||
- Output specifiche in `/export/`
|
||||
|
||||
### 3. Little Often
|
||||
- Task piccoli e verificabili
|
||||
- Progresso incrementale
|
||||
- Commit atomici
|
||||
|
||||
### 4. Memoria
|
||||
- Bug complessi → `docs/bug_ledger.md`
|
||||
- Decisioni design → `docs/architecture.md`
|
||||
- Progresso task → `export/progress.md` (aggiorna inizio/fine task)
|
||||
|
||||
### 5. Git
|
||||
- Conventional commits obbligatori
|
||||
- Commit atomici
|
||||
- Test verdi prima del commit
|
||||
- Documenta contesto in `export/githistory.md`
|
||||
|
||||
## Struttura Progetto (Personalizza)
|
||||
|
||||
```
|
||||
[nome-progetto]/
|
||||
├── src/ # Codice sorgente
|
||||
│ └── [nome_package]/
|
||||
│ ├── [moduli]/ # Moduli applicativi
|
||||
│ └── ...
|
||||
├── tests/ # Test suite
|
||||
│ ├── unit/
|
||||
│ ├── integration/
|
||||
│ └── e2e/
|
||||
├── docs/ # Documentazione
|
||||
│ ├── bug_ledger.md # Log bug risolti
|
||||
│ └── architecture.md # Decisioni architetturali
|
||||
├── export/ # Output spec-driven
|
||||
│ ├── prd.md # Product Requirements
|
||||
│ ├── architecture.md # Architettura
|
||||
│ ├── kanban.md # Task breakdown
|
||||
│ ├── progress.md # Tracciamento progresso
|
||||
│ └── githistory.md # Storico commit
|
||||
├── .opencode/ # Configurazione OpenCode
|
||||
│ ├── WORKFLOW.md # Flusso di lavoro
|
||||
│ ├── agents/ # Configurazioni agenti
|
||||
│ └── skills/ # Skill condivise
|
||||
├── scripts/ # Script utilità
|
||||
├── prd.md # Product Requirements (root)
|
||||
├── AGENTS.md # Linee guida generali (opzionale)
|
||||
└── SKILL.md # Questo file
|
||||
```
|
||||
|
||||
## Convenzioni di Codice (Personalizza)
|
||||
|
||||
### [Linguaggio - es. Python/JavaScript/Go]
|
||||
- Versione: [es. 3.10+]
|
||||
- Stile: [es. PEP 8 / StandardJS / gofmt]
|
||||
- Type hints: [obbligatorio/consigliato]
|
||||
- Line length: [es. 100 caratteri]
|
||||
|
||||
### Testing
|
||||
- Framework: [pytest/jest/go test]
|
||||
- Coverage target: ≥90%
|
||||
- Pattern: AAA (Arrange-Act-Assert)
|
||||
- Mock per dipendenze esterne
|
||||
|
||||
### Commit
|
||||
```
|
||||
<type>(<scope>): <description>
|
||||
|
||||
[body]
|
||||
|
||||
[footer]
|
||||
```
|
||||
|
||||
**Tipi:** feat, fix, docs, test, refactor, chore, ci, style
|
||||
**Scope:** [personalizza in base al progetto - es. api, db, ui, core]
|
||||
|
||||
## Risorse
|
||||
|
||||
| File | Scopo |
|
||||
|------|-------|
|
||||
| `prd.md` | Requisiti prodotto |
|
||||
| `AGENTS.md` | Linee guida progetto (se esiste) |
|
||||
| `.opencode/WORKFLOW.md` | Flusso di lavoro dettagliato |
|
||||
| `.opencode/agents/` | Configurazioni agenti |
|
||||
| `docs/bug_ledger.md` | Log bug risolti |
|
||||
| `docs/architecture.md` | Decisioni architetturali |
|
||||
| `export/progress.md` | Tracciamento progresso task |
|
||||
| `export/githistory.md` | Storico commit con contesto |
|
||||
| `CHANGELOG.md` | Changelog |
|
||||
| `CONTRIBUTING.md` | Guida contribuzione |
|
||||
|
||||
## Comandi Utili (Personalizza)
|
||||
|
||||
```bash
|
||||
# Test
|
||||
[comando test] # Tutti i test
|
||||
[comando test --coverage] # Con coverage
|
||||
|
||||
# Qualità
|
||||
[comando lint] # Linting
|
||||
[comando format] # Formattazione
|
||||
[comando type-check] # Type checking
|
||||
|
||||
# Pre-commit
|
||||
[comando pre-commit]
|
||||
|
||||
# Server/Run
|
||||
[comando run]
|
||||
```
|
||||
|
||||
## Checklist
|
||||
|
||||
### Setup Iniziale (da fare una volta)
|
||||
- [ ] Personalizzato `SKILL.md` con nome progetto
|
||||
- [ ] Creata struttura cartelle `src/`
|
||||
- [ ] Configurato ambiente di sviluppo
|
||||
- [ ] Inizializzato `prd.md` con requisiti
|
||||
- [ ] Inizializzato `export/kanban.md` con task
|
||||
|
||||
### Pre-Implementazione
|
||||
- [ ] Ho letto `prd.md`
|
||||
- [ ] Ho compreso lo scope
|
||||
- [ ] Ho letto `.opencode/WORKFLOW.md`
|
||||
|
||||
### Durante Implementazione
|
||||
- [ ] Test scritto prima (RED)
|
||||
- [ ] Codice minimo (GREEN)
|
||||
- [ ] Refactoring (REFACTOR)
|
||||
|
||||
### Post-Implementazione
|
||||
- [ ] Tutti i test passano
|
||||
- [ ] Coverage ≥90%
|
||||
- [ ] `bug_ledger.md` aggiornato (se bug)
|
||||
- [ ] `architecture.md` aggiornato (se design)
|
||||
- [ ] `progress.md` aggiornato (inizio/fine task)
|
||||
- [ ] `githistory.md` aggiornato (contesto commit)
|
||||
- [ ] Commit con conventional commits
|
||||
|
||||
---
|
||||
|
||||
*Per dettagli su flusso di lavoro, vedere `.opencode/WORKFLOW.md`*
|
||||
|
||||
---
|
||||
|
||||
## 📝 Note per l'Utente
|
||||
|
||||
Questo è un template. Per usarlo:
|
||||
|
||||
1. **Sostituisci** `[NOME PROGETTO]` con il nome reale
|
||||
2. **Descrivi** il progetto nella sezione Panoramica
|
||||
3. **Personalizza** la struttura cartelle in base al tuo stack
|
||||
4. **Aggiungi** comandi specifici del tuo linguaggio/framework
|
||||
5. **Definisci** gli scope dei commit pertinenti al tuo progetto
|
||||
1094
export/architecture.md
Normal file
1094
export/architecture.md
Normal file
File diff suppressed because it is too large
Load Diff
242
export/kanban.md
Normal file
242
export/kanban.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# Kanban Board
|
||||
|
||||
## OpenRouter API Key Monitor - Fase 1 (MVP)
|
||||
|
||||
---
|
||||
|
||||
## Legenda
|
||||
|
||||
- **Complessità**: S (Small < 1h) | M (Medium 1-2h) | L (Large 2-4h, deve essere scomposto)
|
||||
- **Priorità**: P0 (Bloccante) | P1 (Alta) | P2 (Media) | P3 (Bassa)
|
||||
- **Dipendenze**: Task che devono essere completati prima
|
||||
|
||||
---
|
||||
|
||||
## 📋 BACKLOG / TODO
|
||||
|
||||
### 🔧 Setup Progetto (Fondamentale)
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T01 | Creare struttura cartelle progetto | S | P0 | - | `app/`, `tests/`, `alembic/` |
|
||||
| T02 | Inizializzare virtual environment | S | P0 | - | Python 3.11+ |
|
||||
| T03 | Creare requirements.txt con dipendenze | S | P0 | T02 | FastAPI, SQLAlchemy, etc. |
|
||||
| T04 | Setup file configurazione (.env, config.py) | S | P0 | T03 | Variabili d'ambiente |
|
||||
| T05 | Configurare pytest e struttura test | S | P0 | T02 | pytest.ini, conftest.py |
|
||||
|
||||
### 🗄️ Database & Models
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T06 | Creare database.py (connection & session) | S | P0 | T04 | SQLAlchemy engine |
|
||||
| T07 | Creare model User (SQLAlchemy) | M | P0 | T06 | Tabella users |
|
||||
| T08 | Creare model ApiKey (SQLAlchemy) | M | P0 | T07 | Tabella api_keys |
|
||||
| T09 | Creare model UsageStats (SQLAlchemy) | M | P1 | T08 | Tabella usage_stats |
|
||||
| T10 | Creare model ApiToken (SQLAlchemy) | M | P1 | T07 | Tabella api_tokens |
|
||||
| T11 | Setup Alembic e creare migrazione iniziale | M | P0 | T07-T10 | `alembic init` + revision |
|
||||
|
||||
### 🔐 Servizi di Sicurezza
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T12 | Implementare EncryptionService (AES-256) | M | P0 | - | cryptography library |
|
||||
| T13 | Implementare password hashing (bcrypt) | S | P0 | - | passlib |
|
||||
| T14 | Implementare JWT utilities | S | P0 | T12 | python-jose |
|
||||
| T15 | Implementare API token generation | S | P1 | T13 | SHA-256 hash |
|
||||
| T16 | Scrivere test per servizi di encryption | M | P1 | T12-T15 | Unit tests |
|
||||
|
||||
### 👤 Autenticazione Utenti
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T17 | Creare Pydantic schemas auth (register/login) | S | P0 | T07 | Validazione input |
|
||||
| T18 | Implementare endpoint POST /api/auth/register | M | P0 | T13, T17 | Creazione utente |
|
||||
| T19 | Implementare endpoint POST /api/auth/login | M | P0 | T14, T18 | JWT generation |
|
||||
| T20 | Implementare endpoint POST /api/auth/logout | S | P0 | T19 | Token invalidation |
|
||||
| T21 | Creare dipendenza get_current_user | S | P0 | T19 | FastAPI dependency |
|
||||
| T22 | Scrivere test per auth endpoints | M | P0 | T18-T21 | pytest |
|
||||
|
||||
### 🔑 Gestione API Keys
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T23 | Creare Pydantic schemas per API keys | S | P0 | T08 | CRUD schemas |
|
||||
| T24 | Implementare POST /api/keys (create) | M | P0 | T12, T21, T23 | Con cifratura |
|
||||
| T25 | Implementare GET /api/keys (list) | S | P0 | T21, T23 | Lista key utente |
|
||||
| T26 | Implementare PUT /api/keys/{id} (update) | S | P0 | T21, T24 | Modifica nome/stato |
|
||||
| T27 | Implementare DELETE /api/keys/{id} | S | P0 | T21 | Eliminazione |
|
||||
| T28 | Implementare servizio validazione key | M | P1 | T24 | Chiamata a OpenRouter |
|
||||
| T29 | Scrivere test per API keys CRUD | M | P0 | T24-T27 | pytest |
|
||||
|
||||
### 📊 Dashboard & Statistiche (Base)
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T30 | Creare Pydantic schemas per stats | S | P1 | T09 | Response models |
|
||||
| T31 | Implementare servizio aggregazione stats | M | P1 | T09 | Query SQL |
|
||||
| T32 | Implementare endpoint GET /api/stats | M | P1 | T21, T31 | Stats aggregate |
|
||||
| T33 | Implementare endpoint GET /api/usage | M | P1 | T21, T31 | Dettaglio usage |
|
||||
| T34 | Scrivere test per stats endpoints | M | P1 | T32, T33 | pytest |
|
||||
|
||||
### 🌐 Public API v1 (Esterna)
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T35 | Creare dipendenza verify_api_token | S | P0 | T15 | Bearer token auth |
|
||||
| T36 | Implementare POST /api/tokens (generate) | M | P0 | T15, T21 | API token management |
|
||||
| T37 | Implementare GET /api/tokens (list) | S | P0 | T21 | Lista token utente |
|
||||
| T38 | Implementare DELETE /api/tokens/{id} | S | P0 | T21 | Revoca token |
|
||||
| T39 | Implementare GET /api/v1/stats | M | P0 | T31, T35 | Public endpoint |
|
||||
| T40 | Implementare GET /api/v1/usage | M | P0 | T33, T35 | Public endpoint |
|
||||
| T41 | Implementare GET /api/v1/keys | M | P0 | T25, T35 | Public endpoint |
|
||||
| T42 | Implementare rate limiting su public API | M | P1 | T35-T41 | slowapi |
|
||||
| T43 | Scrivere test per public API | M | P1 | T36-T42 | pytest |
|
||||
|
||||
### 🎨 Frontend Web (HTMX)
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T44 | Setup Jinja2 templates e static files | S | P0 | - | Configurazione FastAPI |
|
||||
| T45 | Creare base.html (layout principale) | S | P0 | T44 | Template base |
|
||||
| T46 | Creare login.html | S | P0 | T45 | Form login |
|
||||
| T47 | Creare register.html | S | P0 | T45 | Form registrazione |
|
||||
| T48 | Implementare router /login (GET/POST) | M | P0 | T46 | Web endpoint |
|
||||
| T49 | Implementare router /register (GET/POST) | M | P0 | T47 | Web endpoint |
|
||||
| T50 | Creare dashboard.html | M | P1 | T45 | Panoramica |
|
||||
| T51 | Implementare router /dashboard | S | P1 | T50, T21 | Web endpoint |
|
||||
| T52 | Creare keys.html | M | P1 | T45 | Gestione API keys |
|
||||
| T53 | Implementare router /keys | S | P1 | T52, T24 | Web endpoint |
|
||||
| T54 | Aggiungere HTMX per azioni CRUD | M | P2 | T52 | AJAX senza reload |
|
||||
|
||||
### ⚙️ Background Tasks
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T55 | Configurare APScheduler | S | P2 | - | Setup scheduler |
|
||||
| T56 | Implementare task sync usage stats | M | P2 | T09, T28 | Ogni ora |
|
||||
| T57 | Implementare task validazione key | M | P2 | T28 | Ogni giorno |
|
||||
| T58 | Integrare scheduler in startup app | S | P2 | T55-T57 | Lifespan event |
|
||||
|
||||
### 🔒 Sicurezza & Hardening
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T59 | Implementare security headers middleware | S | P1 | - | XSS, CSRF protection |
|
||||
| T60 | Implementare rate limiting auth endpoints | S | P1 | T18, T19 | slowapi |
|
||||
| T61 | Implementare CORS policy | S | P1 | - | Configurazione |
|
||||
| T62 | Audit: verificare cifratura API keys | S | P1 | T12 | Verifica sicurezza |
|
||||
| T63 | Audit: verificare SQL injection prevention | S | P1 | T06 | Parameterized queries |
|
||||
|
||||
### 🧪 Testing & QA
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T64 | Scrivere test unitari per models | S | P1 | T07-T10 | pytest |
|
||||
| T65 | Scrivere test integrazione auth flow | M | P1 | T18-T22 | End-to-end |
|
||||
| T66 | Scrivere test integrazione API keys | M | P1 | T24-T29 | End-to-end |
|
||||
| T67 | Verificare coverage >= 90% | S | P1 | T64-T66 | pytest-cov |
|
||||
| T68 | Eseguire security scan dipendenze | S | P2 | - | safety, pip-audit |
|
||||
|
||||
### 📝 Documentazione
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T69 | Scrivere README.md completo | M | P2 | - | Setup, usage |
|
||||
| T70 | Documentare API con OpenAPI | S | P2 | - | FastAPI auto-docs |
|
||||
| T71 | Creare esempi curl per API | S | P3 | T39-T41 | Usage examples |
|
||||
|
||||
### 🚀 Deployment
|
||||
|
||||
| ID | Task | Compl. | Priorità | Dipendenze | Note |
|
||||
|----|------|--------|----------|------------|------|
|
||||
| T72 | Creare Dockerfile | M | P2 | - | Containerization |
|
||||
| T73 | Creare docker-compose.yml | S | P2 | T72 | Stack completo |
|
||||
| T74 | Scrivere script avvio produzione | S | P2 | T72 | Entry point |
|
||||
|
||||
---
|
||||
|
||||
## 🚧 IN PROGRESS
|
||||
|
||||
*Task attualmente in lavorazione*
|
||||
|
||||
| ID | Task | Assegnato | Iniziato | Note |
|
||||
|----|------|-----------|----------|------|
|
||||
| - | - | - | - | - |
|
||||
|
||||
---
|
||||
|
||||
## 👀 REVIEW
|
||||
|
||||
*Task completati, in attesa di review*
|
||||
|
||||
| ID | Task | Assegnato | Completato | Reviewer | Note |
|
||||
|----|------|-----------|------------|----------|------|
|
||||
| - | - | - | - | - | - |
|
||||
|
||||
---
|
||||
|
||||
## ✅ DONE
|
||||
|
||||
*Task completati e verificati*
|
||||
|
||||
| ID | Task | Assegnato | Completato | Note |
|
||||
|----|------|-----------|------------|------|
|
||||
| - | - | - | - | - |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Statistiche
|
||||
|
||||
| Stato | Conteggio | Percentuale |
|
||||
|-------|-----------|-------------|
|
||||
| TODO | 74 | 100% |
|
||||
| IN PROGRESS | 0 | 0% |
|
||||
| REVIEW | 0 | 0% |
|
||||
| DONE | 0 | 0% |
|
||||
| **Totale** | **74** | **0%** |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Milestone Fase 1 (MVP)
|
||||
|
||||
### Blocker Tasks (Devono essere completati prima)
|
||||
- T01-T05: Setup progetto
|
||||
- T06-T11: Database setup
|
||||
- T12-T16: Servizi sicurezza
|
||||
|
||||
### Core Features MVP
|
||||
- ✅ Autenticazione utenti (registrazione/login/logout JWT)
|
||||
- ✅ CRUD API key (cifrate AES-256)
|
||||
- ✅ Dashboard statistiche base (aggregazione)
|
||||
- ✅ API pubblica autenticata (sola lettura)
|
||||
|
||||
### Definition of Done (DoD)
|
||||
- [ ] Tutti i test passano (`pytest`)
|
||||
- [ ] Coverage >= 90% (`pytest --cov`)
|
||||
- [ ] Security headers implementati
|
||||
- [ ] Rate limiting attivo
|
||||
- [ ] API documentate (OpenAPI)
|
||||
- [ ] README completo
|
||||
- [ ] Nessun errore linting (`ruff check`)
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Dipendenze Chiave
|
||||
|
||||
```
|
||||
T01-T05 (Setup)
|
||||
└── T06-T11 (Database)
|
||||
├── T12-T16 (Security)
|
||||
│ ├── T17-T22 (Auth)
|
||||
│ ├── T23-T29 (API Keys)
|
||||
│ │ └── T28 (Validation)
|
||||
│ │ └── T55-T58 (Background Tasks)
|
||||
│ └── T30-T34 (Stats)
|
||||
│ └── T35-T43 (Public API)
|
||||
└── T44-T54 (Frontend)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Ultimo aggiornamento: 2024-01-15*
|
||||
*Versione: 1.0*
|
||||
196
export/progress.md
Normal file
196
export/progress.md
Normal file
@@ -0,0 +1,196 @@
|
||||
# Progress Tracking
|
||||
|
||||
## Feature: Fase 1 - MVP OpenRouter API Key Monitor
|
||||
|
||||
---
|
||||
|
||||
## 📊 Stato Generale
|
||||
|
||||
| Metrica | Valore |
|
||||
|---------|--------|
|
||||
| **Stato** | 🟡 In Progress |
|
||||
| **Progresso** | 1% |
|
||||
| **Data Inizio** | 2024-04-07 |
|
||||
| **Data Target** | TBD |
|
||||
| **Task Totali** | 74 |
|
||||
| **Task Completati** | 1 |
|
||||
| **Task In Progress** | 1 |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Obiettivi Fase 1 (MVP)
|
||||
|
||||
### Core Features
|
||||
1. ✅ **Autenticazione utenti** (registrazione/login JWT)
|
||||
2. ✅ **CRUD API key** (cifrate AES-256)
|
||||
3. ✅ **Dashboard statistiche base** (aggregazione dati)
|
||||
4. ✅ **API pubblica autenticata** (sola lettura)
|
||||
|
||||
### Requisiti Non Funzionali
|
||||
- [ ] Tempo di risposta web < 2 secondi
|
||||
- [ ] API response time < 500ms
|
||||
- [ ] Supporto 100+ utenti concorrenti
|
||||
- [ ] Test coverage >= 90%
|
||||
- [ ] Sicurezza: AES-256, bcrypt, JWT, rate limiting
|
||||
|
||||
---
|
||||
|
||||
## 📋 Task Pianificate
|
||||
|
||||
### 🔧 Setup Progetto (T01-T05) - 1/5 completati
|
||||
- [x] T01: Creare struttura cartelle progetto (2024-04-07)
|
||||
- [ ] T02: Inizializzare virtual environment
|
||||
- [ ] T03: Creare requirements.txt con dipendenze
|
||||
- [ ] T04: Setup file configurazione (.env, config.py)
|
||||
- [ ] T05: Configurare pytest e struttura test
|
||||
|
||||
### 🗄️ Database & Models (T06-T11) - 0/6 completati
|
||||
- [ ] T06: Creare database.py (connection & session)
|
||||
- [ ] T07: Creare model User (SQLAlchemy)
|
||||
- [ ] T08: Creare model ApiKey (SQLAlchemy)
|
||||
- [ ] T09: Creare model UsageStats (SQLAlchemy)
|
||||
- [ ] T10: Creare model ApiToken (SQLAlchemy)
|
||||
- [ ] T11: Setup Alembic e creare migrazione iniziale
|
||||
|
||||
### 🔐 Servizi di Sicurezza (T12-T16) - 0/5 completati
|
||||
- [ ] T12: Implementare EncryptionService (AES-256)
|
||||
- [ ] T13: Implementare password hashing (bcrypt)
|
||||
- [ ] T14: Implementare JWT utilities
|
||||
- [ ] T15: Implementare API token generation
|
||||
- [ ] T16: Scrivere test per servizi di encryption
|
||||
|
||||
### 👤 Autenticazione Utenti (T17-T22) - 0/6 completati
|
||||
- [ ] T17: Creare Pydantic schemas auth (register/login)
|
||||
- [ ] T18: Implementare endpoint POST /api/auth/register
|
||||
- [ ] T19: Implementare endpoint POST /api/auth/login
|
||||
- [ ] T20: Implementare endpoint POST /api/auth/logout
|
||||
- [ ] T21: Creare dipendenza get_current_user
|
||||
- [ ] T22: Scrivere test per auth endpoints
|
||||
|
||||
### 🔑 Gestione API Keys (T23-T29) - 0/7 completati
|
||||
- [ ] T23: Creare Pydantic schemas per API keys
|
||||
- [ ] T24: Implementare POST /api/keys (create)
|
||||
- [ ] T25: Implementare GET /api/keys (list)
|
||||
- [ ] T26: Implementare PUT /api/keys/{id} (update)
|
||||
- [ ] T27: Implementare DELETE /api/keys/{id}
|
||||
- [ ] T28: Implementare servizio validazione key
|
||||
- [ ] T29: Scrivere test per API keys CRUD
|
||||
|
||||
### 📊 Dashboard & Statistiche (T30-T34) - 0/5 completati
|
||||
- [ ] T30: Creare Pydantic schemas per stats
|
||||
- [ ] T31: Implementare servizio aggregazione stats
|
||||
- [ ] T32: Implementare endpoint GET /api/stats
|
||||
- [ ] T33: Implementare endpoint GET /api/usage
|
||||
- [ ] T34: Scrivere test per stats endpoints
|
||||
|
||||
### 🌐 Public API v1 (T35-T43) - 0/9 completati
|
||||
- [ ] T35: Creare dipendenza verify_api_token
|
||||
- [ ] T36: Implementare POST /api/tokens (generate)
|
||||
- [ ] T37: Implementare GET /api/tokens (list)
|
||||
- [ ] T38: Implementare DELETE /api/tokens/{id}
|
||||
- [ ] T39: Implementare GET /api/v1/stats
|
||||
- [ ] T40: Implementare GET /api/v1/usage
|
||||
- [ ] T41: Implementare GET /api/v1/keys
|
||||
- [ ] T42: Implementare rate limiting su public API
|
||||
- [ ] T43: Scrivere test per public API
|
||||
|
||||
### 🎨 Frontend Web (T44-T54) - 0/11 completati
|
||||
- [ ] T44: Setup Jinja2 templates e static files
|
||||
- [ ] T45: Creare base.html (layout principale)
|
||||
- [ ] T46: Creare login.html
|
||||
- [ ] T47: Creare register.html
|
||||
- [ ] T48: Implementare router /login (GET/POST)
|
||||
- [ ] T49: Implementare router /register (GET/POST)
|
||||
- [ ] T50: Creare dashboard.html
|
||||
- [ ] T51: Implementare router /dashboard
|
||||
- [ ] T52: Creare keys.html
|
||||
- [ ] T53: Implementare router /keys
|
||||
- [ ] T54: Aggiungere HTMX per azioni CRUD
|
||||
|
||||
### ⚙️ Background Tasks (T55-T58) - 0/4 completati
|
||||
- [ ] T55: Configurare APScheduler
|
||||
- [ ] T56: Implementare task sync usage stats
|
||||
- [ ] T57: Implementare task validazione key
|
||||
- [ ] T58: Integrare scheduler in startup app
|
||||
|
||||
### 🔒 Sicurezza & Hardening (T59-T63) - 0/5 completati
|
||||
- [ ] T59: Implementare security headers middleware
|
||||
- [ ] T60: Implementare rate limiting auth endpoints
|
||||
- [ ] T61: Implementare CORS policy
|
||||
- [ ] T62: Audit: verificare cifratura API keys
|
||||
- [ ] T63: Audit: verificare SQL injection prevention
|
||||
|
||||
### 🧪 Testing & QA (T64-T68) - 0/5 completati
|
||||
- [ ] T64: Scrivere test unitari per models
|
||||
- [ ] T65: Scrivere test integrazione auth flow
|
||||
- [ ] T66: Scrivere test integrazione API keys
|
||||
- [ ] T67: Verificare coverage >= 90%
|
||||
- [ ] T68: Eseguire security scan dipendenze
|
||||
|
||||
### 📝 Documentazione (T69-T71) - 0/3 completati
|
||||
- [ ] T69: Scrivere README.md completo
|
||||
- [ ] T70: Documentare API con OpenAPI
|
||||
- [ ] T71: Creare esempi curl per API
|
||||
|
||||
### 🚀 Deployment (T72-T74) - 0/3 completati
|
||||
- [ ] T72: Creare Dockerfile
|
||||
- [ ] T73: Creare docker-compose.yml
|
||||
- [ ] T74: Scrivere script avvio produzione
|
||||
|
||||
---
|
||||
|
||||
## 📈 Grafico Progresso
|
||||
|
||||
```
|
||||
Progresso MVP Fase 1
|
||||
|
||||
TODO [████████████████████████████████████████] 100%
|
||||
IN PROGRESS [ ] 0%
|
||||
REVIEW [ ] 0%
|
||||
DONE [ ] 0%
|
||||
|
||||
0% 25% 50% 75% 100%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔥 Blockers
|
||||
|
||||
*Nessun blocker attivo*
|
||||
|
||||
| ID | Descrizione | Impatto | Data Apertura | Data Risoluzione |
|
||||
|----|-------------|---------|---------------|------------------|
|
||||
| - | - | - | - | - |
|
||||
|
||||
---
|
||||
|
||||
## 📝 Decisioni Log
|
||||
|
||||
| Data | Decisione | Motivazione | Stato |
|
||||
|------|-----------|-------------|-------|
|
||||
| 2024-01-15 | Stack: FastAPI + SQLite + HTMX | MVP semplice, zero-config | ✅ Approvata |
|
||||
| 2024-01-15 | Cifratura: AES-256-GCM | Requisito sicurezza PRD | ✅ Approvata |
|
||||
| 2024-01-15 | Auth: JWT con cookie | Semplice per web + API | ✅ Approvata |
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Issue Tracking
|
||||
|
||||
*Issue riscontrati durante lo sviluppo*
|
||||
|
||||
| ID | Descrizione | Severità | Stato | Assegnato | Note |
|
||||
|----|-------------|----------|-------|-----------|------|
|
||||
| - | - | - | - | - | - |
|
||||
|
||||
---
|
||||
|
||||
## 📚 Risorse
|
||||
|
||||
- PRD: `/home/google/Sources/LucaSacchiNet/openrouter-watcher/prd.md`
|
||||
- Architettura: `/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/architecture.md`
|
||||
- Kanban: `/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/kanban.md`
|
||||
|
||||
---
|
||||
|
||||
*Ultimo aggiornamento: 2024-01-15*
|
||||
*Prossimo aggiornamento: Alla fine del primo sprint*
|
||||
333
prd.md
Normal file
333
prd.md
Normal file
@@ -0,0 +1,333 @@
|
||||
# Product Requirements Document (PRD)
|
||||
|
||||
## OpenRouter API Key Monitor
|
||||
|
||||
---
|
||||
|
||||
## 1. Panoramica
|
||||
|
||||
### 1.1 Descrizione
|
||||
OpenRouter API Key Monitor e un applicazione web multi-utente che permette agli utenti di monitorare l utilizzo delle loro API key della piattaforma OpenRouter. L applicazione raccoglie statistiche d uso, le persiste in un database SQLite e fornisce sia un interfaccia web che un API programmatica per l accesso ai dati.
|
||||
|
||||
### 1.2 Obiettivi
|
||||
- Fornire una dashboard centralizzata per il monitoraggio delle API key OpenRouter
|
||||
- Permettere a piu utenti di gestire le proprie chiavi in modo indipendente
|
||||
- Offrire API programmatica per integrazioni esterne
|
||||
- Persistere i dati storici per analisi nel tempo
|
||||
|
||||
### 1.3 Target Utenti
|
||||
- Sviluppatori che utilizzano API OpenRouter
|
||||
- Team che gestiscono multiple API key
|
||||
- Utenti che necessitano di reportistica sull utilizzo
|
||||
|
||||
---
|
||||
|
||||
## 2. Requisiti Funzionali
|
||||
|
||||
### 2.1 Gestione Utenti (Multi-utente)
|
||||
|
||||
#### 2.1.1 Registrazione
|
||||
- **F-001**: Gli utenti devono potersi registrare con email e password
|
||||
- **F-002**: La password deve essere salvata in modo sicuro (hash)
|
||||
- **F-003**: Email deve essere univoca nel sistema
|
||||
- **F-004**: Validazione formato email
|
||||
|
||||
#### 2.1.2 Autenticazione
|
||||
- **F-005**: Login con email e password
|
||||
- **F-006**: Gestione sessione utente (JWT o session-based)
|
||||
- **F-007**: Logout funzionante
|
||||
- **F-008**: Protezione route autenticate
|
||||
|
||||
#### 2.1.3 Profilo Utente
|
||||
- **F-009**: Visualizzazione profilo personale
|
||||
- **F-010**: Modifica password
|
||||
- **F-011**: Eliminazione account con conferma
|
||||
|
||||
### 2.2 Gestione API Key
|
||||
|
||||
#### 2.2.1 CRUD API Key
|
||||
- **F-012**: Aggiungere nuova API key OpenRouter
|
||||
- **F-013**: Visualizzare lista API key dell utente
|
||||
- **F-014**: Modificare nome/descrizione API key
|
||||
- **F-015**: Eliminare API key
|
||||
- **F-016**: API key devono essere cifrate nel database
|
||||
|
||||
#### 2.2.2 Validazione
|
||||
- **F-017**: Verifica validita API key con chiamata test a OpenRouter
|
||||
- **F-018**: Visualizzare stato attivo/inattivo per ogni key
|
||||
|
||||
### 2.3 Monitoraggio e Statistiche
|
||||
|
||||
#### 2.3.1 Raccolta Dati
|
||||
- **F-019**: Sincronizzazione automatica statistiche da OpenRouter API
|
||||
- **F-020**: Storico utilizzo (richieste, token, costi)
|
||||
- **F-021**: Aggregazione dati per modello LLM utilizzato
|
||||
|
||||
#### 2.3.2 Dashboard
|
||||
- **F-022**: Vista panoramica utilizzo totale
|
||||
- **F-023**: Grafico utilizzo nel tempo (ultimi 30 giorni)
|
||||
- **F-024**: Distribuzione utilizzo per modello
|
||||
- **F-025**: Costi totali e medi
|
||||
- **F-026**: Numero richieste totali e giornaliere medie
|
||||
|
||||
#### 2.3.3 Report Dettagliati
|
||||
- **F-027**: Filtraggio per intervallo date
|
||||
- **F-028**: Filtraggio per API key specifica
|
||||
- **F-029**: Filtraggio per modello
|
||||
- **F-030**: Esportazione dati (CSV/JSON)
|
||||
|
||||
### 2.4 API Pubblica
|
||||
|
||||
#### 2.4.1 Autenticazione API
|
||||
- **F-031**: Generazione API token per accesso programmatico
|
||||
- **F-032**: Revoca API token
|
||||
- **F-033**: Autenticazione via Bearer token
|
||||
|
||||
#### 2.4.2 Endpoint
|
||||
- **F-034**: GET /api/v1/stats - statistiche aggregate (solo lettura)
|
||||
- **F-035**: GET /api/v1/usage - dati di utilizzo dettagliati (solo lettura)
|
||||
- **F-036**: GET /api/v1/keys - lista API key con statistiche (solo lettura)
|
||||
- **F-037**: Rate limiting su API pubblica
|
||||
|
||||
#### 2.4.3 Risposte
|
||||
- **F-038**: Formato JSON standardizzato
|
||||
- **F-039**: Gestione errori con codici HTTP appropriati
|
||||
- **F-040**: Paginazione per risultati grandi
|
||||
|
||||
---
|
||||
|
||||
## 3. Requisiti Non Funzionali
|
||||
|
||||
### 3.1 Performance
|
||||
- **NF-001**: Tempo di risposta web < 2 secondi
|
||||
- **NF-002**: API response time < 500ms
|
||||
- **NF-003**: Supporto per almeno 100 utenti concorrenti
|
||||
|
||||
### 3.2 Sicurezza
|
||||
- **NF-004**: Tutte le API key cifrate in database (AES-256)
|
||||
- **NF-005**: Password hash con bcrypt/Argon2
|
||||
- **NF-006**: HTTPS obbligatorio in produzione
|
||||
- **NF-007**: Protezione CSRF
|
||||
- **NF-008**: Rate limiting su endpoint di autenticazione
|
||||
- **NF-009**: SQL injection prevention (query parameterizzate)
|
||||
- **NF-010**: XSS prevention
|
||||
|
||||
### 3.3 Affidabilita
|
||||
- **NF-011**: Backup automatico database SQLite
|
||||
- **NF-012**: Gestione errori graceful degradation
|
||||
- **NF-013**: Logging operazioni critiche
|
||||
|
||||
### 3.4 Usabilita
|
||||
- **NF-014**: Interfaccia responsive (mobile-friendly)
|
||||
- **NF-015**: Tema chiaro/scuro
|
||||
- **NF-016**: Messaggi di errore chiari
|
||||
|
||||
### 3.5 Manutenibilita
|
||||
- **NF-017**: Codice documentato
|
||||
- **NF-018**: Test coverage >= 90%
|
||||
- **NF-019**: Struttura modulare
|
||||
|
||||
---
|
||||
|
||||
## 4. Architettura Tecnica
|
||||
|
||||
### 4.1 Stack Tecnologico
|
||||
- **Backend**: Python 3.11+ con FastAPI
|
||||
- **Frontend**: HTML + HTMX / React (opzionale)
|
||||
- **Database**: SQLite
|
||||
- **ORM**: SQLAlchemy
|
||||
- **Autenticazione**: JWT
|
||||
- **Task Background**: APScheduler / Celery (opzionale)
|
||||
|
||||
### 4.2 Struttura Database
|
||||
|
||||
#### Tabella: users
|
||||
- id (PK, INTEGER)
|
||||
- email (UNIQUE, TEXT)
|
||||
- password_hash (TEXT)
|
||||
- created_at (TIMESTAMP)
|
||||
- updated_at (TIMESTAMP)
|
||||
- is_active (BOOLEAN)
|
||||
|
||||
#### Tabella: api_keys
|
||||
- id (PK, INTEGER)
|
||||
- user_id (FK, INTEGER)
|
||||
- name (TEXT)
|
||||
- key_encrypted (TEXT)
|
||||
- is_active (BOOLEAN)
|
||||
- created_at (TIMESTAMP)
|
||||
- last_used_at (TIMESTAMP)
|
||||
|
||||
#### Tabella: usage_stats
|
||||
- id (PK, INTEGER)
|
||||
- api_key_id (FK, INTEGER)
|
||||
- date (DATE)
|
||||
- model (TEXT)
|
||||
- requests_count (INTEGER)
|
||||
- tokens_input (INTEGER)
|
||||
- tokens_output (INTEGER)
|
||||
- cost (DECIMAL)
|
||||
- created_at (TIMESTAMP)
|
||||
|
||||
#### Tabella: api_tokens
|
||||
- id (PK, INTEGER)
|
||||
- user_id (FK, INTEGER)
|
||||
- token_hash (TEXT)
|
||||
- name (TEXT)
|
||||
- last_used_at (TIMESTAMP)
|
||||
- created_at (TIMESTAMP)
|
||||
- is_active (BOOLEAN)
|
||||
|
||||
### 4.3 Integrazione OpenRouter
|
||||
- API Endpoint: https://openrouter.ai/api/v1/
|
||||
- Endpoint utilizzati:
|
||||
- /auth/key - per validazione key
|
||||
- /credits - per controllo crediti
|
||||
- (future estensioni per usage stats quando disponibili)
|
||||
|
||||
---
|
||||
|
||||
## 5. Interfaccia Utente
|
||||
|
||||
### 5.1 Pagine Web
|
||||
|
||||
#### 5.1.1 Pubbliche
|
||||
- **Login** (/login) - Form di accesso
|
||||
- **Registrazione** (/register) - Form di registrazione
|
||||
|
||||
#### 5.1.2 Autenticate
|
||||
- **Dashboard** (/dashboard) - Panoramica utilizzo
|
||||
- **API Keys** (/keys) - Gestione API key
|
||||
- **Statistiche** (/stats) - Report dettagliati
|
||||
- **Profilo** (/profile) - Gestione account
|
||||
- **API Tokens** (/tokens) - Gestione token API
|
||||
|
||||
### 5.2 Componenti UI
|
||||
|
||||
#### 5.2.1 Dashboard
|
||||
- Card riepilogative (richieste totali, costi, etc.)
|
||||
- Grafici utilizzo temporale
|
||||
- Tabella modelli piu utilizzati
|
||||
|
||||
#### 5.2.2 Gestione API Key
|
||||
- Tabella con nome, stato, ultimo utilizzo
|
||||
- Form aggiunta/modifica
|
||||
- Bottone test validita
|
||||
- Bottone eliminazione con conferma
|
||||
|
||||
#### 5.2.3 Statistiche
|
||||
- Filtri per data, key, modello
|
||||
- Tabella dettagliata
|
||||
- Bottone esportazione
|
||||
|
||||
---
|
||||
|
||||
## 6. API Endpoints (Dettaglio)
|
||||
|
||||
### 6.1 Web Routes (HTML)
|
||||
- GET / - redirect a /dashboard o /login
|
||||
- GET/POST /login
|
||||
- GET/POST /register
|
||||
- GET /logout
|
||||
- GET /dashboard (protetta)
|
||||
- GET /keys (protetta)
|
||||
- GET /stats (protetta)
|
||||
- GET /profile (protetta)
|
||||
- GET /tokens (protetta)
|
||||
|
||||
### 6.2 API Routes (JSON)
|
||||
- POST /api/auth/login
|
||||
- POST /api/auth/register
|
||||
- POST /api/auth/logout
|
||||
|
||||
- GET /api/v1/stats (auth: Bearer token)
|
||||
- GET /api/v1/usage (auth: Bearer token)
|
||||
- GET /api/v1/keys (auth: Bearer token)
|
||||
|
||||
---
|
||||
|
||||
## 7. Cron e Background Tasks
|
||||
|
||||
### 7.1 Sincronizzazione Dati
|
||||
- **Task**: Sync Usage Data
|
||||
- **Frequenza**: Ogni ora
|
||||
- **Azione**: Recupera statistiche da OpenRouter per ogni key attiva
|
||||
- **Persistenza**: Salva in usage_stats
|
||||
|
||||
### 7.2 Validazione API Key
|
||||
- **Task**: Validate Keys
|
||||
- **Frequenza**: Giornaliera
|
||||
- **Azione**: Verifica validita di ogni key, aggiorna stato
|
||||
|
||||
### 7.3 Cleanup
|
||||
- **Task**: Cleanup Old Data
|
||||
- **Frequenza**: Settimanale
|
||||
- **Azione**: Rimuove dati piu vecchi di 1 anno (configurabile)
|
||||
|
||||
---
|
||||
|
||||
## 8. Configurazione
|
||||
|
||||
### 8.1 Variabili d Ambiente
|
||||
- DATABASE_URL - path database SQLite
|
||||
- SECRET_KEY - chiave per JWT
|
||||
- ENCRYPTION_KEY - chiave per cifratura API key
|
||||
- OPENROUTER_API_URL - URL base API OpenRouter
|
||||
- SYNC_INTERVAL_MINUTES - intervallo sincronizzazione
|
||||
- MAX_API_KEYS_PER_USER - limite key per utente
|
||||
- RATE_LIMIT_REQUESTS - limite richieste API
|
||||
- RATE_LIMIT_WINDOW - finestra rate limit (secondi)
|
||||
|
||||
### 8.2 File Configurazione
|
||||
- config.yaml (opzionale) - override env vars
|
||||
|
||||
---
|
||||
|
||||
## 9. Deployment
|
||||
|
||||
### 9.1 Requisiti
|
||||
- Python 3.11+
|
||||
- SQLite
|
||||
- (Opzionale) Reverse proxy (nginx/traefik)
|
||||
|
||||
### 9.2 Installazione
|
||||
1. Clone repository
|
||||
2. pip install -r requirements.txt
|
||||
3. Configura variabili d ambiente
|
||||
4. Esegui migrazioni: alembic upgrade head
|
||||
5. Avvia: uvicorn main:app
|
||||
|
||||
### 9.3 Docker (Opzionale)
|
||||
- Dockerfile fornito
|
||||
- docker-compose.yml per stack completo
|
||||
|
||||
---
|
||||
|
||||
## 10. Roadmap
|
||||
|
||||
### Fase 1 (MVP)
|
||||
- [ ] Autenticazione utenti
|
||||
- [ ] CRUD API key
|
||||
- [ ] Dashboard base
|
||||
- [ ] API lettura dati
|
||||
|
||||
### Fase 2
|
||||
- [ ] Grafici avanzati
|
||||
- [ ] Esportazione dati
|
||||
- [ ] Notifiche (email)
|
||||
- [ ] Rate limiting avanzato
|
||||
|
||||
### Fase 3
|
||||
- [ ] Supporto multi-team
|
||||
- [ ] RBAC (Ruoli)
|
||||
- [ ] Webhook
|
||||
- [ ] Mobile app
|
||||
|
||||
---
|
||||
|
||||
## 11. Note
|
||||
|
||||
- L applicazione e progettata per essere self-hosted
|
||||
- I dati rimangono locali (SQLite)
|
||||
- L integrazione con OpenRouter richiede API key valide
|
||||
- Le API key degli utenti sono sempre cifrate nel database
|
||||
226
prompt/prompt-zero.md
Normal file
226
prompt/prompt-zero.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# Prompt Zero: OpenRouter API Key Monitor - Project Kickoff
|
||||
|
||||
## 🎯 Missione
|
||||
|
||||
Sviluppare **OpenRouter API Key Monitor**, un'applicazione web multi-utente per monitorare l'utilizzo delle API key della piattaforma OpenRouter.
|
||||
|
||||
**Repository:** `/home/google/Sources/LucaSacchiNet/openrouter-watcher`
|
||||
**PRD:** `/home/google/Sources/LucaSacchiNet/openrouter-watcher/prd.md`
|
||||
|
||||
---
|
||||
|
||||
## 📊 Stato Attuale
|
||||
|
||||
- ✅ **PRD Completo**: Requisiti funzionali e non funzionali definiti
|
||||
- ✅ **Team Configurato**: 3 agenti specializzati pronti
|
||||
- ❌ **Nessun Codice**: Progetto da zero
|
||||
- ❌ **Nessuna Specifica Tecnica**: Da creare
|
||||
|
||||
---
|
||||
|
||||
## 👥 Team di Sviluppo
|
||||
|
||||
| Agente | Ruolo | File Config |
|
||||
|--------|-------|-------------|
|
||||
| `@spec-architect` | Definisce specifiche e architettura | `.opencode/agents/spec-architect.md` |
|
||||
| `@tdd-developer` | Implementazione TDD | `.opencode/agents/tdd-developer.md` |
|
||||
| `@git-manager` | Gestione commit Git | `.opencode/agents/git-manager.md` |
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Workflow Obbligatorio
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ FASE 1: SPECIFICA │
|
||||
│ @spec-architect │
|
||||
│ └── Legge PRD → Crea architecture.md, kanban.md │
|
||||
│ │
|
||||
│ ↓ │
|
||||
│ │
|
||||
│ FASE 2: IMPLEMENTAZIONE │
|
||||
│ @tdd-developer │
|
||||
│ └── RED → GREEN → REFACTOR per ogni task │
|
||||
│ │
|
||||
│ ↓ │
|
||||
│ │
|
||||
│ FASE 3: COMMIT │
|
||||
│ @git-manager │
|
||||
│ └── Commit atomico + Conventional Commits │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Task Iniziale: Fase 1 - Specifica
|
||||
|
||||
**AGENTE:** `@spec-architect`
|
||||
|
||||
**OBIETTIVO:** Analizzare il PRD e creare le specifiche tecniche dettagliate.
|
||||
|
||||
### Azioni Richieste
|
||||
|
||||
1. **Leggere** `/home/google/Sources/LucaSacchiNet/openrouter-watcher/prd.md`
|
||||
|
||||
2. **Creare** la struttura di output:
|
||||
```
|
||||
/home/google/Sources/LucaSacchiNet/openrouter-watcher/export/
|
||||
├── prd.md # Requisiti prodotti (estratto/dettaglio)
|
||||
├── architecture.md # Architettura sistema
|
||||
├── kanban.md # Task breakdown
|
||||
└── progress.md # Tracciamento progresso
|
||||
```
|
||||
|
||||
3. **Produrre** `architecture.md` con:
|
||||
- Stack tecnologico dettagliato (Python 3.11+, FastAPI, SQLite, SQLAlchemy, JWT)
|
||||
- Struttura cartelle progetto
|
||||
- Diagrammi flusso dati
|
||||
- Schema database completo (DDL)
|
||||
- Interfacce API (OpenAPI specs)
|
||||
- Sicurezza (cifratura, autenticazione)
|
||||
|
||||
4. **Produrre** `kanban.md` con:
|
||||
- Task breakdown per Fase 1 (MVP)
|
||||
- Stima complessità
|
||||
- Dipendenze tra task
|
||||
- Regola "little often": task < 2 ore
|
||||
|
||||
5. **Inizializzare** `progress.md` con:
|
||||
- Feature corrente: "Fase 1 - MVP"
|
||||
- Stato: "🔴 Pianificazione"
|
||||
- Percentuale: 0%
|
||||
|
||||
### Criteri di Accettazione
|
||||
|
||||
- [ ] Architecture.md completo con tutte le sezioni
|
||||
- [ ] Kanban.md con task pronti per @tdd-developer
|
||||
- [ ] Progress.md inizializzato
|
||||
- [ ] Tutti i path usano `/home/google/Sources/LucaSacchiNet/openrouter-watcher/`
|
||||
|
||||
---
|
||||
|
||||
## 📋 Requisiti Chiave (Dal PRD)
|
||||
|
||||
### Funzionalità MVP (Fase 1)
|
||||
|
||||
1. **Autenticazione Utenti**
|
||||
- Registrazione/login multi-utente
|
||||
- JWT-based authentication
|
||||
- Password hash (bcrypt)
|
||||
|
||||
2. **Gestione API Key**
|
||||
- CRUD API key OpenRouter
|
||||
- Cifratura AES-256 in database
|
||||
- Validazione key con OpenRouter API
|
||||
|
||||
3. **Dashboard**
|
||||
- Statistiche utilizzo
|
||||
- Grafici temporali
|
||||
- Costi e richieste
|
||||
|
||||
4. **API Pubblica**
|
||||
- Endpoint autenticati (Bearer token)
|
||||
- Solo lettura dati
|
||||
- Rate limiting
|
||||
|
||||
### Stack Tecnologico
|
||||
|
||||
- **Backend:** Python 3.11+, FastAPI
|
||||
- **Database:** SQLite + SQLAlchemy
|
||||
- **Frontend:** HTML + HTMX (semplice)
|
||||
- **Auth:** JWT + bcrypt
|
||||
- **Task Background:** APScheduler
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Vincoli e Best Practices
|
||||
|
||||
### Sicurezza (Critico)
|
||||
- API key sempre cifrate (AES-256)
|
||||
- Password hash con bcrypt
|
||||
- SQL injection prevention
|
||||
- XSS prevention
|
||||
- CSRF protection
|
||||
- Rate limiting
|
||||
|
||||
### Qualità
|
||||
- Test coverage ≥ 90%
|
||||
- TDD obbligatorio
|
||||
- Conventional commits
|
||||
- Commit atomici
|
||||
|
||||
### Organizzazione
|
||||
- Task "little often" (< 2 ore)
|
||||
- Documentazione in `/export/`
|
||||
- Bug complessi in `/docs/bug_ledger.md`
|
||||
|
||||
---
|
||||
|
||||
## 📁 Struttura Progetto Attesa
|
||||
|
||||
```
|
||||
/home/google/Sources/LucaSacchiNet/openrouter-watcher/
|
||||
├── prd.md # Questo PRD
|
||||
├── prompt/
|
||||
│ └── prompt-zero.md # Questo file
|
||||
├── .opencode/
|
||||
│ ├── agents/ # Configurazioni agenti
|
||||
│ └── skills/ # Skill condivise
|
||||
├── export/ # Output spec-driven (da creare)
|
||||
│ ├── prd.md
|
||||
│ ├── architecture.md
|
||||
│ ├── kanban.md
|
||||
│ └── progress.md
|
||||
├── docs/ # Documentazione (da creare)
|
||||
│ ├── bug_ledger.md
|
||||
│ └── architecture.md
|
||||
├── src/ # Codice sorgente (da creare)
|
||||
│ └── openrouter_monitor/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
│ ├── config.py
|
||||
│ ├── database.py
|
||||
│ ├── models/
|
||||
│ ├── routers/
|
||||
│ ├── services/
|
||||
│ └── utils/
|
||||
├── tests/ # Test suite (da creare)
|
||||
│ ├── unit/
|
||||
│ ├── integration/
|
||||
│ └── conftest.py
|
||||
├── requirements.txt
|
||||
└── README.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist Pre-Sviluppo
|
||||
|
||||
- [ ] @spec-architect ha letto questo prompt
|
||||
- [ ] Cartella `export/` creata
|
||||
- [ ] `architecture.md` creato con schema DB
|
||||
- [ ] `kanban.md` creato con task Fase 1
|
||||
- [ ] `progress.md` inizializzato
|
||||
|
||||
---
|
||||
|
||||
## 🎬 Prossima Azione
|
||||
|
||||
**@spec-architect**: Inizia analizzando il PRD in `prd.md` e crea le specifiche tecniche in `export/`.
|
||||
|
||||
**NON iniziare l'implementazione** finché le specifiche non sono approvate.
|
||||
|
||||
---
|
||||
|
||||
## 📞 Note per il Team
|
||||
|
||||
- **Domande sul PRD?** Leggi prima `prd.md` completamente
|
||||
- **Ambiguità?** Chiedi prima di procedere
|
||||
- **Vincoli tecnici?** Documentali in `architecture.md`
|
||||
- **Task troppo grandi?** Spezza in task più piccoli
|
||||
|
||||
---
|
||||
|
||||
**Data Creazione:** 2025-04-07
|
||||
**Versione:** 1.0
|
||||
**Stato:** Pronto per kickoff
|
||||
0
src/openrouter_monitor/__init__.py
Normal file
0
src/openrouter_monitor/__init__.py
Normal file
0
src/openrouter_monitor/config.py
Normal file
0
src/openrouter_monitor/config.py
Normal file
0
src/openrouter_monitor/database.py
Normal file
0
src/openrouter_monitor/database.py
Normal file
0
src/openrouter_monitor/main.py
Normal file
0
src/openrouter_monitor/main.py
Normal file
0
src/openrouter_monitor/models/__init__.py
Normal file
0
src/openrouter_monitor/models/__init__.py
Normal file
0
src/openrouter_monitor/routers/__init__.py
Normal file
0
src/openrouter_monitor/routers/__init__.py
Normal file
0
src/openrouter_monitor/services/__init__.py
Normal file
0
src/openrouter_monitor/services/__init__.py
Normal file
0
src/openrouter_monitor/utils/__init__.py
Normal file
0
src/openrouter_monitor/utils/__init__.py
Normal file
BIN
tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc
Normal file
BIN
tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc
Normal file
Binary file not shown.
0
tests/conftest.py
Normal file
0
tests/conftest.py
Normal file
0
tests/integration/__init__.py
Normal file
0
tests/integration/__init__.py
Normal file
0
tests/unit/__init__.py
Normal file
0
tests/unit/__init__.py
Normal file
BIN
tests/unit/__pycache__/__init__.cpython-313.pyc
Normal file
BIN
tests/unit/__pycache__/__init__.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
90
tests/unit/test_project_structure.py
Normal file
90
tests/unit/test_project_structure.py
Normal file
@@ -0,0 +1,90 @@
|
||||
"""Test for project structure setup (T01)."""
|
||||
import os
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestProjectStructure:
|
||||
"""Test project directory structure is correctly created."""
|
||||
|
||||
def test_src_directory_exists(self):
|
||||
"""Verify src/openrouter_monitor/ directory exists."""
|
||||
src_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/src/openrouter_monitor"
|
||||
assert os.path.isdir(src_path), f"Directory {src_path} does not exist"
|
||||
|
||||
def test_src_init_file_exists(self):
|
||||
"""Verify src/openrouter_monitor/__init__.py exists."""
|
||||
init_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/src/openrouter_monitor/__init__.py"
|
||||
assert os.path.isfile(init_path), f"File {init_path} does not exist"
|
||||
|
||||
def test_main_py_exists(self):
|
||||
"""Verify main.py exists in src."""
|
||||
main_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/src/openrouter_monitor/main.py"
|
||||
assert os.path.isfile(main_path), f"File {main_path} does not exist"
|
||||
|
||||
def test_config_py_exists(self):
|
||||
"""Verify config.py exists in src."""
|
||||
config_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/src/openrouter_monitor/config.py"
|
||||
assert os.path.isfile(config_path), f"File {config_path} does not exist"
|
||||
|
||||
def test_database_py_exists(self):
|
||||
"""Verify database.py exists in src."""
|
||||
db_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/src/openrouter_monitor/database.py"
|
||||
assert os.path.isfile(db_path), f"File {db_path} does not exist"
|
||||
|
||||
def test_models_directory_exists(self):
|
||||
"""Verify models/ directory exists with __init__.py."""
|
||||
models_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/src/openrouter_monitor/models"
|
||||
init_path = os.path.join(models_path, "__init__.py")
|
||||
assert os.path.isdir(models_path), f"Directory {models_path} does not exist"
|
||||
assert os.path.isfile(init_path), f"File {init_path} does not exist"
|
||||
|
||||
def test_routers_directory_exists(self):
|
||||
"""Verify routers/ directory exists with __init__.py."""
|
||||
routers_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/src/openrouter_monitor/routers"
|
||||
init_path = os.path.join(routers_path, "__init__.py")
|
||||
assert os.path.isdir(routers_path), f"Directory {routers_path} does not exist"
|
||||
assert os.path.isfile(init_path), f"File {init_path} does not exist"
|
||||
|
||||
def test_services_directory_exists(self):
|
||||
"""Verify services/ directory exists with __init__.py."""
|
||||
services_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/src/openrouter_monitor/services"
|
||||
init_path = os.path.join(services_path, "__init__.py")
|
||||
assert os.path.isdir(services_path), f"Directory {services_path} does not exist"
|
||||
assert os.path.isfile(init_path), f"File {init_path} does not exist"
|
||||
|
||||
def test_utils_directory_exists(self):
|
||||
"""Verify utils/ directory exists with __init__.py."""
|
||||
utils_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/src/openrouter_monitor/utils"
|
||||
init_path = os.path.join(utils_path, "__init__.py")
|
||||
assert os.path.isdir(utils_path), f"Directory {utils_path} does not exist"
|
||||
assert os.path.isfile(init_path), f"File {init_path} does not exist"
|
||||
|
||||
def test_tests_directory_structure(self):
|
||||
"""Verify tests/ directory structure exists."""
|
||||
tests_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/tests"
|
||||
unit_path = os.path.join(tests_path, "unit")
|
||||
integration_path = os.path.join(tests_path, "integration")
|
||||
conftest_path = os.path.join(tests_path, "conftest.py")
|
||||
|
||||
assert os.path.isdir(tests_path), f"Directory {tests_path} does not exist"
|
||||
assert os.path.isdir(unit_path), f"Directory {unit_path} does not exist"
|
||||
assert os.path.isfile(os.path.join(unit_path, "__init__.py")), f"unit/__init__.py does not exist"
|
||||
assert os.path.isdir(integration_path), f"Directory {integration_path} does not exist"
|
||||
assert os.path.isfile(os.path.join(integration_path, "__init__.py")), f"integration/__init__.py does not exist"
|
||||
assert os.path.isfile(conftest_path), f"File {conftest_path} does not exist"
|
||||
|
||||
def test_alembic_directory_exists(self):
|
||||
"""Verify alembic/ directory exists."""
|
||||
alembic_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/alembic"
|
||||
assert os.path.isdir(alembic_path), f"Directory {alembic_path} does not exist"
|
||||
|
||||
def test_docs_directory_exists(self):
|
||||
"""Verify docs/ directory exists."""
|
||||
docs_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/docs"
|
||||
assert os.path.isdir(docs_path), f"Directory {docs_path} does not exist"
|
||||
|
||||
def test_scripts_directory_exists(self):
|
||||
"""Verify scripts/ directory exists."""
|
||||
scripts_path = "/home/google/Sources/LucaSacchiNet/openrouter-watcher/scripts"
|
||||
assert os.path.isdir(scripts_path), f"Directory {scripts_path} does not exist"
|
||||
Reference in New Issue
Block a user