Profesjonalny przebieg pracy: projekt Angular z kursorem od konfiguracji do wdrożenia
Dowiedziałeś się o Kursorze, jego zasadach, Trybie Agenta, Trybie Planu, Hookach i protokole MCP. Nadszedł czas, aby połączyć to wszystko w jedną całość naprawdę profesjonalny przepływ pracy. Ten artykuł finał serii i operacyjne studium przypadku: zbudujemy kompletny projekt Angular przy użyciu Cursor as Drugi pilot AI na każdym etapie, od inicjalizacji projektu po wdrożenie produkcyjne.
To nie jest abstrakcyjny zbiór najlepszych praktyk. Each section shows real commands, prompts efektywne, konkretne konfiguracje i decyzje, jakie podejmuje profesjonalny zespół podczas integracji Kursor w codziennym procesie rozwoju. Na końcu tego artykułu będziesz mieć podręcznik kompletne i możliwe do powielenia dla dowolnego projektu Angular.
Projekt, który zbudujemy, jest jeden panel zarządzania zadaniami z Angularem 19, SSR, sygnały, samodzielne komponenty, automatyczne testowanie i CI/CD z GitHub Actions. Projekt odzwierciedlają prawdziwą złożoność, z jaką spotykasz się w swojej codziennej pracy zawodowej.
Czego dowiesz się w tym artykule
- Jak ustrukturyzować plik
.cursor/rules/optymalny dla projektów Angular - Wstępna konfiguracja projektu w trybie agenta: od zera do pełnej struktury w ciągu kilku minut
- Oparte na sztucznej inteligencji generowanie samodzielnych komponentów z sygnałami i formami reaktywnymi
- Konfiguracja SSR i przyrostowego nawodnienia z kursorem jako asystentem
- Przebieg testowania: testy jednostkowe z Jest/Vitest i E2E z Playwright, napisane przy użyciu AI
- Inteligentnie refaktoryzuj starsze wzorce w trybie agenta
- Wspomagana optymalizacja wydajności: leniwe ładowanie, analiza pakietów, podstawowe wskaźniki internetowe
- Kompletny potok CI/CD wygenerowany za pomocą kursora dla akcji GitHub i Firebase
- Kompleksowe studium przypadku: kompletna funkcja od pomysłu do wdrożenia produkcyjnego
- Ekskluzywne wskazówki i triki dla programistów Angular, którzy używają Cursora na co dzień
Wymagania techniczne
- Node.js 22+ i Angular CLI 19+
- Cursor IDE (zalecany plan Pro dla nieograniczonego trybu agenta)
- Git i konto GitHub dla CI/CD
- Podstawowa znajomość Angulara, TypeScriptu i RxJS
- Opcjonalnie: konto Firebase do wdrożenia, znajomość SSR
Krok 1 – Skonfiguruj reguły kursora dla projektu Angular
Pierwszym krokiem w profesjonalnym przepływie pracy jest skonfigurowanie Kursora tak, aby znał konwencji Twojego projektu, zanim jeszcze napiszesz pierwszą linijkę kodu. Plik dobrze zorganizowane reguły przekształcają Cursor z ogólnego asystenta w współpracownik specjalizuje się w twoim stosie Angular.
W Cursor 0.45+ reguły znajdują się w katalogu .cursor/rules/ jako plik
.mdc. Możesz mieć reguły globalne, które są zawsze aktywne i reguły szczegółowe, które uruchamiają się
w oparciu o kontekst. Do profesjonalnego projektu Angular polecam tę strukturę:
# 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
Oto pełna treść angular-core.mdc, najważniejsza zasada
ustala założenia architektoniczne 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 - Profesjonalny przebieg pracy: projekt kątowy z kursorem | Federico Calò
09 - Profesjonalny przebieg pracy: projekt kątowy z kursorem | Federico Calò
Salta al contenuto principaleCześć! Jestem
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 Mnie
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.
Moje Umiejętności
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automatyzacja Procesów
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Systemy Na Zamówienie
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"
]
};
Moja Misja
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Demokratyzacja Technologii
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.
Łączenie IT i Biznesu
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à.
Tworzenie Rozwiązań na Miarę
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.
Przekształć Swój Biznes z Technologią
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.
Porozmawiajmy →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 GitSkontaktuj się
Masz projekt? Porozmawiajmy! Wypełnij formularz, a odpowiem wkrótce.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
come suffisso (`users`, non `users
09 - Profesjonalny przebieg pracy: projekt kątowy z kursorem | Federico Calò
09 - Profesjonalny przebieg pracy: projekt kątowy z kursorem | Federico Calò
Salta al contenuto principaleCześć! Jestem
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 Mnie
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.
Moje Umiejętności
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automatyzacja Procesów
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Systemy Na Zamówienie
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"
]
};
Moja Misja
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Demokratyzacja Technologii
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.
Łączenie IT i Biznesu
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à.
Tworzenie Rozwiązań na Miarę
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.
Przekształć Swój Biznes z Technologią
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.
Porozmawiajmy →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 GitSkontaktuj się
Masz projekt? Porozmawiajmy! Wypełnij formularz, a odpowiem wkrótce.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
ne `usersSignal`)
- Observable: suffisso `
09 - Profesjonalny przebieg pracy: projekt kątowy z kursorem | Federico Calò
09 - Profesjonalny przebieg pracy: projekt kątowy z kursorem | Federico Calò
Salta al contenuto principaleCześć! Jestem
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 Mnie
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.
Moje Umiejętności
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automatyzacja Procesów
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Systemy Na Zamówienie
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"
]
};
Moja Misja
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Demokratyzacja Technologii
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.
Łączenie IT i Biznesu
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à.
Tworzenie Rozwiązań na Miarę
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.
Przekształć Swój Biznes z Technologią
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.
Porozmawiajmy →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 GitSkontaktuj się
Masz projekt? Porozmawiajmy! Wypełnij formularz, a odpowiem wkrótce.
* Campi obbligatori. I tuoi dati saranno utilizzati solo per rispondere alla tua richiesta.
(`users
09 - Profesjonalny przebieg pracy: projekt kątowy z kursorem | Federico Calò
09 - Profesjonalny przebieg pracy: projekt kątowy z kursorem | Federico Calò
Salta al contenuto principaleCześć! Jestem
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 Mnie
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.
Moje Umiejętności
Analisi Dati & Modelli Previsionali
Trasformo i dati in insights strategici con analisi approfondite e modelli predittivi per decisioni informate
Automatyzacja Procesów
Creo strumenti personalizzati che automatizzano operazioni ripetitive e liberano tempo per attività a valore aggiunto
Systemy Na Zamówienie
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"
]
};
Moja Misja
Credo fermamente che l'informatica sia lo strumento più potente per trasformare le idee in realtà e migliorare la vita delle persone.
Demokratyzacja Technologii
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.
Łączenie IT i Biznesu
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à.
Tworzenie Rozwiązań na Miarę
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.
Przekształć Swój Biznes z Technologią
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.
Porozmawiajmy →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 GitSkontaktuj się
Masz projekt? Porozmawiajmy! Wypełnij formularz, a odpowiem wkrótce.
* 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)
Ta reguła zapewnia Cursorowi pełny kontekst architektoniczny. Kiedy poprosisz o wygenerowanie pliku a
komponentu, usługi lub funkcji, Cursor automatycznie wie, którego z nich użyć
inject(), sygnały i nową składnię przepływu sterowania. Nie musisz
powtarzaj to za każdym razem w monicie.
Częsty błąd: zasady, które są zbyt ogólne
Wiele zespołów tworzy jeden plik .cursorrules ogromny, z setkami linii.
W rezultacie Cursor nie ustala priorytetu instrukcji najbardziej istotnych dla
aktualny kontekst. Używaj oddzielnych plików z określonymi wzorami globalnymi: reguła dla i
komponenty zostaną aktywowane tylko wł *.component.ts, zachowując kontekst
skoncentrowanych i najbardziej precyzyjnych odpowiedzi.
Reguła dla komponentów: 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)
Faza 2 — Konfiguracja projektu w trybie agenta
Po skonfigurowaniu reguł nadszedł czas na utworzenie projektu. Zamiast uruchamiać ręcznie każde polecenie i tworzymy każdy plik, używamy trybu agenta do delegowania całej fazy ładowania początkowego. Jest to jeden z najpotężniejszych przypadków użycia Kursora: podaj instrukcje wysokiego poziomu i wyjdź aby agent przeprowadził wszystkie etapy operacyjne.
Otwórz Kursor, utwórz nowy folder dla projektu i uruchom Tryb Agenta Cmd+Shift+I (lub Ctrl+Shift+I w systemie Windows/Linux). Następnie użyj tego monitu:
Tryb agenta podpowiedzi: projekt Bootstrap
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.
Kursor zostanie uruchomiony ng new, zainstaluje zależności, skonfiguruje Jest,
ESLint i Prettier, utworzy strukturę folderów i zainicjuje Git, całość
za kilka minut. Nadchodzi to, co zwykle zajmuje 30–45 minut ręcznej konfiguracji
wykonane dokładnie i konsekwentnie.
Generowanie zadań funkcji w trybie agenta
Po załadowaniu generujemy główną cechę. Ten monit jest wyświetlany jako Agent W trybie można zbudować cały pionowy wycinek aplikacji, od modelu danych po plik komponentów, przestrzegając naszych zasad Angular:
Tryb agenta monitującego: Zadania funkcji zostały ukończone
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.
Kursor wygeneruje wszystkie pliki zgodnie z konwencjami określonymi w regułach. Wynik i spójny kod, który mogłeś napisać sam, ale w ułamku czasu.
Faza 3 – Komponenty z sygnałami i formami reaktywnymi
Przyjrzyjmy się szczegółowo, jak Cursor generuje nowoczesne komponenty Angular. Po udzieleniu monitu
powyżej, przeanalizujmy dane wyjściowe dla TaskFormComponent i jak to udoskonalić:
// 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();
}
}
Zwróć uwagę, jak Cursor automatycznie przestrzega konwencji reguł: inject()
na uzależnienia, input() e output() zamiast
@Input() e @Output(), readonly na właściwościach
tj ChangeDetectionStrategy.OnPush. To jest prawdziwa wartość tych zasad
skonfigurowany: sztuczna inteligencja tworzy kod zgodny ze standardami zespołu bez potrzeby przeglądania
stałe.
Usługa zadań z sygnałami: pełny wzorzec reaktywny
// 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();
}
}
Faza 4 - SSR i stopniowe nawodnienie za pomocą kursora
Port kątowy 19 przyrostowe nawilżenie w stabilnym, funkcja, która pozwala nawilżać tylko te części strony, które stają się widoczne lub interaktywne, redukując drastycznie początkowy JavaScript. Prawidłowa konfiguracja SSR jest jednym z najważniejszych obszarów obarczone subtelnymi błędami. Kursor staje się tutaj szczególnie przydatny.
Użyj tego monitu, aby skonfigurować SSR z przyrostowym nawodnieniem i właściwym zarządzaniem kontekstów serwera/przeglądarki:
Podpowiedź: Skonfiguruj SSR z przyrostowym nawodnieniem
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
Kursor dokona edycji odpowiednich plików i wyjaśni wszelkie zmiany. Wynik będzie
a app.config.ts poprawna i dostosowana do platformy usługa:
// 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 uniknąć podwójnego pobrania
Jednym z najczęstszych błędów Angular SSR jest to, że dane są ładowane dwukrotnie: w jedną stronę
serwerze podczas renderowania i ponownie po stronie klienta po nawodnieniu. Kursor może dodać
automatycznie TransferState do serwisu:
// 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();
}
}
Faza 5 — Przepływ pracy podczas testowania opartego na sztucznej inteligencji
Testowanie jest często najbardziej pomijaną częścią rozwoju zawodowego, ponieważ jest postrzegana jako uciążliwy. Kursor zmienia to równanie: możesz wygenerować kompletny zestaw testów w ciągu kilku minut, dzięki czemu możesz skupić się na przeglądaniu i kończeniu spraw Edge zamiast pisać szablon od zera.
Test jednostkowy z Jest: automatyczne generowanie
Użyj tego monitu w pliku usługi lub komponentu, aby uzyskać kompleksowe testy:
Podpowiedź: Wygeneruj kompletne testy jednostkowe
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 z dramaturgiem
W przypadku kompleksowych testów Cursor specjalizuje się w generowaniu scenariuszy Playwright z jednego opis przepływu użytkownika w języku naturalnym:
Podpowiedź: dramatopisarz testowy 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%');
});
});
Faza 6 — Przestarzały wzorzec refaktoryzacji
Jeden z najczęstszych przypadków użycia w zespołach posiadających istniejące bazy kodu i migrujących kod Angular
dziedzictwo (z NgModules, @Input()/@Output(),
*ngIf/*ngFor) do nowoczesnych wzorów. Cursor jest w tym świetny
rodzaj systematycznej refaktoryzacji.
Podpowiedź: migracja do wersji autonomicznej i sygnałów
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.
Refaktoryzacja w trybie planu w przypadku dużych migracji
W przypadku migracji na dużą skalę (całych modułów lub aplikacji) użyj wcześniej trybu planowania Tryb agenta. Dzięki temu możesz przejrzeć plan, zanim Cursor wprowadzi zmiany nieodwracalne:
Podpowiedź: Tryb planowania migracji modułów
[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.
Faza 7 – Wspomagana optymalizacja wydajności
Wydajność to obszar, w którym Kursor może coś zmienić, ale wymaga to Twojej obecności wie, jak zadawać właściwe pytania. Sztuczna inteligencja nie identyfikuje automatycznie wszystkich problemów wydajności: musisz poprowadzić ją w konkretnym kontekście problemu, który rozwiązujesz.
Analiza pakietów i dzielenie kodu
Podpowiedź: Analiza pakietów i leniwe ładowanie
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 i Signals: podstawowe wskaźniki internetowe
Kursor może pomóc w zidentyfikowaniu komponentów, które powodują niepotrzebne ponowne renderowanie i
przekonwertuj je na ChangeDetectionStrategy.OnPush:
Monit: Inspekcja wykrywania zmian
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 — Potok CI/CD wygenerowany za pomocą kursora
Ostatnią fazą każdego profesjonalnego projektu jest automatyzacja wdrożeń. Kursor może generuj kompletne i zoptymalizowane potoki GitHub Actions, w tym strategie buforowania, Testowanie równoległe i wdrożenia warunkowe oparte na gałęziach.
Monit: Potok akcji GitHub został ukończony
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/
Studium przypadku: funkcja „Powiadomienia w czasie rzeczywistym” od pomysłu do wdrożenia
Aby skonsolidować wszystko, co widzieliśmy, przyjrzyjmy się, jak wygląda profesjonalny programista ukończ cały cykl życia funkcji za pomocą Kursora. Funkcja: dodawaj powiadomienia w czasie rzeczywistym, gdy zadanie jest przydzielone lub zmienia stan.
To studium przypadku pokazuje rzeczywisty przepływ, w tym sytuacje, w których sztuczna inteligencja się myli i jak to poprawić, ponieważ jest to część autentycznego przepływu pracy.
Krok 1 – Tryb planu: Architektura funkcji
Tryb szybkiego planowania
[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).
Tryb Plan tworzy ustrukturyzowany dokument z każdym plikiem, który ma zostać utworzony/modyfikowany, tj zależności pomiędzy nimi a ryzykami. Po zapoznaniu się przystępujemy do realizacji:
Krok 2 – Tryb agenta: Implementacja
// 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 — Kursor identyfikuje błąd: SSR i WebSocket
Podczas przeglądu Cursor zgłasza potencjalny problem: crypto.randomUUID()
może nie być dostępny we wszystkich środowiskach SSR. Użyj czatu, aby to naprawić:
Podpowiedź: Napraw błąd 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 – Testowanie i przegląd PR
Podpowiedź: Przygotuj PR i przetestuj
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.
Wskazówki i porady dla programistów Angular
Po miesiącach intensywnego używania Cursora z Angularem, oto najskuteczniejsze wzorce które profesjonalny programista powinien przyjąć od pierwszego dnia.
1. Użyj @codebase do pytań projektowych
Zanim zapytasz „jak mogę zrobić X”, użyj @codebase żeby ludzie zrozumieli
Najedź kursorem na kontekst swojego projektu. Różnica w odpowiedziach jest znacząca:
Wzorzec podpowiedzi: kontekst bazy kodu
// 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. Podpowiedź „Przegląd i krytyka”.
Jedno z najbardziej przydatnych podpowiedzi, jakie możesz dać Kursorowi i poprosić o krytyczną recenzję kod, który właśnie napisałeś, określający rodzaj problemów, które chcesz znaleźć:
Podpowiedź: Specjalistyczny przegląd kodu
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. Dokument z kursorem, a nie ręcznie
Podpowiedź: Wygeneruj JSDoc i 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. Agenci w tle do długich zadań
Agenty tła Cursor 2.0 idealnie nadają się do bardziej czasochłonnych zadań, takich jak analizując całą bazę kodu lub generując testy dla kilkudziesięciu komponentów. Podczas gdy agent działa, możesz równolegle kontynuować rozwój:
Podpowiedź: Agent działający w tle dla pokrycia testowego
[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. Haki kursora dla automatycznej jakości
Skonfiguruj zaczepy kursora, aby przeprowadzać automatyczne sprawdzanie każdej modyfikacji pliku Kątowy. Eliminuje to potrzebę pamiętania o ręcznym uruchamianiu lint i testów:
// .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
Wskaźniki rzeczywistej produktywności
Uzasadnione pytanie brzmi: „Ile czasu naprawdę oszczędzam dzięki Cursorowi?”. Oparty na udokumentowanych doświadczeniach zespołów, które zaadoptowały Cursora do profesjonalnych projektów Angulara, Oto kilka konkretnych pomiarów:
Benchmark: projekt Angular z kursorem i bez niego
| Działalność | Bez kursora | Z Kursorem | Oszczędności |
|---|---|---|---|
| Projekt Bootstrap (CLI + konfiguracja Jest/ESLint/Prettier) | 45-60 minut | 5-10 minut | ~85% |
| Kompletne generowanie funkcji (model + usługa + 4 komponenty + routing) | 3-4 godziny | 30-45 minut | ~80% |
| Pisanie testów jednostkowych (pokrycie 80%) | 2 godziny na usługę | 20-30 minut | ~75% |
| Migracja starszego komponentu do samodzielnych + sygnałów | 30-45 minut | 5-10 minut | ~80% |
| Skonfiguruj akcje CI/CD w GitHubie | 2-3 godziny | 20-30 minut | ~85% |
| Debugowanie złożonego błędu | 1-2 godziny | 20-40 minut | ~60% |
Należy zauważyć, że liczby te oznaczają czas produkcja kodu, nie czas myśli architektonicznej. Kursor przyspiesza mechaniczne pisanie kodu, pozostawiając więcej czasu na decyzje na wysokim szczeblu, które wymagają ludzkiej wiedzy.
Kiedy kursor nie wystarczy
Kursor jest mnożnikiem produktywności, a nie substytutem wiedzy specjalistycznej. Są sytuacje, w których AI pokazuje swoje ograniczenia w kontekście Angulara:
- Strategiczne decyzje architektoniczne: Kursor może proponować opcje, ale wybór właściwej strategii zarządzania stanem (sygnały vs NgRx vs Akita) Zależy to od czynników biznesowych, które tylko Ty znasz.
- Zaawansowane debugowanie wydajności: Identyfikacja spowodowanego wycieku pamięci od zamknięcia do efektu() lub cyklicznego ponownego renderowania pomiędzy sygnałami wymaga zrozumienia głębokość wykrywania zmian przez Angular.
- Integracja ze złożonymi bibliotekami: Kursor dobrze zna Angulara, ale może mieć ograniczoną wiedzę na temat bardzo specyficznych bibliotek stron trzecich lub niedawno zaktualizowany.
- Przegląd bezpieczeństwa: Nie ufaj ślepo kodowi wygenerowanemu bez niego przegląd bezpieczeństwa. Kursor może wprowadzić subtelne luki w zabezpieczeniach, szczególnie w obszarach takich jak zarządzanie uwierzytelnianiem i oczyszczanie danych wejściowych.
Anty-wzorce, których należy unikać przy użyciu kursora i kąta
Anty-wzorzec 1: Akceptacja kodu bez czytania
Największym ryzykiem związanym z używaniem Kursora jest uzależnienie się od sztucznej inteligencji zaakceptować wygenerowany kod bez jego zrozumienia. Prowadzi to do niespójnych baz kodu, błędy trudne do debugowania i programiści, którzy nie rozumieją własnego kodu.
Praktyczna zasada: Jeśli nie możesz wyjaśnić koledze, dlaczego kod generowane robi to, co robi, nie akceptuj tego, dopóki tego nie zrozumiesz. Użyj kursora do przyspieszać, a nie zastępować zrozumienie.
Antywzorzec 2: Niejasne podpowiedzi dotyczące złożonych problemów
// 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?"
Antywzorzec 3: Przeciwstawne reguły
Jeśli masz reguły, które są ze sobą sprzeczne (na przykład jedna z nich mówi „użyj sygnałów” i inny mówi „użyj BehaviorSubject dla stanu”), Cursor generuje niespójny kod. Wykonuj okresowy audyt swoich reguł, aby usuwać konflikty i aktualizować je przestarzałe podczas migracji bazy kodu.
Antywzorzec 4: Ignorowanie okna kontekstowego
Kursor ma ograniczenie kontekstu. Jeśli masz bardzo długą rozmowę, wiadomości starsze są „zapominane”. W przypadku skomplikowanych zadań, które trwają godzinami, lepiej je otworzyć nowe rozmowy tematyczne zamiast kontynuować niekończącą się sesję. Zapisz skuteczne podpowiedzi jako Pamięci kursora aby je ponownie wykorzystać.
Wnioski: Proces pracy programisty Angular w 2026 roku
Dochodzimy do końca tego artykułu i całej serii na temat Cursor IDE. Przepływ pracy które zbudowaliśmy reprezentuje najnowocześniejszy poziom profesjonalnego rozwoju Angulara w 2026 r.: podejście Natywna sztuczna inteligencja, ale kontrolowana przez programistę, gdzie inteligencja sztuczna technologia przyspiesza każdą fazę, nie zastępując ludzkiego osądu.
Podsumowując cały przepływ pracy:
- Konfiguracja reguł: Zainwestuj czas w tworzenie konkretnych zasad dla Twojego stosu. To jest największy mnożnik: każda dobrze napisana reguła poprawia się każdą przyszłą interakcję ze sztuczną inteligencją.
- Tryb planu przed trybem agenta: W przypadku złożonych funkcji lub migracji Zawsze planuj przed wykonaniem. Poprawiony plan jest szybszy niż zła realizacja.
- Tryb agenta do ładowania początkowego: Pozwól AI zająć się tworzeniem struktury, komponenty i konfiguracje. Twój czas jest zbyt wiele wart jak na szablon.
- Testowanie z AI: Generuj testy za pomocą kursora, przeglądaj przypadki Edge, dodawaj przypadkach, których sztuczna inteligencja nie brała pod uwagę. Uzyskaj pokrycie 80% w ciągu jednej czwartej czasu.
- Refaktoryzacja wspomagana: Użyj kursora do systematycznych migracji wzorców nowoczesny (sygnały, samodzielny, nowa składnia). Skaluj do całych modułów za pomocą agentów działających w tle.
- Wygenerowano CI/CD: Nie pisz ręcznie potoków YAML. Opisz wymagania i pozwól Cursorowi wygenerować prawidłowe i zoptymalizowane konfiguracje.
Programista, który zastosuje ten przepływ pracy, nie staje się mniej ekspertem: staje się wykładniczo bardziej produktywne. Wiedza specjalistyczna pozostaje podstawą oceniaj wygenerowany kod, podejmuj decyzje dotyczące architektury i utrzymuj jakość projektu. Kursor nie jest niwelatorem: rozszerza możliwości tych, którzy są już dobrzy.
Podsumowanie serii Cursor IDE i AI-Native Development
| # | Przedmiot | Główny nacisk |
|---|---|---|
| 1 | Kursor IDE: Kompletny przewodnik | Przegląd, instalacja, podstawowe funkcje |
| 2 | Reguły kursora | Konfiguracja AI dla Twojego projektu |
| 3 | Tryb agenta | Zmień bazę kodu za pomocą polecenia |
| 4 | Tryb planu i agenci działający w tle | Planowanie i równoległość |
| 5 | Haki kursora | Automatyzacja przepływu pracy |
| 6 | MCP i kursor | Połączenie z bazami danych i interfejsami API |
| 7 | Debugowanie za pomocą Cursor AI | Naprawianie błędów 3x szybciej |
| 8 | Kursor kontra windsurfing kontra drugi pilot | Porównanie instrumentów w 2026 roku |
| 9 | Jesteś tutaj - Profesjonalny przepływ pracy Angular | Pełne studium przypadku od konfiguracji do wdrożenia |
Powiązane serie do odkrycia
- Nowoczesny kątowy (ID 224-233): Dowiedz się więcej o sygnałach w wersji autonomicznej komponenty, SSR i najnowsze funkcje Angular z dedykowanymi przewodnikami.
- MCP i kursor (ID 64-77): Zapoznaj się z protokołem kontekstu modelu w szczegóły umożliwiające połączenie Cursora z bazami danych, interfejsami API i narzędziami zewnętrznymi.
- Kodowanie Vibe: Dowiedz się, jak programiści wykorzystują sztuczną inteligencję do tworzenia prototypów szybkie pomysły dzięki Claude Code, systemom wieloagentowym i testowaniu kodu AI.
Dziękuję za śledzenie całej serii. Jeśli masz jakieś pytania, uwagi lub chcesz się podzielić swój Angularowy przepływ pracy z Kursorem, napisz w komentarzach. Twój wkład pomaga ulepsz te przewodniki dla całej włoskiej społeczności programistów.







