Communitygithub.com

estándares-de-codificación

Convenciones de codificación base entre proyectos para nombres, legibilidad, inmutabilidad y revisión de calidad de código. Usa habilidades detalladas de frontend o backend para patrones específicos de frameworks. Actívala al revisar calidad de código o nombres cuando no aplique una habilidad específica de framework.

¿Qué es estándares-de-codificación?

Esta habilidad establece un estándar base de codificación aplicable a todos los proyectos, promoviendo principios de legibilidad, simplicidad (KISS), no repetición (DRY) y evitar funcionalidades innecesarias (YAGNI). Incluye guías detalladas para TypeScript/JavaScript sobre nomenclatura de variables y funciones, patrones de inmutabilidad, manejo de errores, async/await, seguridad de tipos, y estructura de componentes en React. También abarca diseño de APIs REST, validación de esquemas con Zod, organización de archivos, documentación con JSDoc, memoización, carga diferida, pruebas con el patrón AAA, y detección de malos olores en el código. Compatible con cualquier proyecto donde se desee mantener consistencia y calidad, complementando habilidades más específicas como `frontend-patterns` o `backend-patterns`. Su objetivo es ser el piso común de calidad, no un manual detallado de frameworks.

Compatible con~Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/coding-standards

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Estándares de Codificación y Mejores Prácticas

Convenciones de codificación base aplicables entre proyectos.

Esta habilidad es el piso común, no el manual detallado del framework.

  • Usa frontend-patterns para React, estado, formularios, renderizado y arquitectura de UI.
  • Usa backend-patterns o api-design para capas de repositorio/servicio, diseño de endpoints, validación y aspectos específicos del servidor.
  • Usa rules/common/coding-style.md cuando necesites la capa de reglas reutilizables más corta en lugar de un recorrido completo de habilidad.

Cuándo Activar

  • Al iniciar un nuevo proyecto o módulo
  • Al revisar código por calidad y mantenibilidad
  • Al refactorizar código existente para seguir convenciones
  • Al hacer cumplir consistencia en nombres, formato o estructura
  • Al configurar reglas de linting, formato o verificación de tipos
  • Al incorporar nuevos contribuyentes a las convenciones de codificación

Límites del Alcance

Activa esta habilidad para:

  • nombres descriptivos
  • valores predeterminados de inmutabilidad
  • legibilidad, cumplimiento de KISS, DRY y YAGNI
  • expectativas de manejo de errores y revisión de malos olores en el código

No uses esta habilidad como fuente principal para:

  • composición, hooks o patrones de renderizado de React
  • arquitectura backend, diseño de API o capas de base de datos
  • guía de framework específica de dominio cuando ya existe una habilidad ECC más específica

Principios de Calidad de Código

1. Legibilidad Primero

  • El código se lee más de lo que se escribe
  • Nombres de variables y funciones claros
  • Código auto-documentado preferido sobre comentarios
  • Formato consistente

2. KISS (Keep It Simple, Stupid - Mantenlo Simple)

  • La solución más simple que funciona
  • Evitar sobreingeniería
  • Sin optimización prematura
  • Fácil de entender > código ingenioso

3. DRY (Don't Repeat Yourself - No Te Repitas)

  • Extraer lógica común en funciones
  • Crear componentes reutilizables
  • Compartir utilidades entre módulos
  • Evitar programación de copiar y pegar

4. YAGNI (You Aren't Gonna Need It - No lo Vas a Necesitar)

  • No construyas funciones antes de que sean necesarias
  • Evita generalidad especulativa
  • Agrega complejidad solo cuando sea necesario
  • Empieza simple, refactoriza cuando sea necesario

Estándares TypeScript/JavaScript

Nomenclatura de Variables

// PASA: BIEN: Nombres descriptivos
const marketSearchQuery = 'elección'
const isUserAuthenticated = true
const totalRevenue = 1000

// FALLA: MAL: Nombres poco claros
const q = 'elección'
const flag = true
const x = 1000

Nomenclatura de Funciones

// PASA: BIEN: Patrón verbo-sustantivo
async function fetchMarketData(marketId: string) { }
function calculateSimilarity(a: number[], b: number[]) { }
function isValidEmail(email: string): boolean { }

// FALLA: MAL: Poco claro o solo sustantivo
async function market(id: string) { }
function similarity(a, b) { }
function email(e) { }

Patrón de Inmutabilidad (CRÍTICO)

// PASA: SIEMPRE usa el operador spread
const updatedUser = {
  ...user,
  name: 'Nuevo Nombre'
}

const updatedArray = [...items, newItem]

// FALLA: NUNCA mutar directamente
user.name = 'Nuevo Nombre'  // MAL
items.push(newItem)         // MAL

Manejo de Errores

// PASA: BIEN: Manejo integral de errores
async function fetchData(url: string) {
  try {
    const response = await fetch(url)

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`)
    }

    return await response.json()
  } catch (error) {
    console.error('Falló la obtención:', error)
    throw new Error('Falló al obtener datos')
  }
}

// FALLA: MAL: Sin manejo de errores
async function fetchData(url) {
  const response = await fetch(url)
  return response.json()
}

Mejores Prácticas de Async/Await

// PASA: BIEN: Ejecución en paralelo cuando sea posible
const [users, markets, stats] = await Promise.all([
  fetchUsers(),
  fetchMarkets(),
  fetchStats()
])

// FALLA: MAL: Secuencial cuando no es necesario
const users = await fetchUsers()
const markets = await fetchMarkets()
const stats = await fetchStats()

Seguridad de Tipos

// PASA: BIEN: Tipos adecuados
interface Market {
  id: string
  name: string
  status: 'active' | 'resolved' | 'closed'
  created_at: Date
}

function getMarket(id: string): Promise<Market> {
  // Implementación
}

// FALLA: MAL: Usar 'any'
function getMarket(id: any): Promise<any> {
  // Implementación
}

Mejores Prácticas de React

Estructura de Componentes

// PASA: BIEN: Componente funcional con tipos
interface ButtonProps {
  children: React.ReactNode
  onClick: () => void
  disabled?: boolean
  variant?: 'primary' | 'secondary'
}

export function Button({
  children,
  onClick,
  disabled = false,
  variant = 'primary'
}: ButtonProps) {
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      className={`btn btn-${variant}`}
    >
      {children}
    </button>
  )
}

// FALLA: MAL: Sin tipos, estructura poco clara
export function Button(props) {
  return <button onClick={props.onClick}>{props.children}</button>
}

Hooks Personalizados

// PASA: BIEN: Hook personalizado reutilizable
export function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState<T>(value)

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value)
    }, delay)

    return () => clearTimeout(handler)
  }, [value, delay])

  return debouncedValue
}

// Uso
const debouncedQuery = useDebounce(searchQuery, 500)

Gestión de Estado

// PASA: BIEN: Actualizaciones de estado adecuadas
const [count, setCount] = useState(0)

// Actualización funcional para estado basado en estado anterior
setCount(prev => prev + 1)

// FALLA: MAL: Referencia directa al estado
setCount(count + 1)  // Puede quedar obsoleto en escenarios asíncronos

Renderizado Condicional

// PASA: BIEN: Renderizado condicional claro
{isLoading && <Spinner />}
{error && <ErrorMessage error={error} />}
{data && <DataDisplay data={data} />}

// FALLA: MAL: Infierno ternario
{isLoading ? <Spinner /> : error ? <ErrorMessage error={error} /> : data ? <DataDisplay data={data} /> : null}

Estándares de Diseño de API

Convenciones REST

GET    /api/markets              # Listar todos los mercados
GET    /api/markets/:id          # Obtener mercado específico
POST   /api/markets              # Crear nuevo mercado
PUT    /api/markets/:id          # Actualizar mercado (completo)
PATCH  /api/markets/:id          # Actualizar mercado (parcial)
DELETE /api/markets/:id          # Eliminar mercado

# Parámetros de consulta para filtrado
GET /api/markets?status=active&limit=10&offset=0

Formato de Respuesta

// PASA: BIEN: Estructura de respuesta consistente
interface ApiResponse<T> {
  success: boolean
  data?: T
  error?: string
  meta?: {
    total: number
    page: number
    limit: number
  }
}

// Respuesta exitosa
return NextResponse.json({
  success: true,
  data: markets,
  meta: { total: 100, page: 1, limit: 10 }
})

// Respuesta de error
return NextResponse.json({
  success: false,
  error: 'Solicitud inválida'
}, { status: 400 })

Validación de Entrada

import { z } from 'zod'

// PASA: BIEN: Validación de esquema
const CreateMarketSchema = z.object({
  name: z.string().min(1).max(200),
  description: z.string().min(1).max(2000),
  endDate: z.string().datetime(),
  categories: z.array(z.string()).min(1)
})

export async function POST(request: Request) {
  const body = await request.json()

  try {
    const validated = CreateMarketSchema.parse(body)
    // Proceder con datos validados
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json({
        success: false,
        error: 'Validación fallida',
        details: error.issues
      }, { status: 400 })
    }
  }
}

Organización de Archivos

Estructura del Proyecto

src/
├── app/                    # Enrutador de App de Next.js
│   ├── api/               # Rutas de API
│   ├── markets/           # Páginas de mercados
│   └── (auth)/           # Páginas de autenticación (grupos de rutas)
├── components/            # Componentes de React
│   ├── ui/               # Componentes de UI genéricos
│   ├── forms/            # Componentes de formularios
│   └── layouts/          # Componentes de diseño
├── hooks/                # Hooks personalizados de React
├── lib/                  # Utilidades y configuraciones
│   ├── api/             # Clientes de API
│   ├── utils/           # Funciones auxiliares
│   └── constants/       # Constantes
├── types/                # Tipos TypeScript
└── styles/              # Estilos globales

Nomenclatura de Archivos

components/Button.tsx          # PascalCase para componentes
hooks/useAuth.ts              # camelCase con prefijo 'use'
lib/formatDate.ts             # camelCase para utilidades
types/market.types.ts         # camelCase con sufijo .types

Comentarios y Documentación

Cuándo Comentar

// PASA: BIEN: Explicar POR QUÉ, no QUÉ
// Usar retroceso exponencial para evitar sobrecargar la API durante cortes
const delay = Math.min(1000 * Math.pow(2, retryCount), 30000)

// Mutación deliberada aquí por rendimiento con arrays grandes
items.push(newItem)

// FALLA: MAL: Decir lo obvio
// Incrementar contador en 1
count++

// Establecer nombre al nombre del usuario
name = user.name

JSDoc para APIs Públicas

/**
 * Busca mercados usando similitud semántica.
 *
 * @param query - Consulta de búsqueda en lenguaje natural
 * @param limit - Número máximo de resultados (predeterminado: 10)
 * @returns Array de mercados ordenados por puntuación de similitud
 * @throws {Error} Si la API de OpenAI falla o Redis no está disponible
 *
 * @example
 * ```typescript
 * const results = await searchMarkets('elección', 5)
 * console.log(results[0].name) // "Trump vs Biden"
 * ```
 */
export async function searchMarkets(
  query: string,
  limit: number = 10
): Promise<Market[]> {
  // Implementación
}

Mejores Prácticas de Rendimiento

Memoización

import { useMemo, useCallback } from 'react'

// PASA: BIEN: Memoizar cálculos costosos
// Copiar antes de ordenar - Array.prototype.sort muta en su lugar
const sortedMarkets = useMemo(() => {
  return [...markets].sort((a, b) => b.volume - a.volume)
}, [markets])

// PASA: BIEN: Memoizar callbacks
const handleSearch = useCallback((query: string) => {
  setSearchQuery(query)
}, [])

Carga Diferida (Lazy Loading)

import { lazy, Suspense } from 'react'

// PASA: BIEN: Cargar componentes pesados de forma diferida
const HeavyChart = lazy(() => import('./HeavyChart'))

export function Dashboard() {
  return (
    <Suspense fallback={<Spinner />}>
      <HeavyChart />
    </Suspense>
  )
}

Consultas a Base de Datos

// PASA: BIEN: Seleccionar solo las columnas necesarias
const { data } = await supabase
  .from('markets')
  .select('id, name, status')
  .limit(10)

// FALLA: MAL: Seleccionar todo
const { data } = await supabase
  .from('markets')
  .select('*')

Estándares de Pruebas

Estructura de Pruebas (Patrón AAA)

test('calcula la similitud correctamente', () => {
  // Arrange (Organizar)
  const vector1 = [1, 0, 0]
  const vector2 = [0, 1, 0]

  // Act (Actuar)
  const similarity = calculateCosineSimilarity(vector1, vector2)

  // Assert (Afirmar)
  expect(similarity).toBe(0)
})

Nomenclatura de Pruebas

// PASA: BIEN: Nombres de prueba descriptivos
test('devuelve array vacío cuando ningún mercado coincide con la consulta', () => { })
test('lanza error cuando falta la clave de API de OpenAI', () => { })
test('vuelve a búsqueda por subcadena cuando Redis no está disponible', () => { })

// FALLA: MAL: Nombres de prueba vagos
test('funciona', () => { })
test('probar búsqueda', () => { })

Detección de Malos Olores en el Código

Vigila estos anti-patrones:

1. Funciones Largas

// FALLA: MAL: Función > 50 líneas
function processMarketData() {
  // 100 líneas de código
}

// PASA: BIEN: Dividir en funciones más pequeñas
function processMarketData() {
  const validated = validateData()
  const transformed = transformData(validated)
  return saveData(transformed)
}

2. Anidamiento Profundo

// FALLA: MAL: 5+ niveles de anidamiento
if (user) {
  if (user.isAdmin) {
    if (market) {
      if (market.isActive) {
        if (hasPermission) {
          // Hacer algo
        }
      }
    }
  }
}

// PASA: BIEN: Retornos tempranos
if (!user) return
if (!user.isAdmin) return
if (!market) return
if (!market.isActive) return
if (!hasPermission) return

// Hacer algo

3. Números Mágicos

// FALLA: MAL: Números sin explicación
if (retryCount > 3) { }
setTimeout(callback, 500)

// PASA: BIEN: Constantes con nombre
const MAX_RETRIES = 3
const DEBOUNCE_DELAY_MS = 500

if (retryCount > MAX_RETRIES) { }
setTimeout(callback, DEBOUNCE_DELAY_MS)

Recuerda: La calidad del código no es negociable. El código claro y mantenible permite un desarrollo rápido y una refactorización segura.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

Skills relacionados