Sub-architect Frontend. Invocado por /architect orchestrator. Lee 01-spec.md + 02-design-ui.md + story YAML. Produce 03-arch-fe.md con: routes, components FSD-Lite, hooks React Query, Zod schemas, types TS, tests Vitest+Playwright, server-first boundaries. Activa cuando /architect spawna o user dice: '/architect-fe', 'arq frontend', 'diseña FE'.
68
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Owner:
03-arch-fe.md. Diseño técnico capa FE. Output → /architect orchestrator.
frontend-expert — FSD-Lite, conventionstessl__react-patterns — error boundaries, states, accessibilitytessl__zod — schemas validationtessl__shadcn-ui — primitives reusetessl__tailwind — tokenstessl__nextjs-app-router-modularization — Server/Client splittessl__graceful-degradation — timeout/fallback fetchbrand-expert, offer-expert, copilot-expert, etc.)# Component patterns
grep -rn "<keyword>" frontend/src/lib/ frontend/src/hooks/ frontend/src/components/shared/
find frontend/src -name "<basename>.ts*"Si pattern existe en lib/ o components/shared/ → reutilizar. Si pattern emerge en 2+ features → flag para lift a shared.
Seguir template docs/specs/templates/03-arch-template.md con surface=FE. Llenar:
Routes:
| Path | Component | Type |
|---|---|---|
/[tenantId]/{path} | {Section}Page.tsx | Server Component |
/[tenantId]/{path}/edit | {Section}EditClient.tsx | Client Component |
Features (FSD-Lite):
frontend/src/features/{m}/
├── api/use-{action}.ts # React Query hook
├── components/{Component}.tsx # PascalCase
├── schemas/{action}-schema.ts # Zod
├── hooks/use-{custom}.ts
├── types/{m}.types.ts
└── config/{m}.config.tsHooks:
export function use{X}Mutation() {
return useMutation({
mutationFn: ...,
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['{m}', '{action}'] }),
});
}NEVER useEffect for data fetching (use React Query).
NEVER useEffect to derive state.
Schemas Zod:
const schema = z.object({
field: z.string().min(1, "Requerido"), // Spanish neutro
});
type FormData = z.infer<typeof schema>;Types TS:
stringfield?: string)Server vs Client boundaries:
"use client" SOLO cuando state/effects/event handlers/browser APIstessl__nextjs-app-router-modularizationAccessibility:
<button>, <nav>, <main>)aria-label, aria-busy, aria-live)Tests requeridos:
frontend/src/features/{m}/components/{Component}.test.tsxfrontend/src/features/{m}/api/use-{action}.test.tsfrontend/e2e/regression/{m}-{story}.spec.ts>= 20% all dimensions, no debe bajarTelemetría:
{m}_{action}_submitted, {m}_{action}_error{tenant_id, success, duration_ms}Master data:
useTenantLocale() para currency + timezoneformatTenantDate*() (NEVER toLocaleDateString())formatMoney(amount, data.currency ?? locale.currency) (NEVER 'USD' literal)Spanish neutro:
Output al orchestrator:
done -> docs/projects/active/PI-N/sprints/SN/stories/{id}/03-arch-fe.mduseEffect para data fetchingX-Tenant-ID injection (fetchClient lo hace)style={{}} (use Tailwind + cn())'USD' o currency || 'USD'toLocaleDateString()<a> tags (use next/link)<img> tags (use next/image)any / unknown sin type guardsSingle artifact: 03-arch-fe.md. Self-contained.
alpacapurpura/ap_sales_agent
d31f7bc
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.