Synaplan
기업을 위한 오픈소스 AI 플랫폼
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
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: taller-freelancer.vercel.app. 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.