| name | zustand-store |
| description | Creates Zustand stores with IndexedDB persistence, TypeScript strict typing, and comprehensive test coverage following arolariu.ro state management patterns from RFC 1005. |
| lastReviewed | 2026-05-08T00:00:00.000Z |
Zustand Store Scaffolding
Generates Zustand stores following the arolariu.ro state management patterns.
When to Use
- Adding global client-side state
- State that persists across page navigations
- State shared between multiple components
- Replacing prop drilling beyond 2 levels
When NOT to Use
- Server-only data: Use Server Components with direct fetching
- Form state: Use
useState or react-hook-form
- Component-scoped state: Use
useState or useReducer
- Theme/locale: Use React Context
Store Template
import {create} from "zustand";
import {persist} from "zustand/middleware";
import {indexedDBStorage} from "@/stores/indexedDBStorage";
interface [Entity]StoreState {
readonly items: [Entity][];
readonly isLoading: boolean;
readonly error: Error | null;
}
interface [Entity]StoreActions {
fetchAll: () => Promise<void>;
add: (item: [Entity]) => void;
update: (id: string, item: Partial<[Entity]>) => void;
remove: (id: string) => void;
reset: () => void;
}
type [Entity]Store = [Entity]StoreState & [Entity]StoreActions;
const initialState: [Entity]StoreState = {
items: [],
isLoading: false,
error: null,
};
export const use[Entity]Store = create<[Entity]Store>()(
persist(
(set, get) => ({
...initialState,
fetchAll: async () => {
set({isLoading: true, error: null});
try {
const items = await fetch[Entities]();
set({items, isLoading: false});
} catch (error) {
set({
error: error instanceof Error ? error : new Error("Failed to fetch"),
isLoading: false,
});
}
},
add: (item) => {
set((state) => ({items: [...state.items, item]}));
},
update: (id, updates) => {
set((state) => ({
items: state.items.map((item) =>
item.id === id ? {...item, ...updates} : item,
),
}));
},
remove: (id) => {
set((state) => ({
items: state.items.filter((item) => item.id !== id),
}));
},
reset: () => {
set(initialState);
},
}),
{
name: "[entity]-store",
storage: indexedDBStorage,
partialize: (state) => ({
items: state.items,
}),
},
),
);
Test Template
import {describe, expect, it, beforeEach, vi} from "vitest";
import {act} from "@testing-library/react";
import {use[Entity]Store} from "../[entity]Store";
vi.mock("@/stores/indexedDBStorage", () => ({
indexedDBStorage: {
getItem: vi.fn(() => null),
setItem: vi.fn(),
removeItem: vi.fn(),
},
}));
describe("use[Entity]Store", () => {
beforeEach(() => {
act(() => {
use[Entity]Store.getState().reset();
});
});
it("should have correct initial state", () => {
const state = use[Entity]Store.getState();
expect(state.items).toEqual([]);
expect(state.).();
(state.).();
});
(, {
item = {: , : };
( {
use[].().(item);
});
(use[].().).(item);
});
(, {
item = {: , : };
( {
use[].().(item);
use[].().(, {: });
});
(use[].().[]?.).();
});
(, {
item = {: , : };
( {
use[].().(item);
use[].().();
});
(use[].().).();
});
(, {
( {
use[].().({: , : });
use[].().();
});
(use[].().).([]);
});
});
Checklist
RFC Grounding Checklist (Mandatory)
Before final output or code changes:
- Map task scope to relevant RFC IDs using
.github/agent-governance/rfc-grounding-protocol.md.
- Read the referenced source files and verify RFC guidance is still current.
- If RFC and source conflict, follow source-of-truth code and record RFC drift for remediation.
- Include concrete evidence in outputs (file paths, command results, and validation notes).
Execution Contract
Prerequisites
- Confirm feature scope and expected behavior before creating or modifying files.
- Identify whether this task changes architecture-sensitive behavior and trigger RFC grounding.
Required Context Reads
.github/instructions/frontend.instructions.md
.github/instructions/typescript.instructions.md
docs/rfc/1005-state-management-zustand.md
sites/arolariu.ro/src/stores/index.ts
File Mutation Boundaries
- Allowed:
sites/arolariu.ro/src/stores/**, related hooks/tests/messages as needed.
- Disallowed: unrelated domain logic or infrastructure edits.
Validation Commands
npm run build:website
npm run test:website
Success Output Contract
- Return created/updated file paths.
- Summarize validation commands and outcomes.
- Report assumptions made during generation.
Failure Output Contract
- Report failing step and exact error output.
- Provide impacted files and rollback-safe next steps.
- Request user confirmation when risk or ambiguity blocks safe continuation.
Self-Audit and Uncertainty Protocol (Mandatory)
For non-trivial tasks, complete this checklist before final output:
- Assumptions: list non-obvious assumptions that influenced decisions.
- Risk Flags: identify security, behavior, deployment, or data risks.
- Confidence: report
high, medium, or low with brief justification.
- Evidence: cite changed files, executed commands, and validation outcomes.
Escalate to the user before continuing when security/auth/infra/destructive or major behavior-changing decisions are involved.