Build or update the BlueBubbles external channel plugin for Moltbot (extension package, REST...
npx skills add TrenzaCR/trenzaos-config --skill "trenza-api"
Install specific skill from multi-skill repository
# Description
>
# SKILL.md
name: trenza-api
description: >
Estándares de API y Server Actions para TrenzaOS.
Trigger: Al crear Server Actions, API Routes, o integrar con el frontend.
license: MIT
metadata:
author: trenza
version: "1.0"
TrenzaOS API Skills
Purpose
Este skill enforce los estándares de API de TrenzaOS.
Core Rules
1. Server Actions (Patrón Principal)
Estructura obligatoria:
'use server'
import { z } from 'zod'
import { auth } from '@/lib/auth'
import { ActionResponse } from '@/lib/types'
// Schema de validación (OBLIGATORIO)
const CreateInvoiceSchema = z.object({
customerId: z.string().uuid(),
items: z.array(z.object({
productId: z.string().uuid(),
quantity: z.number().int().positive()
}))
})
export async function createInvoice(
prevState: ActionResponse | null,
formData: FormData
): Promise<ActionResponse> {
try {
// 1. Autenticación
const session = await auth()
if (!session?.user) {
return { status: 'error', error_code: 'UNAUTHORIZED' }
}
// 2. Validación
const rawData = Object.fromEntries(formData)
const parsed = CreateInvoiceSchema.safeParse(rawData)
if (!parsed.success) {
return {
status: 'error',
error_code: 'VALIDATION_ERROR',
errors: parsed.error.flatten().fieldErrors
}
}
// 3. Resolución de tenant (NUNCA del cliente)
const tenantId = await getTenantFromSession(session)
// 4. Lógica de negocio
const invoice = await createInvoiceLogic(tenantId, parsed.data)
return { status: 'success', data: { invoiceId: invoice.id } }
} catch (error) {
console.error('createInvoice error:', error)
return { status: 'error', error_code: 'INTERNAL_ERROR' }
}
}
2. Contrato de Respuesta
type ActionResponse<T = unknown> = {
status: 'success' | 'error'
data?: T
message?: string
errors?: Record<string, string[]>
error_code?: string
}
3. Validación con Zod
SIEMPRE validar en el server:
// Schema centralizado
// lib/schemas/invoices.ts
export const InvoiceItemSchema = z.object({
productId: z.string().uuid('ID de producto inválido'),
quantity: z.number().int().min(1, 'Mínimo 1 unidad')
})
// Validar
const result = schema.safeParse(data)
if (!result.success) {
throw new ValidationError(result.error.flatten())
}
4. Rate Limiting
Límites obligatorios:
const RATE_LIMITS = {
login: { limit: 5, window: '15m' },
create: { limit: 30, '1m' },
api: { limit: 100, '1m' }
}
5. Client-Side Integration
'use client'
import { useActionState } from 'react'
import { createInvoice } from '@/actions/invoices'
export function InvoiceForm() {
const [state, formAction, isPending] = useActionState(createInvoice, null)
return (
<form action={formData}>
{/* ... campos ... */}
<button type="submit" disabled={isPending}>
{isPending ? 'Creando...' : 'Crear'}
</button>
</form>
)
}
6. Error Handling
// ❌ NUNCA hacer esto
catch (error) {
return { error: error.message } // Expone detalles internos
}
// ✅ HACER esto
catch (error) {
console.error('Operation failed:', error)
return {
status: 'error',
error_code: 'INTERNAL_ERROR',
message: 'Ha ocurrido un error interno'
}
}
API Checklist
Antes de crear una Server Action:
- [ ] ¿Tiene schema de Zod?
- [ ] ¿Valida autenticación?
- [ ] ¿Resuelve tenant desde la sesión?
- [ ] ¿Usa ActionResponse correctamente?
- [ ] ¿Tiene rate limiting?
- [ ] ¿Maneja errores correctamente?
References
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.