🧰 CodePanel
Espacio de trabajo para programadores: proyectos, ideas, clientes, tiempo y rentabilidad en una sola interfaz
Escala del Proyecto
Descripción General
Cuando trabajas en varios proyectos a la vez, la información se dispersa: las ideas en un bloc, los presupuestos en un Excel, los dominios y servidores en la memoria, y las horas invertidas en ningún sitio. El resultado es que no sabes qué proyecto te está dando dinero y cuál te lo está quitando.
CodePanel reúne todo eso: proyectos personales y comerciales, banco de ideas, bitácora de decisiones técnicas, presupuestos y cobros, entregas y versiones, inventario de infraestructura con sus renovaciones, clientes y leads, tareas, recordatorios y control de tiempo con cronómetro.
La pieza que justifica el proyecto es el cálculo de rentabilidad: cruza los ingresos registrados, el tiempo dedicado según el coste por hora configurado y los costes de infraestructura asociados, y lo hace separando por moneda, porque sumar euros y pesos en el mismo total es una forma elegante de mentirse.
Tecnologías Utilizadas
PHP 8.1+
MySQL 8
PDO
JavaScript
API JSON
CSRF
Adjuntos validados
Módulos del Espacio de Trabajo
Resumen de actividad y próximos vencimientos, con widgets que el usuario elige y ordena.
Personales o comerciales, con estado de avance. Un proyecto personal no arrastra cliente ni fecha objetivo.
Registro de futuros productos y experimentos antes de que se olviden.
Decisiones técnicas y aprendizajes vinculados a cada proyecto.
Presupuesto emitido, pagos recibidos y saldo pendiente.
Publicaciones y releases por proyecto.
Inventario de dominios, servidores y servicios con su coste y fecha de renovación.
Directorio de clientes actuales y oportunidades comerciales.
Trabajo diario vinculado a proyectos.
Centro de avisos con prioridad, estado, fecha y proyecto relacionado.
Registro manual o con cronómetro, asociado a proyecto y tarea. Un solo cronómetro activo por usuario.
Ingresos menos tiempo y coste de infraestructura, por proyecto y separado por moneda.
Tareas, recordatorios, entregas, renovaciones y vencimientos en una sola vista.
Logros, bloqueos, foco de la semana siguiente y valoración.
Documentación con descarga autenticada, cuota por usuario y validación del tipo real de fichero.
Etiquetas reutilizables para clasificar cualquier módulo.
Moneda, formato de fecha, zona horaria, tema, inicio de semana, coste por hora y avisos.
Arquitectura
La interfaz es HTML y JavaScript que consume una API JSON propia
bajo /api/index.php. Catorce recursos siguen el mismo contrato REST, y
las rutas especializadas cubren lo que no encaja en un CRUD: cronómetro, calendario
combinado, rentabilidad y adjuntos.
No hay proceso de compilación, ni Composer, ni npm. Es una decisión de diseño: la aplicación tiene que poder subirse por FTP a un hosting compartido y funcionar.
CodePanel/ ├── index.php # interfaz ├── .env.php # config; empieza por <?php exit; ?> ├── .htaccess # bloquea app/, database/ y storage/ ├── api/ # index.php + wrappers por recurso ├── app/ # lógica de negocio (no accesible por web) ├── database/ │ ├── schema.sql # instalador inicial │ └── migrations/ # 3 migraciones no destructivas ├── storage/uploads/ # adjuntos, nunca públicos ├── assets/ ├── scripts/ # verify.sh └── tests/ # smoke.sh
Base de Datos
17 tablas en schema.sql. El instalador es
deliberadamente destructivo — borra antes de crear — y para actualizar una instancia
con datos existen tres migraciones no destructivas que deben aplicarse en orden.
| Tabla | Contenido |
|---|---|
| users | Cuentas con sesión por cookie |
| projects | Proyectos con project_type personal o comercial |
| ideas | Banco de ideas |
| devlogs | Bitácora de desarrollo por proyecto |
| clients | Directorio de clientes |
| leads | Oportunidades comerciales |
| tasks | Tareas del día a día |
| budgets | Presupuestos emitidos |
| payments | Cobros y saldo pendiente |
| releases | Entregas y versiones publicadas |
| resources | Inventario de infraestructura con coste y renovación |
| reminders | Recordatorios con prioridad, estado y fecha |
| time_entries | Registros de tiempo, manuales o por cronómetro |
| weekly_reviews | Revisiones semanales |
| tags | Etiquetas globales reutilizables |
| attachments | Adjuntos con su entidad asociada y tipo verificado |
| settings | Preferencias y widgets del dashboard por usuario |
Rutas Especializadas de la API
POST /time_entries/timer/start— inicia un cronómetro; solo uno activo por usuario.POST /time_entries/{id}/stop— lo detiene y calcula la duración.GET /calendar?from=&to=— agenda combinada para un intervalo de hasta 366 días.GET /profitability— rentabilidad por proyecto, con importes agrupados por moneda.GET/PATCH /settings— preferencias y widgets del dashboard.POST /attachments— subida pormultipart/form-datacon entidad asociada.GET /attachments/{id}/download— descarga tras validar sesión y propiedad del fichero.GET /health— estado de PHP, MySQL y modo demo.GET /auth/csrf— token requerido por toda operación que modifique estado.
Seguridad Implementada
.env.phpempieza por<?php exit; ?>: aunque el servidor lo sirva directamente, no revela su contenido.- Reglas
.htaccessque bloquean.env,app/,database/y el almacenamiento privado. storage/uploads/con doble defensa: denegación por.htaccessy unindex.phpque responde 404 si el servidor la ignora.- Adjuntos con verificación del tipo real vía
fileinfo: se rechazan HTML, SVG, PHP y cualquier ejecutable. - Nombres internos aleatorios para los ficheros subidos y entrega solo por ruta autenticada.
- Cuota de 10 MiB por archivo y 100 MiB por usuario como máximos internos.
- Token CSRF obligatorio en toda operación con estado.
- Sesiones por cookie con
SESSION_SECUREpara exigir HTTPS en producción. - Modo demo desactivable: permite explorar la interfaz sin MySQL, y debe apagarse antes de publicar.
Retos Técnicos y Decisiones de Diseño
Rentabilidad multimoneda sin inventar tipos de cambio
Un proyecto cobrado en euros con infraestructura pagada en pesos no se puede sumar sin una tasa de conversión, y cualquier tasa que elija el software estará desactualizada y mentirá. La decisión fue no convertir nunca: la rentabilidad se devuelve agrupada por moneda. Es menos vistoso que un número único, pero es el único resultado que no es falso.
Adjuntos en un hosting compartido
Subir ficheros a un servidor donde no controlas la configuración de Nginx es la vía más rápida a servir un PHP malicioso. La defensa es en capas: nombre aleatorio, directorio fuera del alcance web con doble bloqueo, verificación del tipo MIME real en lugar de la extensión, lista blanca de formatos y entrega exclusivamente por una ruta que valida sesión y propiedad.
Un instalador destructivo, avisando de que lo es
schema.sql hace DROP antes de CREATE. Eso es lo correcto para instalar
y catastrófico para actualizar, así que el README lo advierte de forma explícita y
las actualizaciones van por migraciones numeradas separadas. Preferí una herramienta
honesta sobre su comportamiento antes que un instalador que adivine el contexto.
Verificación automatizada del despliegue
scripts/verify.sh comprueba versión y extensiones de PHP, hace lint de
todos los ficheros y detecta opciones de demo inseguras en producción.
tests/smoke.sh valida por HTTP la portada, el health check y las vistas
privadas sin crear ni modificar datos, para poder ejecutarlo contra
el servidor real.
Mi Rol
Desarrollador full stack — autor único.
Modelo de datos, API JSON completa, interfaz, sistema de adjuntos, cálculo de rentabilidad, scripts de verificación y la documentación de despliegue en hosting compartido.
Estado del Proyecto
Aplicación funcional con esquema instalable, tres migraciones para instancias existentes y scripts de verificación. Requiere PHP 8.1+ y MySQL 8; desarrollada sobre PHP 8.5 y MySQL 8.4.
Código y Enlaces
Repositorio no publicado. Puedo mostrar el código y la API en una entrevista.