@ntlinkmx/nt 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +449 -2
- package/dist/cli.js +260 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/http.js +115 -0
- package/dist/http.js.map +1 -0
- package/dist/native-routes.json +698 -0
- package/package.json +41 -6
- package/scripts/postinstall.mjs +7 -0
- package/scripts/sync-routes.mjs +17 -0
package/README.md
CHANGED
|
@@ -1,3 +1,450 @@
|
|
|
1
|
-
#
|
|
1
|
+
# nt · CLI del backend Go
|
|
2
|
+
|
|
3
|
+
## Responsabilidad
|
|
4
|
+
|
|
5
|
+
Cliente Node/TypeScript dentro de este monorepo para comunicarse por HTTP con el
|
|
6
|
+
backend Go de NTLink IA Invoice. Ejecutable **`nt`**, compatible con Windows y
|
|
7
|
+
Linux, Node **22.12 o posterior** y npm. No necesita React abierto ni acceso directo
|
|
8
|
+
a SQL, certificados, Azure o claves de IA: esas dependencias las gestiona Go.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Contrato
|
|
12
|
+
|
|
13
|
+
### Instalar y comenzar
|
|
14
|
+
|
|
15
|
+
Instala el paquete publicado y úsalo en PowerShell o Bash:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npm install --global @ntlinkmx/nt
|
|
19
|
+
nt --version
|
|
20
|
+
nt --help
|
|
21
|
+
nt mode
|
|
22
|
+
nt mode production
|
|
23
|
+
nt client info
|
|
24
|
+
nt client balance
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`npm ci` compila automáticamente; después de cambiar fuentes usa `npm run build`.
|
|
28
|
+
El paquete se publicará como `@ntlinkmx/nt`; instala o actualiza con `npm install --global @ntlinkmx/nt`.
|
|
29
|
+
Para preparar el primer lanzamiento, desde la cuenta npm que será dueña del
|
|
30
|
+
paquete ejecuta `npm login` y `npm publish` dentro de `cli/`. Es un paso inicial:
|
|
31
|
+
npm requiere que el paquete exista antes de activar su trusted publisher.
|
|
32
|
+
Después, en npmjs.com abre `Packages` → `@ntlinkmx/nt` → `Settings` →
|
|
33
|
+
`Trusted Publisher`; elige GitHub Actions y configura
|
|
34
|
+
organización/usuario `NTlink`, repositorio `ntlink-ia-invoice`, workflow
|
|
35
|
+
`publish-invoice-cli.yml` y permite `npm publish`. Para las versiones siguientes,
|
|
36
|
+
cambia la versión del paquete y ejecuta manualmente el workflow desde la rama
|
|
37
|
+
`main` en la pestaña Actions del repositorio. OIDC evita guardar un `NPM_TOKEN`.
|
|
38
|
+
El paquete pertenece al scope `@ntlinkmx`.
|
|
39
|
+
El workflow tiene que estar primero en `main` para poder seleccionarlo en npm.
|
|
40
|
+
Para instalar desde un archivo: ejecuta `npm pack` y luego
|
|
41
|
+
`npm install --global ./ntlinkmx-nt-0.1.0.tgz` desde `cli/`.
|
|
42
|
+
Para retirar el comando global: `npm uninstall --global @ntlinkmx/nt`.
|
|
43
|
+
El perfil predeterminado es `pruebas`. Las instalaciones existentes conservan su configuración guardada.
|
|
44
|
+
El arranque de Go se describe en [desarrollo local](../doc/guides/LOCAL-DEVELOPMENT.md).
|
|
45
|
+
|
|
46
|
+
### Usar en pruebas
|
|
2
47
|
|
|
3
|
-
|
|
48
|
+
Al instalar, el CLI anuncia que queda en modo `pruebas`. La primera operación protegida inicia sesión automáticamente con la cuenta pública de demostración.
|
|
49
|
+
|
|
50
|
+
### Cuenta pública de demostración
|
|
51
|
+
|
|
52
|
+
Estas credenciales son para el modo `pruebas`:
|
|
53
|
+
|
|
54
|
+
- Correo: `URE180429TM6@ntlink.com.mx`
|
|
55
|
+
- Contraseña: `NTPruebas.2021*?`
|
|
56
|
+
|
|
57
|
+
### Modos y perfiles
|
|
58
|
+
|
|
59
|
+
`nt mode` muestra el modo activo sin imprimir el host. `nt mode pruebas` vuelve al entorno de pruebas. `nt mode production` informa que producción estará disponible próximamente y conserva el modo actual.
|
|
60
|
+
|
|
61
|
+
Cada perfil conserva URL, timeout y token independientes. Los nombres de perfiles
|
|
62
|
+
son etiquetas locales; no cambian las banderas fiscales del servidor.
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
nt --profile local config set --base-url http://localhost:8092 --timeout 120
|
|
66
|
+
nt --profile pruebas config set --base-url http://pruebas.ntlink.com.mx:8092
|
|
67
|
+
nt --profile pruebas auth login --email URE180429TM6@ntlink.com.mx
|
|
68
|
+
nt config use pruebas
|
|
69
|
+
nt config show
|
|
70
|
+
nt config list
|
|
71
|
+
nt --profile local health ready
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
La URL debe contener protocolo y host/puerto, sin `/api`, usuario, contraseña, query ni fragmento.
|
|
75
|
+
También existe `config set --url URL`. Cambiar la URL guardada de un perfil borra
|
|
76
|
+
su token anterior. Un `--base-url` temporal a otro origen tampoco reutiliza su token.
|
|
77
|
+
|
|
78
|
+
| Ajuste | Variable | Opción global |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| Perfil | `NTLINK_PROFILE` | `--profile` |
|
|
81
|
+
| Origen Go | `NTLINK_BASE_URL` | `--base-url` |
|
|
82
|
+
| Bearer | `NTLINK_TOKEN` | `--token` |
|
|
83
|
+
| Timeout en segundos | `NTLINK_TIMEOUT` | `--timeout` |
|
|
84
|
+
|
|
85
|
+
Prioridad: opción > variable > perfil guardado > valor inicial. No se leen los
|
|
86
|
+
tokens ni el archivo del CLI Proxy. La configuración está en
|
|
87
|
+
`~/.ntlink-invoice/config.json` (Windows: `%USERPROFILE%\.ntlink-invoice\config.json`);
|
|
88
|
+
`NTLINK_INVOICE_CONFIG_DIR` permite cambiar su carpeta.
|
|
89
|
+
Los tokens se almacenan localmente sin cifrar; los archivos nuevos usan modo 0600
|
|
90
|
+
en POSIX y en Windows heredan las ACL de la carpeta del usuario.
|
|
91
|
+
`config show/list` solo muestran el modo y los perfiles; no imprimen el host ni los tokens.
|
|
92
|
+
|
|
93
|
+
### Autenticación
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
nt auth login
|
|
97
|
+
nt auth login --email usuario@example.invalid
|
|
98
|
+
nt auth status
|
|
99
|
+
nt auth accept-terms
|
|
100
|
+
nt auth logout
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
El login solicita la contraseña sin mostrarla en terminal. Usa
|
|
104
|
+
`POST /api/v2/auth/login` con `email/password` y guarda el campo `token` devuelto
|
|
105
|
+
por Membership Go. **Go no expone refresh token**: un 401 requiere iniciar sesión
|
|
106
|
+
otra vez. `auth status` consulta el perfil real, no solo la existencia del token.
|
|
107
|
+
`logout` borra el token local del perfil; no revoca JWT ya emitidos ni variables
|
|
108
|
+
de entorno que sigan definidas.
|
|
109
|
+
|
|
110
|
+
Para automatizar, usa `NTLINK_PASSWORD` o `--password-stdin` con `--email`:
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
nt auth login --email usuario@example.invalid --password-stdin
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Conecta stdin desde tu gestor de secretos o tubería. No hay opción `--password`
|
|
117
|
+
para evitar dejarla en los argumentos. `auth register registro.json` envía
|
|
118
|
+
`email`, `name`, `phone`, `rfc`, `postalCode`; puede crear una cuenta y enviar correo.
|
|
119
|
+
`auth verify-code codigo.json` envía `email` y `verificationCode`.
|
|
120
|
+
|
|
121
|
+
### Cuenta, directorios, estadísticas y reportes
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
nt client info
|
|
125
|
+
nt client balance
|
|
126
|
+
nt client companies
|
|
127
|
+
nt client usage --year 2026
|
|
128
|
+
nt client blacklist AAA010101AAA
|
|
129
|
+
nt customers list
|
|
130
|
+
nt customers get 123
|
|
131
|
+
nt customers create cliente.json
|
|
132
|
+
nt customers update 123 cliente.json
|
|
133
|
+
nt customers delete 123
|
|
134
|
+
nt companies list
|
|
135
|
+
nt companies get 10
|
|
136
|
+
nt companies create emisor.json
|
|
137
|
+
nt companies update 10 emisor.json
|
|
138
|
+
nt users list
|
|
139
|
+
nt users create usuario.json
|
|
140
|
+
nt users update usuario@example.invalid usuario.json
|
|
141
|
+
nt dashboard daily --range LAST_MONTH
|
|
142
|
+
nt dashboard types
|
|
143
|
+
nt dashboard status
|
|
144
|
+
nt dashboard top-receivers
|
|
145
|
+
nt dashboard top-transmitters
|
|
146
|
+
nt reports pending-ppd --company 10 --page 0 --size 50
|
|
147
|
+
nt reports retentions --from 2026-01-01 --to 2026-01-31
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`users update` recibe el **correo/username** como identificador, conforme a Go.
|
|
151
|
+
La autorización de usuarios exige administrador. Crear emisor no instala su CSD.
|
|
152
|
+
El CLI envía los JSON sin renombrar campos: los directorios usan los DTO del
|
|
153
|
+
[contrato Portal](../backend/doc/modules/Portal.md) y
|
|
154
|
+
[frontend/src/api/portal.ts](../frontend/src/api/portal.ts).
|
|
155
|
+
Ejemplo sintético de cliente (adapta empresa y datos fiscales antes de guardar):
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"companyId": 10,
|
|
160
|
+
"rfc": "AAA010101AAA",
|
|
161
|
+
"legalName": "CLIENTE DE EJEMPLO",
|
|
162
|
+
"taxRegime": "601",
|
|
163
|
+
"postalCode": "06000",
|
|
164
|
+
"email": "cliente@example.invalid"
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
El saldo viene de `/customer/balances`, con canales de portal y web service.
|
|
169
|
+
PPD conserva `outstandingBalance` y `balanceSource`; consultar no registra pagos.
|
|
170
|
+
Los listados CFDI/reportes/borradores aceptan `--page`, `--size`, `--company`,
|
|
171
|
+
`--customer`, `--search`, `--from`, `--to`, `--filter KEY=VALUE` y
|
|
172
|
+
`-q KEY=VALUE`. Cada endpoint aplica solo sus filtros admitidos: para borradores,
|
|
173
|
+
por ejemplo, usa `--filter estado=sin-timbrar` o `--filter folio=eq:BOR-000000001`.
|
|
174
|
+
La paginación del portal comienza en cero y admite hasta 200 filas por solicitud;
|
|
175
|
+
no descarga automáticamente las páginas restantes. La salida conserva el sobre
|
|
176
|
+
con `content`, `totalElements`, `totalPages`, `page` y `size`.
|
|
177
|
+
|
|
178
|
+
### Catálogos, CFDI y borradores
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
nt catalogs list
|
|
182
|
+
nt catalogs get moneda --id MXN
|
|
183
|
+
nt catalogs get ClaveProdServ --description consultoria
|
|
184
|
+
nt cfdi list --from 2026-01-01 --to 2026-01-31 --size 100
|
|
185
|
+
nt cfdi list --filter uuid=eq:00000000-0000-0000-0000-000000000000
|
|
186
|
+
nt cfdi get UUID
|
|
187
|
+
nt cfdi status UUID
|
|
188
|
+
nt cfdi validate factura.xml
|
|
189
|
+
nt cfdi download UUID --format xml --output factura.xml
|
|
190
|
+
nt cfdi download UUID --format pdf --output factura.pdf --force
|
|
191
|
+
nt cfdi prepare cfdi.json
|
|
192
|
+
nt drafts create cfdi.json
|
|
193
|
+
nt drafts list --filter estado=sin-timbrar
|
|
194
|
+
nt drafts get ID
|
|
195
|
+
nt drafts update ID cfdi.json
|
|
196
|
+
nt drafts reserve-folio
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Los nombres de catálogo se normalizan al nombre Go, por ejemplo `moneda` →
|
|
200
|
+
`Moneda`. La búsqueda envía `q`; `--id` busca identificador exacto. El listado
|
|
201
|
+
incluye los 15 catálogos del portal; los catálogos nativos adicionales están en
|
|
202
|
+
`native catalogo`. Que un nombre exista no garantiza que la base tenga sus datos.
|
|
203
|
+
|
|
204
|
+
`cfdi prepare` normaliza/recalcula en Go sin guardar ni emitir. `drafts create`
|
|
205
|
+
y `update` guardan en SQL. `drafts get` devuelve un sobre con `cfdi`, metadatos y
|
|
206
|
+
revisión: para actualizar, envía el **objeto `cfdi` interior**, no todo ese sobre.
|
|
207
|
+
`reserve-folio` reserva un folio provisional BOR, no el consecutivo fiscal.
|
|
208
|
+
Nómina y complementos viajan en el JSON del portal; el CLI no calcula ISR ni
|
|
209
|
+
subsidio. Consulta [emisión](../doc/flows/ISSUANCE.md) y
|
|
210
|
+
[nómina](../backend/doc/parity/payroll.md) para el alcance de cada variante.
|
|
211
|
+
|
|
212
|
+
Las operaciones explícitas siguientes también tienen comando:
|
|
213
|
+
|
|
214
|
+
```sh
|
|
215
|
+
nt cfdi stamp cfdi.json
|
|
216
|
+
nt drafts stamp ID cfdi.json
|
|
217
|
+
nt cfdi cancel UUID --reason 02
|
|
218
|
+
nt cfdi cancel UUID --reason 01 --replacement UUID_SUSTITUTO
|
|
219
|
+
nt cfdi email UUID --to facturacion@example.invalid --to archivo@example.invalid
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Estos comandos pueden emitir, cancelar o enviar realmente si el servidor lo
|
|
223
|
+
permite. No tienen un modo simulado; nombrar un perfil `pruebas` no garantiza
|
|
224
|
+
que su PAC sea sandbox. Las banderas y permisos de Go siguen siendo obligatorios.
|
|
225
|
+
Las descargas del portal usan `/api/v2/cfdis/{uuid}/xml|pdf`, distintas de las
|
|
226
|
+
rutas de descarga del CLI Proxy, y no sobrescriben archivos sin `--force`.
|
|
227
|
+
|
|
228
|
+
### Chat y análisis de PDF/XML/JSON
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
nt chat models
|
|
232
|
+
nt chat sessions create
|
|
233
|
+
nt chat sessions list
|
|
234
|
+
nt chat sessions get SESSION_ID
|
|
235
|
+
nt chat attach documento.pdf
|
|
236
|
+
nt chat send SESSION_ID "Analiza las discrepancias de este documento" --attach documento.pdf
|
|
237
|
+
nt chat send SESSION_ID "Consulta mis comprobantes" --provider google --model MODELO_HABILITADO
|
|
238
|
+
nt --timeout 360 chat events RUN_ID
|
|
239
|
+
nt --timeout 360 chat events RUN_ID --last-event-id 3
|
|
240
|
+
nt chat cancel RUN_ID
|
|
241
|
+
nt chat sessions delete SESSION_ID
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
`send` devuelve `sessionId`, `requestId` y `runId`; consulta sus eventos con
|
|
245
|
+
`chat events`. Se pueden adjuntar hasta tres archivos repitiendo `--attach`.
|
|
246
|
+
`chat attach` extrae el contenido por sí solo. Go conserva los límites de PDF
|
|
247
|
+
(5 MB, 30 páginas) y XML/JSON (1 MB), OCR selectivo y advertencias.
|
|
248
|
+
Los proveedores/modelos deben figurar en `chat models`.
|
|
249
|
+
|
|
250
|
+
`send --request-id UUID` permite reutilizar un identificador conocido sin crear
|
|
251
|
+
una nueva petición de chat; si falta, se genera uno. Los eventos salen como SSE
|
|
252
|
+
original (`id`, `event`, `data`), no como un único JSON. Un evento `error` o
|
|
253
|
+
`cancelled` es parte del protocolo SSE y debe interpretarlo el consumidor.
|
|
254
|
+
Cerrar el CLI o vencer su timeout no cancela la ejecución del servidor;
|
|
255
|
+
usa `chat cancel`, recupera la sesión y revisa borradores antes de repetir.
|
|
256
|
+
No hay reconexión SSE automática: utiliza `--last-event-id`.
|
|
257
|
+
`chat complete solicitud.json` conserva acceso al contrato síncrono de Go.
|
|
258
|
+
|
|
259
|
+
Analizar no autoriza guardar: solicita explícitamente la creación de un borrador
|
|
260
|
+
cuando quieras persistirlo. El chat puede consultar y preparar borradores; sus
|
|
261
|
+
herramientas no timbran, cancelan, cobran ni envían correos. Esas capacidades
|
|
262
|
+
pertenecen a los comandos explícitos y rutas nativas correspondientes.
|
|
263
|
+
|
|
264
|
+
### API manual y rutas nativas
|
|
265
|
+
|
|
266
|
+
```sh
|
|
267
|
+
nt health live
|
|
268
|
+
nt health ready
|
|
269
|
+
nt parity
|
|
270
|
+
nt api GET /api/v2/customer/profile
|
|
271
|
+
nt api GET /api/v2/cfdis -q page=0 -q size=20
|
|
272
|
+
nt api POST /api/v2/cfdis/prepare --data cfdi.json
|
|
273
|
+
nt api POST /api/v2/cfdis/validate --raw factura.xml --content-type application/xml
|
|
274
|
+
nt native routes
|
|
275
|
+
nt native routes --controller Empresa
|
|
276
|
+
nt native empresa --help
|
|
277
|
+
nt native empresa get-empresa -q id=10
|
|
278
|
+
nt native cfdi descargar-acuse --param id=123 --output acuse.xml
|
|
279
|
+
nt native validarxml validar --file archivoXml=factura.xml
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
`native` mapea las 87 rutas del registro nativo: catálogos, clientes, empresas,
|
|
283
|
+
usuarios, sesión, CSF, reportes, CFDI/REP, retenciones, plantillas, CSD/FIEL/convenios,
|
|
284
|
+
entrega y compras según el controlador. Todas conservan el método y path de Go.
|
|
285
|
+
`--param KEY=VALUE` sustituye parámetros de ruta, `-q KEY=VALUE` agrega query,
|
|
286
|
+
`--data archivo.json` envía JSON, `--raw archivo` envía bytes y
|
|
287
|
+
`--file CAMPO=RUTA`/`--field CLAVE=VALOR` construyen multipart.
|
|
288
|
+
`--header NOMBRE=VALOR` permite enviar cabeceras adicionales, por ejemplo las
|
|
289
|
+
requeridas por contratos con firma; sus valores no se imprimen en verbose.
|
|
290
|
+
Las tres formas de cuerpo son excluyentes. `--output` guarda cualquier respuesta
|
|
291
|
+
exitosa como bytes; `--stream` muestra SSE original y excluye `--output`.
|
|
292
|
+
|
|
293
|
+
Para conocer los campos particulares, abre el módulo del controlador desde
|
|
294
|
+
[backend/doc/INDEX.md](../backend/doc/INDEX.md), y consulta los nombres exactos con
|
|
295
|
+
`native GRUPO COMANDO --help`. Los comandos nativos siguen nombres derivados de
|
|
296
|
+
las acciones originales y sus DTO nativos; no reciben automáticamente los DTO del
|
|
297
|
+
portal. Por ejemplo, el `id` nativo de CFDI es el ID SQL, no su UUID.
|
|
298
|
+
La tabla siguiente se sincroniza con `npm run routes:sync`; es un inventario de
|
|
299
|
+
acceso, no una certificación de operación externa.
|
|
300
|
+
|
|
301
|
+
<!-- native-routes:start -->
|
|
302
|
+
| Comando (`nt native …`) | HTTP | Ruta Go |
|
|
303
|
+
|---|---|---|
|
|
304
|
+
| `catalogo get-clave-unidad` | GET | `/api/Catalogo/ClaveUnidad` |
|
|
305
|
+
| `catalogo get-clave-unidad-filtro` | GET | `/api/Catalogo/ClaveUnidadFiltro` |
|
|
306
|
+
| `catalogo get-clave-unidad-peso` | GET | `/api/Catalogo/ClaveUnidadPeso` |
|
|
307
|
+
| `catalogo buscar-estaciones` | GET | `/api/Catalogo/Estaciones` |
|
|
308
|
+
| `catalogo buscar-clave-prod-serv-cp` | GET | `/api/Catalogo/ClaveProdServCP` |
|
|
309
|
+
| `catalogo buscar-fraccion-arancelaria` | GET | `/api/Catalogo/FraccionArancelaria` |
|
|
310
|
+
| `catalogo buscar-prod-serv` | GET | `/api/Catalogo/ClaveProdServ` |
|
|
311
|
+
| `catalogo get-estados` | GET | `/api/Catalogo/GetEstados` |
|
|
312
|
+
| `catalogo get-paises` | GET | `/api/Catalogo/GetPaises` |
|
|
313
|
+
| `catalogo get-localidad` | GET | `/api/Catalogo/GetLocalidad` |
|
|
314
|
+
| `catalogo get-municipios` | GET | `/api/Catalogo/GetMunicipios` |
|
|
315
|
+
| `catalogo get-cps` | GET | `/api/Catalogo/GetCPs` |
|
|
316
|
+
| `catalogo existe-cp` | GET | `/api/Catalogo/ExisteCP` |
|
|
317
|
+
| `catalogo get-tasa-cuota` | GET | `/api/Catalogo/TasaCuota` |
|
|
318
|
+
| `catalogo get-monedas` | GET | `/api/Catalogo/Monedas` |
|
|
319
|
+
| `cfdi timbrar` | POST | `/api/CFDI/Timbrar` |
|
|
320
|
+
| `cfdi timbrado-previo` | POST | `/api/CFDI/TimbradoPrevio` |
|
|
321
|
+
| `cfdi guardar-plantilla` | POST | `/api/CFDI/Plantilla` |
|
|
322
|
+
| `cfdi listar-plantillas` | GET | `/api/CFDI/Plantillas` |
|
|
323
|
+
| `cfdi obtener-plantilla` | GET | `/api/CFDI/Plantilla/{id:long}` |
|
|
324
|
+
| `cfdi eliminar-plantilla` | POST | `/api/CFDI/Plantilla/{id:long}` |
|
|
325
|
+
| `cfdi descargar-xml` | GET | `/api/CFDI/xml/{id:int}` |
|
|
326
|
+
| `cfdi verificar-pdf` | HEAD | `/api/CFDI/pdf/{id:int}` |
|
|
327
|
+
| `cfdi descargar-pdf` | GET | `/api/CFDI/pdf/{id:int}` |
|
|
328
|
+
| `cfdi descargar-acuse` | GET | `/api/CFDI/acuse/{id:int}` |
|
|
329
|
+
| `cfdi enviar-correo` | POST | `/api/CFDI/correo/{id:int}` |
|
|
330
|
+
| `cfdi enviar-whats-app` | POST | `/api/CFDI/whatsapp/{id:int}` |
|
|
331
|
+
| `cfdi descargar-pdf-whats-app` | GET | `/api/CFDI/wa/{token}/{archivo}` |
|
|
332
|
+
| `cfdi cancelar` | POST | `/api/CFDI/cancelar/{id:int}` |
|
|
333
|
+
| `cliente get-clientes` | GET | `/api/Cliente/GetClientes` |
|
|
334
|
+
| `cliente get-by-id` | GET | `/api/Cliente/GetById` |
|
|
335
|
+
| `cliente guardar` | POST | `/api/Cliente/Guardar` |
|
|
336
|
+
| `config get-session-config` | GET | `/api/Config/session` |
|
|
337
|
+
| `empresa get-empresas` | GET | `/api/Empresa/GetEmpresas` |
|
|
338
|
+
| `empresa get-sucursales` | GET | `/api/Empresa/GetSucursales` |
|
|
339
|
+
| `empresa get-empresa` | GET | `/api/Empresa/GetEmpresa` |
|
|
340
|
+
| `empresa get-sucursales-lista` | GET | `/api/Empresa/GetSucursalesLista` |
|
|
341
|
+
| `empresa get-sucursal` | GET | `/api/Empresa/GetSucursal` |
|
|
342
|
+
| `empresa guardar` | POST | `/api/Empresa/Guardar` |
|
|
343
|
+
| `empresa validar-csd` | POST | `/api/Empresa/ValidarCSD` |
|
|
344
|
+
| `empresa tiene-csd` | GET | `/api/Empresa/TieneCsd` |
|
|
345
|
+
| `empresa subir-fiel` | POST | `/api/Empresa/SubirFiel` |
|
|
346
|
+
| `empresa guardar-sucursal` | POST | `/api/Empresa/GuardarSucursal` |
|
|
347
|
+
| `empresa parse-constancia` | POST | `/api/Empresa/ParseConstancia` |
|
|
348
|
+
| `homedashboard get-stats` | GET | `/api/HomeDashboard/stats` |
|
|
349
|
+
| `listanegra consultar-xml` | POST | `/api/ListaNegra/consultar-xml` |
|
|
350
|
+
| `pagos config` | GET | `/api/Pagos/Config` |
|
|
351
|
+
| `pagos crear-cargo2` | POST | `/api/Pagos/CrearCargo2` |
|
|
352
|
+
| `pagos validar-sesion` | GET | `/api/Pagos/ValidarSesion` |
|
|
353
|
+
| `pagos webhook` | POST | `/api/Pagos/Webhook` |
|
|
354
|
+
| `pagos generar-pre-factura-externa` | POST | `/api/Pagos/GenerarPreFacturaExterna` |
|
|
355
|
+
| `renovarfolios obtener-datos-empresa` | GET | `/api/RenovarFolios/ObtenerDatosEmpresa` |
|
|
356
|
+
| `renovarfolios renovar` | POST | `/api/RenovarFolios/Renovar` |
|
|
357
|
+
| `reporte get-cfdi` | GET | `/api/Reporte/GetCFDI` |
|
|
358
|
+
| `reporte lista-timbrado` | GET | `/api/Reporte/lista-timbrado` |
|
|
359
|
+
| `reporte reporte-anual` | GET | `/api/Reporte/reporte-anual` |
|
|
360
|
+
| `reporte reporte-empresa` | GET | `/api/Reporte/reporte-empresa` |
|
|
361
|
+
| `reporte anios` | GET | `/api/Reporte/anios` |
|
|
362
|
+
| `retenciones reporte` | GET | `/api/Retenciones/Reporte` |
|
|
363
|
+
| `retenciones enviar-correo` | POST | `/api/Retenciones/correo/{id:int}` |
|
|
364
|
+
| `retenciones cancelar` | POST | `/api/Retenciones/cancelar/{id:int}` |
|
|
365
|
+
| `retenciones descargar-acuse` | GET | `/api/Retenciones/acuse/{id:int}` |
|
|
366
|
+
| `retenciones timbrar` | POST | `/api/Retenciones/Timbrar` |
|
|
367
|
+
| `retenciones timbrado-previo` | POST | `/api/Retenciones/TimbradoPrevio` |
|
|
368
|
+
| `retenciones descargar-xml` | GET | `/api/Retenciones/xml/{id:int}` |
|
|
369
|
+
| `retenciones verificar-pdf` | HEAD | `/api/Retenciones/pdf/{id:int}` |
|
|
370
|
+
| `retenciones descargar-pdf` | GET | `/api/Retenciones/pdf/{id:int}` |
|
|
371
|
+
| `retenciones enviar-whats-app` | POST | `/api/Retenciones/whatsapp/{id:int}` |
|
|
372
|
+
| `retenciones descargar-pdf-whats-app` | GET | `/api/Retenciones/wa/{token}/{archivo}` |
|
|
373
|
+
| `session login` | POST | `/api/Session/Login` |
|
|
374
|
+
| `session generar-codigo` | POST | `/api/Session/GenerarCodigo` |
|
|
375
|
+
| `session generar-codigo-correo` | POST | `/api/Session/GenerarCodigoCorreo` |
|
|
376
|
+
| `session validar-codigo` | POST | `/api/Session/ValidarCodigo` |
|
|
377
|
+
| `session heartbeat` | POST | `/api/Session/Heartbeat` |
|
|
378
|
+
| `session logout` | POST | `/api/Session/Logout` |
|
|
379
|
+
| `session recuperar-contrasena` | POST | `/api/Session/RecuperarContrasena` |
|
|
380
|
+
| `session upload-csf` | POST | `/api/Session/UploadCSF` |
|
|
381
|
+
| `session registro` | POST | `/api/Session/Registro` |
|
|
382
|
+
| `session cambiar-contrasena` | POST | `/api/Session/CambiarContrasena` |
|
|
383
|
+
| `usuarioadmin get-usuarios` | GET | `/api/UsuarioAdmin/GetUsuarios` |
|
|
384
|
+
| `usuarioadmin debug-profile` | GET | `/api/UsuarioAdmin/DebugProfile` |
|
|
385
|
+
| `usuarioadmin guardar` | POST | `/api/UsuarioAdmin/Guardar` |
|
|
386
|
+
| `usuarioadmin editar` | POST | `/api/UsuarioAdmin/Editar` |
|
|
387
|
+
| `usuarioadmin cambiar-password` | POST | `/api/UsuarioAdmin/CambiarPassword` |
|
|
388
|
+
| `usuarioadmin bloquear` | POST | `/api/UsuarioAdmin/Bloquear/{userId}` |
|
|
389
|
+
| `usuarioadmin eliminar` | POST | `/api/UsuarioAdmin/Eliminar/{userId}` |
|
|
390
|
+
| `validarxml validar` | POST | `/api/ValidarXML/validar` |
|
|
391
|
+
<!-- native-routes:end -->
|
|
392
|
+
|
|
393
|
+
## Flujo y fallos
|
|
394
|
+
|
|
395
|
+
CLI → perfil/variables/opciones → HTTP Bearer a Go → permisos y reglas Go →
|
|
396
|
+
SQL/servicios según la ruta → JSON o archivo. No copia reglas fiscales al cliente.
|
|
397
|
+
Las peticiones anónimas solo se usan en login/registro/verificación, salud/paridad
|
|
398
|
+
y rutas nativas marcadas así por el registro; los catálogos del portal sí llevan JWT.
|
|
399
|
+
`api --anonymous` permite omitirlo deliberadamente.
|
|
400
|
+
|
|
401
|
+
La salida normal es JSON en stdout (`--json` es compatible y opcional). Los
|
|
402
|
+
errores van a stderr y terminan con código 1; el éxito usa 0. Ayuda/versión son
|
|
403
|
+
texto. `--verbose` imprime método, origen, ruta y estado en stderr; omite tokens,
|
|
404
|
+
query y cuerpos. Con `--output`, stdout devuelve `{ "path": "...", "bytes": 123 }`.
|
|
405
|
+
En PowerShell, evita convertir XML/PDF a texto por tubería: usa `--output`.
|
|
406
|
+
|
|
407
|
+
No se reintenta ninguna petición automáticamente, tampoco después de 401. Un
|
|
408
|
+
timeout, 502 o fallo de red durante una escritura puede tener resultado incierto:
|
|
409
|
+
consulta su estado antes de repetir. Un timbrado externo y su persistencia SQL
|
|
410
|
+
pueden tener éxito parcial; sigue la recuperación documentada en Go.
|
|
411
|
+
Los errores HTTP conservan estado y mensaje; `exito:false` nativo también falla.
|
|
412
|
+
Go puede devolver 403 por alcance, 409 por conflicto, 501 por módulo pendiente o
|
|
413
|
+
503 por configuración/servicio/catálogo ausente. El CLI no habilita esas funciones.
|
|
414
|
+
|
|
415
|
+
## Reglas y trazabilidad
|
|
416
|
+
|
|
417
|
+
| Regla | Implementación y evidencia |
|
|
418
|
+
|---|---|
|
|
419
|
+
| Token separado por perfil y origen | `src/config.ts`; pruebas de perfiles, override y logout |
|
|
420
|
+
| Sin refresh ni repetición automática | `src/http.ts`, `auth login`; pruebas 401/503 y escrituras |
|
|
421
|
+
| Descarga exacta y sin sobrescritura implícita | `src/http.ts`; prueba de bytes y `--force` |
|
|
422
|
+
| Rutas reales sin inventar equivalentes Proxy | `src/native-routes.json`, `scripts/sync-routes.mjs`; prueba contra registro Go |
|
|
423
|
+
| Chat conserva requestId y SSE | `src/cli.ts`; prueba de adjuntos, modelo, eventos y cancelación |
|
|
424
|
+
|
|
425
|
+
Fuentes: [Portal](../backend/doc/modules/Portal.md),
|
|
426
|
+
[router Go](../backend/internal/api/server.go),
|
|
427
|
+
[registro nativo](../backend/internal/legacy/routes.json),
|
|
428
|
+
[chat Go](../backend/internal/api/ai.go) y
|
|
429
|
+
[capacidades y límites](../doc/FEATURES.md).
|
|
430
|
+
|
|
431
|
+
## Estado y verificación
|
|
432
|
+
|
|
433
|
+
Implementación 27/oct/2026. Comprobaciones locales:
|
|
434
|
+
|
|
435
|
+
```sh
|
|
436
|
+
npm ci
|
|
437
|
+
npm run typecheck
|
|
438
|
+
npm test
|
|
439
|
+
npm run routes:sync
|
|
440
|
+
npm run build
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
Las pruebas lanzan el ejecutable real contra un servidor HTTP sintético local;
|
|
444
|
+
comprueban comandos, login, perfiles, contratos de transporte, descargas, multipart,
|
|
445
|
+
chat y errores. No equivalen a integración Go/SQL/PAC ni prueban timbrados,
|
|
446
|
+
cancelaciones, correos, compras o disponibilidad productiva. No se modificó Go.
|
|
447
|
+
Las 11 pruebas pasaron en Windows (Node 24) y Ubuntu mediante WSL (Node 22.22.0).
|
|
448
|
+
También se consultaron `/health/live` y `/health/ready` del Go real en
|
|
449
|
+
`localhost:8092`: estado `ok`, `ready: true`, conexiones main/sat/catalogs `ok`.
|
|
450
|
+
Esas consultas no comprueban login real ni escrituras de negocio.
|