Back to 0fee
0fee

Migración a SQLAdmin: del admin SolidJS al backend integrado

Cómo migramos el panel de administración de 0fee.dev de un frontend SolidJS personalizado a SQLAdmin con 16 modelos y 12 vistas. Por Juste A. Gnimavo.

Juste A. Gnimavo (Thales) & Claude | March 27, 2026 3 min 0fee
EN/ FR/ ES
sqladminmigrationbackendormadmin-panel

El panel de administración personalizado que construimos en la sesión 020 funcionaba. Tenía rutas UUID, autenticación JWT y jerarquía de roles. Pero también tenía un problema: era una aplicación frontend completamente separada que necesitaba mantenimiento junto con el panel SolidJS principal y el sitio de marketing. Tres aplicaciones frontend para una plataforma eran dos de más.

En sesiones posteriores, tomamos la decisión de retirar el admin SolidJS personalizado y reemplazarlo con SQLAdmin -- una biblioteca Python que genera una interfaz de administración directamente desde modelos ORM de SQLAlchemy. La migración tocó 12 archivos de modelos ORM, creó 16 modelos SQLAlchemy, construyó 12 vistas de administración y eliminó miles de líneas de código frontend personalizado.

¿Por qué SQLAdmin?

CaracterísticaAdmin SolidJS personalizadoSQLAdmin
Carga de mantenimientoAlta (app separada)Baja (auto-generado desde modelos)
Pipeline de buildVite + SolidJSNinguno (renderizado en servidor)
Soporte de nuevo modeloEscribir frontend + APIAñadir una clase de vista admin
Búsqueda/filtroImplementación personalizadaIncorporado
DespliegueServicio separadoMismo proceso del backend

La compensación fue clara. Perdimos control de diseño píxel por píxel, pero ganamos cero sobrecarga de mantenimiento para operaciones CRUD de admin. Para una herramienta interna usada por una persona (Thales), esa compensación fue fácil de hacer.

Los 16 modelos SQLAlchemy

La migración requirió convertir cada tabla de base de datos a un modelo ORM de SQLAlchemy apropiado: User, App, Transaction, Provider, AppProvider, PaymentMethod, Webhook, WebhookDelivery, Invoice, Coupon, CouponUsage, ApiKey, FeatureRequest, FeatureUpvote, FeatureComment y AuditLog.

El problema del nombre de columna reservado: metadata a meta

metadata es un atributo reservado en la base declarativa de SQLAlchemy. Definir una columna con ese nombre oculta el atributo interno y causa errores crípticos. El renombrado a meta se propagó a través de cada modelo, endpoint API, SDK y la migración de base de datos misma.

Las 12 vistas de administración

Las transacciones son solo lectura (can_create = False, can_edit = False, can_delete = False) -- en una plataforma de pagos, nunca modificas un registro de transacción después de la creación. Esto es un principio fundamental de auditoría financiera: el libro mayor es solo de adición.

SQLAdmin usa sesiones basadas en cookies para autenticación. El panel ahora vive en /thales -- una ruta significativa para Thales (el CEO y único admin) mientras sigue siendo no obvia para escáneres automatizados.

La corrección de compatibilidad de column_filters

Encontramos errores 500 al usar filtros de columna en SQLAdmin. La corrección requirió especificar filtros como cadenas en lugar de atributos del modelo.

Lo que eliminó la migración

~3.000 líneas de código admin SolidJS, 7 endpoints API personalizados, un pipeline de build separado, configuración de despliegue específica del admin y enrutamiento frontend para admin.

Lecciones de la migración

Empieza con SQLAdmin si eres un equipo pequeño. El nombre de columna metadata te morderá. Las vistas de solo lectura son una funcionalidad, no una limitación. Las sesiones de cookies están bien para configuraciones de un solo admin.


Este artículo es parte de la serie "Cómo construimos 0fee.dev". 0fee.dev es un orquestador de pagos que cubre más de 53 proveedores en más de 200 países, construido por Juste A. GNIMAVO y Claude desde Abiyán sin ingenieros humanos. Sigue la serie para conocer la historia completa de la construcción.

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles

Thales & Claude zerosuite

Funciona, y no está terminado

El director recorrió él mismo todos los canales de senndo — cinco canales, de uno en uno y en campaña, la importación, las estadísticas, un reembolso, la API — y todo respondió. El archivo de seguimiento seguía diciendo que no, y la única línea que bloqueaba no era código: era un documento que había dejado de ser cierto en silencio. Cuatro afirmaciones ciertas al escribirse y falsas al leerse, y las guardas legibles por una máquina que ahora atrapan cada una de esas formas.

12 min Sep 14, 2026
senndocpaaslaunch-readinessdocumentation +8
Thales & Claude zerosuite

El navegador en manos de Claude: manejar el propio Chrome del CEO

Claude-in-Chrome permite que una sesión de Claude Code maneje el navegador real del director — mismo perfil, mismas sesiones abiertas. Qué hace la herramienta en realidad, por qué es mejor que pedirle a una persona que haga clic y lo cuente, y dónde el humano sigue ganando. Anclado en el día en que Claude recorrió un alta de cliente completa en la consola de producción de senndo, con mensajes facturados incluidos.

9 min Aug 18, 2026
claude-in-chromebrowser-automationclaude-codeclaude-fable-5 +9
Thales & Claude deblo

El segfault que no era nuestro: cómo lanzamos el tracking del día de lanzamiento de Déblo en la noche del despliegue — analítica condicionada por entorno, atribución nativa de las tiendas, tres bugs que el compilador no podía ver y un build sin memoria que diagnosticamos en lugar de revertir

El 1 de julio de 2026 — el día del lanzamiento — el riesgo nunca fue el texto. Era que las campañas de pago salieran a ciegas. Este es el build-log de cómo desplegamos la analítica y la atribución de instalaciones de Déblo como código en la noche del lanzamiento: etiquetas GA4, Meta y LinkedIn condicionadas por entorno que se despliegan sin riesgo antes de que existan las cuentas publicitarias; atribución enrutada por los canales nativos de las tiendas en lugar del pixel web; una auditoría adversarial que atrapó tres bugs que tanto el typechecker como el build dieron por buenos; y un despliegue en Easypanel que hizo segfault en el primer build — que demostramos que no era nuestro código antes de tocar una sola línea.

18 min Jul 1, 2026
deblolaunch-dayclaude-opus-4.8claude-code +26