# Contratto JSON del Cruciverba

Questo documento definisce il formato di scambio tra:

- `brain`: il motore che genera e compila il cruciverba
- `client`: web app, backend, servizio PDF o altra macchina remota che richiede un cruciverba

L'obiettivo e' avere un payload:

- completo
- stabile
- espandibile
- riusabile per stampa PDF, gioco web e archiviazione

## Flusso

1. Il client invia una `request` JSON al motore.
2. Il motore risponde con una `response` JSON completa del cruciverba.
3. Lo stesso JSON di risposta puo' essere:
   - salvato a database
   - convertito in PDF
   - renderizzato in una pagina web interattiva
   - riaperto in futuro senza rigenerare il cruciverba

## Principi di progettazione

- Ogni cruciverba ha un `crossword_id` univoco.
- La `request` conserva i parametri di generazione originali.
- La `response` include sia la griglia giocabile sia la soluzione.
- Le parole hanno metadati ricchi: posizione, direzione, clue, tema, pos, fonte clue.
- Le coordinate sono sempre assolute e 0-based nella griglia normalizzata esportata.
- La griglia esportata e' rettangolare e normalizzata: niente coordinate negative.
- Il formato supporta versioning con `schema_version`.

## Request

Campi principali:

- `schema_version`: versione del contratto
- `request_id`: id della richiesta lato client
- `requested_at`: timestamp ISO 8601
- `generator`: configurazione del motore
- `output`: preferenze di output
- `client_context`: metadati opzionali del chiamante

### `generator`

- `topic`: stringa o lista di topic
- `difficulty`: alias testuale
- `seed`: opzionale, per riproducibilita'
- `initial_word_count`
- `themed_fill_count`
- `target_empty_ratio`
- `diffxy`
- `time_limit_seconds`
- `max_candidates_per_word`
- `lexicon_file`
- `definitions_enabled`
- `definition_style`: per future varianti clue
- `preferred_output_language`

### `output`

- `include_solution_grid`
- `include_clue_sources`
- `include_diagnostics`
- `include_generation_log`
- `format_hints`

## Response

Campi principali:

- `schema_version`
- `request_id`
- `crossword_id`
- `generated_at`
- `status`
- `generator`
- `summary`
- `grid`
- `entries`
- `clues`
- `solution`
- `diagnostics`
- `artifacts`

## Sezione `grid`

- `rows`
- `cols`
- `cell_size_hint`
- `cells`

Ogni cella ha:

- `row`
- `col`
- `kind`: `block` oppure `letter`
- `solution`
- `display`
- `number`: numero clue se la cella apre una parola
- `across_entry_id`
- `down_entry_id`
- `is_prefilled`

Note:

- `solution` contiene sempre la lettera corretta per celle attive.
- `display` e' vuoto per la scheda giocatore.
- `number` serve per numerazione in stampa e web.

## Sezione `entries`

Ogni entry rappresenta una parola collocata in griglia.

Campi:

- `entry_id`
- `number`
- `direction`: `across` o `down`
- `answer`
- `answer_length`
- `row`
- `col`
- `cells`: lista coordinate
- `clue`
- `clue_source`
- `topics`
- `pos`
- `is_seed`
- `added_by_filler`
- `confidence`

## Sezione `clues`

Ridondante ma utile per client semplici.

- `across`: lista clues orizzontali
- `down`: lista clues verticali

Ogni clue:

- `number`
- `entry_id`
- `text`
- `enumeration`
- `topic_match`
- `source`

## Sezione `solution`

- `grid_rows`: lista di stringhe, una per riga
- `words`: elenco risposte

`grid_rows` usa:

- lettera maiuscola per cella piena
- `#` per casella nera

## Sezione `diagnostics`

Serve a tuning, benchmark e debug.

- `total_words`
- `seed_words_requested`
- `seed_words_placed`
- `filler_words_added`
- `intersections`
- `filled_cells`
- `empty_cells`
- `empty_ratio`
- `target_empty_ratio`
- `topic_words`
- `off_topic_words`
- `pos_counts`
- `runtime_lexicon`
- `seed`
- `generation_seconds`

## Sezione `artifacts`

URL o path futuri per file derivati.

- `pdf_player`
- `pdf_solution`
- `thumbnail`
- `html_preview`

## Estensioni future previste

- `difficulty_profile`: facile/medio/difficile per definizioni separate
- `hints`: aiuti progressivi per singola parola
- `theme_story`: testo introduttivo del cruciverba
- `player_state`: salvataggio partita in corso
- `stats`: tempi, errori, percentuali di completamento

## Regola pratica consigliata

La macchina "brain" deve esporre almeno due endpoint logici:

- `POST /crosswords/generate`
  - input: request JSON
  - output: response JSON

- `GET /crosswords/{crossword_id}`
  - output: stessa response JSON salvata

In questo modo il contratto resta identico sia via file sia via webservice.
