Código base full-stack para control de asistencia, ubicación GPS y evidencias fotográficas en obra.
- Frontend: React (Hooks) + PWA (Service Worker + Manifest)
- Backend: Node.js + Express
- DB: MongoDB + Mongoose
- Evidencias: Google Drive API v3 (Service Account)
server/: API REST, autenticación JWT, modelos Mongoose, lógica de negocio.client/: App React PWA para móviles y escritorio.
- Crear proyecto en Google Cloud.
- Habilitar Google Drive API en
APIs & Services > Library. - Crear una Service Account en
IAM & Admin > Service Accounts. - En la Service Account, generar clave tipo JSON y descargar archivo.
- Compartir la carpeta de Drive destino con el correo de la Service Account (permiso Editor).
- Copiar el
Folder IDde Drive enGOOGLE_DRIVE_FOLDER_ID.
- Opción A: usar archivo JSON con
GOOGLE_SERVICE_ACCOUNT_KEY_PATH. - Opción B: usar JSON inline con
GOOGLE_SERVICE_ACCOUNT_JSON.
Implementación principal:
- Servicio:
server/src/services/googleDriveService.js - Función:
uploadToDrive(imageBuffer, { fileName, mimeType, folderId }) - Retorna:
{ fileId, webViewLink, webContentLink }
User(server/src/models/User.js)employeeId,name,role(OBRERO/SUPERVISOR),passwordHash.
WorkSession(server/src/models/WorkSession.js)workerId,startTime,endTime,durationMinutes,checkInLocationycheckOutLocationen formato GeoJSON (Point),activityPhotoFileIdspara referencias de evidencia por sesión.
Task(server/src/models/Task.js)workerId,workSessionId,description,status,googleDriveFileIds.
- Middleware:
server/src/middleware/authMiddleware.js - Header requerido:
Authorization: Bearer <token>
POST /api/auth/registerPOST /api/auth/loginPOST /api/attendance/check-inPOST /api/attendance/check-outGET /api/attendance/currentPOST /api/activities/upload-activity-photo(conmulter.memoryStorage)GET /api/metrics/hours?workerId=<id>(solo supervisor)POST /api/tasksGET /api/tasks/mePATCH /api/tasks/:id/status
- Check-out calcula automáticamente
durationMinutes. - Upload de foto:
- recibe
photo(multipart/form-data), - sube a Drive con
uploadToDrive, - guarda
fileIdenTask.googleDriveFileIdsoWorkSession.activityPhotoFileIds.
- recibe
- Métricas por agregación MongoDB:
- semanal (
$dateTruncpor semana), - mensual (
$dateTruncpor mes), - suma total de minutos/horas por empleado.
- semanal (
- Middleware global:
server/src/middleware/errorHandler.js - Logging:
server/src/utils/logger.js - Si Drive falla: responde mensaje amigable y log estructurado.
AttendanceAction(client/src/components/AttendanceAction.jsx)- Botones táctiles grandes para Check-in/Check-out.
- Captura ubicación con
navigator.geolocation.
CaptureEvidence(client/src/components/CaptureEvidence.jsx)- Usa
<input type="file" accept="image/*" capture="environment" />. - Sube evidencia al backend vía
FormData.
- Usa
- Login con ID de empleado y PIN.
- Dashboard con estado de jornada activa.
- Check-in/out con GPS.
- Captura y envío de foto de hallazgo.
Archivo: client/public/manifest.json
Campos clave configurados:
name/short_namedisplay: "standalone"start_url,scopetheme_color,background_coloricons(192 y 512)
Archivo: client/public/service-worker.js
- Cache del shell principal.
- Fallback offline para UI.
- Exclusión de llamadas API para no cachear respuestas dinámicas.
En frontend se registra en:
client/src/utils/registerServiceWorker.js- invocado desde
client/src/main.jsx.
Usar como base server/.env.example.
Variables mínimas:
PORTMONGO_URIJWT_SECRETGOOGLE_DRIVE_FOLDER_ID- (
GOOGLE_SERVICE_ACCOUNT_KEY_PATHoGOOGLE_SERVICE_ACCOUNT_JSON)
Usar como base client/.env.example.
VITE_API_BASE_URL=http://localhost:5000/api
cd server
npm install
npm run devcd client
npm install
npm run dev- Diseño modular por responsabilidad (config, servicios, controladores, rutas, middleware).
- Principios SOLID aplicados en separación de capas.
- Preparado para evolucionar a colas de procesamiento, auditoría y notificaciones sin romper contratos actuales.