Profesionální pracovní postup: Úhlový projekt s kurzorem od konfigurace po nasazení
Dozvěděli jste se o kurzoru, jeho pravidlech, režimu agenta, režimu plánu, hácích a protokolu MCP. Nyní je čas dát vše dohromady do jednoho skutečný profesionální pracovní postup. Tento článek finále série a provozní případová studie: postavíme kompletní Angular projekt pomocí Cursor as Druhý pilot AI v každé fázi, od inicializace projektu až po produkční nasazení.
Toto není abstraktní sbírka osvědčených postupů. Každá sekce zobrazuje skutečné příkazy, výzvy efektivní, konkrétní konfigurace a rozhodnutí profesionálního týmu při integraci Kurzor ve vašem každodenním vývojovém procesu. Na konci tohoto článku budete mít učebnici kompletní a replikovatelné pro jakýkoli Angular projekt.
Projekt, který postavíme, je jeden řídicí panel pro správu úkolů s Angular 19, SSR, signály, samostatné komponenty, automatizované testování a CI/CD s akcemi GitHub. Projekt reprezentující skutečnou složitost, se kterou se při své každodenní profesionální práci setkáváte.
Co se dozvíte v tomto článku
- Jak strukturovat soubor
.cursor/rules/optimální pro Angular projekty - Počáteční nastavení projektu s režimem agenta: od začátku po kompletní strukturu během několika minut
- Generování samostatných komponent se signály a reaktivními formami řízené umělou inteligencí
- Konfigurace SSR a přírůstkové hydratace s kurzorem jako asistentem
- Pracovní postup testování: unit testy s Jest/Vitest a E2E s Playwrightem, napsané pomocí AI
- Inteligentně refaktorujte starší vzory pomocí režimu agenta
- Asistovaná optimalizace výkonu: líné načítání, analýza balíků, Core Web Vitals
- Kompletní kanál CI/CD vygenerovaný pomocí Cursor pro akce GitHub a Firebase
- Komplexní případová studie: kompletní funkce od nápadu až po produkční nasazení
- Exkluzivní tipy a triky pro vývojáře Angular, kteří používají Cursor každý den
Technické požadavky
- Node.js 22+ a Angular CLI 19+
- Cursor IDE (Pro plán doporučený pro neomezený režim agenta)
- Git a účet GitHub pro CI/CD
- Základní znalost Angular, TypeScript a RxJS
- Volitelné: Účet Firebase pro nasazení, znalost SSR
Krok 1 – Konfigurace pravidel kurzoru pro úhlový projekt
Prvním krokem pro profesionální pracovní postup je nakonfigurovat kurzor tak, aby znal konvence vašeho projektu ještě předtím, než napíšete první řádek kódu. Soubor dobře strukturovaná pravidla transformují Cursor z generického asistenta na a spolupracovník specializované na váš Angular stack.
S kurzorem 0.45+ jsou pravidla v adresáři .cursor/rules/ jako soubor
.mdc. Můžete mít globální pravidla, která jsou vždy aktivní, a konkrétní pravidla, která se spouští
na základě kontextu. Pro profesionální Angular projekt doporučuji tuto strukturu:
# Struttura directory regole Angular
.cursor/
rules/
angular-core.mdc # Regole fondamentali sempre attive
angular-components.mdc # Regole per componenti standalone
angular-testing.mdc # Regole per la scrittura dei test
angular-performance.mdc # Regole per ottimizzazioni
angular-ssr.mdc # Regole per SSR e hydration
Zde je celý obsah angular-core.mdc, nejdůležitější pravidlo, že
vytváří architektonické základy projektu:
---
description: Regole fondamentali per progetti Angular 19+ con standalone components e signals
globs: ["**/*.ts", "**/*.html"]
alwaysApply: true
---
# Angular Core Rules
## Architettura e Struttura
- Usa SEMPRE standalone components (niente NgModules salvo casi eccezionali)
- Organizza per feature/dominio, non per tipo (no cartelle globali "components/", "services/")
- Struttura directory per feature: `src/app/features/[nome-feature]/`
- Ogni feature ha: components/, services/, models/, guards/ (se necessario)
- Shared components in `src/app/shared/`
- Core singleton services in `src/app/core/`
## TypeScript e Dependency Injection
- Usa SEMPRE `inject()` per l'iniezione delle dipendenze (non costruttore)
- TypeScript strict mode obbligatorio
- Evita `any` - usa `unknown` con type narrowing quando necessario
- Usa `readonly` per proprietà che non cambiano dopo l'inizializzazione
- Interface su Type per definire shape di oggetti
## State Management con Signals
- Usa signals per tutto lo stato locale del componente
- `computed()` per valori derivati, mai getters che chiamano funzioni
- `effect()` solo per side effects (DOM, chiamate API non-reactive, log)
- Per stato condiviso tra componenti: service con signals esposti come readonly
- RxJS per operazioni async complesse (HTTP, WebSocket), poi `toSignal()` per esporre nei template
## Template e Rendering
- Usa SEMPRE la nuova sintassi control flow: @if, @for, @switch (non *ngIf, *ngFor)
- `@for` richiede sempre il `track` expression - usa ID univoci, non index
- ChangeDetectionStrategy.OnPush per TUTTI i componenti (performance default)
- NgOptimizedImage per tutte le immagini (src → ngSrc)
## Naming Conventions
- File: kebab-case (`user-profile.component.ts`)
- Classi: PascalCase (`UserProfileComponent`)
- Signals: nome senza prefisso, non `
09 - Profesionální pracovní postup: Úhlový projekt s kurzorem | Federico Calò
09 - Profesionální pracovní postup: Úhlový projekt s kurzorem | Federico Calò
Salta al contenuto principaleAhoj! Jsem
Federico Calò
Sviluppatore Software | Divulgatore Tecnico
Creo applicazioni web moderne e strumenti digitali personalizzati per aiutare le attività a crescere attraverso l'innovazione tecnologica. La mia passione è unire informatica ed economia per generare valore reale.
O Mně
La mia passione per l'informatica è nata tra i banchi dell'Istituto Tecnico Commerciale di Maglie, dove ho scoperto il potere della programmazione e il fascino di creare soluzioni digitali. Fin da subito, ho capito che l'informatica non era solo codice, ma uno strumento straordinario per trasformare idee in realtà.
Durante gli studi superiori in Sistemi Informativi Aziendali, ho iniziato a intrecciare informatica ed economia, comprendendo come la tecnologia possa essere il motore della crescita per qualsiasi attività. Questa visione mi ha accompagnato all'Università degli Studi di Bari, dove ho conseguito la Laurea in Informatica, approfondendo le mie competenze tecniche e la mia passione per lo sviluppo software.
Oggi metto questa esperienza al servizio di imprese, professionisti e startup, creando soluzioni digitali su misura che automatizzano processi, ottimizzano risorse e aprono nuove opportunità di business. Perché la vera innovazione inizia quando la tecnologia incontra le esigenze reali delle persone.
Mé Dovednosti
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automatizace Procesů
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Systémy na Míru
Sviluppo sistemi software su misura, dalle integrazioni tra piattaforme alle dashboard personalizzate
const federico = {
nome: "Federico Calò",
ruolo: "Sviluppatore Software",
città: "Bari, Italia",
missione: "Aiutare attraverso l'informatica",
passioni: [
"Codice Pulito",
"Innovazione",
"Crescita Continua"
]
};
Mé Poslání
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Demokratizovat Technologie
La mia missione è rendere l'informatica accessibile a tutti: dalle piccole imprese locali alle startup innovative, fino ai professionisti che vogliono digitalizzare la propria attività. Ogni realtà merita di sfruttare le potenzialità del digitale.
Propojení IT a Ekonomiky
Non è solo questione di scrivere codice: è capire come la tecnologia possa generare valore reale. Intrecciando competenze informatiche e visione economica, aiuto le attività a crescere, ottimizzare processi e raggiungere nuovi traguardi di efficienza e redditività.
Tvorba Řešení na Míru
Ogni attività è unica, e così devono esserlo le soluzioni. Sviluppo strumenti personalizzati che rispondono alle esigenze specifiche di ciascun cliente, automatizzando processi ripetitivi e liberando tempo per ciò che conta davvero: far crescere il business.
Transformujte Své Podnikání Technologiemi
Che tu gestisca un negozio, uno studio professionale o un'azienda, posso aiutarti a sfruttare le potenzialità dell'informatica per lavorare meglio, più velocemente e in modo più intelligente.
Pojďme si Promluvit →Unisciti alla Community
Entra nella community di sviluppatori dove discutiamo di software, AI, architettura e DevOps. Condividi idee, fai domande e cresci insieme a noi.
CanaleFC Dev Blog
Ricevi notifiche su nuovi articoli, serie complete, tips settimanali e tool in evidenza. Contenuti bilingui IT/EN direttamente nel tuo Telegram.
Nuovi articoli appena pubblicati Tips e code snippets settimanali Sondaggi sugli argomenti futuri
Iscriviti al CanaleGruppoFC Dev Community
Una community bilingue IT/EN per sviluppatori. Discussioni, Q&A, aiuto reciproco e networking con altri professionisti del settore.
Discussioni su articoli e tecnologie Help coding e code review Opportunità di lavoro e collaborazione
Unisciti al GruppoTopic di Discussione
#general #articles #help-coding #ai-ml #devops-cloud #architecture #tools #jobs-opportunitiesFormazione & Competenze
Il mio percorso accademico e le tecnologie che padroneggio
Certificazioni Professionali
8 certificazioni conseguite
Linguaggi & Tecnologie
Java Python JavaScript Angular React TypeScript SQL PHP CSS/SCSS Node.js Docker GitKontaktujte Mě
Máte projekt na mysli? Pojďme si promluvit! Vyplňte formulář a brzy se ozvu.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
come suffisso (`users`, non `users
09 - Profesionální pracovní postup: Úhlový projekt s kurzorem | Federico Calò
09 - Profesionální pracovní postup: Úhlový projekt s kurzorem | Federico Calò
Salta al contenuto principaleAhoj! Jsem
Federico Calò
Sviluppatore Software | Divulgatore Tecnico
Creo applicazioni web moderne e strumenti digitali personalizzati per aiutare le attività a crescere attraverso l'innovazione tecnologica. La mia passione è unire informatica ed economia per generare valore reale.
O Mně
La mia passione per l'informatica è nata tra i banchi dell'Istituto Tecnico Commerciale di Maglie, dove ho scoperto il potere della programmazione e il fascino di creare soluzioni digitali. Fin da subito, ho capito che l'informatica non era solo codice, ma uno strumento straordinario per trasformare idee in realtà.
Durante gli studi superiori in Sistemi Informativi Aziendali, ho iniziato a intrecciare informatica ed economia, comprendendo come la tecnologia possa essere il motore della crescita per qualsiasi attività. Questa visione mi ha accompagnato all'Università degli Studi di Bari, dove ho conseguito la Laurea in Informatica, approfondendo le mie competenze tecniche e la mia passione per lo sviluppo software.
Oggi metto questa esperienza al servizio di imprese, professionisti e startup, creando soluzioni digitali su misura che automatizzano processi, ottimizzano risorse e aprono nuove opportunità di business. Perché la vera innovazione inizia quando la tecnologia incontra le esigenze reali delle persone.
Mé Dovednosti
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automatizace Procesů
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Systémy na Míru
Sviluppo sistemi software su misura, dalle integrazioni tra piattaforme alle dashboard personalizzate
const federico = {
nome: "Federico Calò",
ruolo: "Sviluppatore Software",
città: "Bari, Italia",
missione: "Aiutare attraverso l'informatica",
passioni: [
"Codice Pulito",
"Innovazione",
"Crescita Continua"
]
};
Mé Poslání
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Demokratizovat Technologie
La mia missione è rendere l'informatica accessibile a tutti: dalle piccole imprese locali alle startup innovative, fino ai professionisti che vogliono digitalizzare la propria attività. Ogni realtà merita di sfruttare le potenzialità del digitale.
Propojení IT a Ekonomiky
Non è solo questione di scrivere codice: è capire come la tecnologia possa generare valore reale. Intrecciando competenze informatiche e visione economica, aiuto le attività a crescere, ottimizzare processi e raggiungere nuovi traguardi di efficienza e redditività.
Tvorba Řešení na Míru
Ogni attività è unica, e così devono esserlo le soluzioni. Sviluppo strumenti personalizzati che rispondono alle esigenze specifiche di ciascun cliente, automatizzando processi ripetitivi e liberando tempo per ciò che conta davvero: far crescere il business.
Transformujte Své Podnikání Technologiemi
Che tu gestisca un negozio, uno studio professionale o un'azienda, posso aiutarti a sfruttare le potenzialità dell'informatica per lavorare meglio, più velocemente e in modo più intelligente.
Pojďme si Promluvit →Unisciti alla Community
Entra nella community di sviluppatori dove discutiamo di software, AI, architettura e DevOps. Condividi idee, fai domande e cresci insieme a noi.
CanaleFC Dev Blog
Ricevi notifiche su nuovi articoli, serie complete, tips settimanali e tool in evidenza. Contenuti bilingui IT/EN direttamente nel tuo Telegram.
Nuovi articoli appena pubblicati Tips e code snippets settimanali Sondaggi sugli argomenti futuri
Iscriviti al CanaleGruppoFC Dev Community
Una community bilingue IT/EN per sviluppatori. Discussioni, Q&A, aiuto reciproco e networking con altri professionisti del settore.
Discussioni su articoli e tecnologie Help coding e code review Opportunità di lavoro e collaborazione
Unisciti al GruppoTopic di Discussione
#general #articles #help-coding #ai-ml #devops-cloud #architecture #tools #jobs-opportunitiesFormazione & Competenze
Il mio percorso accademico e le tecnologie che padroneggio
Certificazioni Professionali
8 certificazioni conseguite
Linguaggi & Tecnologie
Java Python JavaScript Angular React TypeScript SQL PHP CSS/SCSS Node.js Docker GitKontaktujte Mě
Máte projekt na mysli? Pojďme si promluvit! Vyplňte formulář a brzy se ozvu.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
ne `usersSignal`)
- Observable: suffisso `
09 - Profesionální pracovní postup: Úhlový projekt s kurzorem | Federico Calò
09 - Profesionální pracovní postup: Úhlový projekt s kurzorem | Federico Calò
Salta al contenuto principaleAhoj! Jsem
Federico Calò
Sviluppatore Software | Divulgatore Tecnico
Creo applicazioni web moderne e strumenti digitali personalizzati per aiutare le attività a crescere attraverso l'innovazione tecnologica. La mia passione è unire informatica ed economia per generare valore reale.
O Mně
La mia passione per l'informatica è nata tra i banchi dell'Istituto Tecnico Commerciale di Maglie, dove ho scoperto il potere della programmazione e il fascino di creare soluzioni digitali. Fin da subito, ho capito che l'informatica non era solo codice, ma uno strumento straordinario per trasformare idee in realtà.
Durante gli studi superiori in Sistemi Informativi Aziendali, ho iniziato a intrecciare informatica ed economia, comprendendo come la tecnologia possa essere il motore della crescita per qualsiasi attività. Questa visione mi ha accompagnato all'Università degli Studi di Bari, dove ho conseguito la Laurea in Informatica, approfondendo le mie competenze tecniche e la mia passione per lo sviluppo software.
Oggi metto questa esperienza al servizio di imprese, professionisti e startup, creando soluzioni digitali su misura che automatizzano processi, ottimizzano risorse e aprono nuove opportunità di business. Perché la vera innovazione inizia quando la tecnologia incontra le esigenze reali delle persone.
Mé Dovednosti
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automatizace Procesů
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Systémy na Míru
Sviluppo sistemi software su misura, dalle integrazioni tra piattaforme alle dashboard personalizzate
const federico = {
nome: "Federico Calò",
ruolo: "Sviluppatore Software",
città: "Bari, Italia",
missione: "Aiutare attraverso l'informatica",
passioni: [
"Codice Pulito",
"Innovazione",
"Crescita Continua"
]
};
Mé Poslání
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Demokratizovat Technologie
La mia missione è rendere l'informatica accessibile a tutti: dalle piccole imprese locali alle startup innovative, fino ai professionisti che vogliono digitalizzare la propria attività. Ogni realtà merita di sfruttare le potenzialità del digitale.
Propojení IT a Ekonomiky
Non è solo questione di scrivere codice: è capire come la tecnologia possa generare valore reale. Intrecciando competenze informatiche e visione economica, aiuto le attività a crescere, ottimizzare processi e raggiungere nuovi traguardi di efficienza e redditività.
Tvorba Řešení na Míru
Ogni attività è unica, e così devono esserlo le soluzioni. Sviluppo strumenti personalizzati che rispondono alle esigenze specifiche di ciascun cliente, automatizzando processi ripetitivi e liberando tempo per ciò che conta davvero: far crescere il business.
Transformujte Své Podnikání Technologiemi
Che tu gestisca un negozio, uno studio professionale o un'azienda, posso aiutarti a sfruttare le potenzialità dell'informatica per lavorare meglio, più velocemente e in modo più intelligente.
Pojďme si Promluvit →Unisciti alla Community
Entra nella community di sviluppatori dove discutiamo di software, AI, architettura e DevOps. Condividi idee, fai domande e cresci insieme a noi.
CanaleFC Dev Blog
Ricevi notifiche su nuovi articoli, serie complete, tips settimanali e tool in evidenza. Contenuti bilingui IT/EN direttamente nel tuo Telegram.
Nuovi articoli appena pubblicati Tips e code snippets settimanali Sondaggi sugli argomenti futuri
Iscriviti al CanaleGruppoFC Dev Community
Una community bilingue IT/EN per sviluppatori. Discussioni, Q&A, aiuto reciproco e networking con altri professionisti del settore.
Discussioni su articoli e tecnologie Help coding e code review Opportunità di lavoro e collaborazione
Unisciti al GruppoTopic di Discussione
#general #articles #help-coding #ai-ml #devops-cloud #architecture #tools #jobs-opportunitiesFormazione & Competenze
Il mio percorso accademico e le tecnologie che padroneggio
Certificazioni Professionali
8 certificazioni conseguite
Linguaggi & Tecnologie
Java Python JavaScript Angular React TypeScript SQL PHP CSS/SCSS Node.js Docker GitKontaktujte Mě
Máte projekt na mysli? Pojďme si promluvit! Vyplňte formulář a brzy se ozvu.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
(`users
09 - Profesionální pracovní postup: Úhlový projekt s kurzorem | Federico Calò
09 - Profesionální pracovní postup: Úhlový projekt s kurzorem | Federico Calò
Salta al contenuto principaleAhoj! Jsem
Federico Calò
Sviluppatore Software | Divulgatore Tecnico
Creo applicazioni web moderne e strumenti digitali personalizzati per aiutare le attività a crescere attraverso l'innovazione tecnologica. La mia passione è unire informatica ed economia per generare valore reale.
O Mně
La mia passione per l'informatica è nata tra i banchi dell'Istituto Tecnico Commerciale di Maglie, dove ho scoperto il potere della programmazione e il fascino di creare soluzioni digitali. Fin da subito, ho capito che l'informatica non era solo codice, ma uno strumento straordinario per trasformare idee in realtà.
Durante gli studi superiori in Sistemi Informativi Aziendali, ho iniziato a intrecciare informatica ed economia, comprendendo come la tecnologia possa essere il motore della crescita per qualsiasi attività. Questa visione mi ha accompagnato all'Università degli Studi di Bari, dove ho conseguito la Laurea in Informatica, approfondendo le mie competenze tecniche e la mia passione per lo sviluppo software.
Oggi metto questa esperienza al servizio di imprese, professionisti e startup, creando soluzioni digitali su misura che automatizzano processi, ottimizzano risorse e aprono nuove opportunità di business. Perché la vera innovazione inizia quando la tecnologia incontra le esigenze reali delle persone.
Mé Dovednosti
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automatizace Procesů
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Systémy na Míru
Sviluppo sistemi software su misura, dalle integrazioni tra piattaforme alle dashboard personalizzate
const federico = {
nome: "Federico Calò",
ruolo: "Sviluppatore Software",
città: "Bari, Italia",
missione: "Aiutare attraverso l'informatica",
passioni: [
"Codice Pulito",
"Innovazione",
"Crescita Continua"
]
};
Mé Poslání
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Demokratizovat Technologie
La mia missione è rendere l'informatica accessibile a tutti: dalle piccole imprese locali alle startup innovative, fino ai professionisti che vogliono digitalizzare la propria attività. Ogni realtà merita di sfruttare le potenzialità del digitale.
Propojení IT a Ekonomiky
Non è solo questione di scrivere codice: è capire come la tecnologia possa generare valore reale. Intrecciando competenze informatiche e visione economica, aiuto le attività a crescere, ottimizzare processi e raggiungere nuovi traguardi di efficienza e redditività.
Tvorba Řešení na Míru
Ogni attività è unica, e così devono esserlo le soluzioni. Sviluppo strumenti personalizzati che rispondono alle esigenze specifiche di ciascun cliente, automatizzando processi ripetitivi e liberando tempo per ciò che conta davvero: far crescere il business.
Transformujte Své Podnikání Technologiemi
Che tu gestisca un negozio, uno studio professionale o un'azienda, posso aiutarti a sfruttare le potenzialità dell'informatica per lavorare meglio, più velocemente e in modo più intelligente.
Pojďme si Promluvit →Unisciti alla Community
Entra nella community di sviluppatori dove discutiamo di software, AI, architettura e DevOps. Condividi idee, fai domande e cresci insieme a noi.
CanaleFC Dev Blog
Ricevi notifiche su nuovi articoli, serie complete, tips settimanali e tool in evidenza. Contenuti bilingui IT/EN direttamente nel tuo Telegram.
Nuovi articoli appena pubblicati Tips e code snippets settimanali Sondaggi sugli argomenti futuri
Iscriviti al CanaleGruppoFC Dev Community
Una community bilingue IT/EN per sviluppatori. Discussioni, Q&A, aiuto reciproco e networking con altri professionisti del settore.
Discussioni su articoli e tecnologie Help coding e code review Opportunità di lavoro e collaborazione
Unisciti al GruppoTopic di Discussione
#general #articles #help-coding #ai-ml #devops-cloud #architecture #tools #jobs-opportunitiesFormazione & Competenze
Il mio percorso accademico e le tecnologie che padroneggio
Certificazioni Professionali
8 certificazioni conseguite
Linguaggi & Tecnologie
Java Python JavaScript Angular React TypeScript SQL PHP CSS/SCSS Node.js Docker GitKontaktujte Mě
Máte projekt na mysli? Pojďme si promluvit! Vyplňte formulář a brzy se ozvu.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
)
- Metodi privati: prefisso `_` quando servono chiarezza
## Forms
- Reactive Forms (ReactiveFormsModule) per tutti i form non banali
- Template-driven solo per form con 1-2 campi senza validazione complessa
- Typed forms obbligatori (`FormControl<string>`, non `FormControl`)
- Validators personalizzati come funzioni pure (non classi)
Toto pravidlo poskytuje kurzoru úplný architektonický kontext. Když požádáte o vygenerování a
komponentu, službu nebo funkci, kurzor automaticky ví, kterou z nich použít
inject(), signály a nová syntaxe řídicího toku. To nemusíš
opakujte to pokaždé ve výzvě.
Častá chyba: Pravidla, která jsou příliš obecná
Mnoho týmů vytváří jeden soubor .cursorrules obrovský se stovkami řádků.
Výsledkem je, že kurzor nedokáže upřednostnit instrukce, které jsou pro daný objekt nejrelevantnější
aktuální kontext. Použijte samostatné soubory se specifickými vzory glob: pravidlo pro i
komponenty se aktivují pouze za *.component.ts, zachování kontextu
soustředěné a co nejpřesnější odpovědi.
Pravidlo pro komponenty: angular-components.mdc
---
description: Standard per la creazione di componenti Angular standalone
globs: ["**/*.component.ts", "**/*.component.html"]
alwaysApply: false
---
# Component Standards
## Struttura Component File (ordine canonico)
1. Imports Angular/librerie
2. Imports locali (services, models, altri components)
3. @Component decorator
4. export class ComponentName
a. inject() calls (services)
b. @Input() signals con input()
c. @Output() signals con output()
d. Signals interni (private)
e. Computed signals
f. Constructor (solo se necessario per logic inizializzazione)
g. ngOnInit (se necessario)
h. Metodi pubblici (chiamati dal template)
i. Metodi privati (logica interna)
## Template Best Practices
- Niente logica nel template oltre a binding semplici
- Usa pipe per trasformazioni di dati (DatePipe, CurrencyPipe, ecc.)
- Mantieni template sotto le 100 righe - estrai sub-component se necessario
- Usa `aria-*` per accessibilità (WCAG 2.1 AA)
## Input/Output con Signal API (Angular 17+)
- `input()` per input opzionali, `input.required()` per quelli obbligatori
- `output()` al posto di `EventEmitter`
- `model()` per two-way binding custom
## Component-Scoped Styles
- Usa `:host` per stili sul root element
- Evita deep selector `::ng-deep` - estrai stili globali se necessario
- Variabili CSS per colori e spacing (usa il design system del progetto)
Fáze 2 – Nastavení projektu s režimem agenta
S nakonfigurovanými pravidly je čas vytvořit projekt. Místo ručního běhu každý příkaz a vytvoření každého souboru používáme režim agenta k delegování celé fáze bootstrapu. Toto je jeden z nejvýkonnějších případů použití kurzoru: dejte pokyny na vysoké úrovni a odejděte že agent provádí všechny operativní kroky.
Otevřete kurzor, vytvořte novou složku pro projekt a spusťte režim agenta pomocí Cmd+Shift+I (nebo Ctrl+Shift+I v systému Windows/Linux). Pak použijte tuto výzvu:
Režim Prompt Agent: Bootstrap Project
Crea un nuovo progetto Angular 19 chiamato "task-dashboard" con le seguenti caratteristiche:
1. Angular CLI con SSR abilitato (--ssr flag)
2. TypeScript strict mode
3. Jest al posto di Karma per i test unitari (configura jest.config.ts)
4. ESLint con angular-eslint
5. Prettier configurato con .prettierrc
6. Struttura a feature:
- src/app/core/ (interceptors, guards, singleton services)
- src/app/shared/ (components e pipes condivisi)
- src/app/features/tasks/ (feature principale)
- src/app/features/auth/ (autenticazione)
7. Ambiente di sviluppo con proxy verso http://localhost:3000 (API backend)
8. Git inizializzato con .gitignore appropriato
Esegui i comandi necessari, installa le dipendenze e mostrami la struttura finale.
Kurzor se spustí ng new, nainstaluje závislosti, nakonfiguruje Jest,
ESLint a Prettier, vytvoří strukturu složek a inicializuje Git, celou věc
za pár minut. Přichází to, co obvykle trvá 30-45 minut ručního nastavení
dokončeny přesně a důsledně.
Generování úkolů s funkcemi v režimu agenta
Po bootstrappingu vygenerujeme hlavní funkci. Tato výzva se zobrazí jako Agent Režim může sestavit celý vertikální řez aplikace, od datového modelu až po komponenty, respektující naše Angular pravidla:
Režim Prompt Agent: Feature Tasks Complete
Crea la feature "tasks" completa in src/app/features/tasks/ seguendo le regole in .cursor/rules/:
MODELLO DATI (src/app/features/tasks/models/task.model.ts):
- Interface Task con: id (string), title (string), description (string),
status ('todo' | 'in-progress' | 'done'), priority ('low' | 'medium' | 'high'),
createdAt (Date), dueDate (Date | null), assigneeId (string | null)
- Type TaskStatus e TaskPriority (union types)
- Interface CreateTaskRequest e UpdateTaskRequest (Partial<Task> senza id/createdAt)
SERVICE (src/app/features/tasks/services/task.service.ts):
- Usa inject(HttpClient)
- Signals: tasks = signal<Task[]>([]), loading = signal(false), error = signal<string | null>(null)
- Computed: completedTasks, pendingTasks, tasksByPriority
- Metodi: loadTasks(), createTask(), updateTask(), deleteTask(), updateStatus()
- Tutti i metodi aggiornano i signals dopo le chiamate HTTP
COMPONENTI STANDALONE:
1. TaskListComponent - lista tasks con filtri per status/priority
2. TaskCardComponent - card singola task con azioni
3. TaskFormComponent - form creazione/modifica con reactive forms tipizzati
4. TaskDetailComponent - vista dettaglio con routing
ROUTING: configura il routing lazy-loaded in tasks.routes.ts
Rispetta SEMPRE: standalone: true, inject(), signals, ChangeDetectionStrategy.OnPush,
@if/@for syntax, TypeScript strict mode.
Kurzor vygeneruje všechny soubory respektující konvence definované v pravidlech. Výsledek a koherentní kód, který byste mohli napsat sami, ale za zlomek času.
Fáze 3 - Komponenty se signály a reaktivními formami
Podívejme se podrobně, jak Cursor generuje moderní Angular komponenty. Po zadání výzvy
výše, podívejme se na výstup pro TaskFormComponent a jak to vylepšit:
// task-form.component.ts - Generato da Cursor con Agent Mode
import { Component, ChangeDetectionStrategy, inject, input, output } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { CreateTaskRequest, TaskPriority } from '../models/task.model';
import { TaskService } from '../services/task.service';
@Component({
selector: 'app-task-form',
standalone: true,
imports: [ReactiveFormsModule],
templateUrl: './task-form.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TaskFormComponent {
// Dependency injection con inject()
private readonly fb = inject(FormBuilder);
private readonly taskService = inject(TaskService);
// Input signals (Angular 17+ API)
readonly initialData = input<Partial<CreateTaskRequest> | null>(null);
readonly isEdit = input(false);
// Output signals
readonly formSubmit = output<CreateTaskRequest>();
readonly formCancel = output<void>();
// Reactive form tipizzato
readonly form = this.fb.group({
title: this.fb.control('', {
validators: [Validators.required, Validators.minLength(3), Validators.maxLength(100)],
nonNullable: true
}),
description: this.fb.control('', { nonNullable: true }),
priority: this.fb.control<TaskPriority>('medium', { nonNullable: true }),
dueDate: this.fb.control<string | null>(null)
});
// Computed: stato di validita esposto al template
readonly isValid = this.form.statusChanges;
// Loading state dal service (readonly - no mutation)
readonly loading = this.taskService.loading;
onSubmit(): void {
if (this.form.invalid) return;
const value = this.form.getRawValue();
this.formSubmit.emit({
title: value.title,
description: value.description,
priority: value.priority,
dueDate: value.dueDate ? new Date(value.dueDate) : null,
assigneeId: null
});
}
onCancel(): void {
this.form.reset();
this.formCancel.emit();
}
}
Všimněte si, jak kurzor automaticky respektuje konvence pravidel: inject()
pro závislosti, input() e output() místo
@Input() e @Output(), readonly na vlastnostech
e ChangeDetectionStrategy.OnPush. To je skutečná hodnota pravidel dobře
nakonfigurováno: AI vytváří kód, který odpovídá týmovým standardům, aniž by bylo nutné provádět kontroly
konstanty.
TaskService se signály: Úplný reaktivní vzor
// task.service.ts - Pattern signals per stato globale della feature
import { Injectable, inject, signal, computed } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Task, CreateTaskRequest, UpdateTaskRequest, TaskStatus } from '../models/task.model';
import { tap, catchError, EMPTY, finalize } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class TaskService {
private readonly http = inject(HttpClient);
private readonly API_URL = '/api/tasks';
// Signals privati (stato interno del service)
private readonly _tasks = signal<Task[]>([]);
private readonly _loading = signal(false);
private readonly _error = signal<string | null>(null);
// Signals pubblici (readonly - i consumatori non possono mutare)
readonly tasks = this._tasks.asReadonly();
readonly loading = this._loading.asReadonly();
readonly error = this._error.asReadonly();
// Computed signals - derivati dallo stato
readonly completedTasks = computed(() =>
this._tasks().filter(t => t.status === 'done')
);
readonly pendingTasks = computed(() =>
this._tasks().filter(t => t.status !== 'done')
);
readonly tasksByPriority = computed(() => {
const tasks = this._tasks();
return {
high: tasks.filter(t => t.priority === 'high'),
medium: tasks.filter(t => t.priority === 'medium'),
low: tasks.filter(t => t.priority === 'low')
};
});
readonly completionRate = computed(() => {
const total = this._tasks().length;
if (total === 0) return 0;
return Math.round((this.completedTasks().length / total) * 100);
});
loadTasks(): void {
this._loading.set(true);
this._error.set(null);
this.http.get<Task[]>(this.API_URL).pipe(
tap(tasks => this._tasks.set(tasks)),
catchError(err => {
this._error.set('Errore nel caricamento dei task. Riprova.');
console.error('[TaskService] loadTasks error:', err);
return EMPTY;
}),
finalize(() => this._loading.set(false))
).subscribe();
}
createTask(request: CreateTaskRequest): void {
this._loading.set(true);
this.http.post<Task>(this.API_URL, request).pipe(
tap(newTask => {
// Immutable update del signal
this._tasks.update(current => [...current, newTask]);
}),
catchError(err => {
this._error.set('Errore nella creazione del task.');
return EMPTY;
}),
finalize(() => this._loading.set(false))
).subscribe();
}
updateStatus(taskId: string, status: TaskStatus): void {
// Optimistic update: aggiorna UI immediatamente
this._tasks.update(current =>
current.map(t => t.id === taskId ? { ...t, status } : t)
);
this.http.patch<Task>(`${this.API_URL}/${taskId}`, { status }).pipe(
catchError(err => {
// Rollback in caso di errore
this.loadTasks();
this._error.set('Errore nell\'aggiornamento dello stato.');
return EMPTY;
})
).subscribe();
}
}
Fáze 4 - SSR a přírůstková hydratace pomocí kurzoru
Úhlový 19 port přírůstková hydratace ve stabilitě, funkce, která umožňuje hydratují pouze části stránky, které se stanou viditelnými nebo interaktivními, čímž se sníží drasticky počáteční JavaScript. Správná konfigurace SSR je jednou z nejvíce oblastí podléhají jemným chybám. Kurzor se zde stává obzvláště užitečným.
Tuto výzvu použijte ke konfiguraci SSR s přírůstkovou hydratací a správnou správou kontextů serveru/prohlížeče:
Výzva: Nakonfigurujte SSR s přírůstkovou hydratací
Configura SSR con hydration incrementale per questo progetto Angular 19. Fai queste modifiche:
1. In app.config.ts: aggiungi provideClientHydration(withIncrementalHydration())
2. Crea un service isPlatformBrowser (src/app/core/services/platform.service.ts)
che usa PLATFORM_ID per verificare il contesto di esecuzione
3. Nel TaskListComponent: avvolgi la lista task in un blocco @defer con
on viewport per il caricamento lazy + hydration incrementale
4. Aggiungi TransferState per evitare la doppia chiamata HTTP nel TaskService
(carica i dati lato server, trasferiscili al client senza refetch)
5. Gestisci il caso in cui localStorage non sia disponibile lato server
Kurzor upraví příslušné soubory a vysvětlí vám všechny změny. Výsledek bude
a app.config.ts správná a platformově orientovaná služba:
// app.config.ts - Configurazione SSR completa
import { ApplicationConfig, provideZonelessChangeDetection } from '@angular/core';
import { provideRouter, withPreloading, PreloadAllModules } from '@angular/router';
import { provideClientHydration, withIncrementalHydration } from '@angular/platform-browser';
import { provideHttpClient, withFetch } from '@angular/common/http';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
// Zone-less change detection (Angular 18+, raccomandato con signals)
provideZonelessChangeDetection(),
// Router con preloading strategia
provideRouter(routes, withPreloading(PreloadAllModules)),
// HTTP con fetch API (compatibile con SSR nativo)
provideHttpClient(withFetch()),
// SSR Hydration incrementale (Angular 19 stable)
provideClientHydration(withIncrementalHydration()),
]
};
// platform.service.ts - Rilevamento contesto server/browser
import { Injectable, inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
@Injectable({ providedIn: 'root' })
export class PlatformService {
private readonly platformId = inject(PLATFORM_ID);
readonly isBrowser = isPlatformBrowser(this.platformId);
readonly isServer = isPlatformServer(this.platformId);
// Helper per operazioni browser-only
runInBrowser(fn: () => void): void {
if (this.isBrowser) fn();
}
// Safe localStorage access
getLocalStorage(key: string): string | null {
if (!this.isBrowser) return null;
return localStorage.getItem(key);
}
setLocalStorage(key: string, value: string): void {
if (!this.isBrowser) return;
localStorage.setItem(key, value);
}
}
TransferState, aby se zabránilo dvojitému načítání
Jednou z nejčastějších chyb u Angular SSR je, že se data načítají dvakrát: jedna strana
serveru během vykreslování a znovu na straně klienta po hydrataci. Kurzor lze přidat
automaticky TransferState do servisu:
// task.service.ts - Con TransferState per SSR ottimizzato
import { Injectable, inject, signal, computed, makeStateKey, TransferState } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { tap, catchError, EMPTY, finalize } from 'rxjs';
import { Task, CreateTaskRequest, TaskStatus } from '../models/task.model';
import { PlatformService } from '../../../core/services/platform.service';
const TASKS_KEY = makeStateKey<Task[]>('tasks');
@Injectable({ providedIn: 'root' })
export class TaskService {
private readonly http = inject(HttpClient);
private readonly transferState = inject(TransferState);
private readonly platform = inject(PlatformService);
private readonly _tasks = signal<Task[]>([]);
private readonly _loading = signal(false);
private readonly _error = signal<string | null>(null);
readonly tasks = this._tasks.asReadonly();
readonly loading = this._loading.asReadonly();
readonly error = this._error.asReadonly();
loadTasks(): void {
// Se i dati sono già nel TransferState (hydration), usali direttamente
if (this.transferState.hasKey(TASKS_KEY)) {
const cachedTasks = this.transferState.get(TASKS_KEY, []);
this._tasks.set(cachedTasks);
this.transferState.remove(TASKS_KEY);
return;
}
this._loading.set(true);
this.http.get<Task[]>('/api/tasks').pipe(
tap(tasks => {
this._tasks.set(tasks);
// Lato server: salva nel TransferState per il client
if (this.platform.isServer) {
this.transferState.set(TASKS_KEY, tasks);
}
}),
catchError(() => {
this._error.set('Errore nel caricamento.');
return EMPTY;
}),
finalize(() => this._loading.set(false))
).subscribe();
}
}
Fáze 5 – Pracovní postup testování řízený umělou inteligencí
Testování je často nejvíce přehlíženou součástí profesního rozvoje, protože je vnímáno jako obtížný. Kurzor změní tuto rovnici: můžete vytvořit kompletní sadu testů během několika minut, což vám umožní soustředit se na kontrolu a dokončení případů hrana místo psaní standardní od nuly.
Unit Test s Jest: Automatické generování
Pomocí této výzvy pro soubor služby nebo součásti získáte komplexní testování:
Výzva: Vygenerujte kompletní testy jednotek
Genera unit test completi per @task.service.ts usando Jest e Angular Testing Library.
Includi test per:
1. loadTasks(): successo (mock HTTP 200), errore (mock HTTP 500),
loading state durante la chiamata, utilizzo TransferState in hydration
2. createTask(): aggiornamento ottimista del signal, rollback su errore,
validazione che il nuovo task venga aggiunto in coda
3. updateStatus(): optimistic update, verifica che il signal venga aggiornato
immediatamente, rollback su errore HTTP
4. Computed signals: verifica che completedTasks e pendingTasks si aggiornino
correttamente al cambiamento di _tasks
Usa TestBed con provideHttpClientTesting, HttpTestingController per i mock HTTP.
Organizza con describe/it annidati. Aggiungi afterEach con httpMock.verify().
// task.service.spec.ts - Generato da Cursor
import { TestBed } from '@angular/core/testing';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { provideHttpClient } from '@angular/common/http';
import { TaskService } from './task.service';
import { Task, TaskStatus } from '../models/task.model';
const mockTasks: Task[] = [
{ id: '1', title: 'Task 1', description: '', status: 'todo', priority: 'high',
createdAt: new Date(), dueDate: null, assigneeId: null },
{ id: '2', title: 'Task 2', description: '', status: 'done', priority: 'low',
createdAt: new Date(), dueDate: null, assigneeId: null }
];
describe('TaskService', () => {
let service: TaskService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
provideHttpClient(),
provideHttpClientTesting(),
TaskService
]
});
service = TestBed.inject(TaskService);
httpMock = TestBed.inject(HttpTestingController);
});
afterEach(() => httpMock.verify());
describe('loadTasks()', () => {
it('dovrebbe caricare i task e aggiornare il signal', () => {
service.loadTasks();
const req = httpMock.expectOne('/api/tasks');
expect(req.request.method).toBe('GET');
req.flush(mockTasks);
expect(service.tasks()).toEqual(mockTasks);
expect(service.loading()).toBe(false);
expect(service.error()).toBeNull();
});
it('dovrebbe impostare loading a true durante la chiamata', () => {
service.loadTasks();
expect(service.loading()).toBe(true);
httpMock.expectOne('/api/tasks').flush(mockTasks);
expect(service.loading()).toBe(false);
});
it('dovrebbe gestire errori HTTP e impostare error signal', () => {
service.loadTasks();
httpMock.expectOne('/api/tasks').flush(
{ message: 'Server Error' },
{ status: 500, statusText: 'Internal Server Error' }
);
expect(service.error()).toBe('Errore nel caricamento.');
expect(service.tasks()).toEqual([]);
expect(service.loading()).toBe(false);
});
});
describe('updateStatus()', () => {
beforeEach(() => {
// Pre-popola il service con task
service.loadTasks();
httpMock.expectOne('/api/tasks').flush(mockTasks);
});
it('dovrebbe fare optimistic update del signal immediatamente', () => {
service.updateStatus('1', 'done');
// Signal aggiornato prima della risposta HTTP
expect(service.tasks().find(t => t.id === '1')?.status).toBe('done');
httpMock.expectOne('/api/tasks/1').flush({...mockTasks[0], status: 'done'});
});
});
describe('Computed Signals', () => {
it('completedTasks dovrebbe filtrare solo i task con status done', () => {
service.loadTasks();
httpMock.expectOne('/api/tasks').flush(mockTasks);
expect(service.completedTasks()).toHaveLength(1);
expect(service.completedTasks()[0].id).toBe('2');
});
it('completionRate dovrebbe calcolare la percentuale corretta', () => {
service.loadTasks();
httpMock.expectOne('/api/tasks').flush(mockTasks);
expect(service.completionRate()).toBe(50);
});
});
});
Test E2E s Playwrightem
Pro komplexní testování Cursor vyniká v generování scénářů Playwright z jednoho popis uživatelského toku v přirozeném jazyce:
Výzva: autor testu E2E
Genera test Playwright E2E per il flusso "Creazione e completamento di un Task".
Scenario:
1. L'utente apre la dashboard (/)
2. Clicca sul pulsante "Nuovo Task"
3. Compila il form: titolo "Test E2E Task", priorità "high", nessuna data scadenza
4. Clicca "Salva"
5. Verifica che il nuovo task appaia nella lista con status "todo"
6. Clicca sull'icona "segna come completato" sul task appena creato
7. Verifica che lo status diventi "done" e che il task appaia nella sezione completati
8. Verifica che completionRate mostri un valore > 0%
Usa page object pattern. Mock il backend con Playwright apiRoutes.
Aggiungi accessibility check con axe-core su ogni schermata.
// e2e/task-flow.spec.ts - Generato da Cursor
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test.describe('Task Creation and Completion Flow', () => {
test.beforeEach(async ({ page }) => {
// Mock API routes
await page.route('/api/tasks', async (route) => {
if (route.request().method() === 'GET') {
await route.fulfill({ json: [] });
} else if (route.request().method() === 'POST') {
const body = route.request().postDataJSON();
await route.fulfill({
json: { id: 'test-1', ...body, status: 'todo', createdAt: new Date().toISOString() }
});
}
});
await page.route('/api/tasks/test-1', async (route) => {
await route.fulfill({ json: { id: 'test-1', status: 'done' } });
});
});
test('dovrebbe creare un task e marcarlo come completato', async ({ page }) => {
await page.goto('/');
// Accessibility check sulla homepage
const a11yResults = await new AxeBuilder({ page }).analyze();
expect(a11yResults.violations).toEqual([]);
// Crea nuovo task
await page.click('[data-testid="new-task-btn"]');
await page.fill('[data-testid="task-title-input"]', 'Test E2E Task');
await page.selectOption('[data-testid="task-priority-select"]', 'high');
await page.click('[data-testid="task-form-submit"]');
// Verifica task in lista
const taskCard = page.locator('[data-testid="task-card-test-1"]');
await expect(taskCard).toBeVisible();
await expect(taskCard.locator('[data-testid="task-status"]')).toHaveText('todo');
// Completa il task
await taskCard.locator('[data-testid="complete-task-btn"]').click();
// Verifica aggiornamento status
await expect(taskCard.locator('[data-testid="task-status"]')).toHaveText('done');
const rate = page.locator('[data-testid="completion-rate"]');
await expect(rate).not.toHaveText('0%');
});
});
Fáze 6 – Refactoring Pattern Legacy
Jeden z nejčastějších případů použití v týmech se stávajícími kódovými bázemi a migrací Angular kódu
dědictví (s NgModules, @Input()/@Output(),
*ngIf/*ngFor) k moderním vzorům. Cursor v tom vyniká
typ systematického refaktorování.
Výzva: Migrace na samostatný a signály
Esegui la migrazione del componente @legacy-user-profile.component.ts a:
1. Standalone component (rimuovi dal NgModule)
2. Sostituisci @Input() con input() signal
3. Sostituisci @Output() EventEmitter con output()
4. Converti il template da *ngIf/*ngFor a @if/@for
5. Aggiungi ChangeDetectionStrategy.OnPush
6. Se usa ngModel, converti a reactive form con FormControl tipizzato
7. Aggiorna lo spec file per riflettere i cambiamenti
Dopo ogni cambiamento spiega il ragionamento e i benefici di performance.
Refaktoring s režimem plánu pro velké migrace
Pro migrace ve velkém měřítku (celých modulů nebo aplikací) použijte režim plánu dříve Režim agenta. To vám umožní zkontrolovat plán předtím, než Cursor provede změny nevratný:
Výzva: Režim plánu pro migraci modulu
[Attiva Plan Mode con Ctrl+Shift+P → "Plan Mode ON"]
Analizza il modulo UserModule (@src/app/modules/user/) e crea un piano dettagliato
per migrarlo a standalone components con signals. Il modulo ha:
- UserModule.ts (NgModule principale)
- 4 componenti: UserListComponent, UserCardComponent, UserDetailComponent, UserEditComponent
- 2 servizi: UserService, UserPreferencesService
- 1 guard: UserAuthGuard
Per ogni file:
1. Lista le modifiche necessarie
2. Identifica le dipendenze da aggiornare
3. Stima il rischio (Low/Medium/High) con motivazione
4. Suggerisci l'ordine di migrazione per minimizzare il rischio
NON apportare modifiche ancora - solo il piano.
Fáze 7 – Asistovaná optimalizace výkonu
Výkon je jednou z oblastí, kde může kurzor změnit, ale vyžaduje to vy ví, jak klást správné otázky. AI automaticky neidentifikuje všechny problémy výkonu: musíte jej vést konkrétním kontextem problému, který řešíte.
Analýza svazků a dělení kódu
Výzva: Analýza svazků a líné načítání
Analizza @app.routes.ts e @app.config.ts. Ho eseguito "ng build --stats-json" e
il bundle principale e di 850KB (troppo grande).
Fai queste ottimizzazioni:
1. Converti tutte le route in lazy-loaded routes (usa loadComponent per standalone)
2. Aggiungi PreloadStrategy intelligente: PreloadAllModules per route principali,
nessun preload per route admin/settings raramente visitate
3. Identifica import heavy nel bundle principale da spostare nei chunk lazy
4. Aggiungi SplitChunksPlugin config personalizzata nel angular.json per
separare vendor chunks (rxjs, angular/core separati)
5. Configura budget nel angular.json: warning a 500KB, error a 1MB
// app.routes.ts - Ottimizzato da Cursor con lazy loading
import { Routes } from '@angular/router';
export const routes: Routes = [
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
loadComponent: () =>
import('./features/dashboard/dashboard.component').then(m => m.DashboardComponent),
title: 'Dashboard - Task Manager'
},
{
path: 'tasks',
loadChildren: () =>
import('./features/tasks/tasks.routes').then(m => m.TASKS_ROUTES),
title: 'Tasks - Task Manager'
},
{
path: 'settings',
loadComponent: () =>
import('./features/settings/settings.component').then(m => m.SettingsComponent),
// Non preloadare: accesso raro
data: { preload: false },
title: 'Impostazioni - Task Manager'
},
{
path: '**',
loadComponent: () =>
import('./shared/components/not-found/not-found.component').then(m => m.NotFoundComponent)
}
];
OnPush a signály: Core Web Vitals
Kurzor vám může pomoci identifikovat komponenty, které způsobují zbytečné překreslování a a
převést je na ChangeDetectionStrategy.OnPush:
Výzva: Audit Detekce změn
Analizza tutti i componenti in @src/app/features/tasks/ e identifica quelli che:
1. NON usano ChangeDetectionStrategy.OnPush (aggiungi OnPush a tutti)
2. Hanno @Input() che potrebbero diventare input() signals (converti)
3. Usano getters nel template che potrebbero causare re-render (converti a computed())
4. Usano async pipe su Observable (considera toSignal() per semplificare)
Per ogni modifica mostra il codice prima e dopo con spiegazione del beneficio.
Krok 8 - CI/CD potrubí generované pomocí kurzoru
Poslední fází každého profesionálního projektu je automatizace nasazení. Kurzor může generovat kompletní a optimalizované kanály akcí GitHub, včetně strategií ukládání do mezipaměti, Paralelní testování a podmíněné nasazení založené na větvích.
Výzva: Průběh akcí GitHubu dokončen
Crea una pipeline GitHub Actions completa per questo progetto Angular 19 con:
WORKFLOW CI (.github/workflows/ci.yml):
- Trigger: push su feature/*, pull_request verso main e develop
- Jobs paralleli: lint, unit-tests, build
- Cache node_modules con chiave basata su package-lock.json
- Unit test con Jest + coverage report (soglia minima: 80%)
- Upload coverage a Codecov
- Build production con --stats-json
- Comment sul PR con bundle size comparison vs base branch
WORKFLOW CD (.github/workflows/cd.yml):
- Trigger: push su main (dopo CI passata)
- Deploy staging su push develop
- Deploy production su push main con approval manuale
- Deploy su Firebase Hosting (usa secrets: FIREBASE_TOKEN)
- Smoke test post-deploy: verifica che / risponda 200 e che il bundle sia < 1MB
- Notifica Slack in caso di fallimento
Usa Node.js 22, npm ci per installazione deterministica.
# .github/workflows/ci.yml - Generato da Cursor
name: CI
on:
push:
branches: ['feature/**', 'fix/**']
pull_request:
branches: [main, develop]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- run: npm run lint
test:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- name: Run Jest with coverage
run: npm test -- --coverage --coverageThreshold='{"global":{"branches":80,"functions":80,"lines":80}}'
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
build:
name: Production Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- name: Build with stats
run: npm run build -- --stats-json
- name: Bundle size check
run: |
BUNDLE_SIZE=$(stat -c%s dist/browser/main.*.js)
echo "Bundle size: $BUNDLE_SIZE bytes"
if [ $BUNDLE_SIZE -gt 1048576 ]; then
echo "::error::Bundle size exceeds 1MB limit"
exit 1
fi
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
Případová studie: Funkce „Oznámení v reálném čase“ od nápadu po nasazení
Abychom upevnili vše, co jsme viděli, podívejme se, jak profesionální vývojář dokončete celý životní cyklus funkce pomocí kurzoru. Funkce: přidat upozornění v reálném čase, když je úkol přiřazen nebo změní stav.
Tato případová studie ukazuje skutečný tok, včetně případů, kdy to AI udělá špatně a jak to opravit, protože to je součástí autentického pracovního postupu.
Krok 1 – Režim plánu: Architektura prvků
Režim rychlého plánu
[Plan Mode ON]
Voglio aggiungere notifiche in tempo reale usando WebSocket (Socket.io) per questi eventi:
- task_assigned: quando un task viene assegnato all'utente corrente
- task_status_changed: quando cambia lo stato di un task dell'utente
- task_due_soon: 24h prima della scadenza di un task
Crea un piano architetturale che includa:
1. WebSocket service (con gestione reconnect automatico)
2. NotificationCenter component (slide-in panel)
3. NotificationBadge component (icona navbar con counter)
4. Integration con TaskService esistente
5. Persistenza notifiche non lette in localStorage
6. Testing strategy
Considera: SSR (WebSocket non disponibile lato server),
performance (niente memory leak), accessibilità (screen reader per notifiche live).
Režim plánu vytvoří strukturovaný dokument s každým souborem, který má být vytvořen/upraven, závislosti mezi nimi a riziky. Po kontrole přejdeme k provedení:
Krok 2 – Režim agenta: Implementace
// notification.service.ts - Generato dopo approvazione del piano
import { Injectable, inject, signal, computed, effect, OnDestroy } from '@angular/core';
import { PlatformService } from '../../../core/services/platform.service';
export interface Notification {
id: string;
type: 'task_assigned' | 'task_status_changed' | 'task_due_soon';
message: string;
taskId: string;
timestamp: Date;
read: boolean;
}
@Injectable({ providedIn: 'root' })
export class NotificationService implements OnDestroy {
private readonly platform = inject(PlatformService);
private socket: WebSocket | null = null;
private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
private readonly _notifications = signal<Notification[]>([]);
readonly notifications = this._notifications.asReadonly();
readonly unreadCount = computed(() =>
this._notifications().filter(n => !n.read).length
);
readonly hasUnread = computed(() => this.unreadCount() > 0);
constructor() {
// Carica notifiche salvate da localStorage (solo browser)
if (this.platform.isBrowser) {
this._loadPersistedNotifications();
this._initWebSocket();
}
// Persisti automaticamente quando cambiano
effect(() => {
const notifications = this._notifications();
this.platform.setLocalStorage(
'notifications',
JSON.stringify(notifications.slice(0, 50)) // Mantieni max 50
);
});
}
markAsRead(notificationId: string): void {
this._notifications.update(current =>
current.map(n => n.id === notificationId ? { ...n, read: true } : n)
);
}
markAllAsRead(): void {
this._notifications.update(current =>
current.map(n => { ...n, read: true })
);
}
private _initWebSocket(): void {
this.socket = new WebSocket('wss://api.example.com/notifications');
this.socket.onmessage = (event) => {
const notification: Notification = {
...JSON.parse(event.data),
id: crypto.randomUUID(),
timestamp: new Date(),
read: false
};
this._notifications.update(current => [notification, ...current]);
};
this.socket.onclose = () => {
// Reconnect automatico con backoff esponenziale
this.reconnectTimer = setTimeout(() => this._initWebSocket(), 3000);
};
}
private _loadPersistedNotifications(): void {
const stored = this.platform.getLocalStorage('notifications');
if (stored) {
try {
this._notifications.set(JSON.parse(stored));
} catch {
// JSON malformato - ignora
}
}
}
ngOnDestroy(): void {
this.socket?.close();
if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
}
}
Krok 3 – Kurzor identifikace chyby: SSR a WebSocket
Během kontroly Cursor hlásí potenciální problém: crypto.randomUUID()
nemusí být dostupné ve všech prostředích SSR. K opravě použijte chat:
Výzva: Opravte chybu SSR
Ho notato che crypto.randomUUID() potrebbe causare problemi in ambienti SSR o
browser molto vecchi. Nel NotificationService, sostituisci crypto.randomUUID()
con una funzione generaId() che:
1. Usa crypto.randomUUID() se disponibile
2. Fallback su una combinazione di Date.now() + Math.random() per compatibilità
Aggiungi un commento che spiega il perchè del fallback.
Krok 4 – Testování a PR recenze
Výzva: Připravte PR a test
La feature notifiche e completa. Aiutami a prepararla per la code review:
1. Genera test unit per NotificationService (includi test per:
- Caricamento notifiche persisted al bootstrap
- markAsRead() e markAllAsRead()
- Comportamento quando platform.isBrowser e false - verifica no WebSocket inizializzato)
2. Controlla il codice che abbiamo scritto per:
- Memory leak (WebSocket, timers non cleanup)
- Problemi di accessibilità nel NotificationCenter template
- Immutabilita (nessun array.push() o mutazione diretta)
- Typing TypeScript (nessun any)
3. Scrivi un CHANGELOG entry per questa feature
Rispondi solo se trovi problemi reali - non citare cose già corrette.
Tipy a triky pro vývojáře Angular
Po měsících intenzivního používání Cursoru s Angularem jsou zde nejúčinnější vzory který by si měl profesionální vývojář osvojit od prvního dne.
1. Použijte @codebase pro projektové otázky
Než se zeptáte „jak mohu udělat X“, použijte @codebase aby lidé pochopili
Umístěte kurzor do kontextu vašeho projektu. Rozdíl v odpovědích je významný:
Vzor výzvy: Kontext kódové báze
// MENO EFFICACE
"Come aggiungo la paginazione ai task?"
// PIU EFFICACE
"@codebase Guardando TaskListComponent e TaskService,
come aggiungo la paginazione lato server (page + pageSize params sulla GET /api/tasks)
usando i pattern signals e il servizio HTTP già presenti nel progetto?"
2. Výzva „Recenze a kritika“.
Jedna z nejužitečnějších výzev, které můžete dát kurzoru a požádat o kritickou kontrolu kód, který jste právě napsali, s uvedením typu problémů, které chcete najít:
Výzva: Specializovaná kontrola kódu
Rivedi @task.service.ts come senior Angular developer con focus su:
- Performance: computed() non necessari, effect() che potrebbero causare loop,
signal updates che triggherano re-render inutili
- Memory: subscriptions non unsubscribed, timers non cleared,
reference circolari nei signals
- Sicurezza: XSS in template, injection nei parametri HTTP
- Best practices Angular 2025: c'è qualcosa di deprecato?
Dai SOLO feedback concreto con code snippet. Salta gli elogi.
3. Dokumentujte kurzorem, nikoli ručně
Výzva: Vygenerujte JSDoc a README
Per ogni metodo pubblico in @notification.service.ts aggiungi JSDoc con:
- @description: cosa fa il metodo
- @param: tipizzazione e scopo di ogni parametro
- @returns: cosa ritorna e in che condizioni
- @throws: se il metodo può sollevare errori e in quali condizioni
- @example: un esempio d'uso conciso
Poi genera un README.md per la feature notifications in
src/app/features/notifications/ che documenti il NotificationService
per un nuovo developer del team.
4. Agenti pozadí pro dlouhé úkoly
Agenti na pozadí Cursor 2.0 jsou ideální pro časově náročnější úkoly, jako je např analýzu celé kódové základny nebo generování testů pro desítky komponent. Zatímco agent pracuje, můžete pokračovat ve vývoji paralelně:
Výzva: Agent na pozadí pro testovací pokrytí
[Background Agent]
Analizza tutti i componenti in src/app/features/ che hanno copertura test inferiore
all'80% (controlla i file .spec.ts esistenti o crea test dove mancano).
Per ogni componente con coverage insufficiente:
1. Identifica i casi non coperti (branch, funzioni pubbliche, casi di errore)
2. Scrivi i test mancanti
3. Verifica che npm test passi dopo ogni aggiunta
Lavora in ordine di priorità: prima i componenti con 0% coverage,
poi quelli sotto il 50%, poi quelli tra 50% e 80%.
Notificami quando hai finito con un riepilogo delle coperture raggiunte.
5. Háčky kurzoru pro automatickou kvalitu
Nakonfigurujte háky kurzoru pro provádění automatických kontrol při každé změně souboru Hranatý. To eliminuje potřebu pamatovat na ruční spuštění lint a testů:
// .cursor/hooks/post-edit.sh
#!/bin/bash
# Eseguito automaticamente dopo ogni salvataggio di file Angular
CHANGED_FILE="$1"
# Lint solo il file modificato (veloce)
if [[ "$CHANGED_FILE" == *.ts ]]; then
npx eslint "$CHANGED_FILE" --fix
fi
# Type check incrementale
if [[ "$CHANGED_FILE" == *.ts ]]; then
npx tsc --noEmit --incremental 2>&1 | head -20
fi
Skutečné metriky produktivity
Legitimní otázka zní: "Kolik času opravdu ušetřím s kurzorem?". Na základě na zdokumentovaných zkušenostech týmů, které přijaly Cursor pro profesionální Angular projekty, Zde jsou některá konkrétní měření:
Benchmark: Úhlový projekt s kurzorem a bez něj
| Aktivita | Bez kurzoru | S kurzorem | Úspory |
|---|---|---|---|
| Bootstrap projekt (CLI + konfigurace Jest/ESLint/Prettier) | 45-60 min | 5-10 min | ~85 % |
| Kompletní generování funkcí (model + služba + 4 komponenty + směrování) | 3-4 hodiny | 30-45 min | ~80 % |
| Psaní jednotkových testů (80% pokrytí) | 2 hodiny na službu | 20-30 min | ~75 % |
| Migrace starší komponenty na samostatné + signály | 30-45 min | 5-10 min | ~80 % |
| Nastavení akcí CI/CD GitHub | 2-3 hodiny | 20-30 min | ~85 % |
| Ladění složité chyby | 1-2 hodiny | 20-40 min | ~60 % |
Je důležité si uvědomit, že tato čísla představují čas výroba kódu, není doba architektonického myšlení. Kurzor urychluje mechanické psaní kódu, ponechání více času na rozhodnutí na vysoké úrovni, která vyžadují lidské znalosti.
Když kurzor nestačí
Kurzor je multiplikátor produktivity, nenahrazuje odbornost. Existují situace, kdy AI ukazuje své limity v úhlovém kontextu:
- Strategická architektonická rozhodnutí: Kurzor může navrhovat možnosti, ale volba správné strategie řízení státu (signály vs NgRx vs Akita) Záleží na obchodních faktorech, které znáte jen vy.
- Pokročilé ladění výkonu: Identifikujte způsobený únik paměti od uzavření k efektu() nebo cyklickému překreslení mezi signály vyžaduje pochopení hloubka detekce změn Angular.
- Integrace s komplexními knihovnami: Cursor dobře zná Angular, ale může mít omezené znalosti o velmi specifických knihovnách třetích stran nebo nedávno aktualizováno.
- Bezpečnostní revize: Nevěřte slepě kódu vygenerovanému bez něj bezpečnostní revizi. Kurzor může zavádět jemné zranitelnosti, např v oblastech, jako je správa ověřování a sanitace vstupů.
Anti-vzory, kterým je třeba se vyhnout pomocí kurzoru a úhlu
Anti-Pattern 1: Přijetí kódu bez přečtení
Největším rizikem při používání kurzoru je až do té míry závislost na AI přijmout vygenerovaný kód, aniž by mu porozuměl. To vede k nekonzistentním kódovým základnám, chyby, které se obtížně ladí, a vývojáře, kteří nerozumí vlastnímu kódu.
Základní pravidlo: Pokud nemůžete vysvětlit kolegovi, proč kód generované dělá to, co dělá, nepřijímejte to, dokud to nepochopíte. K tomu použijte kurzor urychlit, ne nahradit porozumění.
Anti-Pattern 2: Vágní výzvy ke komplexním problémům
// PROMPT VAGO - risultato mediocre
"La lista task non si aggiorna dopo aver modificato uno status"
// PROMPT SPECIFICO - risultato accurato
"@task-list.component.ts @task.service.ts
Quando chiamo updateStatus() nel TaskService, il signal _tasks viene aggiornato
(ho verificato con un debugger che il valore cambia), ma TaskListComponent NON
mostra il cambiamento. Il componente usa OnPush. Ho verificato che l'input
[tasks] viene passato da un componente padre con async pipe.
Il problema potrebbe essere nella reference immutability?"
Anti-Vzor 3: Protichůdná pravidla
Pokud máte pravidla, která si vzájemně odporují (například jedno pravidlo říká „použít signály“ a jiný říká "použijte BehaviorSubject pro stav"), Cursor vytváří nekonzistentní kód. Provádějte pravidelný audit svých pravidel, abyste odstranili konflikty a aktualizovali je zastaralé při migraci kódové základny.
Anti-Pattern 4: Ignorování kontextového okna
Kurzor má omezení kontextu. Pokud máte velmi dlouhý rozhovor, zprávy starší jsou "zapomenuti". Pro složité úkoly, které trvají hodiny, je lepší otevřít spíše nové tematické rozhovory než pokračování nekonečného sezení. Uložte efektivní výzvy jako Vzpomínky na kurzor znovu je použít.
Závěry: The Angular Developer Workflow v roce 2026
Dostáváme se na konec tohoto článku a celé série o Cursor IDE. Pracovní postup který jsme postavili, představuje nejmodernější profesionální Angular development v roce 2026: přístup AI nativní, ale řízené vývojářem, kde inteligence umělá technologie urychluje každou fázi, aniž by nahradila lidský úsudek.
Abychom shrnuli celý pracovní postup:
- Konfigurace pravidel: Investujte čas do vytváření konkrétních pravidel pro váš zásobník. To je největší multiplikátor: každé dobře napsané pravidlo se zlepšuje každá budoucí interakce s AI.
- Režim plánu před režimem agenta: Pro složité funkce nebo migrace, Vždy plánujte před provedením. Revidovaný plán je rychlejší než špatná realizace.
- Režim agenta pro bootstrapping: Nechte AI, aby se postarala o vytvoření struktury, komponenty a konfigurace. Váš čas má příliš velkou cenu.
- Testování s AI: Generování testů pomocí kurzoru, kontrola okrajových případů, přidání případy, které AI nezohlednila. Získejte 80% pokrytí za čtvrtinu času.
- Asistovaná refaktorizace: Použijte kurzor pro systematické migrace vzorů moderní (signály, samostatný, nová syntaxe). Škálování na celé moduly pomocí agentů na pozadí.
- CI/CD generované: Nepište potrubí YAML ručně. Popište požadavky a nechat Cursor vygenerovat správné a optimalizované konfigurace.
Vývojář, který přijme tento pracovní postup, se nestane méně odborníkem: stane se exponenciálně produktivnější. Základem zůstává odbornost vyhodnocovat generovaný kód, přijímat architektonická rozhodnutí a udržovat kvalitu projektu. Cursor není srovnávač: rozšiřuje možnosti těch, kteří jsou již dobří.
Cursor IDE a AI-Native Development Series Shrnutí
| # | Položka | Hlavní zaměření |
|---|---|---|
| 1 | Cursor IDE: Kompletní průvodce | Přehled, instalace, základní vlastnosti |
| 2 | Pravidla kurzoru | Nastavení AI pro váš projekt |
| 3 | Režim agenta | Změňte kódovou základnu pomocí příkazu |
| 4 | Režim plánu a agenti na pozadí | Plánování a paralelismus |
| 5 | Háčky kurzoru | Automatizace pracovního postupu |
| 6 | MCP a kurzor | Připojení k databázím a API |
| 7 | Ladění pomocí kurzoru AI | Oprava chyb 3x rychlejší |
| 8 | Cursor vs Windsurf vs Copilot | Srovnání nástrojů v roce 2026 |
| 9 | Jste zde - Professional Angular Workflow | Kompletní případová studie od nastavení až po nasazení |
Související série k prozkoumání
- Modern Angular (ID 224–233): Další informace o samostatných signálech komponenty, SSR a nejnovější funkce Angular s vyhrazenými vodítky.
- MCP a kurzor (ID 64–77): Prozkoumejte Kontextový protokol modelu v detail pro připojení Cursoru k databázím, API a externím nástrojům.
- Vibe kódování: Zjistěte, jak vývojáři používají AI k prototypování nápady rychle, pomocí Claude Code, multi-agentních systémů a testování kódu AI.
Děkuji za sledování celé série. Pokud máte nějaké dotazy, zpětnou vazbu nebo se chcete podělit váš Angular workflow s Cursorem, napište do komentářů. Váš příspěvek pomáhá vylepšit tyto průvodce pro celou italskou komunitu vývojářů.







