Files
claude-plugins/acidaos/skills/spoke-dev/SKILL.md
T
ealmeida 24b0b68ed0 feat: adicionar plugin acidaos e skill prompt-refine
Plugin acidaos (novo):
- rust-dev: desenvolvimento Core em Rust (Axum, crates, debug compiler)
- spoke-dev: desenvolvimento Spokes em Next.js/TypeScript + Storybook
- devops: pipelines Gitea Actions CI/CD (adaptado de GitHub para Gitea)
- docs: rustdoc, TypeDoc, Outline e ADRs

dev-tools:
- prompt-refine: skill genérica de engenharia de prompts para agentes IA

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 22:11:22 +00:00

240 lines
5.9 KiB
Markdown

---
name: spoke-dev
description: Desenvolvimento de Spokes do AcidaOS em Next.js/TypeScript — criar aplicações Spoke, componentes React com testes e Storybook. Usar quando "spoke", "dashboard acidaos", "next.js acidaos", "componente react acidaos", "ts-create-spoke", "acidaos ui", "acidaos frontend".
allowed-tools: Read, Write, Edit, Bash, mcp__memory-supabase__search_memories, mcp__gitea__get_file_content, mcp__gitea__create_file, mcp__gitea__update_file
---
# AcidaOS Spoke Dev
Skill para desenvolvimento dos **Spokes do AcidaOS** em Next.js/TypeScript.
## Contexto do Projecto
Os Spokes são as aplicações de interface que comunicam com o Core via API interna:
```
acidaos-dashboard (Next.js 15 + App Router)
├── src/
│ ├── app/ ← App Router pages
│ ├── components/ ← Componentes React
│ │ ├── ui/ ← Componentes base (shadcn/ui)
│ │ └── features/ ← Componentes de funcionalidade
│ ├── lib/
│ │ ├── api/ ← Client para AcidaOS Core API
│ │ └── hooks/ ← React hooks custom
│ └── types/ ← TypeScript types partilhados
├── __tests__/ ← Jest + Testing Library
└── .storybook/ ← Storybook
```
**Stack:** Next.js 15 | TypeScript 5 | React 19 | Tailwind CSS | shadcn/ui | Vercel AI SDK | Vitest | Playwright
## Protocolo Inicial
```
mcp__memory-supabase__search_memories "acidaos spoke dashboard [componente]"
mcp__gitea__get_file_content acidaos-dashboard/package.json
```
---
## Operações
### 1. Criar nova aplicação Spoke (`/ts-create-spoke-app`)
**Input:** Nome do Spoke e propósito
**Estrutura a criar:**
```bash
# No container dev (Regra #48)
cd /root/Dev
npx create-next-app@latest acidaos-<nome> \
--typescript \
--tailwind \
--app \
--src-dir \
--import-alias "@/*" \
--no-git
```
**Ficheiros obrigatórios após scaffold:**
`src/lib/api/core-client.ts` — cliente para o Core:
```typescript
/**
* AcidaOS Core API Client
*
* @author Descomplicar® Crescimento Digital
* @link https://descomplicar.pt
*/
const CORE_API_URL = process.env.ACIDAOS_CORE_URL ?? 'http://localhost:3001';
export async function coreRequest<T>(
endpoint: string,
options?: RequestInit
): Promise<T> {
const res = await fetch(`${CORE_API_URL}${endpoint}`, {
...options,
headers: {
'Content-Type': 'application/json',
'X-AcidaOS-Version': '1',
...options?.headers,
},
});
if (!res.ok) {
throw new Error(`Core API error: ${res.status} ${res.statusText}`);
}
return res.json() as Promise<T>;
}
```
`src/types/index.ts` — tipos base:
```typescript
export interface AgentTask {
id: string;
status: 'pending' | 'running' | 'completed' | 'failed';
createdAt: string;
completedAt?: string;
}
export interface CoreHealth {
status: 'healthy' | 'degraded' | 'down';
version: string;
uptime: number;
}
```
---
### 2. Criar componente React (`/ts-create-react-component`)
**Input:** Descrição do componente (nome, props, comportamento)
**Template base — componente:**
`src/components/features/<Nome>/<Nome>.tsx`:
```typescript
/**
* <Nome> — <Descrição curta>
*
* @author Descomplicar® Crescimento Digital
*/
import { type FC } from 'react';
import { cn } from '@/lib/utils';
interface <Nome>Props {
// props do componente
className?: string;
}
export const <Nome>: FC<<Nome>Props> = ({ className }) => {
return (
<div className={cn('', className)}>
{/* conteúdo */}
</div>
);
};
<Nome>.displayName = '<Nome>';
```
**Template — teste (Vitest + Testing Library):**
`src/components/features/<Nome>/<Nome>.test.tsx`:
```typescript
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { <Nome> } from './<Nome>';
describe('<Nome>', () => {
it('renderiza sem erros', () => {
render(<<Nome> />);
// asserção específica ao componente
});
it('aceita className personalizada', () => {
const { container } = render(<<Nome> className="test-class" />);
expect(container.firstChild).toHaveClass('test-class');
});
});
```
**Template — Storybook:**
`src/components/features/<Nome>/<Nome>.stories.tsx`:
```typescript
import type { Meta, StoryObj } from '@storybook/react';
import { <Nome> } from './<Nome>';
const meta: Meta<typeof <Nome>> = {
title: 'Features/<Nome>',
component: <Nome>,
parameters: {
layout: 'centered',
},
};
export default meta;
type Story = StoryObj<typeof <Nome>>;
export const Default: Story = {
args: {},
};
```
**Criar index de exportação:**
`src/components/features/<Nome>/index.ts`:
```typescript
export { <Nome> } from './<Nome>';
export type { <Nome>Props } from './<Nome>';
```
---
## Padrões Obrigatórios
### TypeScript
- `strict: true` em `tsconfig.json` — sem `any` implícito
- Props sempre tipadas com interface exportada
- Hooks custom em `src/lib/hooks/use<Nome>.ts`
- Server Components por defeito; `'use client'` apenas quando necessário
### Performance
- `next/image` para todas as imagens
- `loading="lazy"` em componentes pesados
- `Suspense` boundaries em torno de data-fetching
- Cache de API calls com `unstable_cache` ou React cache
### Segurança
- Nunca expor `ACIDAOS_CORE_URL` no cliente (apenas server-side)
- Sanitizar input do utilizador antes de enviar ao Core
- Usar Next.js Server Actions para mutações
---
## Quality Gate
```bash
pnpm build # zero erros TypeScript
pnpm test # todos os testes passam
pnpm lint # zero erros ESLint
```
## Checklist Entrega
- [ ] Tipos TypeScript sem `any`
- [ ] Testes criados (>80% cobertura)
- [ ] Story Storybook criada
- [ ] `displayName` definido no componente
- [ ] `pnpm build` sem erros
- [ ] Client/Server components correctamente marcados
- [ ] CHANGELOG.md actualizado
---
**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Plugin**: acidaos