--- name: elixforms-project-architecture description: > Architettura e struttura del progetto elixForms Custom Pages. Descrive il monorepo, la libreria common condivisa, il pattern delle pagine autonome e tutte le convenzioni di naming, configurazione e build. Attiva questa skill quando lavori su qualsiasi parte del progetto, crei nuove pagine, modifichi l'architettura o devi capire come è organizzato il codice. --- # Architettura del Progetto elixForms Custom Pages ## Panoramica Questo progetto è un **monorepo** per la creazione di pagine web React custom destinate alla piattaforma **elixForms** dell'Università di Parma (UniPR). Ogni pagina è un micro-progetto indipendente che produce un **singolo file JS bundle** contenente React, Fluent UI, CSS e il codice custom, da pubblicare su un server remoto. ## Struttura del Workspace ``` elixforms-custom-pages/ ← Root del workspace (VS Code) ├── .vscode/ ← Configurazioni VS Code (launch, tasks) ├── docs/ ← Documentazione (PDF manuali) └── react/ ← Root del monorepo React ├── package.json ← Dipendenze condivise (React, ReactDOM, FluentUI) ├── tsconfig.base.json ← Configurazione TypeScript base condivisa ├── .gitignore ├── common/ ← Libreria condivisa di componenti ElixForms │ ├── package.json │ ├── tsconfig.json ← Estende tsconfig.base, composite: true │ └── src/ │ ├── ElixFormsComponent.tsx │ ├── ElixFormsComponentAbstract.tsx │ ├── ElixFormsElement.tsx │ ├── ElixFormsTypes.tsx │ ├── ElixFormsComponent.module.scss │ ├── IElixFormsComponentProperties.ts │ ├── IElixFormsComponentFormState.tsx │ ├── IElixFormsComponentCustomFormFieldFactory.ts │ └── QueryParamHelper.tsx └── scelta-carriera/ ← Esempio di pagina custom (micro-progetto) ├── package.json ├── tsconfig.json ← Estende tsconfig.base ├── vite.config.js ├── eslint.config.js ├── index.html └── src/ ├── main.jsx ← Entry point React ├── App.jsx ← Componente principale della pagina ├── App.css ← CSS (importa CSS remoti di elixForms) ├── index.css ← CSS globale (attualmente commentato) ├── global.d.ts ← Dichiarazioni di tipo per moduli └── assets/ ← Immagini e risorse statiche ``` ## Pattern Architetturale: Micro-Progetto per Pagina Ogni pagina (es. `scelta-carriera/`) è un progetto Vite completamente autonomo che: 1. **Importa dalla libreria `common/`** tramite alias `@common` configurato in `vite.config.js` 2. **Ha le proprie dipendenze** nel suo `package.json` (solo devDependencies e plugin Vite) 3. **Condivide le dipendenze runtime** (React, ReactDOM, FluentUI) dal `package.json` root di `react/` 4. **Produce un singolo file JS** tramite la configurazione Rollup in `vite.config.js` 5. **Estende il tsconfig base** per avere configurazione TypeScript coerente ## Dipendenze Condivise (react/package.json) Le dipendenze runtime sono hoisted al livello `react/`: - `react` ^19.2.7 - `react-dom` ^19.2.5 - `@fluentui/react` ^8.125.6 ## Configurazione TypeScript ### Base (tsconfig.base.json) - `module`: ESNext - `target`: ES2022 - `moduleResolution`: bundler - `jsx`: react-jsx - `strict`: true - Path alias: `@common/*` → `./common/*` ### Common (common/tsconfig.json) - `composite`: true (per project references) - `declaration`: true, `declarationMap`: true ### Pagine (scelta-carriera/tsconfig.json) - `extends`: `../tsconfig.base.json` - `references`: `../common` - `allowJs`: true, `checkJs`: true (supporto misto JSX/TSX) ## Configurazione Build (Vite) Ogni pagina usa questa configurazione per generare un **singolo bundle JS**: ```js // Plugin chiave react() // Supporto React JSX cssInjectedByJsPlugin() // CSS iniettato nel JS (no file .css separati) // Build options cssCodeSplit: false rollupOptions.input: 'src/main.jsx' rollupOptions.output: codeSplitting: false manualChunks: undefined entryFileNames: '.js' // Nome descrittivo (es. 'scelta-carriera.js') assetFileNames: '[name].[ext]' sourcemap: true ``` ## Resolve Alias ```js resolve.alias: { "@common": path.resolve(__dirname, "../common") } server.fs.allow: [".."] // Permette import da common/ ``` ## CSS Strategy Le pagine caricano CSS dal server remoto elixForms tramite `@import url(...)` in `App.css`: - CSS da `console-unipr.elixforms.it` per il design system dell'università - I componenti FluentUI usano stili inline/theme nativi - SCSS modules sono usati in `common/` per stili dei componenti condivisi - `sass-embedded` è installato come devDependency per supporto SCSS ## Integrazione con elixForms La pagina custom interagisce con la piattaforma elixForms tramite: 1. **Query parameters**: Parametri obbligatori passati nell'URL (es. `RWE2_MODULE_ID`, `RWE2_REQUEST_ID`, `crc`, etc.) 2. **Form POST**: Il form fa submit a `https://procedure.unipr.it/rwe2/ComeBackToElixAndSave` 3. **Hidden inputs**: I parametri query vengono inseriti come campi hidden nel form 4. **Encoding**: `acceptCharset="ISO-8859-1"` per compatibilità con il backend ## Convenzioni di Naming - **Cartelle pagina**: kebab-case (es. `scelta-carriera`) - **Package name**: `@elixforms/` (es. `@elixforms/scelta-carriera`) - **Bundle output**: `.js` (es. `scelta-carriera.js`) - **Componenti React**: PascalCase - **File sorgente**: I file correnti sono `.jsx` ma il progetto ha pieno supporto TypeScript (`.tsx`) - **Tipo moduli**: `"type": "module"` nelle pagine ## Ambiente di Sviluppo - **Dev server**: `npm run dev` (Vite HMR) - **Build**: `npm run build` → output in `dist/` - **Debug VS Code**: Configurazioni in `.vscode/launch.json` per avviare Vite + Chrome - **Lint**: ESLint con plugin react-hooks e react-refresh