refactor solution to PHP through AI

This commit is contained in:
2026-07-20 14:27:17 +02:00
parent a77f6f19cf
commit 151bc70775
21 changed files with 2563 additions and 41 deletions
+171
View File
@@ -0,0 +1,171 @@
# Port elixForms Custom Pages in PHP + Creazione Agenti React e PHP
## Obiettivo
Creare una versione PHP della libreria `common/` e una pagina di esempio `scelta-carriera`, replicando la stessa architettura e logica attualmente implementata in React/TypeScript. Inoltre, creare due agenti specializzati ("React" e "PHP") e le relative skill per il mondo PHP.
## Panoramica dell'architettura React attuale
```mermaid
graph TD
A["ElixFormsComponentAbstract.tsx<br/>(classe astratta)"] --> B["SceltaCarrieraComponent.tsx<br/>(override createCustomFormFields)"]
A --> C["RecuperoPropostaCctDaContrattiComponent.tsx<br/>(override createCustomFormFields + autocomplete)"]
A --> D["ElixFormsElement.tsx<br/>(layout label+input)"]
A --> E["QueryParamHelper.tsx<br/>(lettura query params)"]
A --> F["ElixFormsTypes.tsx<br/>(tipi opzioni)"]
B --> G["App.jsx + main.jsx<br/>(entry point pagina)"]
C --> H["App.jsx + main.jsx<br/>(entry point pagina)"]
```
## Differenze chiave React → PHP
| Aspetto | React | PHP |
|---|---|---|
| **Rendering** | Client-side (JSX → DOM) | Server-side (PHP → HTML) |
| **State management** | `this.state` + `this.setState()` | Valori da `$_GET` / `$_POST` (stateless) |
| **Form field factory** | Callback con oggetto factory | Metodi della classe base chiamati direttamente |
| **Build** | Vite → singolo bundle JS | Nessuna build — file PHP serviti direttamente |
| **CSS** | Iniettati nel JS via plugin | `<link>` tag nell'HTML |
| **Bootstrap Italia** | Classi HTML nel JSX | Stesse classi HTML nel template PHP |
> [!IMPORTANT]
> In PHP non serve un build tool. Ogni pagina è un singolo file PHP (o un set di file PHP) che include la libreria common e produce HTML direttamente.
## Proposed Changes
### 1. Libreria Common PHP
#### [NEW] [ElixFormsComponent.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/common/ElixFormsComponent.php)
Classe astratta PHP che replica `ElixFormsComponentAbstract.tsx`:
- **Proprietà**: `$properties` (array associativo equivalente a `IElixFormsComponentProperties`)
- **Metodi factory**: `createTextInput()`, `createTextAreaInput()`, `createNumberInput()`, `createBooleanInput()`, `createRadioInput()`, `createCheckboxInput()`, `createDropdownInput()`, `createHiddenInput()`
- **Metodi di layout**: `render()` che genera l'intera pagina HTML (header Bootstrap Italia, breadcrumb, card, form, footer)
- **Metodi estensibili**: `createCustomFormFields()`, `renderExtraContentPre()`, `renderExtraContentPost()` — da sovrascrivere nelle pagine figlie
- **Validazione**: Controllo parametri obbligatori (`mandatoryFormFieldNames`) dalla query string
- I valori dei campi vengono pre-popolati da `$_GET` (equivalente di `QueryParamHelper`)
#### [NEW] [ElixFormsElement.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/common/ElixFormsElement.php)
Classe wrapper per layout label+input (replica `ElixFormsElement.tsx`):
- Genera il layout a due colonne Bootstrap (`row`, `col-12 col-md-4`, `col-12 col-md-8`)
#### [NEW] [QueryParamHelper.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/common/QueryParamHelper.php)
Classe statica utility (replica `QueryParamHelper.tsx`):
- `getCheckedFromQuery($paramName)``int[]`
- `getOptionFromQuery($paramName)``?int`
- `getBooleanFromQuery($paramName)``?bool`
- `getDecodedTextFromQuery($paramName)``?string`
---
### 2. Pagina di Esempio
#### [NEW] [index.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/scelta-carriera/index.php)
Pagina di esempio che replica `scelta-carriera` React:
- Estende `ElixFormsComponent` sovrascrivendo `createCustomFormFields()`
- Definisce dropdown, text input, textarea, boolean, radio, checkbox
- Include il CSS di Bootstrap Italia e del design system UniPR via `<link>`
---
### 3. Skill PHP (nuove)
#### [NEW] [SKILL.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/.agents/skills/php-common-library/SKILL.md)
Skill `elixforms-php-common-library`:
- Documenta la libreria PHP common, i metodi della classe base, le proprietà, e il pattern di estensione
#### [NEW] [SKILL.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/.agents/skills/php-create-new-page/SKILL.md)
Skill `elixforms-php-create-new-page`:
- Guida step-by-step per creare una nuova pagina PHP custom
#### [NEW] [SKILL.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/.agents/skills/php-project-architecture/SKILL.md)
Skill `elixforms-php-project-architecture`:
- Descrive la struttura della cartella `php/` e le convenzioni del monorepo PHP
---
### 4. Agenti (AGENTS.md personalizzati)
> [!IMPORTANT]
> Gli "agenti" nella struttura Gemini vengono realizzati creando file `AGENTS.md` nelle rispettive cartelle. In questo modo ogni agente "scopre" automaticamente le regole specifiche per il proprio contesto.
#### [NEW] [AGENTS.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/react/AGENTS.md)
Agente **"React"** — regole specifiche per il framework React:
- Usa React + TypeScript class components per la libreria common
- Usa Vite per il bundling single-file
- Bootstrap Italia con classi HTML nel JSX
- Regola sugli ID dei form fields (ripresa dal root)
- Riferimenti alle skill React esistenti
#### [NEW] [AGENTS.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/AGENTS.md)
Agente **"PHP"** — regole specifiche per PHP:
- PHP puro, nessun framework
- Bootstrap Italia con classi HTML nei template PHP
- Pattern ereditarietà con classe base
- Stessa regola sugli ID dei form fields
- Riferimenti alle skill PHP
---
## Struttura finale del workspace
```
elixforms-custom-pages/
├── .agents/
│ ├── AGENTS.md ← Regole globali (invariate)
│ └── skills/
│ ├── common-library/ ← Skill React (esistente)
│ ├── create-new-page/ ← Skill React (esistente)
│ ├── css-design-system/ ← Skill condivisa (esistente)
│ ├── custom-workflow-logic/ ← Skill condivisa (esistente)
│ ├── dev-workflow/ ← Skill React (esistente)
│ ├── project-architecture/ ← Skill React (esistente)
│ ├── typescript-react-conventions/ ← Skill React (esistente)
│ ├── vite-build-config/ ← Skill React (esistente)
│ ├── php-common-library/ ← [NEW] Skill PHP
│ ├── php-create-new-page/ ← [NEW] Skill PHP
│ └── php-project-architecture/ ← [NEW] Skill PHP
├── react/
│ ├── AGENTS.md ← [NEW] Agente React
│ ├── common/
│ ├── scelta-carriera/
│ └── recupero-proposta-cct-da-contratti/
└── php/
├── AGENTS.md ← [NEW] Agente PHP
├── common/
│ ├── ElixFormsComponent.php ← [NEW]
│ ├── ElixFormsElement.php ← [NEW]
│ └── QueryParamHelper.php ← [NEW]
└── scelta-carriera/
└── index.php ← [NEW]
```
## Open Questions
> [!IMPORTANT]
> **Versione PHP**: quale versione minima di PHP devo usare? (es. PHP 7.4+ o PHP 8.0+ con typed properties, union types, match expression, ecc.)
> [!IMPORTANT]
> **Namespace PHP**: vuoi usare i namespace PSR-4 (es. `namespace ElixForms\Common;`) o preferisci un approccio più semplice con `require_once`?
> [!IMPORTANT]
> **Deploy**: le pagine PHP verranno servite da un web server Apache/Nginx? O dovranno essere incluse/embedded in un sistema esistente?
## Verification Plan
### Manual Verification
- Verificare che la pagina PHP `scelta-carriera/index.php` generi HTML valido con la stessa struttura del corrispettivo React
- Verificare che i campi del form (dropdown, text, textarea, boolean, radio, checkbox) siano tutti presenti e funzionanti
- Verificare che i parametri obbligatori vengano correttamente letti dalla query string
- Verificare che il form faccia POST a `https://procedure.unipr.it/rwe2/ComeBackToElixAndSave` con encoding `ISO-8859-1`
- Verificare che le skill e gli agenti siano correttamente scoperti da Gemini
@@ -0,0 +1,57 @@
# Porting "recupero-proposta-cct-da-contratti" in PHP
## Obiettivo
Convertire la pagina custom `recupero-proposta-cct-da-contratti` in PHP, mantenendo la stessa logica di funzionamento della versione React/TypeScript.
## Architettura e Sicurezza
La pagina originale React esegue una chiamata client-side fetch ad un web service esterno (`http://localhost:8000/contratti/cerca`) utilizzando credenziali Basic Auth ed una API Key custom. Poiché in PHP eseguiamo il rendering server-side, esporre le credenziali nel codice JavaScript inviato al browser è una vulnerabilità di sicurezza.
### Soluzione Proposta: PHP Proxy Script
Proponiamo la creazione di un file `search-contratti.php` locale alla pagina che:
1. Riceve in GET il parametro di ricerca `term` ed il codice fiscale dell'utente `cod_fis`.
2. Esegue una chiamata cURL server-to-server verso il WS reale usando le credenziali memorizzate in sicurezza in `config.json`.
3. Restituisce il JSON dei contratti trovati al client.
Il componente client-side eseguirà la fetch locale verso questo file `search-contratti.php` ed implementerà un dropdown di autocompletamento in JavaScript nativo (Vanilla JS) per mantenere le stesse animazioni ed interazioni della versione React (debounce, navigazione con frecce tastiera, selezione ed autocompilazione dei campi nascosti del form).
```
[Browser Client]
│ (fetch /term=...)
[search-contratti.php] (Proxy locale in php/)
│ (cURL server-to-server + Basic Auth & API Key)
[Web Service Contratti]
```
## Proposed Changes
### Componente: `php/recupero-proposta-cct-da-contratti/`
#### [NEW] [config.json](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/recupero-proposta-cct-da-contratti/config.json)
Copia del file di configurazione con le credenziali API, l'endpoint del Web Service ed i mapping dei campi elixForms.
#### [NEW] [search-contratti.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/recupero-proposta-cct-da-contratti/search-contratti.php)
Script PHP proxy che:
- Valida l'input.
- Effettua la richiesta HTTP GET al WS esterno tramite `curl`.
- Passa l'header `Authorization: Basic ...` e `X-Api-Key: ...`.
- Ritorna `application/json` con i risultati.
#### [NEW] [index.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/recupero-proposta-cct-da-contratti/index.php)
Pagina custom principale:
- Eredita da `ElixFormsComponent`.
- Legge il Codice Fiscale dell'utente tramite `QueryParamHelper::getDecodedTextFromQuery`.
- Genera i campi nascosti per i dati di output (`idDomanda`, `idRicevuta`, `codiceContratto`, `titoloContratto`).
- Rendering dell'input di ricerca ed implementazione del JavaScript nativo per l'autocompletamento (sincronizzato con il file proxy `search-contratti.php`).
## Verification Plan
### Manual Verification
- Avviare il server PHP locale: `php -S localhost:8080` nella cartella `php/recupero-proposta-cct-da-contratti/`.
- Verificare che il proxy `search-contratti.php?term=test&cod_fis=...` risponda correttamente con i dati mock o reali del WS.
- Verificare che digitando nel campo di ricerca "Cerca Contratto" vengano visualizzati i risultati nel menu a discesa.
- Testare la navigazione del menu a discesa con la tastiera (Frecce Su/Giù, Enter, Esc).
- Verificare che alla selezione di un contratto, i campi hidden vengano correttamente compilati con i valori associati (`idDomanda`, `idRicevuta`, ecc.) e venga mostrata la card riepilogativa del contratto selezionato.
+44
View File
@@ -0,0 +1,44 @@
# Walkthrough — Port PHP + Agenti Custom
Ho completato tutte le attività pianificate per la realizzazione della struttura in PHP delle custom pages elixForms e per la configurazione dei due agenti dedicati ("React" e "PHP").
## Modifiche e Creazioni Effettuate
### 1. Libreria Comune PHP (`php/common/`)
Abbiamo replicato la stessa logica e architettura della libreria comune React in PHP 8.0+:
- **[QueryParamHelper.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/common/QueryParamHelper.php)**: Fornisce metodi statici tipizzati per estrarre e decodificare i dati provenienti dalla query string (`$_GET`).
- **[ElixFormsElement.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/common/ElixFormsElement.php)**: Gestisce il layout standard a due colonne (label a sinistra, input a destra) con le classi Bootstrap.
- **[ElixFormsComponent.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/common/ElixFormsComponent.php)**: Classe astratta base che definisce il ciclo di rendering dell'intera pagina e tutti i metodi factory dei campi (testo, textarea, checkbox, radio, dropdown, boolean). Gestisce automaticamente la presenza dei parametri obbligatori elixForms ed inserisce il JavaScript client-side per la sincronizzazione dei checkbox.
### 2. Pagina di Esempio PHP
- **[index.php](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/scelta-carriera/index.php)**: Una pagina "Scelta Carriera" d'esempio che estende `ElixFormsComponent` e definisce tutti i campi form (dropdown, text, textarea, boolean, radio, checkbox), replicando fedelmente la controparte React.
### 3. Nuove Skill PHP
Abbiamo creato tre nuove skill all'interno di `.agents/skills/` per guidare lo sviluppo PHP futuro:
- **[php-common-library/SKILL.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/.agents/skills/php-common-library/SKILL.md)**: Dettaglia i metodi factory, il layout ed i parametri del componente base.
- **[php-create-new-page/SKILL.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/.agents/skills/php-create-new-page/SKILL.md)**: Guida passo-passo per lo scaffolding e testing locale di nuove pagine.
- **[php-project-architecture/SKILL.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/.agents/skills/php-project-architecture/SKILL.md)**: Definisce le differenze architetturali rispetto al mondo React e le modalità di deploy su Apache.
### 4. Configurazione degli Agenti Dedicati
Abbiamo strutturato due file di istruzioni separati che istruiscono l'IDE sul comportamento da adottare a seconda che si stia lavorando in React o in PHP:
- **[react/AGENTS.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/react/AGENTS.md)** (Agente React): Focalizzato su Vite, bundling single-file, TypeScript (`import type`), e React Class/Functional Components.
- **[php/AGENTS.md](file:///c:/__Git/_UniPR/elixforms-custom-pages/php/AGENTS.md)** (Agente PHP): Focalizzato su PHP 8.0+ puro, PSR-4 namespaces, server locale integrato, e deploy diretto su Apache.
---
## Istruzioni per il Test Locale PHP
1. Navigare nella cartella della pagina di esempio:
```bash
cd php/scelta-carriera
```
2. Avviare il server built-in di PHP:
```bash
php -S localhost:8080
```
3. Visitare l'URL inserendo dei parametri fittizi di prova per bypassare il controllo di autenticazione:
```
http://localhost:8080/?RWE2_MODULE_ID=123&RWE2_REQUEST_ID=456&custom-workflow-back-url=http://example.com&custom-workflow-generic-id=1&custom-workflow-current-tabrel-genid=2&custom-workflow-source-field=src&crc=abc&MODULE_TESTMODE_KEY=key&ELANG=it&COL0002=ValoreTest
```
4. Il form caricherà la pagina con il tema e layout corretti di Bootstrap Italia e i campi pre-popolati.