From f359ea1fa7745b04ed29cd437514eb017e9f64ce Mon Sep 17 00:00:00 2001 From: GMNAPI Date: Tue, 30 Jun 2026 20:34:05 +0200 Subject: [PATCH 1/9] =?UTF-8?q?content:=20reescribe=20tarjeta=20Fast=20Byt?= =?UTF-8?q?e=20como=20migraci=C3=B3n=20ERP=20full-stack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/portfolio/messages/en.json | 6 +++--- apps/portfolio/messages/es.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/portfolio/messages/en.json b/apps/portfolio/messages/en.json index 5a6f5c2..f570817 100644 --- a/apps/portfolio/messages/en.json +++ b/apps/portfolio/messages/en.json @@ -605,9 +605,9 @@ }, { "id": "fastbyte-api-servicios", - "title": "Fastbyte - Service Management REST API", - "description": "Consultant and Tech Lead focused on requirement gathering with clients and translating them into practical solutions. Robust REST API for service management with phased deliveries and constant client communication.", - "tech": ["Symfony 7.3", "API Platform", "MariaDB", "Docker"], + "title": "Fastbyte — Technical-Services ERP Modernization", + "description": "Maintenance and evolution of the production ERP of a technical-services company (repair orders, incidents and billing), plus the design and implementation of its full-stack migration to a modern architecture: a Symfony 7.3 + API Platform REST API and a Next.js 15 SPA. The migration was built as a standalone project and paused by the client's business decision.", + "tech": ["Symfony 7.3", "API Platform", "Next.js 15", "React 19", "TypeScript", "Doctrine ORM", "MariaDB", "Docker"], "links": {}, "categoryId": "gestion-servicios" }, diff --git a/apps/portfolio/messages/es.json b/apps/portfolio/messages/es.json index ca896fc..3392ce2 100644 --- a/apps/portfolio/messages/es.json +++ b/apps/portfolio/messages/es.json @@ -605,9 +605,9 @@ }, { "id": "fastbyte-api-servicios", - "title": "Fastbyte - API REST de Gestión de Servicios", - "description": "Consultor y Tech Lead en toma de requisitos con clientes y su traducción a soluciones prácticas. API REST robusta para gestión de servicios con entregas por fases y comunicación constante con el cliente.", - "tech": ["Symfony 7.3", "API Platform", "MariaDB", "Docker"], + "title": "Fastbyte — Modernización de ERP de Servicios Técnicos", + "description": "Mantenimiento y evolución del ERP en producción de una empresa de servicios técnicos (órdenes de reparación, incidencias y facturación), y diseño e implementación de su migración full-stack a una arquitectura moderna: API REST con Symfony 7.3 + API Platform y SPA en Next.js 15. La migración se desarrolló como proyecto independiente y se pausó por decisión de negocio del cliente.", + "tech": ["Symfony 7.3", "API Platform", "Next.js 15", "React 19", "TypeScript", "Doctrine ORM", "MariaDB", "Docker"], "links": {}, "categoryId": "gestion-servicios" }, From f05fd7e903ff58c192c1c89cd8fbd10073989b61 Mon Sep 17 00:00:00 2001 From: GMNAPI Date: Tue, 30 Jun 2026 20:36:33 +0200 Subject: [PATCH 2/9] content: actualiza experiencia Fast Byte (full-stack) y corrige stack --- .../src/shared/constants/experience.ts | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/apps/portfolio/src/shared/constants/experience.ts b/apps/portfolio/src/shared/constants/experience.ts index dc7a54d..d6ea003 100644 --- a/apps/portfolio/src/shared/constants/experience.ts +++ b/apps/portfolio/src/shared/constants/experience.ts @@ -103,40 +103,43 @@ export const experienceTimeline: ExperienceItem[] = [ { id: 'fastbyte', - role: 'Consultor & Tech Lead', + role: 'Desarrollador Full-Stack & Tech Lead', company: 'Fastbyte SL', location: 'Barcelona, España', period: { start: '2019-01', - end: 'present', + end: '2025-11', }, type: 'consultant', description: - 'Toma de requisitos con clientes/equipos y traducción a soluciones prácticas. Comunicación constante, seguimiento de tareas y entrega por fases.', + 'Mantenimiento y evolución de un ERP en producción para servicios técnicos, y diseño e implementación de su migración full-stack a Symfony/API Platform + Next.js. Trabajo hands-on en backend y frontend, con foco en arquitectura, calidad y entregas por fases.', responsibilities: [ - 'Toma de requisitos con clientes y equipos técnicos', - 'Traducción de necesidades de negocio a soluciones técnicas', - 'Comunicación constante y seguimiento de tareas', - 'Coordinación técnica para alinear expectativas', - 'Resolución proactiva de bloqueos e incidencias', + 'Mantenimiento y modernización incremental del ERP legacy en PHP', + 'Diseño de la API REST con API Platform (patrón State Provider/Processor)', + 'Desarrollo del frontend SPA en Next.js / React / TypeScript', + 'Definición de arquitectura y decisiones técnicas (ADRs)', + 'Testing automatizado en backend y frontend', ], achievements: [ - 'Comunicación efectiva con stakeholders de múltiples proyectos', - 'Entregas por fases con seguimiento constante', - 'Resolución proactiva de bloqueos técnicos', - 'Alineación exitosa de expectativas cliente-equipo', + 'API con 16 entidades y ~34 endpoints documentados (OpenAPI / JSON-LD)', + 'SPA con 300+ tests y validación schema-first (Zod)', + 'Modernización incremental del legacy (Repository pattern, DI, Twilio/WhatsApp, DomPDF)', ], technologies: [ 'Symfony', + 'API Platform', + 'Doctrine', + 'PHP', 'Next.js', + 'React', + 'TypeScript', + 'Tailwind CSS', + 'MariaDB', 'Docker', - 'Kubernetes', - 'GitLab CI', - 'Microservices', - 'API Gateway', - 'Message Queues', + 'PHPUnit', + 'Jest', ], - highlights: ['Toma de requisitos', 'Comunicación cliente', 'Entregas por fases'], + highlights: ['Migración full-stack', 'Arquitectura API', 'Modernización legacy'], }, { From 3364fcce43157b61d9eeedeb420f511a13f42963 Mon Sep 17 00:00:00 2001 From: GMNAPI Date: Tue, 30 Jun 2026 20:39:12 +0200 Subject: [PATCH 3/9] =?UTF-8?q?feat:=20a=C3=B1ade=20selector=20getProjectD?= =?UTF-8?q?etail=20para=20fichas=20de=20proyecto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../projects/utils/projectDetail.test.ts | 26 ++++++++++++++++++ .../features/projects/utils/projectDetail.ts | 27 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 apps/portfolio/src/features/projects/utils/projectDetail.test.ts create mode 100644 apps/portfolio/src/features/projects/utils/projectDetail.ts diff --git a/apps/portfolio/src/features/projects/utils/projectDetail.test.ts b/apps/portfolio/src/features/projects/utils/projectDetail.test.ts new file mode 100644 index 0000000..e8e5f04 --- /dev/null +++ b/apps/portfolio/src/features/projects/utils/projectDetail.test.ts @@ -0,0 +1,26 @@ +import { describe, expect, it } from 'vitest'; + +import { getProjectDetail, type ProjectDetailContent } from './projectDetail'; + +describe('getProjectDetail', () => { + const details: Record = { + 'fastbyte-api-servicios': { + sections: [{ heading: 'Contexto', body: 'ERP en producción.' }], + metrics: [{ label: 'Endpoints API', value: '~34' }], + }, + }; + + it('returns the detail content when the slug exists', () => { + expect(getProjectDetail(details, 'fastbyte-api-servicios')).toEqual( + details['fastbyte-api-servicios'], + ); + }); + + it('returns null when the slug has no detail content', () => { + expect(getProjectDetail(details, 'seedstockers-b2b-platform')).toBeNull(); + }); + + it('returns null when details is undefined', () => { + expect(getProjectDetail(undefined, 'fastbyte-api-servicios')).toBeNull(); + }); +}); diff --git a/apps/portfolio/src/features/projects/utils/projectDetail.ts b/apps/portfolio/src/features/projects/utils/projectDetail.ts new file mode 100644 index 0000000..2c2a6ad --- /dev/null +++ b/apps/portfolio/src/features/projects/utils/projectDetail.ts @@ -0,0 +1,27 @@ +/** + * Tipos y selector del contenido de la página de detalle de un proyecto. + * El contenido vive en los ficheros i18n (messages/*.json) bajo `projects.details`, + * indexado por slug. `getProjectDetail` es puro para poder testearlo sin next-intl. + */ + +export interface ProjectDetailSection { + heading: string; + body: string; +} + +export interface ProjectDetailMetric { + label: string; + value: string; +} + +export interface ProjectDetailContent { + sections: ProjectDetailSection[]; + metrics?: ProjectDetailMetric[]; +} + +export function getProjectDetail( + details: Record | undefined, + slug: string, +): ProjectDetailContent | null { + return details?.[slug] ?? null; +} From a5c492aa4a58547b4ec01c9db586e03866873e29 Mon Sep 17 00:00:00 2001 From: GMNAPI Date: Tue, 30 Jun 2026 20:42:09 +0200 Subject: [PATCH 4/9] =?UTF-8?q?content:=20a=C3=B1ade=20contenido=20de=20de?= =?UTF-8?q?talle=20de=20Fast=20Byte=20(ES/EN)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/portfolio/messages/en.json | 43 ++++++++++++++++++++++++++++++++- apps/portfolio/messages/es.json | 43 ++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/apps/portfolio/messages/en.json b/apps/portfolio/messages/en.json index f570817..257e8ff 100644 --- a/apps/portfolio/messages/en.json +++ b/apps/portfolio/messages/en.json @@ -506,6 +506,38 @@ } }, "projects": { + "details": { + "fastbyte-api-servicios": { + "sections": [ + { + "heading": "Context", + "body": "A technical-services company with its own in-house ERP (\"Genesis\") running in production: ~16 modules and ~118,000 lines of code covering repair orders, incidents, quotes, delivery notes, billing and clients." + }, + { + "heading": "Legacy maintenance and modernization", + "body": "A hybrid PHP 7.4 system (procedural + OOP). Production maintenance and incremental modernization: Repository pattern and dependency injection in the newer modules, Twig templates, PDF generation (FPDF → DomPDF) and WhatsApp notifications via Twilio. Team work with a pull-request workflow." + }, + { + "heading": "Full-stack migration", + "body": "Design and implementation of the decoupled rewrite. Backend: Symfony 7.3 + API Platform 4.1 with the State Provider/Processor pattern, custom normalizers, a sequential ID generator with locking, and JSON-LD/Hydra serialization. Frontend: Next.js 15 + React 19 + TypeScript with shadcn/ui, React Hook Form + Zod (schema-first validation) and TanStack Table." + }, + { + "heading": "Quality and architecture", + "body": "Decisions documented in ADRs, ~24 backend tests (API, entities, serialization) and 300+ frontend tests with MSW for API mocking, plus continuous integration and documentation (OpenAPI, CHANGELOG)." + }, + { + "heading": "Outcome", + "body": "The migration was built as a standalone project and paused by the client's business decision; the legacy ERP remains in production." + } + ], + "metrics": [ + { "label": "API endpoints", "value": "~34" }, + { "label": "Domain entities", "value": "16" }, + { "label": "Tests (front + back)", "value": "320+" }, + { "label": "Stack", "value": "Symfony · Next.js" } + ] + } + }, "title": "Projects", "subtitle": "Selection of SaaS products, internal tools and technical documentation created in professional projects. Organized into 6 strategic categories.", "filters": { @@ -607,7 +639,16 @@ "id": "fastbyte-api-servicios", "title": "Fastbyte — Technical-Services ERP Modernization", "description": "Maintenance and evolution of the production ERP of a technical-services company (repair orders, incidents and billing), plus the design and implementation of its full-stack migration to a modern architecture: a Symfony 7.3 + API Platform REST API and a Next.js 15 SPA. The migration was built as a standalone project and paused by the client's business decision.", - "tech": ["Symfony 7.3", "API Platform", "Next.js 15", "React 19", "TypeScript", "Doctrine ORM", "MariaDB", "Docker"], + "tech": [ + "Symfony 7.3", + "API Platform", + "Next.js 15", + "React 19", + "TypeScript", + "Doctrine ORM", + "MariaDB", + "Docker" + ], "links": {}, "categoryId": "gestion-servicios" }, diff --git a/apps/portfolio/messages/es.json b/apps/portfolio/messages/es.json index 3392ce2..0d80e85 100644 --- a/apps/portfolio/messages/es.json +++ b/apps/portfolio/messages/es.json @@ -506,6 +506,38 @@ } }, "projects": { + "details": { + "fastbyte-api-servicios": { + "sections": [ + { + "heading": "Contexto", + "body": "Empresa de servicios técnicos con un ERP propio (\"Genesis\") en producción: ~16 módulos y ~118.000 líneas de código que cubren órdenes de reparación, incidencias, presupuestos, albaranes, facturación y clientes." + }, + { + "heading": "Mantenimiento y modernización del legacy", + "body": "Sistema PHP 7.4 de arquitectura híbrida (procedural + OOP). Mantenimiento en producción y modernización incremental: Repository pattern e inyección de dependencias en los módulos nuevos, plantillas Twig, generación de PDF (FPDF → DomPDF) y notificaciones por WhatsApp vía Twilio. Trabajo en equipo con flujo de pull requests." + }, + { + "heading": "Migración full-stack", + "body": "Diseño e implementación de la reescritura desacoplada. Backend: Symfony 7.3 + API Platform 4.1 con patrón State Provider/Processor, normalizers a medida, generador secuencial de IDs con bloqueo y serialización JSON-LD/Hydra. Frontend: Next.js 15 + React 19 + TypeScript con shadcn/ui, React Hook Form + Zod (validación schema-first) y TanStack Table." + }, + { + "heading": "Calidad y arquitectura", + "body": "Decisiones documentadas en ADRs, ~24 tests en el backend (API, entidades, serialización) y 300+ tests en el frontend con MSW para el mocking de la API, además de integración continua y documentación (OpenAPI, CHANGELOG)." + }, + { + "heading": "Desenlace", + "body": "La migración se desarrolló como proyecto independiente y se pausó por decisión de negocio del cliente; el ERP legacy continúa en producción." + } + ], + "metrics": [ + { "label": "Endpoints API", "value": "~34" }, + { "label": "Entidades de dominio", "value": "16" }, + { "label": "Tests (front + back)", "value": "320+" }, + { "label": "Stack", "value": "Symfony · Next.js" } + ] + } + }, "title": "Proyectos", "subtitle": "Selección de productos SaaS, herramientas internas y documentación técnica desarrollada en proyectos profesionales. Organizados en 6 categorías estratégicas.", "filters": { @@ -607,7 +639,16 @@ "id": "fastbyte-api-servicios", "title": "Fastbyte — Modernización de ERP de Servicios Técnicos", "description": "Mantenimiento y evolución del ERP en producción de una empresa de servicios técnicos (órdenes de reparación, incidencias y facturación), y diseño e implementación de su migración full-stack a una arquitectura moderna: API REST con Symfony 7.3 + API Platform y SPA en Next.js 15. La migración se desarrolló como proyecto independiente y se pausó por decisión de negocio del cliente.", - "tech": ["Symfony 7.3", "API Platform", "Next.js 15", "React 19", "TypeScript", "Doctrine ORM", "MariaDB", "Docker"], + "tech": [ + "Symfony 7.3", + "API Platform", + "Next.js 15", + "React 19", + "TypeScript", + "Doctrine ORM", + "MariaDB", + "Docker" + ], "links": {}, "categoryId": "gestion-servicios" }, From 05b7f4b1f850dd3bb4a75c7a070196bb681fe2bb Mon Sep 17 00:00:00 2001 From: GMNAPI Date: Tue, 30 Jun 2026 21:37:00 +0200 Subject: [PATCH 5/9] Revert "content: actualiza experiencia Fast Byte (full-stack) y corrige stack" This reverts commit f05fd7e903ff58c192c1c89cd8fbd10073989b61. --- .../src/shared/constants/experience.ts | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/apps/portfolio/src/shared/constants/experience.ts b/apps/portfolio/src/shared/constants/experience.ts index d6ea003..dc7a54d 100644 --- a/apps/portfolio/src/shared/constants/experience.ts +++ b/apps/portfolio/src/shared/constants/experience.ts @@ -103,43 +103,40 @@ export const experienceTimeline: ExperienceItem[] = [ { id: 'fastbyte', - role: 'Desarrollador Full-Stack & Tech Lead', + role: 'Consultor & Tech Lead', company: 'Fastbyte SL', location: 'Barcelona, España', period: { start: '2019-01', - end: '2025-11', + end: 'present', }, type: 'consultant', description: - 'Mantenimiento y evolución de un ERP en producción para servicios técnicos, y diseño e implementación de su migración full-stack a Symfony/API Platform + Next.js. Trabajo hands-on en backend y frontend, con foco en arquitectura, calidad y entregas por fases.', + 'Toma de requisitos con clientes/equipos y traducción a soluciones prácticas. Comunicación constante, seguimiento de tareas y entrega por fases.', responsibilities: [ - 'Mantenimiento y modernización incremental del ERP legacy en PHP', - 'Diseño de la API REST con API Platform (patrón State Provider/Processor)', - 'Desarrollo del frontend SPA en Next.js / React / TypeScript', - 'Definición de arquitectura y decisiones técnicas (ADRs)', - 'Testing automatizado en backend y frontend', + 'Toma de requisitos con clientes y equipos técnicos', + 'Traducción de necesidades de negocio a soluciones técnicas', + 'Comunicación constante y seguimiento de tareas', + 'Coordinación técnica para alinear expectativas', + 'Resolución proactiva de bloqueos e incidencias', ], achievements: [ - 'API con 16 entidades y ~34 endpoints documentados (OpenAPI / JSON-LD)', - 'SPA con 300+ tests y validación schema-first (Zod)', - 'Modernización incremental del legacy (Repository pattern, DI, Twilio/WhatsApp, DomPDF)', + 'Comunicación efectiva con stakeholders de múltiples proyectos', + 'Entregas por fases con seguimiento constante', + 'Resolución proactiva de bloqueos técnicos', + 'Alineación exitosa de expectativas cliente-equipo', ], technologies: [ 'Symfony', - 'API Platform', - 'Doctrine', - 'PHP', 'Next.js', - 'React', - 'TypeScript', - 'Tailwind CSS', - 'MariaDB', 'Docker', - 'PHPUnit', - 'Jest', + 'Kubernetes', + 'GitLab CI', + 'Microservices', + 'API Gateway', + 'Message Queues', ], - highlights: ['Migración full-stack', 'Arquitectura API', 'Modernización legacy'], + highlights: ['Toma de requisitos', 'Comunicación cliente', 'Entregas por fases'], }, { From 6cb30041d076c0fdecb6e4a5e0a141d169af7fcf Mon Sep 17 00:00:00 2001 From: GMNAPI Date: Tue, 30 Jun 2026 21:39:14 +0200 Subject: [PATCH 6/9] content: actualiza timeline viva (about.career) de Fast Byte y GMN --- apps/portfolio/messages/en.json | 22 ++++++++++++++-------- apps/portfolio/messages/es.json | 22 ++++++++++++++-------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/apps/portfolio/messages/en.json b/apps/portfolio/messages/en.json index 257e8ff..4eaf19b 100644 --- a/apps/portfolio/messages/en.json +++ b/apps/portfolio/messages/en.json @@ -105,14 +105,17 @@ "career": { "experiences": [ { - "role": "Consultant & Tech Lead", + "role": "Full-Stack Developer & Tech Lead", "company": "Fastbyte SL", "period": { "start": "2019", "end": "2025" }, - "headline": "Requirements gathering with clients/teams and translation into practical solutions.", - "achievements": ["Constant communication, task follow-up and phased delivery."] + "headline": "Maintenance of a production ERP for a technical-services company and the design and implementation of its full-stack migration (Symfony/API Platform + Next.js).", + "achievements": [ + "Full-stack migration: a Symfony 7.3 + API Platform REST API and a Next.js 15 SPA; paused by the client's business decision.", + "Incremental modernization of the legacy PHP system (Repository pattern, DI, Twilio/WhatsApp, DomPDF)." + ] }, { "role": "Program Specialist", @@ -125,14 +128,17 @@ "achievements": [] }, { - "role": "Co-founder & Lead Dev", - "company": "GestionoMiNegocio", + "role": "Co-founder & Lead Developer", + "company": "GestionoMiNegocio (GMN)", "period": { "start": "2020", - "end": "2025" + "end": "Present" }, - "headline": "Working with beta users: collecting feedback, improvements and product onboarding support.", - "achievements": ["Focus on clarity, quality and user experience."] + "headline": "Multi-tenant electronic-invoicing SaaS platform with Veri*factu/AEAT compliance; distributed architecture with a compliance microservice.", + "achievements": [ + "Veri*factu/AEAT microservice: SHA-256 hash chaining, XAdES signatures and SOAP/mTLS (Symfony Messenger).", + "Database-per-tenant multi-tenancy and SaaS monetization with Stripe." + ] }, { "role": "Developer", diff --git a/apps/portfolio/messages/es.json b/apps/portfolio/messages/es.json index 0d80e85..45d002e 100644 --- a/apps/portfolio/messages/es.json +++ b/apps/portfolio/messages/es.json @@ -105,14 +105,17 @@ "career": { "experiences": [ { - "role": "Consultor & Tech Lead", + "role": "Desarrollador Full-Stack & Tech Lead", "company": "Fastbyte SL", "period": { "start": "2019", "end": "2025" }, - "headline": "Toma de requisitos con clientes/equipos y traducción a soluciones prácticas.", - "achievements": ["Comunicación constante, seguimiento de tareas y entrega por fases."] + "headline": "Mantenimiento de un ERP en producción para servicios técnicos y diseño e implementación de su migración full-stack (Symfony/API Platform + Next.js).", + "achievements": [ + "Migración full-stack: API REST con Symfony 7.3 + API Platform y SPA en Next.js 15; pausada por decisión de negocio del cliente.", + "Modernización incremental del legacy PHP (Repository pattern, DI, Twilio/WhatsApp, DomPDF)." + ] }, { "role": "Especialista de Programa", @@ -125,14 +128,17 @@ "achievements": [] }, { - "role": "Cofundador & Lead Dev", - "company": "GestionoMiNegocio", + "role": "Cofundador & Lead Developer", + "company": "GestionoMiNegocio (GMN)", "period": { "start": "2020", - "end": "2025" + "end": "Actualidad" }, - "headline": "Trabajo con usuarios beta: recogida de feedback, mejoras y acompañamiento en uso del producto.", - "achievements": ["Enfoque en claridad, calidad y experiencia de usuario."] + "headline": "Plataforma SaaS multi-tenant de facturación electrónica con cumplimiento Veri*factu/AEAT; arquitectura distribuida con microservicio de compliance.", + "achievements": [ + "Microservicio Veri*factu/AEAT: hash encadenado SHA-256, firma XAdES y SOAP/mTLS (Symfony Messenger).", + "Multi-tenancy database-per-tenant y monetización SaaS con Stripe." + ] }, { "role": "Developer", From e47bf5c0af61a18b0820f4028491c47e360d78c0 Mon Sep 17 00:00:00 2001 From: GMNAPI Date: Tue, 30 Jun 2026 21:42:25 +0200 Subject: [PATCH 7/9] content: reescribe tarjeta GMN (SaaS Veri*factu) y corrige stack --- apps/portfolio/messages/en.json | 21 ++++++++++++++------- apps/portfolio/messages/es.json | 21 ++++++++++++++------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/apps/portfolio/messages/en.json b/apps/portfolio/messages/en.json index 4eaf19b..26cbf65 100644 --- a/apps/portfolio/messages/en.json +++ b/apps/portfolio/messages/en.json @@ -606,16 +606,23 @@ "items": [ { "id": "gestiono-mi-negocio-facturacion", - "title": "GestionoMiNegocio - Billing Software", - "description": "Led development as Co-founder & Lead Dev. Comprehensive platform for basic administrative management, including billing and collection control. Architecture oriented to handle workload peaks while maintaining quality and response times.", + "title": "GestionoMiNegocio (GMN) — Electronic invoicing SaaS platform", + "description": "Multi-tenant SaaS platform for business management and electronic invoicing for freelancers and SMEs, fully compliant with Spain's Veri*factu / AEAT regulation. Distributed architecture: a management app (invoices, quotes, delivery notes and clients) on a database-per-tenant model, plus a standalone microservice that handles tax registration with the Spanish Tax Agency (hash chaining, XAdES digital signatures and SOAP communication). Includes Stripe subscription billing, plan-based feature gating and self-service onboarding. Live in production with real businesses.", "tech": [ "Symfony 7", - "API Platform", - "PostgreSQL", - "React", - "TypeScript", + "PHP 8.2", + "Doctrine ORM", + "MariaDB", + "Twig", + "Bootstrap 5", + "REST API", + "Stripe", + "Symfony Messenger", "Docker", - "GitHub Actions" + "GitHub Actions", + "Veri*factu/AEAT", + "XAdES", + "Multi-tenant" ], "links": { "demo": "https://gestionominegocio.com/" diff --git a/apps/portfolio/messages/es.json b/apps/portfolio/messages/es.json index 45d002e..af4b54d 100644 --- a/apps/portfolio/messages/es.json +++ b/apps/portfolio/messages/es.json @@ -606,16 +606,23 @@ "items": [ { "id": "gestiono-mi-negocio-facturacion", - "title": "GestionoMiNegocio - Software de Facturación", - "description": "Desarrollo liderado como Cofundador y Lead Dev. Plataforma integral para la gestión administrativa básica, facturación y control de cobros. Arquitectura orientada a resolver picos de trabajo manteniendo calidad y tiempos de respuesta.", + "title": "GestionoMiNegocio (GMN) — Plataforma SaaS de facturación electrónica", + "description": "Plataforma SaaS multi-tenant para la gestión y la facturación electrónica de autónomos y pymes, con cumplimiento de la normativa española Veri*factu (AEAT). Arquitectura distribuida: una aplicación de gestión (facturas, presupuestos, albaranes y clientes) sobre un modelo database-per-tenant, y un microservicio independiente que resuelve el registro fiscal ante la AEAT (hash encadenado, firma digital XAdES y comunicación SOAP). Incluye suscripciones y cobros con Stripe, control de planes por funcionalidad y onboarding self-service. En producción con empresas reales.", "tech": [ "Symfony 7", - "API Platform", - "PostgreSQL", - "React", - "TypeScript", + "PHP 8.2", + "Doctrine ORM", + "MariaDB", + "Twig", + "Bootstrap 5", + "API REST", + "Stripe", + "Symfony Messenger", "Docker", - "GitHub Actions" + "GitHub Actions", + "Veri*factu/AEAT", + "XAdES", + "Multi-tenant" ], "links": { "demo": "https://gestionominegocio.com/" From 2dd48010add44d10439022348e1e1711567650e8 Mon Sep 17 00:00:00 2001 From: GMNAPI Date: Tue, 30 Jun 2026 21:50:42 +0200 Subject: [PATCH 8/9] =?UTF-8?q?content:=20a=C3=B1ade=20contenido=20de=20de?= =?UTF-8?q?talle=20de=20GMN=20(ES/EN)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/portfolio/messages/en.json | 30 ++++++++++++++++++++++++++++++ apps/portfolio/messages/es.json | 30 ++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/apps/portfolio/messages/en.json b/apps/portfolio/messages/en.json index 26cbf65..9229ade 100644 --- a/apps/portfolio/messages/en.json +++ b/apps/portfolio/messages/en.json @@ -513,6 +513,36 @@ }, "projects": { "details": { + "gestiono-mi-negocio-facturacion": { + "sections": [ + { + "heading": "Context", + "body": "GestionoMiNegocio (GMN) is a multi-tenant SaaS platform for business management and electronic invoicing for freelancers and SMEs, compliant with Spain's Veri*factu/AEAT regulation. Live in production with real businesses. As co-founder and Lead Dev (2020–present) I led its evolution from a legacy management system to the current distributed architecture." + }, + { + "heading": "Multi-tenant architecture", + "body": "A management app (invoices, quotes, delivery notes and clients) on a database-per-tenant model with full data isolation, dynamic connection switching and automated tenant provisioning/migration. Built with Symfony 7, PHP 8.2, Doctrine ORM, MariaDB, Twig and Bootstrap 5." + }, + { + "heading": "Veri*factu/AEAT compliance microservice", + "body": "A standalone service that handles tax registration with the Spanish Tax Agency (Anti-Fraud Law, RD 1007/2023): SHA-256 hash chaining, XAdES-EPES digital signatures with FNMT certificates (PKCS#12), QR generation and SOAP/mTLS communication, processed asynchronously via Symfony Messenger." + }, + { + "heading": "Monetization and product", + "body": "A SaaS monetization layer with Stripe (plans, trials, idempotent webhooks and plan-based feature gating), self-service onboarding and integrations with TwentyCRM and an OpenAI assistant. Full product cycle with beta users: feedback, improvements and support." + }, + { + "heading": "Engineering", + "body": "Docker containerization, CI on GitHub Actions and a REST API. ~31,000 lines of code across the GMN app and the compliance microservice, which has 33 REST endpoints and 27 test files." + } + ], + "metrics": [ + { "label": "LOC (app + microservice)", "value": "~31k" }, + { "label": "Microservice endpoints", "value": "33" }, + { "label": "Compliance", "value": "Veri*factu/AEAT" }, + { "label": "Data model", "value": "Database-per-tenant" } + ] + }, "fastbyte-api-servicios": { "sections": [ { diff --git a/apps/portfolio/messages/es.json b/apps/portfolio/messages/es.json index af4b54d..ffdc21c 100644 --- a/apps/portfolio/messages/es.json +++ b/apps/portfolio/messages/es.json @@ -513,6 +513,36 @@ }, "projects": { "details": { + "gestiono-mi-negocio-facturacion": { + "sections": [ + { + "heading": "Contexto", + "body": "GestionoMiNegocio (GMN) es una plataforma SaaS multi-tenant de gestión y facturación electrónica para autónomos y pymes, con cumplimiento de la normativa española Veri*factu/AEAT. En producción con empresas reales. Como cofundador y Lead Dev (2020–actualidad) lideré su evolución desde un software de gestión legacy hasta la arquitectura distribuida actual." + }, + { + "heading": "Arquitectura multi-tenant", + "body": "Aplicación de gestión (facturas, presupuestos, albaranes y clientes) sobre un modelo database-per-tenant con aislamiento total de datos, conmutación dinámica de conexión y provisión/migración automatizada de tenants. Construida con Symfony 7, PHP 8.2, Doctrine ORM, MariaDB, Twig y Bootstrap 5." + }, + { + "heading": "Microservicio de compliance Veri*factu/AEAT", + "body": "Servicio independiente que resuelve el registro fiscal ante la AEAT (Ley Antifraude, RD 1007/2023): hash encadenado SHA-256, firma digital XAdES-EPES con certificados FNMT (PKCS#12), generación de QR y comunicación SOAP con mTLS, procesado de forma asíncrona con Symfony Messenger." + }, + { + "heading": "Monetización y producto", + "body": "Capa de monetización SaaS con Stripe (planes, periodo de prueba, webhooks idempotentes y feature-gating por plan), onboarding self-service e integraciones con TwentyCRM y un asistente con OpenAI. Ciclo completo de producto con usuarios beta: feedback, mejoras y soporte." + }, + { + "heading": "Ingeniería", + "body": "Contenedorización con Docker, CI con GitHub Actions y API REST. ~31.000 líneas de código entre la app GMN y el microservicio de compliance, que cuenta con 33 endpoints REST y 27 ficheros de test." + } + ], + "metrics": [ + { "label": "LOC (app + microservicio)", "value": "~31k" }, + { "label": "Endpoints microservicio", "value": "33" }, + { "label": "Compliance", "value": "Veri*factu/AEAT" }, + { "label": "Modelo de datos", "value": "Database-per-tenant" } + ] + }, "fastbyte-api-servicios": { "sections": [ { From bddfdfeaef165ca23ee51c13b0d887c9254fb9c8 Mon Sep 17 00:00:00 2001 From: GMNAPI Date: Tue, 30 Jun 2026 23:02:42 +0200 Subject: [PATCH 9/9] feat: fichas de detalle ricas (Fast Byte y GMN) con render condicional --- .../app/[locale]/projects/[slug]/page.tsx | 86 ++++++++++++++----- .../projects/utils/projectDetail.test.ts | 2 +- .../features/projects/utils/projectDetail.ts | 2 +- 3 files changed, 68 insertions(+), 22 deletions(-) diff --git a/apps/portfolio/app/[locale]/projects/[slug]/page.tsx b/apps/portfolio/app/[locale]/projects/[slug]/page.tsx index 00f06c2..572a0f7 100644 --- a/apps/portfolio/app/[locale]/projects/[slug]/page.tsx +++ b/apps/portfolio/app/[locale]/projects/[slug]/page.tsx @@ -3,6 +3,10 @@ import { notFound } from 'next/navigation'; import { getTranslations } from 'next-intl/server'; import { Project, type ProjectData } from '@/core/entities/Project'; +import { + getProjectDetail, + type ProjectDetailContent, +} from '@/features/projects/utils/projectDetail'; import { routing } from '@/i18n/routing'; import { PROJECT_SLUGS } from '@/shared/constants/project-slugs'; @@ -36,6 +40,8 @@ export default async function ProjectDetailPage({ params }: ProjectDetailPagePro } const project = new Project(projectData); + const details = t.raw('details') as Record | undefined; + const detail = getProjectDetail(details, slug); return (
@@ -49,32 +55,72 @@ export default async function ProjectDetailPage({ params }: ProjectDetailPagePro

- Detalle en preparación + {detail ? project.categoryId.replace(/-/g, ' ') : 'Detalle en preparación'}

{project.title}

{project.description}

-
-

- Estamos preparando una ficha completa con arquitectura, capturas y métricas clave de - este proyecto. Mientras tanto, puedes solicitar una demo privada o más información - directa. -

-
- - {project.categoryId.replace(/-/g, ' ')} - - {project.tech.map((tech) => ( - - {tech} + {detail ? ( + <> + {detail.metrics && detail.metrics.length > 0 && ( +
+ {detail.metrics.map((metric) => ( +
+

{metric.value}

+

+ {metric.label} +

+
+ ))} +
+ )} + +
+ {detail.sections.map((item) => ( +
+

{item.heading}

+

{item.body}

+
+ ))} +
+ +
+ {project.tech.map((tech) => ( + + {tech} + + ))} +
+ + ) : ( +
+

+ Estamos preparando una ficha completa con arquitectura, capturas y métricas clave de + este proyecto. Mientras tanto, puedes solicitar una demo privada o más información + directa. +

+
+ + {project.categoryId.replace(/-/g, ' ')} - ))} -
-
+ {project.tech.map((tech) => ( + + {tech} + + ))} +
+
+ )}

diff --git a/apps/portfolio/src/features/projects/utils/projectDetail.test.ts b/apps/portfolio/src/features/projects/utils/projectDetail.test.ts index e8e5f04..4eec62b 100644 --- a/apps/portfolio/src/features/projects/utils/projectDetail.test.ts +++ b/apps/portfolio/src/features/projects/utils/projectDetail.test.ts @@ -12,7 +12,7 @@ describe('getProjectDetail', () => { it('returns the detail content when the slug exists', () => { expect(getProjectDetail(details, 'fastbyte-api-servicios')).toEqual( - details['fastbyte-api-servicios'], + details['fastbyte-api-servicios'] ); }); diff --git a/apps/portfolio/src/features/projects/utils/projectDetail.ts b/apps/portfolio/src/features/projects/utils/projectDetail.ts index 2c2a6ad..8864c0d 100644 --- a/apps/portfolio/src/features/projects/utils/projectDetail.ts +++ b/apps/portfolio/src/features/projects/utils/projectDetail.ts @@ -21,7 +21,7 @@ export interface ProjectDetailContent { export function getProjectDetail( details: Record | undefined, - slug: string, + slug: string ): ProjectDetailContent | null { return details?.[slug] ?? null; }