ywai/skills/angular/architecture/SKILL.md
Angular architecture: Scope Rule, project structure, file naming, style guide. Trigger: When structuring Angular projects or deciding where to place components.
npx skillsauth add Yoizen/dev-ai-workflow angular-architectureInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
"Scope determines structure" - Where a component lives depends on its usage.
| Usage | Placement |
|-------|-----------|
| Used by 1 feature | features/[feature]/components/ |
| Used by 2+ features | features/shared/components/ |
features/
shopping-cart/
shopping-cart.ts # Main component = feature name
components/
cart-item.ts # Used ONLY by shopping-cart
cart-summary.ts # Used ONLY by shopping-cart
checkout/
checkout.ts
components/
payment-form.ts # Used ONLY by checkout
shared/
components/
button.ts # Used by shopping-cart AND checkout
modal.ts # Used by multiple features
src/app/
features/
[feature-name]/
[feature-name].ts # Main component (same name as folder)
components/ # Feature-specific components
services/ # Feature-specific services
models/ # Feature-specific types
shared/ # ONLY for 2+ feature usage
components/
services/
pipes/
core/ # App-wide singletons
services/
interceptors/
guards/
app.ts
app.config.ts
routes.ts
main.ts
No .component, .service, .model suffixes. The folder tells you what it is.
✅ user-profile.ts
❌ user-profile.component.ts
✅ cart.ts
❌ cart.service.ts
✅ user.ts
❌ user.model.ts
inject() over constructor injectionclass and style bindings over ngClass/ngStyleprotected for template-only membersreadonly for inputs, outputs, queriessaveUser) not event (handleClick)@Component({...})
export class UserProfileComponent {
// 1. Injected dependencies
private readonly userService = inject(UserService);
// 2. Inputs/Outputs
readonly userId = input.required<string>();
readonly userSaved = output<User>();
// 3. Internal state
private readonly _loading = signal(false);
readonly loading = this._loading.asReadonly();
// 4. Computed
protected readonly displayName = computed(() => ...);
// 5. Methods
save(): void { ... }
}
| Official Says | We Do | Why |
|---------------|-------|-----|
| user-profile.component.ts | user-profile.ts | Redundant - folder tells context |
| user.service.ts | user.ts | Same |
# New project
ng new my-app --style=scss --ssr=false
# Component in feature
ng g c features/products/components/product-card --flat
# Service in feature
ng g s features/products/services/product --flat
# Guard in core
ng g g core/guards/auth --functional
documentation
Yoizen UI design system guidelines and resources. Trigger: When working on Yoizen UI components, styling, colors, typography, or icons.
development
TypeScript strict patterns and best practices. Trigger: When writing TypeScript code - types, interfaces, generics.
development
Tailwind CSS 4 patterns and best practices. Trigger: When styling with Tailwind - cn(), theme variables, no var() in className.
data-ai
name: skill-sync description: > Sync skill metadata with the Auto-invoke sections in AGENTS.md. Trigger: When you change a skill's metadata (metadata.scope/metadata.auto_invoke), regenerate the Auto-invoke tables, or run ./skills/skill-sync/assets/sync.sh. metadata: author: Yoizen version: "1.0" scope: [root] auto_invoke: - "skill operations" - "workflow" - "sdd" author: Yoizen version: "1.0" scope: [root] auto_invoke: - "skill operations" - "workflow"