Synaplan
Open-source AI platform for companies: self-hosted AI agents, GDPR-compliant chatbot widget, RAG knowledge base, WhatsApp and Outlook AI, MCP, multi-model routing. Docker, Kubernetes or hosted in Germ
Administra tus proyectos de cliente: stack, accesos, enlaces, pagos y vencimientos.
Translation pending
BusinessGitHub @yrvin-devOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Dashboard para que un freelancer administre sus proyectos de cliente en un solo lugar: stack, accesos, enlaces, pagos, vencimientos de dominio y hosting, y una bitácora por proyecto. Entras con Google y cada usuario ve solo sus datos.
En producción: tallerfreelance.com. Se entra con Google y cada cuenta empieza vacía.
| Proyectos (tema oscuro) | Ficha · Accesos |
|---|---|
| Mobile · inicio | Mobile · ficha |
|---|---|
| Capa | Herramienta | Por qué |
|---|---|---|
| Framework | Next.js 15 (App Router), React 19, TypeScript strict | Server Components y Server Actions: sin API aparte para una app detrás de login. |
| Datos y auth | Supabase: Postgres, Auth (Google OAuth) y Row Level Security | La autorización vive en la base: aunque falle el frontend, nadie lee datos ajenos. |
| Validación | Zod | Un mismo esquema valida el formulario y la Server Action. |
| Formularios | React Hook Form | |
| Estilos | Tailwind CSS 3.4 sobre CSS custom properties | Los tokens de diseño son la única fuente de color, radio y sombra. |
| Tests | Vitest + Testing Library, Playwright + axe, Lighthouse | Unitarios, integración contra la base real, e2e y accesibilidad. |
| CI/CD | GitHub Actions → Vercel | Previews por PR y producción en main. |
auth.uid(), y los tests de integración lo comprueban con dos usuarios: A no puede leer ni escribir lo de B. Con RLS, un update sobre una fila ajena no da error (afecta 0 filas), así que las acciones piden .select() y tratan "0 filas" como fallo. La service_role aparece en un solo módulo server-only, para borrar la cuenta, y el id del usuario sale de la sesión, nunca del navegador.CREDENTIALS_KEY con la que se cifró. pnpm rotate-key re-cifra todo con una clave nueva (con --dry-run para practicar). Las credenciales nunca van en el HTML inicial ni en el export JSON.{ ok, error }. Si la sesión venció, la UI abre un diálogo para volver a entrar en lugar de fallar en silencio.script-src solo acepta scripts con el nonce del pedido (sin unsafe-inline ni unsafe-eval). El tema se lee de una cookie en el servidor, así que no hace falta un script inline para evitar el parpadeo. Un e2e recorre todas las rutas y falla ante cualquier violación de CSP.tokens.css: lo bloquean una regla de ESLint y un grep en CI. Un test mide el contraste AA de cada par de texto en los dos temas.La CI corre todo en cada PR. Incluye levantar Supabase en el runner y comprobar que database.types.ts coincide con las migraciones.
Cambiar de pestaña en la ficha a veces no hacía nada, solo en producción. En pnpm dev no pasaba nunca y ningún test unitario lo podía ver. La causa: un loading.tsx por encima de una página que navega solo por searchParams deja ese segmento sin datos en Next 15.5, y una carrera entre dos respuestas dejaba la transición suspendida para siempre. Se encontró midiendo cada variante con muchas corridas contra el build, porque con un fallo del 50 % una pasada sola no prueba nada. Quedó fijado con un test que impide volver a introducirlo (tests/unit/loading-boundaries.test.ts).
Requisitos: Node 22, pnpm 12 y Docker (para la Supabase local).
pnpm install
pnpm db:start # Supabase en Docker: migraciones + datos de ejemplo
cp .env.example .env.local # completa con `pnpm supabase status`
# CREDENTIALS_KEY: openssl rand -base64 32
pnpm dev
Para entrar con Google en local, las credenciales de OAuth van en supabase/.env (SUPABASE_AUTH_EXTERNAL_GOOGLE_CLIENT_ID y ..._SECRET). Después, pnpm db:seed-me [email protected] copia los proyectos de ejemplo a tu cuenta.
| Comando | Qué hace |
|---|---|
pnpm lint · pnpm typecheck · pnpm test | Calidad y tests unitarios |
pnpm test:integration | Contra la Supabase local (RLS, acciones, cifrado) |
pnpm test:e2e | Compila un build propio (.next-e2e, puerto 3100) y corre Playwright |
pnpm a11y:lighthouse | Lighthouse (accesibilidad) en todas las rutas y los dos temas |
pnpm screenshots | Regenera las capturas de este README |
pnpm rotate-key | Re-cifra las credenciales con una clave nueva |
src/
app/(app)/ páginas privadas y sus Server Actions (actions.ts)
app/(auth)/ login con Google
components/ UI portada del diseño (ui/, layout/, projects/…)
lib/ dominio, esquemas Zod, formato, cifrado, cabeceras de seguridad
lib/data/ lecturas de datos (server-only)
styles/tokens.css única fuente de color, radio, sombra y espaciado
supabase/ migraciones, políticas RLS y seed
tests/ unit/, integration/, e2e/
docs/ requerimientos, design system, arquitectura y plan por tandas
El proyecto se construyó por tandas pequeñas y verificables (docs/04-plan.md). Lo aprendido en el camino está en la sección Gotchas de CLAUDE.md.
Código publicado como portafolio: se puede leer y revisar, pero todos los derechos están reservados. No se permite copiarlo ni reutilizarlo sin permiso del autor.