Skip to main content

personal-tracking-database

Patrón para construir sistemas de seguimiento personal con base de datos JSON estructurada + dashboard HTML interactivo + scripts de registro rápido. Reutilizable para dieta, finanzas, hábitos, productividad, etc.

Jump to install

Source facts

Repository
Ntizar/NtizarBrainMasterMind
Last source activity
June 26, 2026 at 12:05
Detected SKILL.md language
Spanish
Stars
2
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
4 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
personal-tracking-database
version
1.0.0
description
Patrón para construir sistemas de seguimiento personal con base de datos JSON estructurada + dashboard HTML interactivo + scripts de registro rápido. Reutilizable para dieta, finanzas, hábitos, productividad, etc.
tags
["tracking","database","json","dashboard","personal","patterns"]
# Personal Tracking Database — Patrón de sistema de seguimiento ## Cuándo usarlo El usuario quiere hacer seguimiento de algo personal (peso, dieta, finanzas, hábitos, deporte, sueño, etc.) y necesita: - Una base de datos estructurada (no un markdown plano) - Un dashboard visual para ver el progreso - Scripts para registrar rápido - Proyecciones o análisis ## Arquitectura estándar ``` /root/workspace/<proyecto>/ ├── data/ │ └── database.json ← Fuente de verdad única (JSON estructurado) ├── dashboard.html ← Dashboard interactivo (Aurora + Chart.js) ├── scripts/ │ ├── registrar-<tipo1>.sh ← Scripts de registro rápido │ └── registrar-<tipo2>.sh ├── README.md └── SEGUIMIENTO.md ← Vista legible (generada, no editable) ``` ## Principios 1. **JSON es la fuente de verdad** — nunca editar vistas generadas directamente 2. **Dashboard autocontenido** — un solo HTML que carga el JSON con fetch() 3. **Scripts de registro** — para cuando no hay dashboard abierto 4. **Aurora Design System** — para el dashboard (CDN, sin build) 5. **Chart.js** — para gráficos (vía CDN) 6. **Commit siempre** — cada cambio va a git ## Estructura JSON base ```json { "meta": { "nombre": "Nombre del usuario", "fecha_inicio": "YYYY-MM-DD", "objetivo": "descripción", "version": "1.0.0" }, "<entidad1>": [ {"fecha": "YYYY-MM-DD", ...campos específicos...} ], "<entidad2>": [...] } ``` ### Reglas de diseño del JSON - Arrays planos, no anidados (fáciles de filtrar con Array.filter) - Fechas siempre en formato `YYYY-MM-DD` - Sin valores null — usar 0 para numéricos, "" para strings - `meta` siempre presente con versión semver ## Dashboard HTML — Plantilla ### Stack técnico ```html <!-- Aurora CDN --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Ntizar/Ntizar-Aurora@latest/ntizar.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Ntizar/Ntizar-Aurora@latest/ntizar.next.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Ntizar/Ntizar-Aurora@latest/ntizar.data.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Ntizar/Ntizar-Aurora@latest/ntizar.ui.css"> <!-- Chart.js --> <script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script> <!-- Body --> <body class="nz" data-nz-theme="light" data-nz-skin="aurora"> ``` ### Secciones recomendadas 1. **KPIs principales** — valor actual, delta, objetivo (usar `.nz-kpi`, `.nz-stat-grid`) 2. **Gráfico de evolución** — línea temporal con Chart.js 3. **Desglose por categoría** — barras, donuts, según el dominio 4. **Proyecciones** — si aplica (3 ritmos: lento/medio/rápido) 5. **Timeline de eventos** — entrenamientos, hitos, etc. 6. **Resumen semanal** — tabla con métricas agregadas ### Patrón de carga de datos ```javascript fetch('data/database.json') .then(r => r.json()) .then(db => { renderDashboard(db); }) .catch(err => { document.getElementById('loading').innerHTML = '<div class="nz-alert nz-alert--danger">Error cargando datos</div>'; }); ``` ### Chart.js — Patrón seguro ```javascript // Destruir chart anterior antes de crear nuevo if (window.pesoChart) window.pesoChart.destroy(); window.pesoChart = new Chart(ctx, { ... }); ``` ## Scripts de registro — Patrón Cada script debe: 1. Recibir datos como argumentos o pedirlos interactivamente 2. Leer database.json 3. Añadir el nuevo registro 4. Escribir database.json 5. Hacer git add + commit ```bash #!/bin/bash # registrar-ejemplo.sh — Registro rápido de [entidad] # Uso: ./registrar-ejemplo.sh "2026-06-09" "valor" "notas" DB="/root/workspace/proyecto/data/database.json" TMP=$(mktemp) python3 -c " import json, sys with open('$DB') as f: db = json.load(f) db['entidad'].append({ 'fecha': sys.argv[1], 'valor': float(sys.argv[2]), 'notas': sys.argv[3] if len(sys.argv) > 3 else '' }) with open('$DB', 'w') as f: json.dump(db, f, ensure_ascii=False, indent=2) " "$@" cd /root/workspace/proyecto git add data/database.json git commit -m "Registro [entidad]: $(date +%Y-%m-%d)" ``` ## Deploy en NaN — Actualización automática Cuando el dashboard se deploya en NaN.builders, **cada push a GitHub triggera un redeploy automático** (polling cada 1-5 min). Esto permite actualizar datos sin tocar el dashboard: ### Flujo de actualización automática 1. **Actualizar `database.json`** con nuevos datos (por script, por chat, por API) 2. **`git add data/database.json && git commit -m "..."`** 3. **`git push origin main`** → NaN detecta cambio → reconstruye → redeploy 4. **Dashboard fresco** en `https://<app>-<owner>-<owner>.apps.nan.builders/` ### Dockerfile mínimo (Node.js + Express estático) ```dockerfile FROM node:20-alpine WORKDIR /app COPY package.json package-lock.json* ./ RUN npm install --production COPY . . EXPOSE 5050 CMD ["node", "server.js"] ``` ### server.js mínimo ```javascript const express = require('express'); const path = require('path'); const app = express(); const PORT = process.env.PORT || 5050; app.use(express.static(path.join(__dirname))); app.get('/', (req, res) => res.sendFile(path.join(__dirname, 'dashboard.html'))); app.listen(PORT, '0.0.0.0', () => console.log(`MastermindFit en puerto ${PORT}`)); ``` ### ⚠️ Pitfall: healthz endpoint El server.js **debe incluir un endpoint `/healthz`** para que el HEALTHCHECK del Dockerfile funcione: ```javascript app.get('/healthz', (req, res) => res.json({status: 'ok', uptime: process.uptime()})); ``` Sin él, NaN devuelve 404 en `/healthz` y el pod puede marcar el servicio como no saludable. ### Puerto - Usar `process.env.PORT || 5050` como default - El EXPOSE del Dockerfile debe coincidir con el puerto del espacio en NaN - Ver skill `esios-nan-deploy` para detalles completos de deploy ## Proyecciones — Framework genérico Cuando el sistema permite proyecciones (peso, ahorros, etc.): ### Técnica recomendada: regresión lineal (mínimos cuadrados) Para calcular el ritmo real a partir de datos temporales con fluctuaciones diarias: 1. **Filtrar solo registros consistentes** — ej. solo pesajes de mañana (elimina ruido intra-día) 2. **Usar regresión lineal en vez de primer-último** — un simple `(first - last) / días` amplifica el ruido. La regresión lineal usa TODOS los puntos intermedios y da una tendencia robusta 3. **Multiplicar pendiente × 7** para obtener kg/semana ### Fórmula (mínimos cuadrados) ```javascript function calcRitmoLineal(registros) { var datos = registros.filter(function(r){ return r.hora === 'mañana'; }); if(datos.length < 2) return 0; var n = datos.length, sumX = 0, sumY = 0, sumXY = 0, sumXX = 0; var ref = new Date(datos[0].fecha); datos.forEach(function(d){ var x = (new Date(d.fecha) - ref) / 86400000; sumX += x; sumY += d.peso_kg; sumXY += x*d.peso_kg; sumXX += x*x; }); var pendiente = (n*sumXY - sumX*sumY) / (n*sumXX - sumX*sumX) || 0; return Math.max(0, -pendiente * 7); // kg/semana } ``` ### Escenarios de proyección 1. **Real (regresión lineal)** — calculado automáticamente de los datos reales 2. **Sostenible** — ritmo conservador 3. **Normal** — ritmo moderado 4. **Acelerado** — ritmo óptimo 5. **Agresivo** — ritmo máximo (solo para déficit extremo) Siempre mostrar el real DESTACADO primero (morado/llamativo). Separar nítidamente los escenarios fijos del dato real. ### ⚠️ Pitfalls de proyecciones - **`slice(-7)` NO son los últimos 7 días** — son las últimas 7 ENTRADAS. Si los datos son irregulares (saltos de días), usar la regresión lineal que considera TODOS los puntos, no solo 7 - **Datos con dos tomas/día** — si pesas mañana y tarde, filtrar solo mañana para consistencia. La regresión con dos puntos el mismo día infla artificialmente el dataset - **Primera semana engaña** — los primeros días suelen tener mayor pérdida de agua. La regresión con más puntos suaviza este efecto - **Mostrar número de semanas Y fecha concreta** — el usuario necesita visualizar cuándo llega - **Poner el escenario real primero en la lista** — siempre debe ser el que ve nada más abrir ### Chart de proyecciones ```javascript // Destruir anterior if(charts.proyeccion) charts.proyeccion.destroy(); // Crear con datasets: real + 3-4 escenarios + línea objetivo charts.proyeccion = new Chart(ctx, { type:'line', data:{labels:labels, datasets:[ {label:'Real (regresión) X.XX kg/sem', data:dReal, borderColor:'#7c3aed', borderWidth:3, pointRadius:3, pointBackgroundColor:'#7c3aed'}, // ... escenarios fijos ... {label:'Objetivo', data:Array(labels.length).fill(objetivo), borderColor:'#22c55e', borderDash:[8,4], pointRadius:0, borderWidth:2} ]} }); ``` La línea real debe ser la única con puntos visibles y trazo más grueso — resalta visualmente frente a las teóricas. ## Pitfalls - **CORS en file://** — el dashboard necesita un servidor HTTP. Usar `python3 -m http.server` - **Chart.js acumula instancias** — siempre destruir antes de recrear - **JSON corrupto** — si el script de registro falla, el JSON puede quedar a medias. Usar escritura atómica (escribir a temp, luego renombrar) - **Fechas inconsistentes** — forzar siempre YYYY-MM-DD, nunca DD/MM/YYYY ni timestamps - **Git sin commit** — los scripts deben hacer commit automático, el usuario no se acuerda - **Dashboard muy grande** — si el JSON crece mucho (>1MB), considerar lazy loading o paginación en el dashboard ## Referencias - `references/dieta-dashboard-example.md` — Estructura real de database.json para MastermindFit (dieta+deporte+pasos) - `references/linear-regression-projection.js` — Implementación completa de proyecciones con regresión lineal (helper + tabla + chart real)
View on GitHub