alpha01 backoffice: crossword engine, lexicon curation and JSON contract
This commit is contained in:
209
crossword_contract.md
Normal file
209
crossword_contract.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user