원클릭으로
create-signal-store
Use when the user asks to add state management or create a store for a feature in this Angular workspace.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when the user asks to add state management or create a store for a feature in this Angular workspace.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when writing or editing an Angular component in this workspace — presentational (ui) or container components. Covers the clean component rules: dumb ui components, thin containers, and where logic must not go.
Use whenever writing, editing, running, or fixing a Vitest spec (`*.spec.ts`) in this workspace — signal stores, `rxMethod`s, `computed`s, presentational and container components, mocks/spies, or pure utils. ESPECIALLY reach for this the moment a test involves anything async (`rxMethod`, HTTP, a timer) or a signal-driven effect, because this app is zoneless and the usual `fakeAsync`/`tick` recipe silently does not work here. If you find yourself about to import `fakeAsync`, `tick`, or reach for `zone.js`, stop and read this first. Also reach for this when you're chasing 100% Vitest coverage.
Use when adding or changing any state in this Angular workspace — creating a signal store, deciding whether state belongs in a local or root store, or wiring an async load. Always applies when state is introduced, not only when refactoring existing stores.
Use whenever writing or editing an Angular `computed()` or `effect()` — including signal-based derivations inside `signalStore` (`withComputed`), component `computed`s, and any `effect`. Applies even for one-line derivations.
Use when the user asks to create a new Nx library in this workspace.
| name | create-signal-store |
| description | Use when the user asks to add state management or create a store for a feature in this Angular workspace. |
In this workspace we manage state exclusively with the NgRx Signal Store. When asked to create a store, follow these rules:
signalStore from @ngrx/signals.providedIn: 'root' vs. component-provided scope using the
placement test in the state-management skill — don't default to root.withEntities<T>(); keep flags and scalar values
with withState({ ... }).rxMethod and wrap the HTTP
call in tapResponse. Track loading with a loading flag kept in
withState({ loading: false }): set it to true before the call in a
leading tap, and back to false when the data arrives.NotificationService. On error, show an error notification.withMethods factory.withHooks({ onInit }) hook.export const DogsStore = signalStore(
{ providedIn: 'root' },
withEntities<Dog>(),
withState({ loading: false }),
withMethods(
(
store,
notificationService = inject(NotificationService),
dogsApiService = inject(DogsApiService),
) => ({
loadDogs: rxMethod<void>(
pipe(
tap(() => patchState(store, { loading: true })),
exhaustMap(() =>
dogsApiService.getDogs().pipe(
tapResponse({
next: (dogs) => {
patchState(store, setAllEntities(dogs), { loading: false });
notificationService.showSuccess('Dogs Loaded');
},
error: () => notificationService.showError(),
}),
),
),
),
),
}),
),
withHooks({
onInit(store) {
store.loadDogs();
},
}),
);