Aplicación web para crear formularios personalizados con drag & drop, compartirlos mediante link público y visualizar las respuestas con gráficas y estadísticas.
- Frontend: React + TypeScript + Next.js 16 (App Router)
- Backend: Server Actions de Next.js + Arquitectura Hexagonal
- BaaS: Supabase (PostgreSQL, Auth)
- UI: shadcn/ui + Tailwind CSS
- Drag & Drop: @dnd-kit
- Gráficas: Recharts
- Testing: Jest (unit) + Playwright (E2E)
- Deployment: Vercel
- Node.js >= 18
- npm >= 9
- Cuenta de Supabase (capa gratuita)
git clone https://github.com/carloscuatin/form-craft.git
cd form-craftnpm install- Crea un proyecto en Supabase
- Ve a SQL Editor y ejecuta el contenido de
supabase/migrations/20260208033356_initial_schema.sql - Copia las credenciales de tu proyecto (Settings → API)
Crea un archivo .env.local en la raíz del proyecto:
NEXT_PUBLIC_SUPABASE_URL=https://tu-proyecto.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=tu-publishable-keyLa lógica de redirección (proteger /dashboard y /builder, redirigir a login si no hay sesión) está en src/proxy.ts. Para que Next.js la ejecute, crea en la raíz del proyecto un archivo middleware.ts con:
export { proxy as default } from '@/proxy';Si no creas este archivo, las rutas no se redirigen por middleware (las Server Actions seguirán comprobando auth con requireAuth() y mostrarán error en dashboard si no hay sesión). Detalle en DECISIONS.md §15.
npm run devAbre http://localhost:3000 en tu navegador.
npm run test # ejecutar tests
npm run test:watch # modo watch
npm run test:coverage # coberturaLos tests unitarios viven en __tests__/ dentro de cada slice o módulo (p. ej. components/auth/__tests__/, core/use-cases/__tests__/).
npm run test:e2e # ejecutar tests E2E (Chromium, Firefox, WebKit)
npm run test:e2e:ui # interfaz gráfica de PlaywrightLos tests E2E están en tests/e2e/. Playwright arranca el servidor de desarrollo (npm run dev) si no está ya en marcha.
Tests que requieren login: Algunos tests del dashboard (flujo tras iniciar sesión) solo se ejecutan si defines las variables de entorno E2E_TEST_EMAIL y E2E_TEST_PASSWORD. Si no están definidas, esos tests se omiten.
E2E_TEST_EMAIL=tu@email.com E2E_TEST_PASSWORD=tupassword npm run test:e2eLa primera vez, instala los navegadores de Playwright:
npx playwright installLa decisión de usar Jest + Playwright y la estructura de tests E2E se documenta en DECISIONS.md §10.
src/
├── app/ # Next.js App Router
│ ├── actions/ # Server Actions (orquestación)
│ ├── builder/ # Editor de formularios
│ ├── dashboard/ # Dashboard + detalle de respuestas
│ ├── forms/[id]/ # Formulario público
│ ├── login/ # Página de login
│ └── register/ # Página de registro
│
├── core/ # 🏛️ Arquitectura Hexagonal
│ ├── domain/
│ │ ├── entities/ # Form, Response, User
│ │ ├── ports/ # Interfaces de repositorios
│ │ └── value-objects/ # FieldType, constantes
│ └── use-cases/ # Casos de uso del negocio
│
├── infrastructure/ # 🔌 Adapters
│ ├── adapters/supabase/ # Implementación Supabase
│ └── mappers/ # Transformación Domain ↔ DB
│
├── components/ # 🎨 Vertical slicing (por feature)
│ ├── auth/ # Slice: login/registro
│ ├── builder/ # Slice: editor (layout, fields, preview, hooks)
│ ├── dashboard/ # Slice: listado, detalle, gráficas
│ ├── forms/ # Slice: formulario público y renderer
│ ├── theme/ # Slice: ThemeProvider, ThemeToggle
│ └── ui/ # Primitivos shadcn (sin slice; import por archivo)
│
├── utils/ # Utilidades (chart, cn, etc.)
└── proxy.ts # Middleware de auth (protección de rutas)
tests/
└── e2e/ # Tests E2E con Playwright
├── home.spec.ts # Home, navegación, tema
└── dashboard.spec.ts # Dashboard (auth, empty state, builder)
El frontend usa vertical slicing (arquitectura por features): cada slice (auth, dashboard, forms, builder, theme) es una unidad vertical autocontenida con su propio index.ts (API pública) y, opcionalmente, subcarpetas por responsabilidad. La app importa desde el barrel del slice, no por archivo. Detalle en DECISIONS.md §3.
| Regla | Descripción |
|---|---|
| API por slice | import { AuthForm } from '@/components/auth', import { FormBuilder } from '@/components/builder', etc. |
| ui/ | Sin index; imports directos: @/components/ui/button, @/components/ui/card (patrón shadcn). |
| Subcarpetas | Si un slice crece (ej. builder), se agrupa en layout/, fields/, preview/, hooks/, cada uno con su index.ts. |
| Schemas y contexto | Pertenecen al slice: auth-form-schema.ts, form-builder-context.tsx, form-builder-schema.ts. |
| Hooks | No hay components/hooks global. Cada slice lleva sus hooks dentro (ej. builder/hooks/). Hooks de utilidad reutilizables irían en src/hooks/ si se necesitan. |
| Naming | Archivos en kebab-case; componentes/hooks en PascalCase/camelCase. |
| Tests | __tests__/ dentro del slice; imports relativos a archivos. |
- ✅ Autenticación (login/registro) con Supabase Auth
- ✅ Protección de rutas (lógica en
src/proxy.ts; ver DECISIONS.md §15 para activarla conmiddleware.ts) - ✅ Form Builder con drag & drop
- ✅ 6 tipos de campo: texto corto, texto largo, número, fecha, selección única, selección múltiple
- ✅ Vista previa en tiempo real
- ✅ Formularios públicos con URL única
- ✅ Validación client-side y server-side
- ✅ Dashboard con listado y contador de respuestas
- ✅ Tabla de respuestas
- ✅ Gráficas (pie chart y barras) para campos de selección
- ✅ Copiar link público al portapapeles
- ✅ RLS en PostgreSQL
- ✅ Diseño responsive (desktop y mobile)
- ✅ Arquitectura Hexagonal (Clean Architecture) en backend
- ✅ Arquitectura por componentes, estructura en vertical slicing (por features) en frontend
- ✅ TypeScript estricto
- ✅ Separación de responsabilidades
El esquema SQL con RLS se encuentra en:
supabase/migrations/20260208033356_initial_schema.sql
Ver DECISIONS.md para el por qué de las decisiones de arquitectura, librerías y trade-offs. Incluye, entre otros:
- §1–2 Arquitectura hexagonal y esquema JSONB
- §3 Vertical slicing en el frontend
- §4 Librerías (shadcn, Recharts, next-themes, Zod, etc.)
- §5–6 Auth bajo hexagonal y RLS (respuestas anónimas)
- §10 Testing (Jest + Playwright)
- §12–14 Composition root, clientes Supabase, Realtime
- §15 Middleware de protección de rutas
- §16 Husky, lint-staged, Prettier, ESLint
Puedes registrarte con cualquier email y contraseña (mínimo 6 caracteres) o usar las credenciales de prueba:
- Email: test@formcraft.com
- Password: formcraft123
El proyecto está desplegado en Vercel:
MIT