# Spec di design — Fase 3.5: Migrazione storico

**Data:** 2026-06-12 · **Stato:** deciso in autonomia · **Autore:** Claude
**Base:** F3.0 (schema). Master spec §12. Sorgenti: `data/sorgenti/` + workbook Drive `1964VC-C-IFZGQV4H6xr3MhASWhIVd1qn`.

## 1. Obiettivo e ambito
Popolare l'anagrafica giocatori e (quando disponibile) lo storico ranking dai dati pre-esistenti.

**Cosa è fattibile in autonomia (in repo):**
- **Roster EST26 (86 giocatori)**: i nick `nome_app_tta` sono in `data/sorgenti/workbook-xlsx-mappa.md`. Si **parsano** e si **upsertano** in `player` (idempotente, per `nome_app_tta`). È l'anagrafica reale corrente.
- **Albo d'oro**: già transcritto in `src/lib/content/albo.ts` (resta statico in vetrina).

**Cosa dipende da un export di Paolo (workbook):**
- **Griglia "Andamento Ranking" (~177 giocatori × stagioni)**: vive solo nell'xlsx binario; non è strutturata nel repo. Parsare l'xlsx in autonomia non è affidabile → si costruisce l'**importer** che accetta un JSON `{ playerNomeApp, seasonIdent, serie, posizione, isCoda, note }[]` e lo importa idempotente; il JSON va esportato da Paolo dal foglio.

## 2. Decisioni
1. **Idempotenza per `nome_app_tta`**: l'upsert salta i player già presenti (niente duplicati su re-run).
2. **Parsing dalla fonte** (no trascrizione a mano): lo script legge `workbook-xlsx-mappa.md`, estrae le voci `NNN nick/nomeApp` della sezione roster EST26 e ne ricava `nome_app_tta`; riporta il conteggio (atteso 86) per auto-verifica.
3. **Solo `nome_app_tta`** nel seed roster (campo unico/obbligatorio); `nick_tdg` lasciato null (evita collisioni di unicità; si arricchirà dopo).
4. **Ranking import separato e opzionale**: script `import-ranking.mjs` che legge un JSON e scrive righe `ranking` append-only, idempotente per (player, season). Pronto, in attesa del JSON dal workbook.
5. **PlayerAlias**: la dedup dei nick eterogenei tra i 26 fogli serve solo all'import del ranking storico (quando arriverà il JSON). Non necessaria per il roster EST26 (già nick app puliti).

## 3. Architettura
- `scripts/seed-roster-est26.mjs` (standalone, `@neondatabase/serverless`, `--env-file`): parsa la mappa, upsert player, report.
- `scripts/import-ranking.mjs` (standalone): legge `data/ranking-storico.json` (da fornire), upsert `season` + `ranking` idempotente.

## 4. Test/verifica
- Esecuzione `seed-roster-est26.mjs`: riporta "86 trovati, N inseriti, M già presenti"; ri-eseguibile senza duplicati.
- Gate check/build invariati (script standalone, fuori dalla build).

## 5. Note (da validare / azione Paolo)
- **Serve a Paolo**: export del foglio "Andamento Ranking" in JSON (o CSV) per l'import ranking storico. Senza, /ranking resta vuoto finché non si conclude una stagione reale dal gestionale.
- Il roster seedato rende i 86 giocatori disponibili nell'anagrafica (selezionabili in admin per le iscrizioni).
</content>
