Del Escritorio (FWH + Eagle1) a la Web (Hix + Harbour + Node.js) en mes y medio..
Re: Del Escritorio (FWH + Eagle1) a la Web (Hix + Harbour + Node.js) en mes y medio..
Como no tengo acceso al contenido completo del mensaje original (solo veo el título y la URL), te doy una **guía general** para este tipo de migración **FWH + Eagle1 → Hix + Harbour + Node.js** en ~6 semanas.
---
### Arquitectura objetivo recomendada
```
┌─────────────┐ REST/WS ┌──────────────┐ Harbour ┌─────────┐
│ Frontend │ ◄──────────────► │ Node.js │ ◄──────────────► │ Core │
│ (Hix/HTML) │ JSON / Socket │ (API Gateway)│ RPC / Direct │ Logic │
└─────────────┘ └──────────────┘ └─────────┘
▲
┌──────┴──────┐
│ Datos │
│ (SQL/DBF) │
└─────────────┘
```
---
### Plan de 6 semanas (alto nivel)
| Semana | Foco | Entregable |
|--------|------|------------|
| **1** | **Inventario & desacoplamiento** | Catálogo de *forms*, *reports*, *menus*; separar lógica de negocio (`*.prg`) de UI (`*.fw`). |
| **2** | **Capa de datos** | Wrapper Harbour (`dbo` / `hbmysql` / `hbpgsql` / `adb`) que expone `SELECT/INSERT/UPDATE/DELETE` como funciones puras (sin `DBSELECTAREA`, `RECNO()`, etc.). |
| **3** | **API Node.js** | `express` + `harbour-node` (o `child_process` + JSON stdin/stdout) → endpoints REST (`/api/clientes`, `/api/facturas`, …). Autenticación JWT. |
| **4** | **Frontend Hix** | *Layout* base (menú lateral, toolbar), *grid* genérica (`hbx_grid`), *form* genérica (`hbx_form`), binding `fetch()` ↔ API. |
| **5** | **Módulos críticos** | Migrar 2-3 módulos *core* (ej. **Clientes**, **Facturación**) end-to-end. Pruebas de integración. |
| **6** | **Resto + hardening** | Migración masiva de formularios restantes, *reports* → PDF (`hbhpdf` / `pdf.js`), logs, CI/CD, despliegue. |
---
### Puntos técnicos clave
1. **Eagle1 → Hix**
- Eagle1 usa *windows* modales y *browse* ligados a `DBF`.
- En Hix: **`hbx_browse`** + `hbx_grid` con `dataSource: "api/..."`.
- Eventos `OnClick`, `OnChange` → callbacks JS que llaman a `fetch('/api/...')`.
2. **Código compartido (Harbour)**
- Mueve *validaciones*, *cálculos*, *reglas de negocio* a **`*.prg` puros** (sin `STATIC`, `PUBLIC`, ni `SET GET`).
- Compílalos como **librería estática (`.lib`)** yリンка tanto en el **exe de escritorio** (para coexistencia) como en el **módulo Node.js** (vía `hb_*` API o `hbmk2 -shared`).
3. **Node.js ↔ Harbour**
- Opción A: **`harbour-node`** (NAPI) – llamadas directas, máximo rendimiento.
- Opción B: **Proceso hijo** (`spawn('miapp.exe', ['--api', 'json'])`) – aislamiento total, fácil depuración.
- Protocolo: **JSON por stdin/stdout** (una línea = un request/response).
4. **Sesión / Estado**
- **Stateless**: JWT en header `Authorization: Bearer`.
- Datos de sesión en **Redis** (Node) o tabla `SESIONES` (Harbour).
5. **Reportes**
- `FiveWin REPORT` → **`hbhpdf`** (Harbour) o **`pdfmake` / `pdf.js`** (frontend).
- Genera PDF en servidor y devuelve `blob` al navegador.
6. **Despliegue**
- Docker:
```dockerfile
FROM node:20-alpine
COPY . /app
RUN npm ci --production
# Copia binarios Harbour compilados estáticamente
COPY bin/harbour_core /app/bin/
CMD ["node", "server.js"]
```
- Reverse proxy **Nginx** → `proxy_pass http://localhost:3000;`.
---
### Checklist rápido de “trampas”
| Riesgo | Mitigación |
|--------|------------|
| `SET SOFTSEEK`, `SET EXACT`, `SET DELETED` | Centraliza en `dbo:SetSession()` al abrir conexión. |
| `RLOCK()` / `FLOCK()` en lógica legacy | Migra a **transacciones SQL** (`BEGIN/COMMIT/ROLLBACK`) o *optimistic locking* (`version` column). |
| `ACCEPT`, `MEMOEDIT`, `GET` anidados | Reemplaza por **modales HTML** (`hbx_modal`) + callbacks. |
| Impresión directa a `LPT1` / PDF virtual | Genera PDF en servidor → `window.open('/api/report/123.pdf')`. |
| `PUBLIC` variables entre módulos | Elimina: pasa parámetros explícitos o usa *dependency injection* simple (`hb_New('Service', {cfg})`). |
---
### ¿Por dónde empezar *mañana*?
1. **`hbmk2 -w -shared core.prg`** → genera `core.lib` / `core.so` / `core.dll`.
2. Crea **`api.prg`** con una función `HB_FUN_API_DISPATCH(cJsonIn) → cJsonOut`.
3. Prueba en Node:
```js
const { spawn } = require('child_process');
const hb = spawn('./core_api', ['--json']);
hb.stdin.write(JSON.stringify({op:'clientes_list', page:1, rows:20})+'\n');
hb.stdout.on('data', d => console.log('→', JSON.parse(d)));
```
4. Monta **`express`** y expón `/api/clientes` → llama al `spawn` arriba.
5. En Hix: `hbx_grid({url:'/api/clientes', columns:[...]})`.
---
### Recursos FiveTech útiles
- **`hbx_*` samples** → `samples/hix/` en tu instalación FWH.
- **`harbour-node`** → `contrib/harbour-node/` (NAPI binding).
- **`hbhpdf`** → `contrib/hbhpdf/` para PDFs puros Harbour.
- **`hbmysql` / `hbpgsql` / `ados`** → capa de datos unificada.
---
Si puedes pegar aquí el **contenido del mensaje original** (qué módulos tienes, qué base de datos, si ya probaste algo, qué bloqueos ves), te doy **pasos concretos y código de ejemplo** para tu caso exacto.
---
Respuesta generada por Inteligencia Artificial usando el modelo nemotron-3-ultra-free via OpenCode Zen. Puede contener errores; por favor verifiquela antes de aplicar.
AI-generated reply using the nemotron-3-ultra-free model via OpenCode Zen. May contain mistakes; please verify before applying.
---
### Arquitectura objetivo recomendada
```
┌─────────────┐ REST/WS ┌──────────────┐ Harbour ┌─────────┐
│ Frontend │ ◄──────────────► │ Node.js │ ◄──────────────► │ Core │
│ (Hix/HTML) │ JSON / Socket │ (API Gateway)│ RPC / Direct │ Logic │
└─────────────┘ └──────────────┘ └─────────┘
▲
┌──────┴──────┐
│ Datos │
│ (SQL/DBF) │
└─────────────┘
```
---
### Plan de 6 semanas (alto nivel)
| Semana | Foco | Entregable |
|--------|------|------------|
| **1** | **Inventario & desacoplamiento** | Catálogo de *forms*, *reports*, *menus*; separar lógica de negocio (`*.prg`) de UI (`*.fw`). |
| **2** | **Capa de datos** | Wrapper Harbour (`dbo` / `hbmysql` / `hbpgsql` / `adb`) que expone `SELECT/INSERT/UPDATE/DELETE` como funciones puras (sin `DBSELECTAREA`, `RECNO()`, etc.). |
| **3** | **API Node.js** | `express` + `harbour-node` (o `child_process` + JSON stdin/stdout) → endpoints REST (`/api/clientes`, `/api/facturas`, …). Autenticación JWT. |
| **4** | **Frontend Hix** | *Layout* base (menú lateral, toolbar), *grid* genérica (`hbx_grid`), *form* genérica (`hbx_form`), binding `fetch()` ↔ API. |
| **5** | **Módulos críticos** | Migrar 2-3 módulos *core* (ej. **Clientes**, **Facturación**) end-to-end. Pruebas de integración. |
| **6** | **Resto + hardening** | Migración masiva de formularios restantes, *reports* → PDF (`hbhpdf` / `pdf.js`), logs, CI/CD, despliegue. |
---
### Puntos técnicos clave
1. **Eagle1 → Hix**
- Eagle1 usa *windows* modales y *browse* ligados a `DBF`.
- En Hix: **`hbx_browse`** + `hbx_grid` con `dataSource: "api/..."`.
- Eventos `OnClick`, `OnChange` → callbacks JS que llaman a `fetch('/api/...')`.
2. **Código compartido (Harbour)**
- Mueve *validaciones*, *cálculos*, *reglas de negocio* a **`*.prg` puros** (sin `STATIC`, `PUBLIC`, ni `SET GET`).
- Compílalos como **librería estática (`.lib`)** yリンка tanto en el **exe de escritorio** (para coexistencia) como en el **módulo Node.js** (vía `hb_*` API o `hbmk2 -shared`).
3. **Node.js ↔ Harbour**
- Opción A: **`harbour-node`** (NAPI) – llamadas directas, máximo rendimiento.
- Opción B: **Proceso hijo** (`spawn('miapp.exe', ['--api', 'json'])`) – aislamiento total, fácil depuración.
- Protocolo: **JSON por stdin/stdout** (una línea = un request/response).
4. **Sesión / Estado**
- **Stateless**: JWT en header `Authorization: Bearer
- Datos de sesión en **Redis** (Node) o tabla `SESIONES` (Harbour).
5. **Reportes**
- `FiveWin REPORT` → **`hbhpdf`** (Harbour) o **`pdfmake` / `pdf.js`** (frontend).
- Genera PDF en servidor y devuelve `blob` al navegador.
6. **Despliegue**
- Docker:
```dockerfile
FROM node:20-alpine
COPY . /app
RUN npm ci --production
# Copia binarios Harbour compilados estáticamente
COPY bin/harbour_core /app/bin/
CMD ["node", "server.js"]
```
- Reverse proxy **Nginx** → `proxy_pass http://localhost:3000;`.
---
### Checklist rápido de “trampas”
| Riesgo | Mitigación |
|--------|------------|
| `SET SOFTSEEK`, `SET EXACT`, `SET DELETED` | Centraliza en `dbo:SetSession()` al abrir conexión. |
| `RLOCK()` / `FLOCK()` en lógica legacy | Migra a **transacciones SQL** (`BEGIN/COMMIT/ROLLBACK`) o *optimistic locking* (`version` column). |
| `ACCEPT`, `MEMOEDIT`, `GET` anidados | Reemplaza por **modales HTML** (`hbx_modal`) + callbacks. |
| Impresión directa a `LPT1` / PDF virtual | Genera PDF en servidor → `window.open('/api/report/123.pdf')`. |
| `PUBLIC` variables entre módulos | Elimina: pasa parámetros explícitos o usa *dependency injection* simple (`hb_New('Service', {cfg})`). |
---
### ¿Por dónde empezar *mañana*?
1. **`hbmk2 -w -shared core.prg`** → genera `core.lib` / `core.so` / `core.dll`.
2. Crea **`api.prg`** con una función `HB_FUN_API_DISPATCH(cJsonIn) → cJsonOut`.
3. Prueba en Node:
```js
const { spawn } = require('child_process');
const hb = spawn('./core_api', ['--json']);
hb.stdin.write(JSON.stringify({op:'clientes_list', page:1, rows:20})+'\n');
hb.stdout.on('data', d => console.log('→', JSON.parse(d)));
```
4. Monta **`express`** y expón `/api/clientes` → llama al `spawn` arriba.
5. En Hix: `hbx_grid({url:'/api/clientes', columns:[...]})`.
---
### Recursos FiveTech útiles
- **`hbx_*` samples** → `samples/hix/` en tu instalación FWH.
- **`harbour-node`** → `contrib/harbour-node/` (NAPI binding).
- **`hbhpdf`** → `contrib/hbhpdf/` para PDFs puros Harbour.
- **`hbmysql` / `hbpgsql` / `ados`** → capa de datos unificada.
---
Si puedes pegar aquí el **contenido del mensaje original** (qué módulos tienes, qué base de datos, si ya probaste algo, qué bloqueos ves), te doy **pasos concretos y código de ejemplo** para tu caso exacto.
---
Respuesta generada por Inteligencia Artificial usando el modelo nemotron-3-ultra-free via OpenCode Zen. Puede contener errores; por favor verifiquela antes de aplicar.
AI-generated reply using the nemotron-3-ultra-free model via OpenCode Zen. May contain mistakes; please verify before applying.