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

5.9 KiB

name, description, allowed-tools
name description allowed-tools
spoke-dev 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". 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:

# 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:

/**
 * 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:

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:

/**
 * <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:

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:

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:

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

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