Javis OS
Javis OS는 기업가를 돕는 에이전시 AI로, 업무를 지원하고 함께 성장합니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Aplicación web para la gestión de rutas, flotas, cotizaciones, finanzas y equipo de una operación logística. Incluye dashboards por rol (administrador, transportista, colaborador, vendedor, desarrollador), autenticación con Better Auth, permisos granulares por módulo y base de datos PostgreSQL. Dominio: www.jtplogistics.com (el dominio sin www redirige aquí)README 전문 보기 ↗
Aplicación web para la gestión de rutas, flotas, cotizaciones, finanzas y equipo de una operación logística. Incluye dashboards por rol (administrador, transportista, colaborador, vendedor, desarrollador), autenticación con Better Auth, permisos granulares por módulo y base de datos PostgreSQL.
Dominio: www.jtplogistics.com (el dominio sin www redirige aquí)
Calendar de shadcnLos roles se guardan en inglés en la BD: admin, carrier, collaborator, vendor, developer.
El administrador tiene acceso total. El colaborador no ve nada por defecto: el admin le enciende permisos módulo por módulo desde Colaboradores → editar, con cuatro niveles por módulo (leer, crear, editar, eliminar). Esos permisos viven como columnas booleanas en users (can_view_*, can_create_*, can_update_*, can_delete_*) y se aplican en dos capas:
requireCollaboratorPermission() en el layout.tsx del módulo (redirige si no tiene permiso).gateTasks, gateMural) que responde 403.El admin siempre pasa ambas capas sin necesidad de tener los flags encendidos.
Los mismos módulos que el admin, pero limitados a los permisos que el admin le encienda: rutas, cotizador, cotización marítima, tipos de unidad, mensajes, embarques, finanzas, clientes, proveedores, vendedores, colaboradores, laptops, celulares, correos, ideas, tareas, historial y mural.
Las contraseñas de laptops, celulares, cuentas de correo y las notas de contraseña de colaboradores no son credenciales de acceso a la plataforma: son datos que el administrador necesita poder consultar. Por eso se cifran de forma reversible (AES-256-GCM) en vez de guardarse con hash.
CREDENTIALS_ENCRYPTION_KEY, fuera de la base de datos: un volcado de la BD por sí solo no revela nada.hasPassword. El valor se pide de uno en uno a /api/credentials/<tipo>/<id> al pulsar el ojo.revealed.v1:<iv>:<tag>:<datos>. Los valores sin ese prefijo se tratan como texto plano heredado y se devuelven tal cual, para que la app funcione durante una migración.pnpm db:encrypt-credentials (simulación) y --apply para escribir. Es idempotente.Tablero interno visible solo para el personal de JTP (admin y colaboradores con canViewMural). Transportistas y vendedores quedan fuera.
users.birth_date y employee_profiles.hire_date. Si esas fechas están vacías, la persona no aparece.vercel.json) dispara /api/cron/mural-greetings todos los días a las 14:00 UTC (8:00 en Guadalajara). Felicita a quien cumple años o aniversario y avisa al equipo ese mismo día. No hay resumen diario ni semanal: cada entrada avisa sola al crearse, editarse o cancelarse. Protegido con CRON_SECRET.Para que RH administre el mural, el admin le enciende los cuatro permisos de Mural; al resto del equipo le basta con leer.
jtplogistics/
├── prisma/
│ ├── schema.prisma # Modelos (users, routes, shipments, mural_*, etc.)
│ ├── seed.ts # Datos de prueba (usuarios, rutas, activos)
│ └── migrations/ # SQL versionado (se escribe a mano, ver más abajo)
├── src/
│ ├── app/
│ │ ├── (auth)/ # login, register, forgot-password, reset-password
│ │ ├── admin/dashboard/
│ │ ├── carrier/dashboard/
│ │ ├── collaborator/dashboard/
│ │ ├── vendor/dashboard/
│ │ ├── developer/dashboard/
│ │ └── api/ # auth, admin, collaborator, carrier, vendor, mural, cron
│ ├── components/
│ │ ├── ui/ # shadcn + componentes base (DataTable, DatePicker, Lexical)
│ │ └── dashboard/ # componentes por módulo
│ ├── hooks/
│ ├── lib/ # auth, db, validators, utils, config, data, correos
│ └── types/
├── public/
├── docs/
│ ├── conventions.md # Convenciones de BD y datos
│ └── reporte-ciberseguridad.html # Controles de seguridad (imprimible a PDF)
├── instrumentation.ts # Normalización de BETTER_AUTH_URL al arranque
├── vercel.json # Cron del resumen diario del mural
└── next.config.ts
La interfaz y los textos visibles están en español; el código (rutas, variables, comentarios) en inglés.
Crear .env en la raíz (no se commitea). Ejemplo:
# Base de datos
DATABASE_URL="postgresql://..."
# Better Auth (en producción usar el dominio final CON www)
BETTER_AUTH_SECRET="..." # mínimo 32 caracteres (openssl rand -base64 32)
BETTER_AUTH_URL="http://localhost:3000"
# Opcional: orígenes adicionales (CSRF)
# BETTER_AUTH_TRUSTED_ORIGINS=https://www.jtplogistics.com
# Cloudinary
CLOUDINARY_CLOUD_NAME="..."
CLOUDINARY_API_KEY="..."
CLOUDINARY_API_SECRET="..."
# Resend. Sin RESEND_API_KEY los correos solo se imprimen en consola (útil en dev).
RESEND_API_KEY="..."
EMAIL_FROM="JTP Logistics <[email protected]>"
# URL pública usada en los enlaces y el logo de los correos.
# Sin ella los correos salen sin logo ni botón (no se rompen, usan un respaldo).
NEXT_PUBLIC_APP_URL="http://localhost:3000"
# Secreto del cron del resumen diario del mural. Vercel lo manda como
# "Authorization: Bearer <valor>". Si está vacío, el endpoint no exige credencial
# (cómodo en local, nunca en producción).
CRON_SECRET=""
# Llave del almacén de credenciales de activos (contraseñas de laptops,
# celulares, cuentas de correo y notas de colaborador). Generar con:
# openssl rand -base64 32
CREDENTIALS_ENCRYPTION_KEY=""
Notas:
VERCEL_URL se rellena automáticamente y se usa para trustedOrigins si hace falta.NEXT_PUBLIC_APP_URL se incrusta en el bundle durante el build: al cambiarla hay que redesplegar para que surta efecto.CREDENTIALS_ENCRYPTION_KEY no se puede perder. Sin ella, las contraseñas de activos guardadas quedan irrecuperables. Debe existir una copia fuera de Vercel (gestor de contraseñas o resguardo físico).# Instalar dependencias (también corre prisma generate)
pnpm install
# Aplicar migraciones
pnpm db:migrate:deploy
# (Opcional) Poblar datos de prueba
pnpm db:seed
# (Opcional) Sembrar configuración de portada/branding
pnpm db:seed-settings
# (Opcional) Crear cuenta demo transportista
pnpm db:create-demo-carrier
# Desarrollo
pnpm dev
Abrir http://localhost:3000. Para entrar con datos de prueba, ver el mensaje al final de pnpm db:seed (correos y contraseñas por rol).
pnpm db:migrate(prisma migrate dev) está roto en este proyecto: falla al crear la shadow database en Neon.
El flujo que sí funciona:
prisma/schema.prisma.prisma/migrations/<AAAAMMDDHHMMSS>_<nombre>/migration.sql con el SQL correspondiente.pnpm db:migrate:deploy.pnpm db:generate.Ojo: db:migrate:deploy aplica contra la base de datos de DATABASE_URL, que es la BD real compartida. Revisar el SQL antes de correrlo.
| Comando | Descripción |
|---|---|
pnpm dev | Servidor de desarrollo |
pnpm build | Build de producción |
pnpm start | Servidor de producción |
pnpm lint | ESLint |
pnpm test | Pruebas con Vitest |
pnpm test:watch | Pruebas en modo watch |
pnpm db:generate | Generar Prisma Client |
pnpm db:migrate | Migraciones en desarrollo (roto, ver arriba) |
pnpm db:migrate:deploy | Aplicar migraciones |
pnpm db:seed | Ejecutar seed |
pnpm db:seed-settings | Seed de ajustes/configuración |
pnpm db:create-demo-carrier | Crear cuenta demo transportista |
pnpm db:encrypt-credentials | Cifrar credenciales de activos que sigan en claro |
pnpm db:assign-route-creator | Asignar creador a rutas existentes |
pnpm db:sync-route-destination-states | Sincronizar estados destino de rutas |
pnpm db:studio | Abrir Prisma Studio |
pnpm test corre Vitest sobre la lógica pura (sin BD ni red): coincidencia de embarques y finanzas, búsqueda, fechas de cumpleaños y aniversarios, y armado de los correos de felicitación.
Los módulos con lógica que valga la pena probar se separan de los que tocan Prisma —por ejemplo mural-celebrations.ts (puro) frente a mural-celebrations-query.ts (BD)— porque importar @/lib/db en una prueba falla si no hay DATABASE_URL.
CI (.github/workflows/ci.yml) corre en cada push y PR: typecheck, lint, test y build.
skipDuplicates), pero reinicia otras entidades de prueba.EMAIL_FROM.DATABASE_URL, BETTER_AUTH_SECRET, BETTER_AUTH_URL, NEXT_PUBLIC_APP_URL (con la URL final, https://www.jtplogistics.com) y CRON_SECRET.pnpm build; si BETTER_AUTH_URL no trae protocolo, se normaliza a https:// al arrancar.vercel.json queda registrado solo, sin configuración extra en el panel.Reglas de base de datos, nombres y validaciones: docs/conventions.md.
En resumen: tablas y columnas en snake_case, código en camelCase, correos y slugs normalizados a minúsculas, y los roles guardados en inglés.
Proyecto privado.