angular-frontend-clean-architecture

Angular 21 standalone frontend with Clean Architecture, vertical slice (pages by feature), signals, OnPush, and ng-zorro. Use when creating or refactoring Angular apps, adding pages, components, services, directives, pipes, or when the user mentions Angular frontend, standalone components, or signals.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "angular-frontend-clean-architecture" with this command: npx skills add luismpenholato/maurao-skills/luismpenholato-maurao-skills-angular-frontend-clean-architecture

Frontend Angular – Clean Architecture + Standalone

Guia para criar e manter frontends Angular com estrutura por features (vertical slice), componentes standalone, signals e ng-zorro-antd.

Quando usar esta skill

  • Adicionar nova página/feature (nova pasta em pages/ com listagem, formulário, service, modelos).
  • Criar componente reutilizável em shared/components/, diretiva em shared/directives/, pipe em shared/pipes/.
  • Adicionar service (HTTP, estado global), guard, interceptor.
  • Definir ou alterar rotas em app.routes.ts.
  • Revisar ou refatorar código para seguir a estrutura e convenções do boilerplate.

Estrutura do projeto

frontend/src/app/
├── app.ts                    # Bootstrap, providers (HTTP, interceptors)
├── app.config.ts             # provideRouter, provideHttpClient, etc.
├── app.routes.ts             # Rotas (guards quando necessário)
├── layout/                   # Layout principal (header, drawer, outlet)
│   └── main-layout/
├── pages/                    # Features por domínio (vertical slice)
│   └── products/
│       ├── product.model.ts
│       ├── product.service.ts
│       └── products-list/    # Uma tela = uma pasta com tudo junto
│           ├── products-list.component.ts
│           ├── products-list.component.html
│           ├── products-list.component.scss
│           └── products-list.component.spec.ts
├── shared/
│   ├── components/           # Componentes reutilizáveis (page-header, loading, etc.)
│   ├── directives/           # Diretivas (autofocus, currency-mask, etc.)
│   ├── pipes/
│   ├── services/             # Serviços globais (loading, layout)
│   ├── guards/
│   ├── interceptors/
│   └── utils/
└── environments/             # environment.apiBaseUrl, etc.

Regra: pages/ contém uma pasta por domínio (ex.: products). Dentro da feature ficam o modelo, o service e uma pasta por tela (cada tela com component, html, scss e spec juntos). Nem toda feature tem listagem ou formulário — cria-se só as telas que existirem. shared/ contém apenas o que é reutilizado entre páginas.

Checklist – Nova feature (ex.: Orders)

Use este checklist e crie os itens na ordem indicada.

Modelo e service

  • pages/orders/order.model.ts: interfaces (ex.: Order, OrderCreateRequest).
  • pages/orders/order.service.ts: @Injectable({ providedIn: 'root' }), inject(HttpClient), métodos que retornam Observable<T> (list, getById, create, update, delete). Usar environment.apiBaseUrl para base da API.

Telas da feature (cada uma em sua pasta, tudo junto)

  • Uma pasta por tela em pages/orders/ (ex.: orders-list/), com *.component.ts, *.component.html, *.component.scss, *.component.spec.ts na mesma pasta.
  • Componente: ChangeDetectionStrategy.OnPush, host: { class: 'app-orders-list' }, inject(OrderService), signals/computed conforme a tela. Template: @if / @for, [class.x] ou [style.x], track item.id no @for.
  • Se a tela for formulário: form reativo, FormBuilder, validações; helper opcional (validação/build request) na mesma pasta; diretivas compartilhadas (ex.: appCurrencyMask) quando aplicável.

Rotas

  • Em app.routes.ts: uma rota por tela que existir na feature, com canActivate: [authGuard] quando necessário.

Shared (somente se reutilizável)

  • Componente/diretiva/pipe em shared/ apenas quando usado em mais de uma feature ou quando for UI genérica (ex.: page-header, loading).

Padrões de código

Componente standalone (sem standalone: true – é padrão no Angular 21)

import { ChangeDetectionStrategy, Component, inject, input, signal } from '@angular/core';

@Component({
  selector: 'app-page-header',
  changeDetection: ChangeDetectionStrategy.OnPush,
  host: { class: 'app-page-header' },
  imports: [RouterLink, NzBreadCrumbModule],
  templateUrl: './page-header.component.html',
  styleUrl: './page-header.component.scss'
})
export class PageHeaderComponent {
  title = input.required<string>();
  subtitle = input<string>();
  breadcrumb = input<BreadcrumbItem[]>([]);
}

Service com HttpClient

@Injectable({ providedIn: 'root' })
export class ProductService {
  private readonly http = inject(HttpClient);
  private readonly baseUrl = `${environment.apiBaseUrl}/api/products`;

  list(): Observable<Product[]> {
    return this.http.get<Product[]>(this.baseUrl);
  }
}

Template – controle de fluxo e bindings

@if (loading()) {
  <nz-spin nzSimple></nz-spin>
} @else {
  @for (item of items(); track item.id) {
    <div [class.active]="item.isActive">{{ item.name }}</div>
  }
}

Diretiva com signal input e host

@Directive({
  selector: '[appAutofocus]',
  host: {
    '(focus)': 'onFocus($event)'
  }
})
export class AutofocusDirective {
  readonly appAutofocus = input(true, { transform: booleanAttribute });
}

Convenções

  • Componentes: OnPush, host: { class: 'app-<nome>' }, signal input()/output() quando fizer sentido; evitar @Input()/@Output() em código novo.
  • Templates: @if, @for, @switch; track item.id (ou estável) no @for; sem ngClass/ngStyle.
  • Serviços: inject() em vez de constructor injection; providedIn: 'root' para serviços globais.
  • Rotas: um arquivo app.routes.ts; guards em shared/guards/, importados nas rotas.
  • Nomes: kebab-case para pastas e arquivos; prefixo app para seletores de componentes/diretivas do app.

Tratamento de erros e loading

  • Chamadas HTTP: usar catchError, finalize, timeout nos subscribes; mensagens via NzMessageService quando fizer sentido.
  • Loading: signal loading no componente; [nzLoading]="loading()" ou overlay compartilhado via LoadingService quando for global.

Recursos adicionais

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

dotnet-backend-clean-architecture

No summary provided by upstream source.

Repository SourceNeeds Review
General

Lyrics

Lyrics - command-line tool for everyday use

Registry SourceRecently Updated
General

Lint

Lint - command-line tool for everyday use

Registry SourceRecently Updated
General

Linkedin Post

LinkedIn文案生成、开头Hook、热门话题标签、轮播内容规划、高质量评论、个人简介优化。LinkedIn post writer with hooks, hashtags, carousel planning, comment templates, profile optimization. Use whe...

Registry SourceRecently Updated
1790ckchzh