Files
elixforms-web-pages/.agents/skills/project-architecture/SKILL.md
T

151 lines
6.2 KiB
Markdown

---
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: '<nome-pagina>.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/<nome-pagina>` (es. `@elixforms/scelta-carriera`)
- **Bundle output**: `<nome-pagina>.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