| name | siae-frontend |
| description | Use when writing Vue.js/Angular/React components, Vitest tests, S3+CloudFront deploys, or frontend integrations (Pinia, Vue Router, Firebase). Guida la scrittura di componenti frontend, test e deploy. Trigger: componente Vue.js, Vitest, test frontend, deploy S3 CloudFront, Firebase, Pinia, Vue Router, responsive design, drag drop, upload file.
|
| paths | **/*.tsx, **/*.jsx |
SIAE Frontend
╔══════════════════════════════════════════════════════════════════╗
║ ███████╗██╗ █████╗ ███████╗ ██████╗ ███████╗██╗ ██╗ ║
║ ██╔════╝██║██╔══██╗██╔════╝ ██╔══██╗██╔════╝██║ ██║ ║
║ ███████╗██║███████║█████╗ ██║ ██║█████╗ ██║ ██║ ║
║ ╚════██║██║██╔══██║██╔══╝ ██║ ██║██╔══╝ ╚██╗ ██╔╝ ║
║ ███████║██║██║ ██║███████╗ ██████╔╝███████╗ ╚████╔╝ ║
║ ╚══════╝╚═╝╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚══════╝ ╚═══╝ ║
║ 🔨 DevForge · SIAE Frontend Patterns ║
╚══════════════════════════════════════════════════════════════════╝
Tipo: Flexible | Fase SDLC: 4. Implementation
📊 Dai repo itsiae: Il 45% dei bug frontend reportati in collaudo era riproducibile solo con test E2E — unit test insufficienti.
Fonte: analisi dei repository GitHub dell'org itsiae.
Panoramica
Pattern frontend SIAE per sviluppo, testing, deploy e brand. Vue.js 3 e' lo stack standard SIAE per i nuovi progetti. Angular e React sono supportati dove gia' adottati.
Le sezioni di deploy, Firebase e brand si applicano a tutti i framework. Le sezioni di stack e testing variano per framework.
Trigger: componenti frontend (Vue/Angular/React), test frontend, deploy S3+CloudFront, Firebase config, GA error tracking.
1. Stack Tecnologico
Vue.js 3 — Stack standard SIAE
| Tecnologia | Ruolo | Versione |
|---|
| Vue.js 3 | Framework UI | 3.x |
| TypeScript | Type safety | 5.x |
| Pinia | State management | 2.x |
| PrimeVue | UI component library | 4.x |
| Vite | Build tool | 5.x |
| vitest | Testing framework | 1.x |
Struttura src/: assets/styles/ (CSS variables), components/ (common, layout), composables/ (use*), router/, stores/ (Pinia), views/, services/ (api.ts, firebase.ts, analytics.ts), types/
Angular — Stack supportato
| Tecnologia | Ruolo | Versione |
|---|
| Angular | Framework UI | 17+ |
| TypeScript | Type safety | 5.x |
| RxJS | State/async management | 7.x |
| Angular Material / CDK | UI component library | 17+ |
| Vite (via @analogjs/vite-plugin-angular) | Build tool | — |
| vitest | Testing framework | 1.x |
Struttura src/app/: components/, services/, models/, guards/, pipes/
React — Stack supportato
| Tecnologia | Ruolo | Versione |
|---|
| React | Framework UI | 18+ |
| TypeScript | Type safety | 5.x |
| Zustand / Redux Toolkit | State management | — |
| Vite | Build tool | 5.x |
| vitest | Testing framework | 1.x |
Struttura src/: components/, hooks/, services/, store/, types/
2. Deploy (S3 + CloudFront)
🔴 CRITICO — Mostra pre-flight card prima di eseguire
Costruisci la card come MARKDOWN TABLE direttamente nella risposta testuale.
| 🔴 CRITICO (Deploy S3 + CloudFront) — 🔨 DevForge · siae-frontend |
|---|
| ⚠️ OPERAZIONE REMOTA — WRITE/UPDATE/DELETE SU S3 + CloudFront |
📋 Risorsa: {BUCKET_NAME} · 🌍 Ambiente: {AMBIENTE} |
| ▼ Azioni |
1. aws s3 sync dist/ s3://{BUCKET_NAME} — sovrascrive tutti gli asset nel bucket |
2. aws cloudfront create-invalidation --distribution-id {DISTRIBUTION_ID} — invalida la cache CloudFront |
| 💡 Perché: Il deploy sovrascrive gli asset in produzione e invalida la cache CloudFront. L'operazione è irreversibile senza un re-deploy. |
| 🚫 Se NO: STOP — nessun sync S3 né invalidazione CloudFront eseguiti |
⏸️ ATTENDI CONFERMA ESPLICITA — mostra la card e NON eseguire finché l'utente
risponde esplicitamente ("sì, procedi" / "no, annulla"). Silenzio ≠ consenso.
Solo dopo "sì, procedi", esegui:
vite build -> dist/ -> S3 bucket (no static hosting, access via CloudFront OAI/OAC). index.html no-cache, assets con hash per cache busting.
Pipeline: git push tag rc-* --> GitHub Actions --> vite build --> S3 sync --> CloudFront invalidation
3. Testing
Runner comune: vitest. La library DOM cambia per framework. Coverage minima 70% per tutti gli stack (CI enforcement). Testa comportamento utente, non implementazione interna.
vitest.config.ts (comune): environment jsdom, coverage provider v8, thresholds 70% (statements, branches, functions, lines).
Vue.js
Stack: vitest + @testing-library/vue + @vue/test-utils
File test: {Component}.spec.ts, affiancato al componente.
import { render, screen, fireEvent } from '@testing-library/vue'
import { describe, it, expect } from 'vitest'
import MyComponent from './MyComponent.vue'
describe('MyComponent', () => {
it('mostra il titolo', () => {
render(MyComponent, { props: { title: 'Test' } })
expect(screen.getByText('Test')).toBeTruthy()
})
it('emette evento click', async () => {
const { emitted } = render(MyComponent)
await fireEvent.click(screen.getByRole('button'))
expect(emitted()).toHaveProperty('click')
})
})
Angular
Stack: vitest + @testing-library/angular
File test: {component}.spec.ts, affiancato al componente.
import { render, screen, fireEvent } from '@testing-library/angular'
import { describe, it, expect } from 'vitest'
import { MyComponent } from './my.component'
describe('MyComponent', () => {
it('mostra il titolo', async () => {
await render(MyComponent, { componentProperties: { title: 'Test' } })
expect(screen.getByText('Test')).toBeTruthy()
})
})
React
Stack: vitest + @testing-library/react
File test: {Component}.spec.tsx o {Component}.test.tsx, affiancato al componente.
import { render, screen, fireEvent } from '@testing-library/react'
import { describe, it, expect } from 'vitest'
import MyComponent from './MyComponent'
describe('MyComponent', () => {
it('mostra il titolo', () => {
render(<MyComponent title="Test" />)
expect(screen.getByText('Test')).toBeTruthy()
})
it('chiama onClick al click', async () => {
const onClick = vi.fn()
render(<MyComponent onClick={onClick} />)
await fireEvent.click(screen.getByRole('button'))
expect(onClick).toHaveBeenCalled()
})
})
4. Configurazioni Esterne
Firebase Remote Config
Feature flags e app settings senza deploy. Config da env variables (VITE_FIREBASE_*), MAI hardcoded.
import { initializeApp } from 'firebase/app'
import { getRemoteConfig, fetchAndActivate, getValue } from 'firebase/remote-config'
const app = initializeApp({
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID
})
const remoteConfig = getRemoteConfig(app)
export async function getFeatureFlag(key: string): Promise<boolean> {
await fetchAndActivate(remoteConfig)
return getValue(remoteConfig, key).asBoolean()
}
Firebase Analytics: getAnalytics(app) + logEvent() per tracking eventi.
Aggiornamento parametri Remote Config (write/update/delete)
🔴 CRITICO — Mostra pre-flight card prima di eseguire
Per qualsiasi operazione di scrittura, aggiornamento o eliminazione di parametri Firebase Remote Config (via Firebase Console, Admin SDK o REST API), mostra la card seguente prima di procedere.
| 🔴 CRITICO (Firebase Remote Config Update) — 🔨 DevForge · siae-frontend |
|---|
| ⚠️ OPERAZIONE REMOTA — WRITE/UPDATE/DELETE SU Firebase Remote Config |
📋 Risorsa: {NOME_PARAMETRO} · 🌍 Ambiente: {AMBIENTE} |
| ▼ Azioni |
1. Aggiorna/crea/elimina il parametro {NOME_PARAMETRO} su Firebase Remote Config |
| 2. Pubblica la nuova versione della configurazione (publish) |
| 💡 Perché: Le modifiche alla Remote Config hanno effetto immediato su tutti i client alla prossima fetch. Valori errati possono disabilitare feature flags o alterare comportamenti in produzione. |
| 🚫 Se NO: STOP — nessuna modifica alla Remote Config eseguita |
⏸️ ATTENDI CONFERMA ESPLICITA — mostra la card e NON eseguire finché l'utente
risponde esplicitamente ("sì, procedi" / "no, annulla"). Silenzio ≠ consenso.
Solo dopo "sì, procedi", esegui: la modifica/creazione/eliminazione del parametro {NOME_PARAMETRO} su Firebase Remote Config e pubblica la nuova versione.
5. Error Tracking con Google Analytics
Funzione centralizzata trackError(category, detail) con gtag('event', 'error', ...):
| Tipo | Condizione | Category | Label |
|---|
| Server | HTTP 5xx | 'Server' | statusCode |
| Client | HTTP 4xx | 'Client' | statusCode |
| Network | timeout / DNS / connection failure | 'Network' | errorType |
type ErrorCategory = 'Server' | 'Client' | 'Network'
export function trackError(category: ErrorCategory, detail: string): void {
gtag('event', 'error', { event_category: category, event_label: detail })
}
6. SIAE Brand
Palette colori
| Ruolo | Colore | Uso |
|---|
| Primary | #000000 | Testi principali, header |
| Secondary | #2F3546 | Sidebar, elementi secondari |
| Accent | #00B4F9 | CTA, link, elementi interattivi |
| Background | #F6F6F6 | Sfondo pagine, card |
CSS Variables e Font
:root {
--siae-primary: #000000; --siae-secondary: #2F3546;
--siae-accent: #00B4F9; --siae-background: #F6F6F6;
--siae-font-family: 'Roboto', sans-serif;
}
Font: Roboto (Google Fonts), fallback sans-serif.
7. Vincoli Inviolabili
Queste regole sono OBBLIGATORIE. Violarne una significa bloccare la review.
| # | Vincolo | Motivazione |
|---|
| V1 | No CSS inline | Usa CSS variables o Tailwind utilities |
| V2 | Responsive mobile-first | Breakpoint min-width, mobile come base |
| V3 | No any in TypeScript | Type safety e' il motivo di usare TS |
| V4 | Accessibilita' WCAG 2.1 AA | aria-* attributes, contrasto colori |
| V5 | Coverage test >= 70% | Enforcement in CI, no merge sotto soglia |
| V6 | No secret in codice frontend | Usa env variables (VITE_*) |
| V7 | Componenti tipizzati con defineComponent | Props, emits, slots tipizzati |
| V8 | No dipendenze non approvate | Review team lead per nuovi package |
Limiti Operativi
| Vincolo | Limite | Se superato |
|---|
| Tentativi fix per errore | 2 | Fermati. Diagnosi diversa necessaria. |
| File modificati per singolo step | 5 | Se devi toccare piu' file, decomponi in sub-task. |
| Output max per raccomandazione | 200 righe | Prioritizza. Top 5 issue, non lista esaustiva. |
REQUIRED SUB-SKILL: siae-tdd
Implementa ogni componente frontend seguendo siae-tdd (test Vitest fallente prima del codice).
Tabella Anti-Razionalizzazione
| Pensiero | Realta' |
|---|
| "Questo componente e' solo per questa pagina" | I componenti 'locali' vengono riusati. Costruiscili per il riuso. |
| "I test Vitest rallentano il build" | I bug UI in produzione rallentano i developer per giorni. |
| "Il CSS lo sistemo dopo" | Il CSS non sistemato diventa tech debt che blocca il restyling. |
| "Non serve il brand SIAE per questo prototipo" | I prototipi diventano produzione. Il brand si aggiunge male in corsa. |
| "Firebase config la metto nel codice" | Le config hardcoded vanno in git. Le credenziali non devono andare in git. |
| "L'error tracking lo aggiungo in produzione" | Senza error tracking non sai cosa sta rompendosi in produzione. |
| "Vue 2 funziona ancora, non migro" | Vue 2 e' EOL. Il debito di migrazione cresce ogni giorno. |
Classificazione Rischio Operazioni
| Operazione | Rischio |
|---|
| Lettura/analisi componenti frontend | 🟢 Sicuro |
| Creazione/modifica componenti | 🟡 Medio |
| Modifica CSS variables / brand | 🟡 Medio |
Esecuzione test (vitest) | 🟡 Medio |
| Modifica Firebase config | 🚨 Critico |
| Modifica analytics/error tracking | 🔴 Alto |
| Deploy S3 + CloudFront invalidation | 🚨 Critico |
| Modifica variabili environment | 🔴 Alto |