Ptime es una aplicación robusta para el registro y gestión de horas trabajadas y facturación, utilizando Google Sheets como base de datos en tiempo real (BaaS). Optimizado para despliegues rápidos y sin fricción, aprovecha el ecosistema de Vercel y Google Workspace.
- Persistencia Cross-Device y Workspaces Compartidos: El Sheet ID del usuario ahora persiste automáticamente vía JWT, eliminando la necesidad de reconfiguración. Los workspaces se pueden compartir, permitiendo a los propietarios invitar colaboradores o espectadores con roles definidos (
OWNER,COLABORADOR,VIEWER). La auto-configuración de Workspaces simplifica el onboarding de nuevos miembros. - Google Sheets como DB: Utiliza una hoja de cálculo como backend, permitiendo a los administradores editar datos directamente o visualizar reportes crudos sin salir de Google.
- Autenticación Segura: NextAuth.js integrado con Google OAuth 2.0 y control de acceso basado en roles (RBAC) para proteger zonas administrativas. Soporte para JWTs Edge-compatible.
- Experiencia de Usuario Moderna: Componentes Shadcn/UI reescritos y optimizados para Tailwind CSS v3 (Combobox, Popover, Card, Button, etc.). Diseño completamente migrado a tokens semánticos, ofreciendo un Dark/Light Mode unificado, instantáneo y consistente en toda la aplicación. Nuevos efectos "glass" y animaciones "slide-up" mejoran la interfaz.
- Tarifas y Facturación Escalonada: Algoritmo mensual por usuario: primeras 20h a precio base, fracciones del tramo base redondeadas a 0.5h y tramo alto redondeado a hora completa. Se guardan horas trabajadas y horas facturables por separado.
- Mis Horas con Cierre Mensual: Vista por último mes, mes anterior o todo. Totales de horas trabajadas, horas facturables, monto USD, conversión manual ARS/USD, cotización BNA oficial y acción segura para marcar un mes como
facturado. - Módulo BI / Reportes: Dashboard completo y exportación PDF con branding TuCloud, fechas DD-MM-AA, layouts optimizados y gráficos interactivos (
react-pdfy Recharts). - Gestión Administrativa Completa: CRUD de Clientes, Proyectos, Tareas, Configuraciones y Usuarios. Los clientes pueden compartir email si el negocio lo requiere; la identidad real sigue siendo el
iddel cliente. - Server Actions con Seguridad Mejorada: Configuración de
allowedOriginsparaptime.tucloud.proy*.ptime.tucloud.pro, garantizando el correcto funcionamiento en producción. - Modo Local sin OAuth: Para desarrollo se puede entrar en localhost sin OAuth con
LOCAL_DEV_ACCESS=true; este bypass queda bloqueado en producción. - Suite de Tests: Vitest cubre pricing, horas, serialización, BNA, acciones y helpers críticos.
- Next.js 14 (App Router)
- React 18
- Tailwind CSS v3
- Shadcn/UI (Radix Primitives)
- NextAuth.js v5 (beta)
- Google APIs Node.js Client
- Zod
- React Hook Form
- Node.js >= 20
- npm o yarn
- Una cuenta en Google Cloud Console para habilitar la API de Sheets y obtener las credenciales de OAuth.
- Clona este repositorio.
- Instala las dependencias:
npm install
- Crea un archivo
.envbasado en.env.example:cp .env.example .env
- Configura las variables en
.env:GOOGLE_CLIENT_IDyGOOGLE_CLIENT_SECRET: Obtenidos de tu proyecto en GCP.AUTH_SECRET(oNEXTAUTH_SECRET): Genera uno conopenssl rand -base64 32.AUTH_URL(oNEXTAUTH_URL):http://localhost:3000en desarrollo local.MASTER_SHEET_ID: El ID de tu hoja maestra de Google Sheets (donde se gestionan los usuarios y workspaces).
npm run devLa aplicación estará corriendo en http://localhost:3000.
Para probar en localhost sin depender del callback OAuth de Google:
LOCAL_DEV_ACCESS=true npm run devReglas de seguridad:
- Solo funciona con
NODE_ENV !== "production". - Solo funciona en
localhosto127.0.0.1. - Aunque la variable exista en Vercel/producción, el acceso local queda bloqueado.
npm run test:run
npx tsc --noEmit
npm run lint
npm run buildnpm run test:run usa Vitest en modo no-watch.
Ptime calcula costos por usuario y por mes:
- Primeras 20h mensuales: precio base del proyecto/configuración.
- Después de 20h mensuales: precio alto.
- En tramo base, cualquier fracción menor a 0.5h se redondea a 0.5h.
- En tramo alto, cualquier fracción se redondea a la siguiente hora completa.
horas_trabajadasconserva lo cargado por el usuario.horas_a_cobrarconserva lo facturable después del redondeo.
Ejemplos:
| Acumulado mensual | Nueva carga | Tramo | Horas facturables |
|---|---|---|---|
| 0h | 0.1h | Base | 0.5h |
| 0h | 0.5h | Base | 0.5h |
| 19.5h | 0.5h | Base | 0.5h |
| 20h | 0.5h | Alto | 1h |
| 20h | 2.5h | Alto | 3h |
En Mis Horas, la vista default muestra el último mes con registros. También hay filtro de mes anterior y ver todo. La acción “Marcar mes como facturado” solo opera sobre el mes seleccionado y no toca registros rechazados ni ya facturados.
El proyecto está preparado para desplegarse fácilmente en Vercel.
Asegúrate de:
- Importar el repositorio en Vercel.
- Configurar las variables de entorno de producción (incluyendo
MASTER_SHEET_ID). - Actualizar la URI de redirección autorizada en Google Cloud Console con el dominio de tu Vercel (ej:
https://tu-proyecto.vercel.app/api/auth/callback/googleohttps://ptime.tucloud.pro/api/auth/callback/googlesi usas el dominio oficial). - Configurar variables de Auth en Vercel para producción:
AUTH_SECRET(recomendado) y opcionalmenteNEXTAUTH_SECRETpor compatibilidad.AUTH_URL(oNEXTAUTH_URL) exactamente con el dominio productivo canónico (https://ptime.tucloud.pro).GOOGLE_CLIENT_IDyGOOGLE_CLIENT_SECRETen el environment Production.
- Asegurarte que los
allowedOriginsennext.config.mjsincluyan tu dominio de producción para Server Actions.
Para más detalles, revisa el CHANGELOG.md.
Propiedad intelectual y desarrollo bajo TuCloud.pro.
Esta es la organización principal de los directorios de Ptime (Next.js 14 App Router):
.
├── app/ # Rutas y páginas de Next.js (App Router)
│ ├── (auth)/ # Rutas de autenticación (login)
│ ├── (dashboard)/ # Vistas protegidas (panel, horas, reportes, admin)
│ ├── actions/ # Server Actions para mutaciones (CRUD)
│ └── api/ # Endpoints API (health, auth, bna-dolar)
├── components/ # Componentes de React (Shadcn/UI reescritos)
│ ├── admin/ # Componentes específicos de administración
│ ├── charts/ # Gráficos con Recharts
│ ├── forms/ # Formularios con react-hook-form + Zod
│ ├── layout/ # Sidebar, Topbar, Shell (migrados a tokens semánticos)
│ ├── pdf/ # Plantillas para exportación PDF (react-pdf)
│ └── shared/ # Componentes reutilizables (DataTables, Botones)
├── hooks/ # Custom hooks (e.g. usePricingPreview)
├── lib/ # Lógica de negocio y utilidades
│ ├── actions/ # Helpers comunes para Server Actions
│ ├── env/ # Modo local sin OAuth y guards de entorno
│ ├── hours/ # Save-flow, accounting, mensualización y moneda
│ ├── pricing/ # Algoritmo de cálculo de precios y unit tests
│ ├── schemas/ # Esquemas de validación Zod
│ ├── sheets/ # Cliente, queries, mutations y serializers Google Sheets
│ └── utils/ # Utilidades generales y formateo
├── public/ # Archivos estáticos y logos (e.g., logo_tucloud_white.png)
├── types/ # Definiciones de TypeScript e interfaces
├── auth.ts # Configuración de NextAuth.js (integración con MASTER_SHEET_ID)
└── middleware.ts # Middleware para protección de rutas y control de RBAC (usa JWT para sheetId)