se agrega .md de tailscale para hacer gitea https
This commit is contained in:
1 parent
f915802fb4
commit
920a4a2d56
10 files changed
+2081
-2066
No files matched your search
Vendored
+33
-12
@@ -4,11 +4,11 @@
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "7eb63950e584c8c8",
|
||||
"id": "74bf841407436ba6",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "52972da0bc9d4ad0",
|
||||
"id": "0519cc60f14f90b9",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
@@ -41,7 +41,9 @@
|
||||
"type": "file-explorer",
|
||||
"state": {
|
||||
"sortOrder": "alphabetical",
|
||||
"autoReveal": false
|
||||
"autoReveal": false,
|
||||
"showSearch": false,
|
||||
"searchQuery": ""
|
||||
},
|
||||
"icon": "lucide-folder-closed",
|
||||
"title": "Files"
|
||||
@@ -183,16 +185,38 @@
|
||||
"bases:Create new base": false
|
||||
}
|
||||
},
|
||||
"active": "52972da0bc9d4ad0",
|
||||
"active": "0519cc60f14f90b9",
|
||||
"lastOpenFiles": [
|
||||
"005-Learn/Instructivo Git Gitea.md",
|
||||
"005-Learn/Instructivo Entornos Virtuales Python.md",
|
||||
"005-Learn/Instructivo Git Branches.md",
|
||||
"005-Learn/Instructivo Git Gitea.md",
|
||||
"005-Learn/Planificación desarrollo agente ia.md",
|
||||
"005-Learn/Obsidian WorkingCopy Manual.md",
|
||||
"005-Learn/Proyecto SAP B1 - FastAPI - React - Next.js.md",
|
||||
"005-Learn/Roadmap Next.js.md",
|
||||
"005-Learn/Instructivo launchd iOS.md",
|
||||
"005-Learn/Guia_Entornos_Virtuales_Python.md",
|
||||
"005-Learn/Stack Tecnológico Recomendado.md",
|
||||
"005-Learn/Roadmap Next.js.md",
|
||||
"005-Learn/Proyecto SAP B1 - FastAPI - React - Next.js.md",
|
||||
"006-Proyecto-Bingo/07 UI Components.md",
|
||||
"006-Proyecto-Bingo/06 Estados (Zustand).md",
|
||||
"006-Proyecto-Bingo/04 Motor lógico de Bingo.md",
|
||||
"006-Proyecto-Bingo/02 Diagrama.md",
|
||||
"006-Proyecto-Bingo/01 Markdown del proyecto.md",
|
||||
"006-Proyecto-Bingo/00 App Bingo.md",
|
||||
"006-Proyecto-Bingo/03 SQLite.md",
|
||||
"006-Proyecto-Bingo/05 Navegación.md",
|
||||
"005-Learn/Instructivo_launchd_SAP_B1_SUNAT.md",
|
||||
"006-Proyecto-Bingo/sqlite_erd_flat_design.png",
|
||||
"006-Proyecto-Bingo/mockup-bingo.png",
|
||||
"006-Proyectos/01 Proyecto App Bingo.md",
|
||||
"006-Proyectos/07 Modelo de datos Isar.md",
|
||||
"006-Proyectos/02 Arquitectura técnica.md",
|
||||
"006-Proyectos/03 Entorno de desarrollo.md",
|
||||
"006-Proyectos/06 Mockups base.md",
|
||||
"006-Proyectos/04 Estructura de carpetas.md",
|
||||
"006-Proyectos/05 Mockups iniciales.md",
|
||||
"006-Proyecto-Bingo",
|
||||
"005-Learn/roadmap_nextjs_erp.html",
|
||||
"Instructivo Git Gitea.md",
|
||||
"005-Learn",
|
||||
"004-SDK-SAP",
|
||||
"003-Hana",
|
||||
@@ -200,9 +224,6 @@
|
||||
"001-Linux",
|
||||
"Untitled.canvas",
|
||||
"Untitled.base",
|
||||
"Roadmap-nextjs-erp.md",
|
||||
"roadmap_nextjs_erp.html",
|
||||
"2026-05-18.md",
|
||||
"Welcome.md"
|
||||
"roadmap_nextjs_erp.html"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
# Creación de entornos virtuales en Python
|
||||
|
||||
## Requisitos
|
||||
|
||||
- Tener Python instalado.
|
||||
- Verificar:
|
||||
|
||||
``` bash
|
||||
python --version
|
||||
```
|
||||
|
||||
## Crear el entorno
|
||||
|
||||
``` bash
|
||||
python -m venv .venv
|
||||
```
|
||||
|
||||
## Activar
|
||||
|
||||
### macOS / Linux
|
||||
|
||||
``` bash
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
### Windows CMD
|
||||
|
||||
``` cmd
|
||||
.venv\Scripts\activate.bat
|
||||
```
|
||||
|
||||
### Windows PowerShell
|
||||
|
||||
``` powershell
|
||||
.venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
## Instalar dependencias
|
||||
|
||||
``` bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
o
|
||||
|
||||
``` bash
|
||||
pip install requests fastapi uvicorn
|
||||
```
|
||||
|
||||
## Guardar dependencias
|
||||
|
||||
``` bash
|
||||
pip freeze > requirements.txt
|
||||
```
|
||||
|
||||
## Desactivar
|
||||
|
||||
``` bash
|
||||
deactivate
|
||||
```
|
||||
|
||||
## Verificar el intérprete
|
||||
|
||||
``` bash
|
||||
python -c "import sys; print(sys.executable)"
|
||||
```
|
||||
|
||||
## .gitignore recomendado
|
||||
|
||||
``` gitignore
|
||||
.venv/
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
.vscode/
|
||||
.idea/
|
||||
.env
|
||||
.pytest_cache/
|
||||
.mypy_cache/
|
||||
.ruff_cache/
|
||||
*.sqlite3
|
||||
*.db
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
```
|
||||
@@ -1,192 +1,755 @@
|
||||
# 🌿 Guía Completa para Crear y Manejar un Branch en Git
|
||||
|
||||
Porque romper `main` directamente es una tradición demasiado popular en desarrollo de software.
|
||||
Git existe precisamente para evitar ese tipo de tragedias humanas.
|
||||
|
||||
|
||||
Romper `main` directamente sigue siendo una tradición muy popular en desarrollo de software.
|
||||
|
||||
Git existe precisamente para evitar ese tipo de tragedias.
|
||||
|
||||
|
||||
|
||||
En esta guía usaremos un caso real como hilo conductor: una agencia que lleva un **proyecto por cada cliente**, y necesita crear una rama nueva cada vez que empieza a trabajar en la funcionalidad de un cliente específico (por ejemplo, `cliente-acme`).
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
gitGraph
|
||||
|
||||
commit id: "inicio"
|
||||
|
||||
commit id: "version estable"
|
||||
|
||||
branch cliente-acme
|
||||
|
||||
checkout cliente-acme
|
||||
|
||||
commit id: "dashboard acme"
|
||||
|
||||
commit id: "ajustes acme"
|
||||
|
||||
checkout main
|
||||
|
||||
merge cliente-acme id: "merge acme a main"
|
||||
|
||||
branch cliente-globex
|
||||
|
||||
checkout cliente-globex
|
||||
|
||||
commit id: "reporte globex"
|
||||
|
||||
checkout main
|
||||
|
||||
merge cliente-globex id: "merge globex a main"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 1️⃣ Verifica el estado actual del proyecto
|
||||
|
||||
|
||||
## 🗺️ Flujo general del proceso
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
flowchart TD
|
||||
|
||||
A[git status] --> B{Hay cambios sin guardar?}
|
||||
|
||||
B -- Si --> C[git add . + git commit]
|
||||
|
||||
B -- No --> D
|
||||
|
||||
C --> D[git checkout main]
|
||||
|
||||
D --> E[git pull]
|
||||
|
||||
E --> F["git checkout -b cliente-acme"]
|
||||
|
||||
F --> G[git branch para confirmar]
|
||||
|
||||
G --> H[Trabajar y hacer commits]
|
||||
|
||||
H --> I[git checkout main]
|
||||
|
||||
I --> J["git merge cliente-acme"]
|
||||
|
||||
J --> K[git push]
|
||||
|
||||
K --> L["git branch -d cliente-acme"]
|
||||
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
Esto te mostrará:
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
## 1️⃣ Verifica el estado actual del proyecto
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git status
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
Esto te muestra:
|
||||
|
||||
|
||||
|
||||
- Archivos modificados
|
||||
|
||||
- Archivos en stage
|
||||
|
||||
- Archivos sin seguimiento
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 2️⃣ Guarda tus cambios importantes
|
||||
|
||||
|
||||
Si tienes cambios importantes, crea un commit antes de crear el branch.
|
||||
## 2️⃣ Guarda tus cambios importantes
|
||||
|
||||
|
||||
|
||||
Si tienes cambios importantes, crea un commit antes de crear el branch:
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git add .
|
||||
|
||||
git commit -m "Version estable antes de nueva funcionalidad"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
✅ Esto crea un punto seguro al cual regresar.
|
||||
|
||||
---
|
||||
|
||||
|
||||
## 📦 Alternativa: usar stash
|
||||
### 📦 Alternativa: usar stash
|
||||
|
||||
|
||||
|
||||
Si todavía no quieres hacer commit:
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git stash
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
Luego podrás recuperarlos con:
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git stash pop
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 3️⃣ Ve a la rama principal
|
||||
|
||||
|
||||
## 3️⃣ Ve a la rama principal
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git checkout main
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 4️⃣ Descarga lo último del repositorio
|
||||
|
||||
|
||||
## 4️⃣ Descarga lo último del repositorio
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git pull
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
Esto sincroniza tu proyecto local con el remoto.
|
||||
|
||||
---
|
||||
|
||||
# 5️⃣ Crea la nueva rama
|
||||
|
||||
```bash
|
||||
git checkout -b nueva-funcionalidad
|
||||
```
|
||||
|
||||
## 📌 Ejemplo real
|
||||
|
||||
```bash
|
||||
git checkout -b agregar-dashboard-powerbi
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 6️⃣ Verifica que estás en la nueva rama
|
||||
|
||||
|
||||
## 5️⃣ Crea la nueva rama
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git checkout -b nombre-de-la-rama
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 📌 Ejemplo con proyecto por cliente
|
||||
|
||||
|
||||
|
||||
Supongamos que la agencia empieza a trabajar en el dashboard del cliente **Acme**:
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git checkout -b cliente-acme
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
Si más adelante empieza otro proyecto, para el cliente **Globex**:
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git checkout -b cliente-globex
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
De esta forma cada cliente tiene su propio espacio de trabajo aislado, sin afectar el código de los demás.
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
gitGraph
|
||||
|
||||
commit id: "main estable"
|
||||
|
||||
branch cliente-acme
|
||||
|
||||
branch cliente-globex
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
## 6️⃣ Verifica que estás en la nueva rama
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git branch
|
||||
|
||||
```
|
||||
|
||||
La rama actual aparecerá con un `*`
|
||||
|
||||
|
||||
## 📌 Ejemplo
|
||||
La rama actual aparecerá marcada con un `*`.
|
||||
|
||||
|
||||
|
||||
### 📌 Ejemplo
|
||||
|
||||
|
||||
|
||||
```text
|
||||
|
||||
main
|
||||
* agregar-dashboard-powerbi
|
||||
|
||||
* cliente-acme
|
||||
|
||||
cliente-globex
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 7️⃣ Trabaja normalmente y guarda cambios
|
||||
|
||||
|
||||
## 7️⃣ Trabaja normalmente y guarda cambios
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git add .
|
||||
git commit -m "Agrega nueva funcionalidad"
|
||||
|
||||
git commit -m "Agrega dashboard de ventas para Acme"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
Puedes repetir este paso tantas veces como necesites mientras avanzas en el proyecto del cliente:
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git add .
|
||||
|
||||
git commit -m "Ajusta colores y logo segun manual de marca de Acme"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
gitGraph
|
||||
|
||||
commit id: "main estable"
|
||||
|
||||
branch cliente-acme
|
||||
|
||||
checkout cliente-acme
|
||||
|
||||
commit id: "dashboard ventas"
|
||||
|
||||
commit id: "ajustes de marca"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 8️⃣ Regresa a main cuando todo funcione
|
||||
|
||||
|
||||
## 8️⃣ Regresa a main cuando todo funcione
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git checkout main
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 9️⃣ Une la nueva funcionalidad a main
|
||||
|
||||
|
||||
## 9️⃣ Une la nueva funcionalidad a main
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
git merge nueva-funcionalidad
|
||||
|
||||
git merge cliente-acme
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 📌 Ejemplo del resultado
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
gitGraph
|
||||
|
||||
commit id: "main estable"
|
||||
|
||||
branch cliente-acme
|
||||
|
||||
checkout cliente-acme
|
||||
|
||||
commit id: "dashboard ventas"
|
||||
|
||||
commit id: "ajustes de marca"
|
||||
|
||||
checkout main
|
||||
|
||||
merge cliente-acme id: "entrega a Acme lista"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 🔟 Sube los cambios al repositorio remoto
|
||||
|
||||
|
||||
## 🔟 Sube los cambios al repositorio remoto
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git push
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 1️⃣1️⃣ Elimina la rama si ya no la necesitas
|
||||
|
||||
|
||||
## 1️⃣1️⃣ Elimina la rama si ya no la necesitas
|
||||
|
||||
|
||||
|
||||
Una vez que el trabajo del cliente ya fue entregado y fusionado a `main`, puedes borrar la rama para mantener el repositorio limpio:
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
git branch -d nueva-funcionalidad
|
||||
|
||||
git branch -d cliente-acme
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
# 🧠 Recomendaciones importantes
|
||||
Si Git no te deja borrarla porque detecta cambios sin fusionar, y estás seguro de que quieres eliminarla de todos modos:
|
||||
|
||||
✅ Nunca trabajes directamente sobre `main`
|
||||
✅ Haz commits pequeños y claros
|
||||
✅ Usa nombres descriptivos para tus branches
|
||||
✅ Verifica siempre con `git status`
|
||||
|
||||
---
|
||||
|
||||
# 🚨 Comandos útiles extra
|
||||
|
||||
## Ver historial de commits
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git branch -D cliente-acme
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
## 🧠 Recomendaciones importantes
|
||||
|
||||
|
||||
|
||||
✅ Nunca trabajes directamente sobre `main`
|
||||
|
||||
✅ Haz commits pequeños y claros
|
||||
|
||||
✅ Usa nombres descriptivos para tus branches (por ejemplo, `cliente-acme`, no `rama1`)
|
||||
|
||||
✅ Verifica siempre con `git status` antes de cambiar de rama
|
||||
|
||||
✅ Si manejas varios clientes a la vez, mantén una rama por cliente para evitar mezclar entregas
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
gitGraph
|
||||
|
||||
commit id: "main"
|
||||
|
||||
branch cliente-acme
|
||||
|
||||
branch cliente-globex
|
||||
|
||||
branch cliente-initech
|
||||
|
||||
checkout cliente-acme
|
||||
|
||||
commit id: "avance acme"
|
||||
|
||||
checkout cliente-globex
|
||||
|
||||
commit id: "avance globex"
|
||||
|
||||
checkout cliente-initech
|
||||
|
||||
commit id: "avance initech"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
## ❓ ¿Siempre hay que hacer merge a main?
|
||||
|
||||
|
||||
|
||||
No. El `merge` a `main` solo tiene sentido si `main` representa algo que **todos los clientes comparten**. Si los cambios son exclusivos de un cliente y no deben mezclarse con nada más, tienes otras opciones.
|
||||
|
||||
|
||||
|
||||
### Opción 1: La rama del cliente vive sola (sin merge a main)
|
||||
|
||||
|
||||
|
||||
Trabajas y subes esa rama directamente, sin tocar `main`:
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git checkout -b cliente-acme
|
||||
|
||||
# ... trabajas y haces commits ...
|
||||
|
||||
git push origin cliente-acme
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
`main` se queda intacto, y `cliente-acme` existe como una línea de desarrollo independiente para siempre (o hasta que ya no la necesites).
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
gitGraph
|
||||
|
||||
commit id: "main estable"
|
||||
|
||||
branch cliente-acme
|
||||
|
||||
checkout cliente-acme
|
||||
|
||||
commit id: "dashboard acme"
|
||||
|
||||
commit id: "ajustes acme"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
Aquí `cliente-acme` nunca se vuelve a juntar con `main`.
|
||||
|
||||
|
||||
|
||||
### Opción 2: main es solo una plantilla base
|
||||
|
||||
|
||||
|
||||
Si cada cliente parte de una base común (por ejemplo, la plantilla del proyecto), tiene sentido traer cambios **de main hacia el cliente** cuando la plantilla mejora, pero no al revés:
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git checkout cliente-acme
|
||||
|
||||
git merge main
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
Esto trae las mejoras de la plantilla al proyecto del cliente. Es al revés del flujo normal: en vez de `cliente-acme → main`, es `main → cliente-acme`.
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
gitGraph
|
||||
|
||||
commit id: "plantilla v1"
|
||||
|
||||
branch cliente-acme
|
||||
|
||||
checkout main
|
||||
|
||||
commit id: "plantilla v2 mejorada"
|
||||
|
||||
checkout cliente-acme
|
||||
|
||||
commit id: "avance acme"
|
||||
|
||||
merge main id: "trae mejoras de plantilla"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Opción 3: Cada cliente es su propio repositorio o deploy
|
||||
|
||||
|
||||
|
||||
Si el código de cada cliente es tan distinto que ni siquiera comparte historial útil con los demás, muchas agencias usan directamente **una rama por cliente que se despliega tal cual**, sin merges entre ellas. En este caso `main` queda solo como referencia general, o incluso no se usa en ese repo.
|
||||
|
||||
|
||||
|
||||
```mermaid
|
||||
|
||||
gitGraph
|
||||
|
||||
commit id: "main (referencia)"
|
||||
|
||||
branch cliente-acme
|
||||
|
||||
branch cliente-globex
|
||||
|
||||
checkout cliente-acme
|
||||
|
||||
commit id: "deploy acme"
|
||||
|
||||
checkout cliente-globex
|
||||
|
||||
commit id: "deploy globex"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
> 💡 Elige la opción según qué tan relacionado esté el trabajo entre clientes: si comparten código base, usa la Opción 2; si son totalmente independientes, la Opción 1 o la Opción 3.
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
## 🚨 Comandos útiles extra
|
||||
|
||||
|
||||
|
||||
### Ver historial de commits
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git log --oneline
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Ver diferencias de archivos
|
||||
### Ver diferencias de archivos
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git diff
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Salir del visor de git diff
|
||||
### Salir del visor de git diff / git log
|
||||
|
||||
|
||||
|
||||
Presiona:
|
||||
|
||||
|
||||
|
||||
```text
|
||||
|
||||
q
|
||||
|
||||
```
|
||||
|
||||
Porque claramente mostrar texto simple en terminal era demasiado fácil para Unix.
|
||||
|
||||
|
||||
### Ver todas las ramas, incluidas las remotas
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git branch -a
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Cambiar de una rama de cliente a otra rápidamente
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
git checkout cliente-globex
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
# 🎯 Resultado esperado
|
||||
|
||||
|
||||
Tu flujo ideal debería verse así:
|
||||
## 🎯 Resultado esperado
|
||||
|
||||
|
||||
|
||||
Tu flujo ideal, aplicado al caso de proyectos por cliente, debería verse así:
|
||||
|
||||
|
||||
|
||||
```text
|
||||
|
||||
main
|
||||
└── nueva-funcionalidad
|
||||
└── commits
|
||||
└── merge a main
|
||||
|
||||
├── cliente-acme
|
||||
|
||||
│ └── commits del proyecto Acme
|
||||
|
||||
│ └── merge a main
|
||||
|
||||
├── cliente-globex
|
||||
|
||||
│ └── commits del proyecto Globex
|
||||
|
||||
│ └── merge a main
|
||||
|
||||
└── cliente-initech
|
||||
|
||||
└── commits del proyecto Initech
|
||||
|
||||
└── merge a main
|
||||
|
||||
```
|
||||
|
||||
Un proceso ordenado.
|
||||
Casi sospechosamente profesional para estándares normales de desarrollo.
|
||||
|
||||
|
||||
Un proceso ordenado, con una rama independiente por cada cliente, y `main` siempre reflejando el estado estable y entregado del trabajo.
|
||||
@@ -1,17 +1,30 @@
|
||||
# 🚀 Subir proyecto local a Gitea (Mac + Tailscale)
|
||||
|
||||
## 1. Crear `.gitignore`
|
||||
> Guía ordenada por **flujo normal de trabajo**. Si algo falla, sigue las marcas ⚠️ que apuntan a su resolución al final del documento.
|
||||
|
||||
---
|
||||
|
||||
## PARTE A — FLUJO NORMAL (paso a paso)
|
||||
|
||||
### 1. Crear repositorio en Gitea
|
||||
- Nombre: `descarga_adjuntos_correos_cpe`
|
||||
- Sin README
|
||||
- Sin opciones automáticas
|
||||
|
||||
> Guarda la URL del repositorio para usarla después.
|
||||
|
||||
### 2. Crear `.gitignore`
|
||||
```bash
|
||||
cd /Users/george/descarga_adjuntos_correos_cpe
|
||||
touch .gitignore
|
||||
```
|
||||
|
||||
## 2. Editar `.gitignore`
|
||||
### 3. Editar `.gitignore`
|
||||
```bash
|
||||
nano .gitignore
|
||||
```
|
||||
|
||||
### Contenido recomendado
|
||||
#### Contenido recomendado
|
||||
```bash
|
||||
__pycache__/
|
||||
*.pyc
|
||||
@@ -23,100 +36,131 @@ secrets.yaml
|
||||
.idea/
|
||||
```
|
||||
|
||||
## 3. Si ya hiciste `git add` antes del `.gitignore`
|
||||
```bash
|
||||
git rm -r --cached .
|
||||
git add .
|
||||
git commit -m "aplicar gitignore correctamente"
|
||||
```
|
||||
> ⚠️ ¿Ya habías hecho `git add` antes de crear el `.gitignore`? → [[#Resolución: archivos que debían ignorarse siguen apareciendo]]
|
||||
|
||||
## 4. Inicializar repositorio Git
|
||||
### 4. Inicializar repositorio Git
|
||||
```bash
|
||||
cd /Users/george/descarga_adjuntos_correos_cpe
|
||||
git init
|
||||
```
|
||||
|
||||
## 5. Agregar archivos
|
||||
### 5. Agregar archivos
|
||||
```bash
|
||||
git add .
|
||||
```
|
||||
|
||||
## 6. Primer commit
|
||||
> ⚠️ ¿Agregaste errores o archivos incorrectos? → [[#Resolución: quitar archivos del staging (deshacer git add)]]
|
||||
|
||||
### 6. Primer commit
|
||||
```bash
|
||||
git commit -m "primer commit"
|
||||
```
|
||||
|
||||
## 6.1 Commit de un proyecto dentro de una Solución
|
||||
> ⚠️ ¿El commit quedó mal y aún no hice push? → [[#Resolución: deshacer un commit antes de subirlo]]
|
||||
|
||||
### 7. Conectar repo local con Gitea
|
||||
```bash
|
||||
git remote add origin http://100.68.242.27:30000/george/descarga_adjuntos_correos_cpe.git
|
||||
```
|
||||
|
||||
> ⚠️ ¿El remote ya existe o está mal configurado? → [[#Resolución: problemas con el remote]]
|
||||
|
||||
### 8. Subir código por primera vez
|
||||
```bash
|
||||
git branch -M main
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
> ⚠️ ¿El push falla por conexión o autenticación? → [[#Resolución: no puedo subir (push)]]
|
||||
|
||||
---
|
||||
|
||||
## PARTE B — VARIANTES DE COMMIT
|
||||
|
||||
Estos pasos van **después** del commit básico según lo que necesites.
|
||||
|
||||
### Commit de un proyecto dentro de una Solución
|
||||
```bash
|
||||
git add ProyectoA/
|
||||
git status
|
||||
git commit -m "mensaje commit para los archivos modificados del proyecto"
|
||||
```
|
||||
|
||||
## 6.2 Commit de un archivo específico dentro de un proyecto
|
||||
### Commit de un archivo específico dentro de un proyecto
|
||||
```bash
|
||||
git add ProyectoA/FacturaNegociable.cs
|
||||
git status
|
||||
git commit -m "mensaje commit para el archivo especifico del proyecto"
|
||||
```
|
||||
|
||||
## 6. 3 Git reset , quita todos los archivos del staging area que coloco git add, reversa el git add antes del git commit
|
||||
```bash
|
||||
git reset
|
||||
```
|
||||
---
|
||||
|
||||
## 6. 4 Git reset , si ya hice commit, pero aún no hice push
|
||||
```bash
|
||||
git reset --soft HEAD~1
|
||||
git reset
|
||||
```
|
||||
## PARTE C — FLUJO DIARIO
|
||||
|
||||
## 7. Crear repositorio en Gitea
|
||||
- Nombre: descarga_adjuntos_correos_cpe
|
||||
- Sin README
|
||||
- Sin opciones automáticas
|
||||
|
||||
## 8. URL del repositorio
|
||||
```bash
|
||||
http://100.68.242.27:30000/george/descarga_adjuntos_correos_cpe.git
|
||||
```
|
||||
|
||||
## 9. Conectar repo local con Gitea
|
||||
```bash
|
||||
git remote add origin http://100.68.242.27:30000/george/descarga_adjuntos_correos_cpe.git
|
||||
```
|
||||
|
||||
## 10. Subir código por primera vez
|
||||
```bash
|
||||
git branch -M main
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
## 11. Cambiar URL del repositorio
|
||||
```bash
|
||||
git remote set-url origin http://100.x.x.x:3000/george/descarga_adjuntos_correos_cpe.git
|
||||
git remote -v
|
||||
```
|
||||
|
||||
## 12. Eliminar y volver a configurar remote
|
||||
```bash
|
||||
git remote remove origin
|
||||
git remote add origin http://100.68.242.27:3000/george/descarga_adjuntos_correos_cpe.git
|
||||
```
|
||||
|
||||
## 13. Validar conexión
|
||||
```bash
|
||||
curl http://100.68.242.27:30000
|
||||
```
|
||||
|
||||
## 14. Acceso a Gitea
|
||||
|
||||
[URL de Gitea en NAS](http://100.68.242.27:30000)
|
||||
|
||||
|
||||
## 15. Flujo diario
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "mensaje claro"
|
||||
git push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PARTE D — CLONAR / REUTILIZAR
|
||||
|
||||
### Clonar repositorio
|
||||
```bash
|
||||
git clone http://100.68.242.27:3000/george/descarga_adjuntos_correos_cpe.git
|
||||
```
|
||||
|
||||
### Validar conexión con Gitea
|
||||
```bash
|
||||
curl http://100.68.242.27:30000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PARTE E — ACCESO
|
||||
|
||||
- [URL de Gitea en NAS](http://100.68.242.27:30000)
|
||||
|
||||
---
|
||||
|
||||
# 🔧 RESOLUCIÓN DE PROBLEMAS
|
||||
|
||||
## Resolución: archivos que debían ignorarse siguen apareciendo
|
||||
Si ya hiciste `git add` antes del `.gitignore`, quitalos del índice:
|
||||
```bash
|
||||
git rm -r --cached .
|
||||
git add .
|
||||
git commit -m "aplicar gitignore correctamente"
|
||||
```
|
||||
|
||||
## Resolución: quitar archivos del staging (deshacer git add)
|
||||
Si agregaste archivos que no deberían ir, reversa el `git add` **antes** de commitear:
|
||||
```bash
|
||||
git reset
|
||||
```
|
||||
|
||||
## Resolución: deshacer un commit antes de subirlo
|
||||
Si ya hiciste commit pero **aún no** hiciste push:
|
||||
```bash
|
||||
git reset --soft HEAD~1
|
||||
git reset
|
||||
```
|
||||
|
||||
## Resolución: no puedo subir (push)
|
||||
- Verifica la conexión con el NAS: `curl http://100.68.242.27:30000`
|
||||
- Revisa si el remote está bien configurado: `git remote -v`
|
||||
|
||||
## Resolución: problemas con el remote (URL incorrecta o antigua)
|
||||
### Cambiar la URL del repositorio
|
||||
```bash
|
||||
git remote set-url origin http://100.x.x.x:3000/george/descarga_adjuntos_correos_cpe.git
|
||||
git remote -v
|
||||
```
|
||||
|
||||
### Eliminar y volver a configurar el remote
|
||||
```bash
|
||||
git remote remove origin
|
||||
git remote add origin http://100.68.242.27:3000/george/descarga_adjuntos_correos_cpe.git
|
||||
```
|
||||
@@ -0,0 +1,171 @@
|
||||
# Instructivo: Ejecutar un servicio Python con launchd en macOS
|
||||
|
||||
## Objetivo
|
||||
|
||||
Ejecutar un servicio de Python de forma automática utilizando `launchd`.
|
||||
|
||||
## Estructura sugerida
|
||||
|
||||
``` text
|
||||
/Users/george/services/sap_sunat/
|
||||
.venv/
|
||||
main.py
|
||||
config.ini
|
||||
logs/
|
||||
stdout.log
|
||||
stderr.log
|
||||
```
|
||||
|
||||
## Verificar el entorno virtual
|
||||
|
||||
Activar:
|
||||
|
||||
``` bash
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
Obtener el intérprete:
|
||||
|
||||
``` bash
|
||||
which python
|
||||
```
|
||||
|
||||
Usar esa ruta en `ProgramArguments`.
|
||||
|
||||
## Archivo .plist
|
||||
|
||||
Ubicación recomendada para un usuario:
|
||||
|
||||
``` text
|
||||
~/Library/LaunchAgents/com.george.sap.sunat.plist
|
||||
```
|
||||
|
||||
Claves habituales:
|
||||
|
||||
- `Label`
|
||||
- `ProgramArguments`
|
||||
- `WorkingDirectory`
|
||||
- `RunAtLoad`
|
||||
- `KeepAlive`
|
||||
- `StandardOutPath`
|
||||
- `StandardErrorPath`
|
||||
|
||||
## Comentarios
|
||||
|
||||
Se permiten comentarios XML:
|
||||
|
||||
``` xml
|
||||
<!-- Comentario -->
|
||||
```
|
||||
|
||||
También se pueden comentar bloques completos de claves.
|
||||
|
||||
## Cargar el servicio
|
||||
|
||||
``` bash
|
||||
launchctl load ~/Library/LaunchAgents/com.george.sap.sunat.plist
|
||||
```
|
||||
|
||||
En versiones recientes también:
|
||||
|
||||
``` bash
|
||||
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.george.sap.sunat.plist
|
||||
```
|
||||
|
||||
## Verificar
|
||||
|
||||
``` bash
|
||||
launchctl list | grep sap
|
||||
```
|
||||
|
||||
Información detallada:
|
||||
|
||||
``` bash
|
||||
launchctl print gui/$(id -u)/com.george.sap.sunat
|
||||
```
|
||||
|
||||
## Detener
|
||||
|
||||
``` bash
|
||||
launchctl unload ~/Library/LaunchAgents/com.george.sap.sunat.plist
|
||||
```
|
||||
|
||||
o
|
||||
|
||||
``` bash
|
||||
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.george.sap.sunat.plist
|
||||
```
|
||||
|
||||
## Monitorización
|
||||
|
||||
Monitor de Actividad: - Buscar `python` o `python3`.
|
||||
|
||||
Terminal:
|
||||
|
||||
``` bash
|
||||
ps -ef | grep python
|
||||
```
|
||||
|
||||
Consumo:
|
||||
|
||||
``` bash
|
||||
ps -o pid,rss,vsz,%cpu,command -p <PID>
|
||||
```
|
||||
|
||||
Ver logs:
|
||||
|
||||
``` bash
|
||||
tail -f logs/stdout.log
|
||||
tail -f logs/stderr.log
|
||||
```
|
||||
|
||||
## Recomendaciones
|
||||
|
||||
- Usar `logging` con rotación.
|
||||
- Manejar reconexión a SAP HANA.
|
||||
- Implementar reintentos para SUNAT.
|
||||
- Mantener configuración en `config.ini` o `.env`.
|
||||
- Capturar `SIGTERM` para cerrar conexiones correctamente.
|
||||
- Si el servicio es permanente, controlar internamente la frecuencia
|
||||
de ejecución (cada 10 s entre 06:00 y 13:15; cada 30 min entre 13:15
|
||||
y 14:00).
|
||||
|
||||
|
||||
## Ejemplo de archivo .plist
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
|
||||
<key>Label</key>
|
||||
<string>com.george.sap.sunat</string>
|
||||
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Users/george/services/sap_sunat/.venv/bin/python</string>
|
||||
<string>/Users/george/services/sap_sunat/main.py</string>
|
||||
</array>
|
||||
|
||||
<key>WorkingDirectory</key>
|
||||
<string>/Users/george/services/sap_sunat</string>
|
||||
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
|
||||
<key>StandardOutPath</key>
|
||||
<string>/Users/george/services/sap_sunat/logs/stdout.log</string>
|
||||
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/Users/george/services/sap_sunat/logs/stderr.log</string>
|
||||
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
@@ -0,0 +1,674 @@
|
||||
# Agente IA para SAP Business One + HANA
|
||||
|
||||
## Objetivo
|
||||
|
||||
Construir progresivamente un agente de IA tipo chat para la empresa, conectado a SAP Business One sobre HANA, usando modelos locales mediante Ollama.
|
||||
|
||||
La evolución prevista es:
|
||||
|
||||
- Consultas de negocio en lenguaje natural.
|
||||
- KPIs.
|
||||
- Análisis de datos.
|
||||
- Gráficos y cuadros resumen.
|
||||
- Reportes PDF y Excel.
|
||||
- Resúmenes gerenciales.
|
||||
- Alertas y análisis automáticos.
|
||||
|
||||
La estrategia es comenzar pequeño y agregar capacidades mediante herramientas independientes.
|
||||
|
||||
## Arquitectura
|
||||
|
||||
```text
|
||||
USUARIO
|
||||
|
|
||||
v
|
||||
+-------------+
|
||||
| Chat Web UI |
|
||||
| React/Vite |
|
||||
+------+------+
|
||||
|
|
||||
v
|
||||
+-------------+
|
||||
| FastAPI |
|
||||
| Backend |
|
||||
+------+------+
|
||||
|
|
||||
+---------+---------+
|
||||
| |
|
||||
v v
|
||||
+-----------+ +--------------+
|
||||
| Ollama | | Tool / Skill |
|
||||
| Local LLM | | Engine |
|
||||
+-----------+ +-------+------+
|
||||
|
|
||||
+--------+--------+
|
||||
| |
|
||||
v v
|
||||
SAP HANA SAP Service Layer
|
||||
```
|
||||
|
||||
### Principio fundamental
|
||||
|
||||
El modelo de IA no debe tener acceso directo e irrestricto a SAP.
|
||||
|
||||
El LLM debe solicitar herramientas (`tools`) que ejecuten consultas controladas.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
```text
|
||||
Usuario: ¿Cuánto vendimos este mes?
|
||||
|
|
||||
v
|
||||
Ollama
|
||||
|
|
||||
v
|
||||
ventas_mes()
|
||||
|
|
||||
v
|
||||
Python / FastAPI
|
||||
|
|
||||
v
|
||||
SAP HANA
|
||||
|
|
||||
v
|
||||
Resultado
|
||||
|
|
||||
v
|
||||
Ollama
|
||||
|
|
||||
v
|
||||
Respuesta al usuario
|
||||
```
|
||||
|
||||
Esto permite controlar permisos, consultas y calidad de los resultados.
|
||||
|
||||
## Tecnologías
|
||||
|
||||
### Frontend
|
||||
- React
|
||||
- Vite
|
||||
- Interfaz tipo ChatGPT
|
||||
- Tablas
|
||||
- Gráficos
|
||||
- Dashboards
|
||||
|
||||
### Backend
|
||||
- Python
|
||||
- FastAPI
|
||||
- Herramientas / Skills
|
||||
- Control de acceso
|
||||
- Gestión de conversaciones
|
||||
- Generación de reportes
|
||||
|
||||
### IA
|
||||
- Ollama
|
||||
- Modelos locales
|
||||
- Candidatos iniciales: Qwen 3 8B, Qwen 3 14B, Mistral Small y Gemma 3 12B.
|
||||
- La elección final dependerá del hardware y de pruebas reales.
|
||||
|
||||
### Datos e integración
|
||||
- SAP Business One
|
||||
- SAP HANA
|
||||
- Vistas HANA
|
||||
- SQL controlado
|
||||
- SAP Service Layer para operaciones que necesiten la lógica de SAP
|
||||
|
||||
### Visualización y documentos
|
||||
- Plotly para gráficos interactivos
|
||||
- Matplotlib para imágenes/gráficos destinados a documentos
|
||||
- ReportLab para PDF
|
||||
- OpenPyXL para Excel
|
||||
|
||||
# Fase 1: herramientas básicas
|
||||
|
||||
Crear inicialmente un conjunto pequeño de funciones Python:
|
||||
|
||||
```text
|
||||
ventas_hoy()
|
||||
ventas_mes()
|
||||
top_clientes()
|
||||
productos_mas_vendidos()
|
||||
facturas_pendientes()
|
||||
compras_mes()
|
||||
stock_critico()
|
||||
cuentas_por_cobrar()
|
||||
cuentas_por_pagar()
|
||||
utilidad_mes()
|
||||
```
|
||||
|
||||
Cada herramienta ejecutará internamente una consulta SQL o utilizará una vista HANA.
|
||||
|
||||
El usuario pregunta:
|
||||
|
||||
```text
|
||||
¿Cuánto vendimos este mes?
|
||||
```
|
||||
|
||||
El agente determina:
|
||||
|
||||
```text
|
||||
tool = ventas_mes()
|
||||
```
|
||||
|
||||
Obtiene el resultado y genera una respuesta en lenguaje natural.
|
||||
|
||||
## Fase 2: herramientas con parámetros
|
||||
|
||||
Agregar parámetros:
|
||||
|
||||
```text
|
||||
ventas_por_cliente(cliente)
|
||||
ventas_por_fecha(desde, hasta)
|
||||
compras_por_proveedor(proveedor, desde, hasta)
|
||||
stock_almacen(almacen)
|
||||
articulo(codigo)
|
||||
```
|
||||
|
||||
Ejemplo:
|
||||
|
||||
```text
|
||||
¿Cuánto le hemos vendido a Alicorp este año?
|
||||
```
|
||||
|
||||
Puede interpretarse como:
|
||||
|
||||
```text
|
||||
ventas_cliente(
|
||||
cliente="ALICORP",
|
||||
año=2026
|
||||
)
|
||||
```
|
||||
|
||||
## Fase 3: capa semántica empresarial
|
||||
|
||||
En lugar de hacer que el modelo conozca todas las tablas de SAP Business One, crear vistas orientadas al negocio:
|
||||
|
||||
```text
|
||||
VW_VENTAS
|
||||
VW_COMPRAS
|
||||
VW_STOCK
|
||||
VW_CXC
|
||||
VW_CXP
|
||||
VW_CLIENTES
|
||||
VW_PRODUCTOS
|
||||
VW_VENDEDORES
|
||||
VW_KPI_VENTAS
|
||||
VW_KPI_COBRANZAS
|
||||
```
|
||||
|
||||
Las vistas deben presentar información clara y consistente, por ejemplo:
|
||||
|
||||
```text
|
||||
Cliente
|
||||
RUC
|
||||
Vendedor
|
||||
Línea
|
||||
Ciudad
|
||||
Total
|
||||
Margen
|
||||
Cantidad
|
||||
Fecha
|
||||
```
|
||||
|
||||
## Fase 4: SQL generado por IA
|
||||
|
||||
Cuando el sistema básico sea estable, se puede permitir que el modelo genere SQL, pero únicamente sobre vistas analíticas autorizadas.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
```text
|
||||
Vista: VW_VENTAS
|
||||
|
||||
Campos:
|
||||
Fecha
|
||||
Cliente
|
||||
Ciudad
|
||||
Total
|
||||
Margen
|
||||
Cantidad
|
||||
Vendedor
|
||||
```
|
||||
|
||||
Pregunta:
|
||||
|
||||
```text
|
||||
¿Cuánto vendimos por ciudad?
|
||||
```
|
||||
|
||||
Consulta posible:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
Ciudad,
|
||||
SUM(Total) AS TotalVentas
|
||||
FROM VW_VENTAS
|
||||
GROUP BY Ciudad;
|
||||
```
|
||||
|
||||
El backend debe validar el SQL antes de ejecutarlo.
|
||||
|
||||
## Fase 5: conversación con contexto
|
||||
|
||||
El agente debe mantener el contexto:
|
||||
|
||||
```text
|
||||
Usuario: Muéstrame las ventas de marzo.
|
||||
Agente: ...
|
||||
|
||||
Usuario: Ahora solo Lima.
|
||||
Agente: ...
|
||||
|
||||
Usuario: Compáralo con febrero.
|
||||
Agente: ...
|
||||
|
||||
Usuario: Haz un gráfico.
|
||||
Agente: ...
|
||||
```
|
||||
|
||||
## Fase 6: gráficos
|
||||
|
||||
El agente podrá generar visualizaciones como:
|
||||
|
||||
- Ventas por vendedor
|
||||
- Ventas por ciudad
|
||||
- Ventas mensuales
|
||||
- Margen por línea
|
||||
- Top 10 productos
|
||||
- Top 10 clientes
|
||||
- Evolución de cobranza
|
||||
- Stock por almacén
|
||||
|
||||
Flujo:
|
||||
|
||||
```text
|
||||
Pregunta -> Tool -> HANA -> Datos -> Motor de gráficos -> Gráfico -> Chat
|
||||
```
|
||||
|
||||
## Fase 7: KPIs
|
||||
|
||||
Crear un catálogo de indicadores.
|
||||
|
||||
### Ventas
|
||||
- Ventas del mes
|
||||
- Ventas acumuladas
|
||||
- Cumplimiento de meta
|
||||
- Crecimiento vs. período anterior
|
||||
- Ticket promedio
|
||||
- Ventas por vendedor
|
||||
- Ventas por cliente
|
||||
- Ventas por producto
|
||||
|
||||
### Rentabilidad
|
||||
- Margen bruto
|
||||
- Margen por producto
|
||||
- Margen por línea
|
||||
- Margen por vendedor
|
||||
|
||||
### Inventario
|
||||
- Stock disponible
|
||||
- Stock crítico
|
||||
- Rotación
|
||||
- Productos sin movimiento
|
||||
- Productos próximos a agotarse
|
||||
|
||||
### Finanzas
|
||||
- Cuentas por cobrar
|
||||
- Cuentas por pagar
|
||||
- Vencimientos
|
||||
- Cobranza
|
||||
- Antigüedad de saldos
|
||||
|
||||
## Fase 8: reportes
|
||||
|
||||
El usuario podrá solicitar:
|
||||
|
||||
```text
|
||||
Genera un resumen gerencial de junio.
|
||||
```
|
||||
|
||||
El sistema:
|
||||
|
||||
1. Consulta los datos.
|
||||
2. Calcula KPIs.
|
||||
3. Genera gráficos.
|
||||
4. Utiliza el LLM para interpretar los resultados.
|
||||
5. Genera conclusiones.
|
||||
6. Crea un PDF.
|
||||
7. Puede crear un Excel.
|
||||
|
||||
Estructura posible:
|
||||
|
||||
```text
|
||||
REPORTE GERENCIAL
|
||||
|
||||
Resumen ejecutivo
|
||||
Ventas
|
||||
Rentabilidad
|
||||
Inventario
|
||||
Cuentas por cobrar
|
||||
Principales variaciones
|
||||
Principales clientes
|
||||
Principales productos
|
||||
Conclusiones
|
||||
```
|
||||
|
||||
## Fase 9: alertas automáticas
|
||||
|
||||
Ejemplo de resumen diario:
|
||||
|
||||
```text
|
||||
Ventas: S/ 124,500
|
||||
Meta: 95%
|
||||
Margen: 28%
|
||||
|
||||
Top vendedor: Carlos
|
||||
Productos sin stock: 14
|
||||
Clientes con deuda: 18
|
||||
```
|
||||
|
||||
El agente también podría detectar anomalías:
|
||||
|
||||
```text
|
||||
- Las ventas de Arequipa disminuyeron 15%.
|
||||
- El producto X cayó 20% respecto al promedio.
|
||||
- Las cobranzas aumentaron 12%.
|
||||
- Tres clientes concentran una parte importante de la deuda vencida.
|
||||
```
|
||||
|
||||
La IA debe aportar principalmente interpretación de datos reales, no inventar respuestas plausibles.
|
||||
|
||||
## Seguridad
|
||||
|
||||
Principios desde el inicio:
|
||||
|
||||
- El LLM no debe tener credenciales directas de HANA.
|
||||
- Las herramientas deben estar controladas por el backend.
|
||||
- Separar consultas de lectura de operaciones de escritura.
|
||||
- No permitir SQL arbitrario inicialmente.
|
||||
- Validar parámetros.
|
||||
- Registrar las consultas ejecutadas.
|
||||
- Registrar usuario, herramienta y fecha.
|
||||
- Controlar qué herramientas puede utilizar cada usuario.
|
||||
- Utilizar Service Layer para operaciones que modifiquen SAP.
|
||||
- No permitir que una pregunta de lenguaje natural ejecute operaciones destructivas.
|
||||
|
||||
Arquitectura de lectura:
|
||||
|
||||
```text
|
||||
Usuario -> LLM -> Tool controlada -> Vista/Query HANA -> Resultado
|
||||
```
|
||||
|
||||
Arquitectura de operaciones:
|
||||
|
||||
```text
|
||||
Usuario -> LLM -> Tool controlada -> Validación -> Service Layer -> SAP Business One
|
||||
```
|
||||
|
||||
# Capa semántica empresarial
|
||||
|
||||
Uno de los componentes más importantes será un catálogo que explique al agente qué significa cada dato.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
```text
|
||||
VW_VENTAS
|
||||
|
||||
Descripción:
|
||||
Información consolidada de documentos de venta.
|
||||
|
||||
Campos:
|
||||
|
||||
Fecha
|
||||
Fecha del documento.
|
||||
|
||||
Cliente
|
||||
Código del cliente.
|
||||
|
||||
NombreCliente
|
||||
Nombre comercial.
|
||||
|
||||
Vendedor
|
||||
Vendedor responsable.
|
||||
|
||||
Total
|
||||
Importe total del documento.
|
||||
|
||||
Margen
|
||||
Margen bruto calculado.
|
||||
|
||||
Cantidad
|
||||
Cantidad vendida.
|
||||
```
|
||||
|
||||
También se deben documentar reglas de negocio, por ejemplo:
|
||||
|
||||
```text
|
||||
"Ventas" significa documentos de venta contabilizados.
|
||||
|
||||
"No considerar documentos cancelados."
|
||||
|
||||
"Margen" se calcula utilizando el costo correspondiente.
|
||||
|
||||
"Ventas del mes" utiliza DocDate salvo que se indique otra fecha.
|
||||
```
|
||||
|
||||
Esto será más importante que intentar meter miles de tablas SAP en el contexto del LLM.
|
||||
|
||||
# Estructura inicial del proyecto
|
||||
|
||||
```text
|
||||
agente_sap/
|
||||
|
|
||||
+-- app/
|
||||
| +-- main.py
|
||||
| +-- api/
|
||||
| | +-- chat.py
|
||||
| | +-- reports.py
|
||||
| +-- agent/
|
||||
| | +-- agent.py
|
||||
| | +-- prompts.py
|
||||
| | +-- tools.py
|
||||
| +-- tools/
|
||||
| | +-- ventas.py
|
||||
| | +-- compras.py
|
||||
| | +-- stock.py
|
||||
| | +-- clientes.py
|
||||
| | +-- finanzas.py
|
||||
| +-- database/
|
||||
| | +-- hana.py
|
||||
| +-- sap/
|
||||
| | +-- service_layer.py
|
||||
| +-- reports/
|
||||
| | +-- pdf.py
|
||||
| | +-- excel.py
|
||||
| +-- charts/
|
||||
| +-- charts.py
|
||||
|
|
||||
+-- frontend/
|
||||
| +-- ...
|
||||
|
|
||||
+-- sql/
|
||||
| +-- views/
|
||||
| +-- queries/
|
||||
|
|
||||
+-- docs/
|
||||
| +-- semantic_layer/
|
||||
|
|
||||
+-- tests/
|
||||
|
|
||||
+-- .env
|
||||
+-- requirements.txt
|
||||
+-- README.md
|
||||
```
|
||||
|
||||
# Primera versión recomendada
|
||||
|
||||
No empezar con dashboards, agentes autónomos ni SQL generado por IA.
|
||||
|
||||
La primera versión debería hacer solamente:
|
||||
|
||||
```text
|
||||
Chat
|
||||
|
|
||||
v
|
||||
Ollama
|
||||
|
|
||||
v
|
||||
Tools Python
|
||||
|
|
||||
v
|
||||
HANA
|
||||
|
|
||||
v
|
||||
Resultado
|
||||
|
|
||||
v
|
||||
Ollama
|
||||
|
|
||||
v
|
||||
Respuesta
|
||||
```
|
||||
|
||||
Con cinco herramientas iniciales:
|
||||
|
||||
```text
|
||||
ventas_hoy()
|
||||
ventas_mes()
|
||||
top_clientes()
|
||||
stock_critico()
|
||||
cuentas_por_cobrar()
|
||||
```
|
||||
|
||||
Y una interfaz web sencilla.
|
||||
|
||||
# Evolución recomendada
|
||||
|
||||
```text
|
||||
FASE 1
|
||||
Chat + Ollama + 5 tools
|
||||
|
|
||||
v
|
||||
FASE 2
|
||||
Tools con parámetros
|
||||
|
|
||||
v
|
||||
FASE 3
|
||||
Vistas HANA / capa semántica
|
||||
|
|
||||
v
|
||||
FASE 4
|
||||
SQL controlado sobre vistas
|
||||
|
|
||||
v
|
||||
FASE 5
|
||||
Contexto conversacional
|
||||
|
|
||||
v
|
||||
FASE 6
|
||||
Gráficos
|
||||
|
|
||||
v
|
||||
FASE 7
|
||||
KPIs
|
||||
|
|
||||
v
|
||||
FASE 8
|
||||
PDF / Excel
|
||||
|
|
||||
v
|
||||
FASE 9
|
||||
Dashboards
|
||||
|
|
||||
v
|
||||
FASE 10
|
||||
Alertas y análisis automáticos
|
||||
```
|
||||
|
||||
# Objetivo final
|
||||
|
||||
El asistente podrá responder preguntas como:
|
||||
|
||||
```text
|
||||
¿Cuánto vendimos este mes?
|
||||
|
||||
¿Cuáles son nuestros 10 mejores clientes?
|
||||
|
||||
¿Qué productos están cayendo en ventas?
|
||||
|
||||
¿Qué vendedores no están alcanzando su meta?
|
||||
|
||||
¿Cuánto tenemos pendiente de cobrar?
|
||||
|
||||
¿Qué clientes tienen mayor deuda vencida?
|
||||
|
||||
¿Cómo se comportaron las ventas frente al mes anterior?
|
||||
|
||||
¿Cuál es nuestro margen promedio?
|
||||
|
||||
Genera un reporte gerencial del mes.
|
||||
|
||||
Genera un Excel con las ventas por vendedor.
|
||||
|
||||
Muéstrame un gráfico de ventas de los últimos 12 meses.
|
||||
|
||||
¿Qué problemas ves en los datos de este mes?
|
||||
```
|
||||
|
||||
Posteriormente:
|
||||
|
||||
```text
|
||||
Analiza la situación comercial de la empresa
|
||||
y dame las principales conclusiones.
|
||||
```
|
||||
|
||||
Las conclusiones deben basarse en datos reales obtenidos de SAP, no en respuestas inventadas por el modelo.
|
||||
|
||||
# Principio de diseño
|
||||
|
||||
La arquitectura debe ser modular.
|
||||
|
||||
Cada nueva capacidad debe incorporarse como una nueva herramienta:
|
||||
|
||||
```text
|
||||
Nueva necesidad
|
||||
|
|
||||
v
|
||||
Nueva Tool
|
||||
|
|
||||
v
|
||||
Consulta / Vista HANA
|
||||
|
|
||||
v
|
||||
Documentación semántica
|
||||
|
|
||||
v
|
||||
Disponible para el agente
|
||||
```
|
||||
|
||||
Esto permite crecer sin rehacer toda la aplicación.
|
||||
|
||||
# Conclusión
|
||||
|
||||
La estrategia recomendada es construir primero un **asistente de consulta sobre SAP Business One**, no un sistema autónomo.
|
||||
|
||||
La combinación:
|
||||
|
||||
```text
|
||||
React
|
||||
+
|
||||
FastAPI
|
||||
+
|
||||
Ollama
|
||||
+
|
||||
Tools Python
|
||||
+
|
||||
SAP HANA
|
||||
+
|
||||
Service Layer
|
||||
```
|
||||
|
||||
es suficiente para construir una primera versión sólida.
|
||||
|
||||
La pieza más importante no será el modelo de IA, sino la **capa de herramientas y conocimiento empresarial** que conectará el lenguaje natural con los datos reales de SAP.
|
||||
|
||||
El modelo puede cambiarse posteriormente. Las herramientas, vistas, reglas de negocio y capa semántica serán el verdadero activo del proyecto.
|
||||
@@ -1,587 +0,0 @@
|
||||
# Proyecto ERP Web Empresarial Integrado con SAP Business One Service Layer
|
||||
|
||||
# Objetivo General
|
||||
|
||||
Desarrollar una aplicación web empresarial para mantenimiento de datos maestros de Socios de Negocio similar al formulario estándar de SAP Business One.
|
||||
|
||||
La solución utilizará:
|
||||
|
||||
- Frontend:
|
||||
- React.js
|
||||
- Next.js
|
||||
- TypeScript
|
||||
|
||||
- Backend:
|
||||
- Python
|
||||
- FastAPI
|
||||
|
||||
- Integración:
|
||||
- SAP Business One Service Layer
|
||||
|
||||
---
|
||||
|
||||
# Filosofía de Arquitectura
|
||||
|
||||
La solución debe:
|
||||
|
||||
- Ser escalable
|
||||
- Ser desacoplada
|
||||
- Tener arquitectura por capas
|
||||
- Tener código mantenible
|
||||
- Tener funciones pequeñas y reutilizables
|
||||
- Aplicar principios SOLID
|
||||
- Tener separación de responsabilidades
|
||||
- Tener documentación técnica
|
||||
|
||||
---
|
||||
|
||||
# Arquitectura General
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
|
||||
A[Frontend Next.js] --> B[Backend FastAPI]
|
||||
B --> C[SAP Business One Service Layer]
|
||||
C --> D[SAP Business One Database]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Tecnologías
|
||||
|
||||
# Frontend
|
||||
|
||||
- React.js
|
||||
- Next.js
|
||||
- TypeScript
|
||||
- React Hook Form
|
||||
- Zod
|
||||
- Axios
|
||||
- Zustand
|
||||
- TailwindCSS
|
||||
- Shadcn UI
|
||||
|
||||
---
|
||||
|
||||
# Backend
|
||||
|
||||
- Python
|
||||
- FastAPI
|
||||
- Pydantic
|
||||
- SQLAlchemy
|
||||
- httpx
|
||||
- passlib[bcrypt]
|
||||
- JWT Authentication
|
||||
|
||||
---
|
||||
|
||||
# Integración SAP
|
||||
|
||||
- SAP Business One Service Layer
|
||||
- Session Management
|
||||
- B1SESSION
|
||||
- ROUTEID
|
||||
|
||||
---
|
||||
|
||||
# Estrategia de Desarrollo por Etapas
|
||||
|
||||
# IMPORTANTE
|
||||
|
||||
NO desarrollar frontend y backend simultáneamente.
|
||||
|
||||
El proyecto debe ejecutarse por etapas para:
|
||||
- minimizar errores
|
||||
- facilitar pruebas
|
||||
- mantener arquitectura limpia
|
||||
- evitar acoplamiento prematuro
|
||||
|
||||
---
|
||||
|
||||
# ETAPA 1 - Diseño de Arquitectura
|
||||
|
||||
## Objetivo
|
||||
|
||||
Definir completamente la arquitectura antes de programar.
|
||||
|
||||
---
|
||||
|
||||
## Tareas
|
||||
|
||||
### 1. Crear diagramas Mermaid
|
||||
|
||||
Crear:
|
||||
|
||||
- arquitectura general
|
||||
- flujo login
|
||||
- flujo CRUD
|
||||
- flujo Service Layer
|
||||
- arquitectura backend
|
||||
- arquitectura frontend
|
||||
|
||||
---
|
||||
|
||||
## Diagramas recomendados
|
||||
|
||||
### Flujo Login
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
Frontend->>Backend: Login usuario
|
||||
Backend->>SAP Service Layer: Login técnico SAP
|
||||
SAP Service Layer-->>Backend: B1SESSION
|
||||
Backend->>SAP Service Layer: Consultar EmployeesInfo
|
||||
SAP Service Layer-->>Backend: Datos usuario
|
||||
Backend-->>Frontend: JWT
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Arquitectura Backend
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
|
||||
A[Routes] --> B[Services]
|
||||
B --> C[Repositories]
|
||||
C --> D[SAP Integration]
|
||||
D --> E[Service Layer]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Resultado esperado ETAPA 1
|
||||
|
||||
- Diagramas completos
|
||||
- Arquitectura definida
|
||||
- Carpetas definidas
|
||||
- Responsabilidades definidas
|
||||
|
||||
---
|
||||
|
||||
# ETAPA 2 - Backend Base
|
||||
|
||||
# IMPORTANTE
|
||||
|
||||
Primero construir backend.
|
||||
|
||||
Razones:
|
||||
- frontend depende APIs
|
||||
- frontend depende autenticación
|
||||
- frontend depende estructura JSON
|
||||
- frontend depende validaciones
|
||||
|
||||
---
|
||||
|
||||
# Objetivos ETAPA 2
|
||||
|
||||
Construir:
|
||||
- estructura FastAPI
|
||||
- autenticación
|
||||
- integración SAP
|
||||
- manejo sesiones
|
||||
- JWT
|
||||
- logging
|
||||
- manejo errores
|
||||
|
||||
---
|
||||
|
||||
# Estructura Backend
|
||||
|
||||
```text
|
||||
/app
|
||||
/api
|
||||
/services
|
||||
/repositories
|
||||
/schemas
|
||||
/models
|
||||
/validators
|
||||
/middlewares
|
||||
/core
|
||||
/integrations
|
||||
/sap
|
||||
/utils
|
||||
/queries
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Funcionalidades Backend Iniciales
|
||||
|
||||
## 1. Login SAP técnico
|
||||
|
||||
Endpoint:
|
||||
|
||||
```text
|
||||
POST /auth/login
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Session Manager SAP
|
||||
|
||||
Implementar:
|
||||
|
||||
- login automático
|
||||
- refresh automático
|
||||
- manejo cookies
|
||||
- timeout
|
||||
- retry policy
|
||||
|
||||
---
|
||||
|
||||
## 3. JWT propio
|
||||
|
||||
Implementar:
|
||||
|
||||
- access token
|
||||
- refresh token
|
||||
- expiración
|
||||
- middleware autenticación
|
||||
|
||||
---
|
||||
|
||||
## 4. Integración OHEM
|
||||
|
||||
Usar:
|
||||
|
||||
```text
|
||||
EmployeesInfo
|
||||
```
|
||||
|
||||
del Service Layer.
|
||||
|
||||
---
|
||||
|
||||
# Usuarios
|
||||
|
||||
Los usuarios funcionales estarán en:
|
||||
|
||||
```text
|
||||
OHEM
|
||||
```
|
||||
|
||||
mediante Service Layer.
|
||||
|
||||
---
|
||||
|
||||
# UDFs requeridos
|
||||
|
||||
| Campo | Uso |
|
||||
|---|---|
|
||||
| U_APP_USERNAME | Usuario |
|
||||
| U_APP_PASSWORD | Password hash |
|
||||
| U_APP_ROLE | Rol |
|
||||
| U_APP_ACTIVE | Estado |
|
||||
|
||||
---
|
||||
|
||||
# Seguridad Passwords
|
||||
|
||||
Usar:
|
||||
|
||||
```text
|
||||
bcrypt
|
||||
```
|
||||
|
||||
Nunca guardar passwords en texto plano.
|
||||
|
||||
---
|
||||
|
||||
# Resultado esperado ETAPA 2
|
||||
|
||||
- Backend funcionando
|
||||
- Login funcionando
|
||||
- JWT funcionando
|
||||
- Integración SAP funcionando
|
||||
|
||||
---
|
||||
|
||||
# ETAPA 3 - CRUD Socios de Negocio
|
||||
|
||||
# Objetivo
|
||||
|
||||
Implementar CRUD Business Partners.
|
||||
|
||||
---
|
||||
|
||||
# Entidad principal
|
||||
|
||||
```text
|
||||
BusinessPartners
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Campos OCRD
|
||||
|
||||
| Campo | Uso |
|
||||
|---|---|
|
||||
| CardCode | Código |
|
||||
| CardName | Nombre |
|
||||
| CardType | Tipo |
|
||||
| LicTradNum | Documento |
|
||||
| Phone1 | Teléfono |
|
||||
| E_Mail | Correo |
|
||||
| Currency | Moneda |
|
||||
| GroupCode | Grupo |
|
||||
|
||||
---
|
||||
|
||||
# Campos CRD1
|
||||
|
||||
| Campo | Uso |
|
||||
|---|---|
|
||||
| Address | Dirección |
|
||||
| Country | País |
|
||||
| Street | Calle |
|
||||
| ZipCode | Código Postal |
|
||||
| AdresType | Tipo |
|
||||
|
||||
---
|
||||
|
||||
# Reglas de negocio
|
||||
|
||||
## LicTradNum
|
||||
|
||||
Debe:
|
||||
- tener 8 caracteres
|
||||
- ser numérico
|
||||
|
||||
---
|
||||
|
||||
## CardCode
|
||||
|
||||
Debe autogenerarse:
|
||||
|
||||
```text
|
||||
CardType + LicTradNum
|
||||
```
|
||||
|
||||
Ejemplo:
|
||||
|
||||
```text
|
||||
C12345678
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Operaciones CRUD
|
||||
|
||||
| Operación | Método |
|
||||
|---|---|
|
||||
| Listar | GET |
|
||||
| Obtener | GET |
|
||||
| Crear | POST |
|
||||
| Actualizar | PATCH |
|
||||
| Eliminar | DELETE/PATCH |
|
||||
|
||||
---
|
||||
|
||||
# Resultado esperado ETAPA 3
|
||||
|
||||
- CRUD completo
|
||||
- Validaciones
|
||||
- Integración real SAP
|
||||
|
||||
---
|
||||
|
||||
# ETAPA 4 - Queries Optimizados
|
||||
|
||||
# Objetivo
|
||||
|
||||
Mejorar performance.
|
||||
|
||||
---
|
||||
|
||||
# IMPORTANTE
|
||||
|
||||
NO usar entidades completas SAP para listados masivos.
|
||||
|
||||
---
|
||||
|
||||
# Estrategia
|
||||
|
||||
## Escrituras
|
||||
|
||||
Usar:
|
||||
- Service Layer estándar
|
||||
|
||||
---
|
||||
|
||||
## Lecturas masivas
|
||||
|
||||
Usar:
|
||||
- SQLQueries
|
||||
- queries optimizados
|
||||
- paginación
|
||||
|
||||
---
|
||||
|
||||
# Resultado esperado ETAPA 4
|
||||
|
||||
- Listados rápidos
|
||||
- Filtros
|
||||
- Paginación
|
||||
|
||||
---
|
||||
|
||||
# ETAPA 5 - Frontend Base
|
||||
|
||||
# Objetivo
|
||||
|
||||
Construir frontend luego de estabilizar backend.
|
||||
|
||||
---
|
||||
|
||||
# Estructura Frontend
|
||||
|
||||
```text
|
||||
/src
|
||||
/app
|
||||
/components
|
||||
/services
|
||||
/hooks
|
||||
/layouts
|
||||
/store
|
||||
/validators
|
||||
/types
|
||||
/utils
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Pantallas Iniciales
|
||||
|
||||
## Login
|
||||
|
||||
Campos:
|
||||
- usuario
|
||||
- password
|
||||
- company db
|
||||
|
||||
---
|
||||
|
||||
## Master Layout
|
||||
|
||||
- sidebar
|
||||
- header
|
||||
- content
|
||||
|
||||
---
|
||||
|
||||
## Socio de Negocio
|
||||
|
||||
- formulario OCRD
|
||||
- grid CRD1
|
||||
- CRUD
|
||||
- validaciones
|
||||
|
||||
---
|
||||
|
||||
# Resultado esperado ETAPA 5
|
||||
|
||||
- Login UI
|
||||
- navegación
|
||||
- consumo APIs
|
||||
|
||||
---
|
||||
|
||||
# ETAPA 6 - Frontend Empresarial
|
||||
|
||||
# Objetivo
|
||||
|
||||
Mejorar experiencia usuario.
|
||||
|
||||
---
|
||||
|
||||
# Funcionalidades
|
||||
|
||||
- loading states
|
||||
- toast notifications
|
||||
- manejo errores
|
||||
- tablas
|
||||
- búsqueda
|
||||
- debounce
|
||||
- paginación
|
||||
- responsive
|
||||
|
||||
---
|
||||
|
||||
# ETAPA 7 - Seguridad y Performance
|
||||
|
||||
# Objetivo
|
||||
|
||||
Preparar entorno productivo.
|
||||
|
||||
---
|
||||
|
||||
# Implementar
|
||||
|
||||
- cache
|
||||
- retry policy
|
||||
- correlation ID
|
||||
- logs
|
||||
- auditoría
|
||||
- middleware seguridad
|
||||
- rate limiting
|
||||
- circuit breaker
|
||||
|
||||
---
|
||||
|
||||
# ETAPA 8 - DevOps y Despliegue
|
||||
|
||||
# Backend
|
||||
|
||||
- Docker
|
||||
- Variables entorno
|
||||
- Gunicorn/Uvicorn
|
||||
|
||||
---
|
||||
|
||||
# Frontend
|
||||
|
||||
- Build Next.js
|
||||
- Reverse proxy
|
||||
|
||||
---
|
||||
|
||||
# Infraestructura
|
||||
|
||||
- HTTPS
|
||||
- NGINX
|
||||
- SSL
|
||||
- monitoreo
|
||||
|
||||
---
|
||||
|
||||
# Recomendaciones Arquitectónicas
|
||||
|
||||
## NO hacer
|
||||
|
||||
- acceso SQL directo escritura SAP
|
||||
- passwords en texto plano
|
||||
- lógica SAP en frontend
|
||||
- consultas gigantes Service Layer
|
||||
|
||||
---
|
||||
|
||||
# SI hacer
|
||||
|
||||
- backend desacoplado
|
||||
- funciones pequeñas
|
||||
- validaciones separadas
|
||||
- logs centralizados
|
||||
- manejo global errores
|
||||
|
||||
---
|
||||
|
||||
# Objetivo Final
|
||||
|
||||
Construir una plataforma empresarial:
|
||||
- mantenible
|
||||
- escalable
|
||||
- desacoplada
|
||||
- compatible con SAP Business One
|
||||
- optimizada para crecimiento futuro
|
||||
@@ -1,746 +0,0 @@
|
||||
# Hoja de Ruta: Desarrollo de Aplicaciones Operacionales para SAP Business One con Next.js
|
||||
|
||||
> Duración estimada: 4 a 5 meses
|
||||
> Objetivo: Construir aplicaciones web operacionales simples, rápidas y mantenibles conectadas a SAP Business One mediante Service Layer.
|
||||
|
||||
---
|
||||
|
||||
# Objetivo real del proyecto
|
||||
|
||||
El objetivo NO es crear un ERP completo como SAP Business One.
|
||||
|
||||
El objetivo es desarrollar:
|
||||
|
||||
- formularios operacionales específicos
|
||||
- módulos independientes
|
||||
- validaciones empresariales
|
||||
- procesos rápidos para usuarios internos
|
||||
|
||||
Cada módulo tendrá:
|
||||
- una funcionalidad específica
|
||||
- su propia lógica
|
||||
- su propio formulario
|
||||
- integración con SAP Business One
|
||||
|
||||
---
|
||||
|
||||
# Filosofía del sistema
|
||||
|
||||
SAP Business One seguirá siendo:
|
||||
|
||||
```text
|
||||
Sistema maestro ERP
|
||||
```
|
||||
|
||||
La aplicación web será:
|
||||
|
||||
```text
|
||||
Frontend operacional especializado
|
||||
↓
|
||||
Validaciones empresariales
|
||||
↓
|
||||
Integración con SAP Service Layer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Ejemplos reales de módulos
|
||||
|
||||
## Almacén
|
||||
- Recepción de Orden de Compra
|
||||
- Transferencias de almacén
|
||||
- Validación de lotes
|
||||
- Conteo de inventario
|
||||
|
||||
---
|
||||
|
||||
## Compras
|
||||
- Factura de gastos
|
||||
- Factura de productos
|
||||
- Distribución por centros de costo
|
||||
- Validación SUNAT
|
||||
|
||||
---
|
||||
|
||||
## Ventas
|
||||
- Validación de pedidos
|
||||
- Aprobaciones
|
||||
- Seguimiento comercial
|
||||
|
||||
---
|
||||
|
||||
# Arquitectura recomendada
|
||||
|
||||
```text
|
||||
Frontend
|
||||
- Next.js
|
||||
- TypeScript
|
||||
- React Hook Form
|
||||
- TanStack Table
|
||||
|
||||
Backend Integración
|
||||
- FastAPI
|
||||
|
||||
ERP
|
||||
- SAP Business One Service Layer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Flujo típico de trabajo
|
||||
|
||||
```text
|
||||
1. Consultar información desde SAP
|
||||
2. Mostrar información al usuario
|
||||
3. Validar reglas operacionales
|
||||
4. Permitir edición controlada
|
||||
5. Enviar información final a SAP
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Principios de diseño UI
|
||||
|
||||
## El sistema debe ser:
|
||||
|
||||
- rápido
|
||||
- minimalista
|
||||
- estable
|
||||
- predecible
|
||||
- orientado a productividad
|
||||
|
||||
---
|
||||
|
||||
## Evitar
|
||||
|
||||
- animaciones
|
||||
- dashboards innecesarios
|
||||
- exceso de colores
|
||||
- imágenes decorativas
|
||||
- diseño tipo startup
|
||||
|
||||
---
|
||||
|
||||
## Priorizar
|
||||
|
||||
- velocidad
|
||||
- teclado
|
||||
- tabulación
|
||||
- búsqueda rápida
|
||||
- formularios densos
|
||||
- tablas operacionales
|
||||
|
||||
---
|
||||
|
||||
# Fase 1 — Fundamentos web modernos
|
||||
Duración: ~3 semanas
|
||||
|
||||
---
|
||||
|
||||
# JavaScript moderno
|
||||
|
||||
## Aprender
|
||||
|
||||
- let / const
|
||||
- funciones
|
||||
- arrays
|
||||
- objetos
|
||||
- async / await
|
||||
- fetch API
|
||||
- módulos
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Consumir APIs y transformar datos empresariales.
|
||||
|
||||
Ejemplos:
|
||||
- obtener OC
|
||||
- obtener proveedores
|
||||
- listar artículos
|
||||
- validar estados
|
||||
|
||||
---
|
||||
|
||||
# HTML y CSS
|
||||
|
||||
## Aprender
|
||||
|
||||
- formularios
|
||||
- tablas
|
||||
- inputs
|
||||
- layouts
|
||||
- Flexbox
|
||||
- CSS Grid
|
||||
- responsive básico
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Construir:
|
||||
- formularios operacionales
|
||||
- tablas densas
|
||||
- layouts empresariales
|
||||
|
||||
---
|
||||
|
||||
# TypeScript
|
||||
|
||||
## Aprender
|
||||
|
||||
- interfaces
|
||||
- types
|
||||
- arrays tipados
|
||||
- objetos anidados
|
||||
- generics
|
||||
- Partial
|
||||
- Pick
|
||||
- Omit
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Modelar:
|
||||
- documentos
|
||||
- líneas
|
||||
- almacenes
|
||||
- lotes
|
||||
- centros de costo
|
||||
|
||||
---
|
||||
|
||||
# Fase 2 — React para sistemas empresariales
|
||||
Duración: ~3 semanas
|
||||
|
||||
---
|
||||
|
||||
# Componentes
|
||||
|
||||
## Aprender
|
||||
|
||||
- componentes reutilizables
|
||||
- props
|
||||
- composición
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Crear:
|
||||
- inputs
|
||||
- tablas
|
||||
- formularios
|
||||
- modales
|
||||
|
||||
---
|
||||
|
||||
# Hooks React
|
||||
|
||||
## Aprender
|
||||
|
||||
- useState
|
||||
- useEffect
|
||||
- useMemo
|
||||
- useCallback
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Controlar:
|
||||
- formularios
|
||||
- búsquedas
|
||||
- filtros
|
||||
- cálculos
|
||||
|
||||
---
|
||||
|
||||
# Formularios controlados
|
||||
|
||||
## Aprender
|
||||
|
||||
- eventos
|
||||
- validaciones
|
||||
- manejo errores
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Validar:
|
||||
- cantidades
|
||||
- RUC
|
||||
- fechas
|
||||
- almacenes
|
||||
- centros de costo
|
||||
|
||||
---
|
||||
|
||||
# Fase 3 — Formularios empresariales modernos
|
||||
Duración: ~2 semanas
|
||||
|
||||
> Esta es una de las fases MÁS importantes.
|
||||
|
||||
---
|
||||
|
||||
# React Hook Form
|
||||
|
||||
## Aprender
|
||||
|
||||
- useForm
|
||||
- Controller
|
||||
- FormProvider
|
||||
- useFieldArray
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Manejar:
|
||||
- formularios grandes
|
||||
- líneas dinámicas
|
||||
- validaciones rápidas
|
||||
|
||||
---
|
||||
|
||||
# Zod
|
||||
|
||||
## Aprender
|
||||
|
||||
- schemas
|
||||
- validaciones
|
||||
- refinements
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Centralizar reglas empresariales.
|
||||
|
||||
Ejemplos:
|
||||
- cantidad > 0
|
||||
- RUC válido
|
||||
- lote obligatorio
|
||||
- centro de costo requerido
|
||||
|
||||
---
|
||||
|
||||
# Fase 4 — Next.js moderno
|
||||
Duración: ~4 semanas
|
||||
|
||||
---
|
||||
|
||||
# App Router
|
||||
|
||||
## Aprender
|
||||
|
||||
- app/
|
||||
- layouts
|
||||
- rutas dinámicas
|
||||
|
||||
---
|
||||
|
||||
## Ejemplos
|
||||
|
||||
```text
|
||||
/recepcion-oc
|
||||
/factura-gastos
|
||||
/factura-productos
|
||||
/transferencias
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Server Components y Client Components
|
||||
|
||||
## Aprender
|
||||
|
||||
- use client
|
||||
- separación cliente/servidor
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Separar:
|
||||
- carga datos
|
||||
- UI
|
||||
- validaciones
|
||||
|
||||
---
|
||||
|
||||
# API Routes
|
||||
|
||||
## Aprender
|
||||
|
||||
- GET
|
||||
- POST
|
||||
- PATCH
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Comunicación:
|
||||
- frontend
|
||||
- FastAPI
|
||||
- SAP
|
||||
|
||||
---
|
||||
|
||||
# Autenticación
|
||||
|
||||
## Aprender
|
||||
|
||||
- sesiones
|
||||
- middleware
|
||||
- protección rutas
|
||||
|
||||
---
|
||||
|
||||
## Escenario real
|
||||
|
||||
Usuario:
|
||||
- existe en OHEM
|
||||
- usa login corporativo
|
||||
- trabaja con usuario SAP indirecto
|
||||
|
||||
---
|
||||
|
||||
# Fase 5 — Estado servidor y tablas
|
||||
Duración: ~2 semanas
|
||||
|
||||
---
|
||||
|
||||
# TanStack Query
|
||||
|
||||
## Aprender
|
||||
|
||||
- fetching
|
||||
- cache
|
||||
- invalidaciones
|
||||
- mutations
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Optimizar:
|
||||
- búsquedas
|
||||
- consultas SAP
|
||||
- refresco de datos
|
||||
|
||||
---
|
||||
|
||||
# TanStack Table
|
||||
|
||||
## Aprender
|
||||
|
||||
- filtros
|
||||
- sorting
|
||||
- paginación
|
||||
- selección filas
|
||||
|
||||
---
|
||||
|
||||
## Objetivo ERP
|
||||
|
||||
Construir:
|
||||
- líneas documento
|
||||
- búsquedas
|
||||
- listados operacionales
|
||||
|
||||
---
|
||||
|
||||
# Fase 6 — Componentes ERP reutilizables
|
||||
Duración: ~2 semanas
|
||||
|
||||
> Esta fase define la calidad del sistema completo.
|
||||
|
||||
---
|
||||
|
||||
# Componentes clave
|
||||
|
||||
## ERPDataTable
|
||||
|
||||
Tabla reutilizable:
|
||||
- filtros
|
||||
- búsqueda
|
||||
- selección
|
||||
- teclado
|
||||
|
||||
---
|
||||
|
||||
# SearchModal
|
||||
|
||||
Modal reutilizable para:
|
||||
- artículos
|
||||
- proveedores
|
||||
- clientes
|
||||
- órdenes
|
||||
- almacenes
|
||||
|
||||
---
|
||||
|
||||
# Inputs inteligentes
|
||||
|
||||
Crear componentes:
|
||||
- InputRUC
|
||||
- InputCurrency
|
||||
- InputDate
|
||||
- InputQuantity
|
||||
- InputWarehouse
|
||||
|
||||
---
|
||||
|
||||
# Layouts reutilizables
|
||||
|
||||
## Crear
|
||||
|
||||
- FormLayout
|
||||
- FilterLayout
|
||||
- ModalLayout
|
||||
|
||||
---
|
||||
|
||||
# Fase 7 — Backend integración FastAPI
|
||||
Duración: ~2 semanas
|
||||
|
||||
---
|
||||
|
||||
# FastAPI
|
||||
|
||||
## Aprender
|
||||
|
||||
- endpoints
|
||||
- modelos Pydantic
|
||||
- autenticación
|
||||
- manejo errores
|
||||
|
||||
---
|
||||
|
||||
# Objetivo ERP
|
||||
|
||||
Centralizar:
|
||||
- login SAP
|
||||
- sesión Service Layer
|
||||
- validaciones
|
||||
- logs
|
||||
- auditoría
|
||||
|
||||
---
|
||||
|
||||
# Arquitectura recomendada
|
||||
|
||||
```text
|
||||
Next.js
|
||||
↓
|
||||
FastAPI
|
||||
↓
|
||||
SAP Service Layer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Fase 8 — Integración SAP Business One
|
||||
Duración: ~2 semanas
|
||||
|
||||
---
|
||||
|
||||
# Aprender
|
||||
|
||||
- login Service Layer
|
||||
- cookies sesión
|
||||
- GET
|
||||
- POST
|
||||
- PATCH
|
||||
|
||||
---
|
||||
|
||||
# Escenarios reales
|
||||
|
||||
## Recepción OC
|
||||
|
||||
```text
|
||||
1. Buscar OC
|
||||
2. Mostrar pendientes
|
||||
3. Registrar cantidades
|
||||
4. Crear Entrada Mercancía
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Factura proveedor
|
||||
|
||||
```text
|
||||
1. Traer Entrada Mercancía
|
||||
2. Completar datos contables
|
||||
3. Distribuir gastos
|
||||
4. Crear Factura Proveedor
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Validaciones reales
|
||||
|
||||
## Manejar
|
||||
|
||||
- sesión expirada
|
||||
- errores SAP
|
||||
- timeouts
|
||||
- validaciones SUNAT
|
||||
- concurrencia
|
||||
|
||||
---
|
||||
|
||||
# Fase 9 — Seguridad y despliegue
|
||||
Duración: ~1 semana
|
||||
|
||||
---
|
||||
|
||||
# Seguridad
|
||||
|
||||
## Aprender
|
||||
|
||||
- HTTPS
|
||||
- CORS
|
||||
- middleware
|
||||
- protección APIs
|
||||
|
||||
---
|
||||
|
||||
# Deploy
|
||||
|
||||
## Aprender
|
||||
|
||||
- Docker
|
||||
- Nginx
|
||||
- Linux
|
||||
- variables entorno
|
||||
|
||||
---
|
||||
|
||||
# Estructura recomendada
|
||||
|
||||
```text
|
||||
/apps
|
||||
/recepcion-oc
|
||||
/factura-gastos
|
||||
/factura-productos
|
||||
/transferencias
|
||||
|
||||
/shared-ui
|
||||
/shared-api
|
||||
/shared-types
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Filosofía modular
|
||||
|
||||
Cada módulo:
|
||||
- independiente
|
||||
- simple
|
||||
- mantenible
|
||||
- desplegable
|
||||
|
||||
---
|
||||
|
||||
# Proyecto inicial recomendado
|
||||
|
||||
## Recepción de Orden de Compra
|
||||
|
||||
Porque incluye:
|
||||
|
||||
- filtros
|
||||
- tablas
|
||||
- modales
|
||||
- líneas
|
||||
- validaciones
|
||||
- SAP Service Layer
|
||||
|
||||
---
|
||||
|
||||
# Stack recomendado
|
||||
|
||||
## Frontend
|
||||
|
||||
- Next.js
|
||||
- TypeScript
|
||||
- Tailwind CSS
|
||||
- shadcn/ui
|
||||
|
||||
---
|
||||
|
||||
## Formularios
|
||||
|
||||
- React Hook Form
|
||||
- Zod
|
||||
|
||||
---
|
||||
|
||||
## Tablas
|
||||
|
||||
- TanStack Table
|
||||
|
||||
---
|
||||
|
||||
## Estado servidor
|
||||
|
||||
- TanStack Query
|
||||
|
||||
---
|
||||
|
||||
## Backend
|
||||
|
||||
- FastAPI
|
||||
|
||||
---
|
||||
|
||||
# Recursos recomendados
|
||||
|
||||
| Tema | Recurso |
|
||||
|---|---|
|
||||
| JavaScript | https://javascript.info |
|
||||
| TypeScript | https://www.typescriptlang.org/docs |
|
||||
| React | https://react.dev |
|
||||
| Next.js | https://nextjs.org/learn |
|
||||
| Tailwind CSS | https://tailwindcss.com |
|
||||
| React Hook Form | https://react-hook-form.com |
|
||||
| Zod | https://zod.dev |
|
||||
| TanStack Query | https://tanstack.com/query |
|
||||
| TanStack Table | https://tanstack.com/table |
|
||||
| FastAPI | https://fastapi.tiangolo.com |
|
||||
|
||||
---
|
||||
|
||||
# Resumen total
|
||||
|
||||
| Fase | Tema | Semanas |
|
||||
|---|---|---|
|
||||
| 1 | Fundamentos web | 3 |
|
||||
| 2 | React empresarial | 3 |
|
||||
| 3 | Formularios modernos | 2 |
|
||||
| 4 | Next.js | 4 |
|
||||
| 5 | Estado y tablas | 2 |
|
||||
| 6 | Componentes ERP reutilizables | 2 |
|
||||
| 7 | FastAPI integración | 2 |
|
||||
| 8 | SAP Business One | 2 |
|
||||
| 9 | Seguridad y deploy | 1 |
|
||||
| Total | | ~21 semanas |
|
||||
|
||||
---
|
||||
|
||||
# Meta final
|
||||
|
||||
Construir aplicaciones operacionales empresariales:
|
||||
- rápidas
|
||||
- simples
|
||||
- mantenibles
|
||||
- desacopladas
|
||||
- conectadas a SAP Business One
|
||||
|
||||
Sin intentar reinventar un ERP completo. La humanidad ya ha sufrido suficiente con eso.
|
||||
@@ -1,593 +0,0 @@
|
||||
## Aplicaciones Operacionales para SAP Business One
|
||||
|
||||
> Objetivo: construir aplicaciones web empresariales simples, rápidas, mantenibles y desacopladas para procesos específicos conectados a SAP Business One mediante Service Layer.
|
||||
|
||||
---
|
||||
|
||||
# Filosofía tecnológica
|
||||
|
||||
El objetivo NO es crear:
|
||||
- una plataforma compleja
|
||||
- microservicios innecesarios
|
||||
- interfaces visualmente exageradas
|
||||
|
||||
El objetivo es construir:
|
||||
- formularios operacionales rápidos
|
||||
- tablas empresariales eficientes
|
||||
- validaciones sólidas
|
||||
- integración estable con SAP Business One
|
||||
|
||||
---
|
||||
|
||||
# Arquitectura general recomendada
|
||||
|
||||
```text
|
||||
Frontend (Next.js)
|
||||
↓
|
||||
Backend Integración (FastAPI)
|
||||
↓
|
||||
SAP Business One Service Layer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Lenguajes recomendados
|
||||
|
||||
# 1. TypeScript
|
||||
|
||||
## Uso principal
|
||||
Frontend empresarial.
|
||||
|
||||
---
|
||||
|
||||
## Se utilizará en:
|
||||
- Next.js
|
||||
- React
|
||||
- Formularios
|
||||
- Tablas
|
||||
- Validaciones
|
||||
- Componentes reutilizables
|
||||
|
||||
---
|
||||
|
||||
## ¿Por qué usar TypeScript?
|
||||
|
||||
Porque los sistemas ERP manejan:
|
||||
- muchos datos
|
||||
- documentos complejos
|
||||
- estructuras anidadas
|
||||
- validaciones empresariales
|
||||
|
||||
TypeScript ayuda a:
|
||||
- reducir errores
|
||||
- mantener consistencia
|
||||
- mejorar mantenimiento
|
||||
- detectar problemas temprano
|
||||
|
||||
---
|
||||
|
||||
## Ejemplo típico ERP
|
||||
|
||||
```ts
|
||||
interface PurchaseOrderLine {
|
||||
itemCode: string
|
||||
description: string
|
||||
quantity: number
|
||||
warehouseCode: string
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 2. Python
|
||||
|
||||
## Uso principal
|
||||
Backend de integración.
|
||||
|
||||
---
|
||||
|
||||
## Se utilizará en:
|
||||
- FastAPI
|
||||
- integración SAP
|
||||
- validaciones empresariales
|
||||
- integración SUNAT
|
||||
- logs
|
||||
- auditoría
|
||||
- automatizaciones
|
||||
- procesos auxiliares
|
||||
|
||||
---
|
||||
|
||||
## ¿Por qué Python?
|
||||
|
||||
Porque:
|
||||
- es rápido de desarrollar
|
||||
- excelente para APIs
|
||||
- ideal para integración empresarial
|
||||
- muy compatible con automatización
|
||||
- excelente ecosistema
|
||||
|
||||
---
|
||||
|
||||
# IDE recomendado
|
||||
|
||||
# Antigravity
|
||||
|
||||
## IDE principal
|
||||
|
||||
Antigravity puede ser muy útil para este proyecto debido a:
|
||||
- generación acelerada de código
|
||||
- asistencia IA
|
||||
- productividad
|
||||
- soporte moderno TypeScript y React
|
||||
|
||||
---
|
||||
|
||||
# Uso recomendado de Antigravity
|
||||
|
||||
## Excelente para generar:
|
||||
- formularios
|
||||
- CRUDs
|
||||
- tablas
|
||||
- hooks
|
||||
- componentes
|
||||
- validaciones
|
||||
- clientes API
|
||||
- schemas Zod
|
||||
|
||||
---
|
||||
|
||||
## NO depender completamente de IA para:
|
||||
- arquitectura
|
||||
- seguridad
|
||||
- lógica SAP
|
||||
- reglas contables
|
||||
- autorizaciones
|
||||
- estructura del sistema
|
||||
|
||||
---
|
||||
|
||||
# Filosofía correcta con IA
|
||||
|
||||
```text
|
||||
Arquitectura y lógica:
|
||||
Manual
|
||||
|
||||
Implementación repetitiva:
|
||||
Asistida por IA
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Recomendación importante
|
||||
|
||||
La IA debe:
|
||||
- acelerar desarrollo
|
||||
- reducir boilerplate
|
||||
- mejorar productividad
|
||||
|
||||
La IA NO debe:
|
||||
- tomar decisiones arquitectónicas
|
||||
- definir reglas empresariales
|
||||
- controlar diseño de integración SAP
|
||||
|
||||
---
|
||||
|
||||
# VS Code como respaldo
|
||||
|
||||
## Recomendado instalar también:
|
||||
Visual Studio Code.
|
||||
|
||||
---
|
||||
|
||||
## Motivos
|
||||
- estabilidad
|
||||
- debugging excelente
|
||||
- ecosistema enorme
|
||||
- respaldo confiable
|
||||
- herramientas empresariales
|
||||
|
||||
---
|
||||
|
||||
# Extensiones recomendadas
|
||||
|
||||
## Frontend
|
||||
|
||||
- ES7+ React snippets
|
||||
- Tailwind CSS IntelliSense
|
||||
- ESLint
|
||||
- Prettier
|
||||
- Error Lens
|
||||
|
||||
---
|
||||
|
||||
## Python
|
||||
|
||||
- Python
|
||||
- Pylance
|
||||
- Ruff
|
||||
- Black Formatter
|
||||
|
||||
---
|
||||
|
||||
# Librerías Frontend
|
||||
|
||||
# Next.js
|
||||
|
||||
## Framework principal
|
||||
|
||||
Se utilizará para:
|
||||
- páginas
|
||||
- layouts
|
||||
- formularios
|
||||
- módulos operacionales
|
||||
- autenticación
|
||||
- API routes
|
||||
|
||||
---
|
||||
|
||||
## ¿Por qué Next.js?
|
||||
|
||||
Porque:
|
||||
- estructura moderna
|
||||
- excelente soporte TypeScript
|
||||
- arquitectura ordenada
|
||||
- ideal para aplicaciones empresariales
|
||||
|
||||
---
|
||||
|
||||
# React
|
||||
|
||||
## Base UI
|
||||
|
||||
React será utilizado para:
|
||||
- componentes
|
||||
- formularios
|
||||
- tablas
|
||||
- modales
|
||||
- interacción usuario
|
||||
|
||||
---
|
||||
|
||||
# Tailwind CSS
|
||||
|
||||
## Framework CSS recomendado
|
||||
|
||||
Ideal para:
|
||||
- sistemas empresariales
|
||||
- diseño minimalista
|
||||
- formularios densos
|
||||
- layouts rápidos
|
||||
|
||||
---
|
||||
|
||||
## Ventajas
|
||||
|
||||
- rápido
|
||||
- consistente
|
||||
- fácil mantenimiento
|
||||
- poco CSS manual
|
||||
|
||||
---
|
||||
|
||||
# shadcn/ui
|
||||
|
||||
## Librería UI recomendada
|
||||
|
||||
Ideal para:
|
||||
- modales
|
||||
- dialogs
|
||||
- tablas
|
||||
- formularios
|
||||
- selects
|
||||
- popovers
|
||||
|
||||
---
|
||||
|
||||
## Ventaja principal
|
||||
|
||||
Los componentes:
|
||||
- son modificables
|
||||
- quedan dentro del proyecto
|
||||
- no dependen de librerías cerradas
|
||||
|
||||
---
|
||||
|
||||
# Formularios
|
||||
|
||||
# React Hook Form
|
||||
|
||||
## Librería MÁS importante del frontend
|
||||
|
||||
Se utilizará para:
|
||||
- formularios complejos
|
||||
- validaciones
|
||||
- líneas dinámicas
|
||||
- formularios ERP
|
||||
|
||||
---
|
||||
|
||||
## Casos reales
|
||||
|
||||
- facturas
|
||||
- entradas mercancía
|
||||
- transferencias
|
||||
- gastos
|
||||
- validaciones tributarias
|
||||
|
||||
---
|
||||
|
||||
# Zod
|
||||
|
||||
## Validaciones empresariales
|
||||
|
||||
Se utilizará para:
|
||||
- validar formularios
|
||||
- validar payloads
|
||||
- centralizar reglas
|
||||
|
||||
---
|
||||
|
||||
## Ejemplos
|
||||
|
||||
- RUC válido
|
||||
- cantidad > 0
|
||||
- centro costo obligatorio
|
||||
- lote requerido
|
||||
|
||||
---
|
||||
|
||||
# Manejo de datos
|
||||
|
||||
# TanStack Query
|
||||
|
||||
## Manejo de estado servidor
|
||||
|
||||
Se utilizará para:
|
||||
- consultas SAP
|
||||
- cache
|
||||
- refresh
|
||||
- sincronización datos
|
||||
|
||||
---
|
||||
|
||||
## Ventajas
|
||||
|
||||
- evita consultas repetidas
|
||||
- mejora performance
|
||||
- simplifica fetching
|
||||
|
||||
---
|
||||
|
||||
# Tablas ERP
|
||||
|
||||
# TanStack Table
|
||||
|
||||
## Librería crítica ERP
|
||||
|
||||
Se utilizará para:
|
||||
- líneas documento
|
||||
- listados
|
||||
- filtros
|
||||
- selección
|
||||
- edición
|
||||
|
||||
---
|
||||
|
||||
## Funcionalidades importantes
|
||||
|
||||
- filtros
|
||||
- sorting
|
||||
- búsqueda
|
||||
- navegación teclado
|
||||
- paginación
|
||||
|
||||
---
|
||||
|
||||
# Backend recomendado
|
||||
|
||||
# FastAPI
|
||||
|
||||
## Backend principal
|
||||
|
||||
FastAPI será utilizado para:
|
||||
- integración SAP
|
||||
- autenticación
|
||||
- validaciones
|
||||
- logs
|
||||
- auditoría
|
||||
- APIs internas
|
||||
|
||||
---
|
||||
|
||||
# Arquitectura recomendada
|
||||
|
||||
```text
|
||||
Next.js
|
||||
↓
|
||||
FastAPI
|
||||
↓
|
||||
SAP Service Layer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# ¿Por qué usar FastAPI?
|
||||
|
||||
Porque:
|
||||
- rápido
|
||||
- limpio
|
||||
- tipado
|
||||
- excelente documentación
|
||||
- ideal para APIs empresariales
|
||||
|
||||
---
|
||||
|
||||
# SAP Business One
|
||||
|
||||
## SAP seguirá siendo:
|
||||
|
||||
```text
|
||||
Sistema maestro ERP
|
||||
```
|
||||
|
||||
La aplicación web:
|
||||
- NO reemplaza SAP
|
||||
- NO replica SAP completo
|
||||
|
||||
La aplicación:
|
||||
- simplifica procesos específicos
|
||||
- mejora experiencia operacional
|
||||
- agrega validaciones
|
||||
- acelera tareas
|
||||
|
||||
---
|
||||
|
||||
# Herramientas adicionales
|
||||
|
||||
# Postman o Insomnia
|
||||
|
||||
## Para pruebas API
|
||||
|
||||
Utilizados para probar:
|
||||
- SAP Service Layer
|
||||
- FastAPI
|
||||
- APIs SUNAT
|
||||
|
||||
---
|
||||
|
||||
# Obsidian
|
||||
|
||||
## Documentación técnica
|
||||
|
||||
Ideal para:
|
||||
- arquitectura
|
||||
- flujos
|
||||
- snippets
|
||||
- documentación SAP
|
||||
|
||||
---
|
||||
|
||||
# Git
|
||||
|
||||
## Control versiones
|
||||
|
||||
Recomendado:
|
||||
- Git
|
||||
- GitHub
|
||||
- Gitea
|
||||
|
||||
---
|
||||
|
||||
# Docker
|
||||
|
||||
## Deploy empresarial
|
||||
|
||||
Aprender:
|
||||
- Docker
|
||||
- Docker Compose
|
||||
- Nginx
|
||||
|
||||
---
|
||||
|
||||
# Organización recomendada
|
||||
|
||||
```text
|
||||
/apps
|
||||
/recepcion-oc
|
||||
/factura-gastos
|
||||
/factura-productos
|
||||
/transferencias
|
||||
|
||||
/shared-ui
|
||||
/shared-api
|
||||
/shared-types
|
||||
/shared-validations
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Filosofía modular
|
||||
|
||||
Cada módulo debe ser:
|
||||
- independiente
|
||||
- simple
|
||||
- mantenible
|
||||
- desacoplado
|
||||
|
||||
---
|
||||
|
||||
# Componentes reutilizables críticos
|
||||
|
||||
## SearchModal
|
||||
|
||||
Modal reutilizable para:
|
||||
- artículos
|
||||
- proveedores
|
||||
- clientes
|
||||
- órdenes compra
|
||||
|
||||
---
|
||||
|
||||
# ERPDataTable
|
||||
|
||||
Tabla reutilizable:
|
||||
- filtros
|
||||
- búsqueda
|
||||
- selección
|
||||
- teclado
|
||||
|
||||
---
|
||||
|
||||
# Inputs inteligentes
|
||||
|
||||
Crear:
|
||||
- InputRUC
|
||||
- InputCurrency
|
||||
- InputDate
|
||||
- InputQuantity
|
||||
- InputWarehouse
|
||||
|
||||
---
|
||||
|
||||
# Prioridades reales de aprendizaje
|
||||
|
||||
# Prioridad máxima
|
||||
|
||||
1. TypeScript
|
||||
2. React Hook Form
|
||||
3. TanStack Table
|
||||
4. FastAPI
|
||||
5. SAP Service Layer
|
||||
|
||||
---
|
||||
|
||||
# Prioridad media
|
||||
|
||||
6. Next.js
|
||||
7. TanStack Query
|
||||
8. Zod
|
||||
9. Docker
|
||||
|
||||
---
|
||||
|
||||
# Prioridad baja
|
||||
|
||||
- Redux
|
||||
- animaciones
|
||||
- dashboards complejos
|
||||
- SEO
|
||||
- diseño visual avanzado
|
||||
|
||||
---
|
||||
|
||||
# Objetivo final
|
||||
|
||||
Construir aplicaciones empresariales:
|
||||
- rápidas
|
||||
- operacionales
|
||||
- mantenibles
|
||||
- desacopladas
|
||||
- integradas con SAP Business One
|
||||
|
||||
Sin intentar reinventar un ERP completo. La industria ya tiene suficientes cicatrices por eso.
|
||||
@@ -0,0 +1,384 @@
|
||||
# Gitea público con Tailscale Funnel en NAS UGREEN
|
||||
|
||||
Guía para exponer Gitea (en Docker, NAS UGREEN con UGOS) por HTTPS a internet usando **Tailscale Funnel**, de modo que funcione desde cualquier equipo **sin instalar Tailscale**, en casa y fuera, con una sola URL.
|
||||
|
||||
## Datos de esta instalación
|
||||
|
||||
| Elemento | Valor |
|
||||
|---|---|
|
||||
| URL pública final | `https://unasgeorge.vaquita-hadar.ts.net` |
|
||||
| Tailnet | `vaquita-hadar.ts.net` |
|
||||
| Nombre del NAS en Tailscale | `unasgeorge` |
|
||||
| IP Tailscale del NAS (contenedor) | `100.68.242.27` |
|
||||
| IP local del NAS | `192.168.1.145` |
|
||||
| Puerto de Gitea en el NAS (host) | `30000` (interno del contenedor: `3000`) |
|
||||
| Puerta de enlace Docker (bridge) | `172.17.0.1` |
|
||||
| Destino del proxy de Funnel | `http://172.17.0.1:30000` |
|
||||
| Usuario Gitea | `george` |
|
||||
|
||||
### Esquema
|
||||
|
||||
```
|
||||
Cualquier equipo (con o sin Tailscale)
|
||||
│
|
||||
▼
|
||||
https://unasgeorge.vaquita-hadar.ts.net (puerto 443, HTTPS, Let's Encrypt)
|
||||
│
|
||||
▼ Tailscale Funnel (contenedor Tailscale en el NAS)
|
||||
http://172.17.0.1:30000 (interno, nadie lo usa directamente)
|
||||
│
|
||||
▼
|
||||
Gitea
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. Preparar Tailscale (panel web)
|
||||
|
||||
### 1.1 Activar certificados HTTPS
|
||||
|
||||
1. Entrar a <https://login.tailscale.com/admin/dns>.
|
||||
2. En **HTTPS Certificates**, pulsar **Enable HTTPS**.
|
||||
|
||||
### 1.2 Permitir Funnel en la política de acceso
|
||||
|
||||
1. Entrar a <https://login.tailscale.com/admin/acls>.
|
||||
2. Verificar que exista este bloque (añadirlo si no está, respetando las comas):
|
||||
|
||||
```json
|
||||
"nodeAttrs": [
|
||||
{
|
||||
"target": ["autogroup:member"],
|
||||
"attr": ["funnel"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
3. Guardar (**Save**).
|
||||
|
||||
> Alternativa: la primera vez que se ejecuta `tailscale funnel`, el comando muestra un enlace (`https://login.tailscale.com/f/funnel?node=...`) que añade este permiso automáticamente.
|
||||
|
||||
**Validación:** después del paso 2, en <https://login.tailscale.com/admin/machines> debe aparecer la etiqueta **Funnel** junto a `unasgeorge`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Configurar Funnel en el contenedor de Tailscale
|
||||
|
||||
### 2.1 Abrir la terminal del contenedor
|
||||
|
||||
1. Entrar al panel del NAS (UGOS) → app **Docker** → **Contenedores**.
|
||||
2. Abrir el contenedor de **Tailscale** → **Terminal** → añadir terminal.
|
||||
3. En *Command* usar **`/bin/sh`** (la imagen de Tailscale no trae bash).
|
||||
|
||||
> Si algún comando da *failed to connect to local tailscaled*, anteponer el socket:
|
||||
> `tailscale --socket=/tmp/tailscaled.sock <comando>`
|
||||
|
||||
### 2.2 Comprobar que Tailscale está conectado
|
||||
|
||||
```sh
|
||||
tailscale status
|
||||
tailscale version
|
||||
```
|
||||
|
||||
Debe aparecer `unasgeorge` con IP `100.68.242.27`. Versión recomendada: 1.50 o superior.
|
||||
|
||||
### 2.3 Encontrar por dónde ve el contenedor a Gitea
|
||||
|
||||
El contenedor de Tailscale está en la red bridge de Docker: **no** llega a Gitea por la IP local del NAS ni por `127.0.0.1`. Hay que usar la puerta de enlace de Docker.
|
||||
|
||||
```sh
|
||||
ip route | head -1
|
||||
# Resultado esperado: default via 172.17.0.1 dev eth0
|
||||
|
||||
wget -qO- -T 5 http://172.17.0.1:30000 | head -c 200
|
||||
# Debe devolver HTML que empieza con <!DOCTYPE html>
|
||||
```
|
||||
|
||||
Referencia de lo que **no** funciona en esta instalación:
|
||||
|
||||
```sh
|
||||
wget -qO- -T 5 http://192.168.1.145:30000 | head -c 200 # download timed out
|
||||
wget -qO- -T 5 http://127.0.0.1:30000 | head -c 200 # Connection refused
|
||||
```
|
||||
|
||||
### 2.4 Activar Funnel
|
||||
|
||||
```sh
|
||||
tailscale serve reset
|
||||
tailscale funnel --bg http://172.17.0.1:30000
|
||||
```
|
||||
|
||||
Salida esperada:
|
||||
|
||||
```
|
||||
Available on the internet:
|
||||
|
||||
https://unasgeorge.vaquita-hadar.ts.net/
|
||||
|-- proxy http://172.17.0.1:30000
|
||||
|
||||
Funnel started and running in the background.
|
||||
```
|
||||
|
||||
### 2.5 Validar
|
||||
|
||||
```sh
|
||||
tailscale funnel status
|
||||
```
|
||||
|
||||
Debe mostrar **un solo** destino:
|
||||
|
||||
```
|
||||
https://unasgeorge.vaquita-hadar.ts.net (Funnel on)
|
||||
|-- / proxy http://172.17.0.1:30000
|
||||
```
|
||||
|
||||
> `--bg` deja Funnel activo en segundo plano y sobrevive a reinicios del contenedor. Si el contenedor se **recrea** (no solo se reinicia) y su estado no está en un volumen, hay que repetir el paso 2.4.
|
||||
>
|
||||
> Para desactivar Funnel: `tailscale funnel --https=443 off`
|
||||
|
||||
---
|
||||
|
||||
## 3. Configurar Gitea
|
||||
|
||||
### 3.1 Variables de entorno del contenedor (prioritario)
|
||||
|
||||
Las variables `GITEA__seccion__CLAVE` **tienen prioridad sobre `app.ini`** y lo reescriben en cada arranque. En esta instalación existía `GITEA__server__ROOT_URL = http://100.68.242.27:30000/`, que era la causa de que el botón *Clone* mostrara la URL antigua.
|
||||
|
||||
1. App **Docker** de UGOS → contenedor de **Gitea** → **Detener**.
|
||||
2. **Editar → Variables de entorno**.
|
||||
3. Dejar los valores así (cambiar o añadir):
|
||||
|
||||
```
|
||||
GITEA__server__ROOT_URL = https://unasgeorge.vaquita-hadar.ts.net/
|
||||
GITEA__server__DOMAIN = unasgeorge.vaquita-hadar.ts.net
|
||||
GITEA__server__SSH_DOMAIN = 192.168.1.145
|
||||
GITEA__server__PUBLIC_URL_DETECTION = never
|
||||
GITEA__service__DISABLE_REGISTRATION = true
|
||||
```
|
||||
|
||||
4. Guardar e **Iniciar** el contenedor. Los repositorios no se pierden: están en el volumen.
|
||||
|
||||
### 3.2 `app.ini` (si no se usan variables)
|
||||
|
||||
Ruta habitual dentro del volumen: `.../gitea/gitea/conf/app.ini` (en el contenedor: `/data/gitea/conf/app.ini`). Se puede editar desde el **Gestor de archivos** de UGOS.
|
||||
|
||||
```ini
|
||||
[server]
|
||||
DOMAIN = unasgeorge.vaquita-hadar.ts.net
|
||||
ROOT_URL = https://unasgeorge.vaquita-hadar.ts.net/
|
||||
SSH_DOMAIN = 192.168.1.145
|
||||
PUBLIC_URL_DETECTION = never
|
||||
|
||||
[service]
|
||||
DISABLE_REGISTRATION = true
|
||||
```
|
||||
|
||||
Reiniciar el contenedor de Gitea tras editar.
|
||||
|
||||
> `PUBLIC_URL_DETECTION = never` hace que Gitea use siempre `ROOT_URL` para los enlaces, aunque se entre por otra dirección (IP de Tailscale, `ugdocker.link`, etc.).
|
||||
> `SSH_DOMAIN` apunta a la IP local: SSH **no** pasa por Funnel, solo funciona en la red de casa.
|
||||
|
||||
### 3.3 Validar
|
||||
|
||||
- **Administración del sitio → Configuración → URL de la aplicación** debe ser `https://unasgeorge.vaquita-hadar.ts.net/`.
|
||||
- En cualquier repo, el botón **Clone (HTTPS)** debe mostrar:
|
||||
`https://unasgeorge.vaquita-hadar.ts.net/george/<repo>.git`
|
||||
- Al cerrar sesión **no** debe aparecer la opción *Registrarse*.
|
||||
|
||||
> El aviso *"The detected web site URL is ... unlikely matching the site config"* solo aparece cuando se entra por una dirección distinta de `ROOT_URL`. Desaparece al entrar por `https://unasgeorge.vaquita-hadar.ts.net`.
|
||||
|
||||
### 3.4 Crear un token de acceso
|
||||
|
||||
Git por HTTPS usa el token como contraseña.
|
||||
|
||||
1. Gitea → avatar → **Configuración → Aplicaciones** → *Administrar tokens de acceso*.
|
||||
2. Nombre: uno por equipo (ej. `macbook-air`, `serfactpro`).
|
||||
3. Permisos: **repository → Read and Write** (y **user → Read** si lo pide).
|
||||
4. **Generar token** y copiarlo (solo se muestra una vez).
|
||||
|
||||
> No usar **Manage SSH Keys** para esto: las claves SSH no funcionan a través de Funnel.
|
||||
|
||||
---
|
||||
|
||||
## 4. Validaciones de acceso
|
||||
|
||||
### 4.1 Desde un equipo con Tailscale encendido
|
||||
|
||||
```bash
|
||||
curl -I https://unasgeorge.vaquita-hadar.ts.net
|
||||
```
|
||||
|
||||
Esperado:
|
||||
|
||||
```
|
||||
HTTP/2 200
|
||||
```
|
||||
|
||||
Si se queda colgado después de `Request completely sent off`, Funnel no llega a Gitea: revisar el paso 2.3 y el destino del proxy.
|
||||
|
||||
### 4.2 DNS público (sin Tailscale)
|
||||
|
||||
```bash
|
||||
dig +short unasgeorge.vaquita-hadar.ts.net A @1.1.1.1
|
||||
dig +short unasgeorge.vaquita-hadar.ts.net A @8.8.8.8
|
||||
```
|
||||
|
||||
Esperado (IPs de los servidores de entrada de Funnel, pueden variar):
|
||||
|
||||
```
|
||||
209.177.145.97
|
||||
209.177.145.192
|
||||
```
|
||||
|
||||
> Si sale vacío o `No answer`, el registro DNS público aún no se ha creado. Puede tardar desde 10 minutos hasta unas horas. No hay que cambiar nada, solo esperar.
|
||||
|
||||
### 4.3 Desde un equipo o servidor **sin Tailscale**
|
||||
|
||||
En el Mac: apagar Tailscale (icono de la barra de menú) y limpiar caché DNS:
|
||||
|
||||
```bash
|
||||
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
|
||||
```
|
||||
|
||||
En Linux (si usa systemd-resolved):
|
||||
|
||||
```bash
|
||||
sudo resolvectl flush-caches
|
||||
```
|
||||
|
||||
En Windows (PowerShell):
|
||||
|
||||
```powershell
|
||||
ipconfig /flushdns
|
||||
```
|
||||
|
||||
Comprobaciones (válidas en macOS, Linux y Windows con curl/git):
|
||||
|
||||
```bash
|
||||
# 1. Resuelve por DNS público
|
||||
nslookup unasgeorge.vaquita-hadar.ts.net 8.8.8.8
|
||||
|
||||
# 2. Responde por HTTPS
|
||||
curl -I https://unasgeorge.vaquita-hadar.ts.net
|
||||
# Esperado: HTTP/2 200
|
||||
|
||||
# 3. Git llega al repositorio (pedirá usuario y token si es privado)
|
||||
git ls-remote https://unasgeorge.vaquita-hadar.ts.net/george/sap-legacy-webhook-emulator.git
|
||||
```
|
||||
|
||||
### 4.4 Prueba desde una red totalmente externa
|
||||
|
||||
En el iPhone (o cualquier móvil): desactivar Wi-Fi, desactivar Tailscale y abrir en el navegador:
|
||||
|
||||
```
|
||||
https://unasgeorge.vaquita-hadar.ts.net
|
||||
```
|
||||
|
||||
Debe cargar la página de Gitea.
|
||||
|
||||
### 4.5 URLs de comprobación
|
||||
|
||||
| Qué | URL |
|
||||
|---|---|
|
||||
| Gitea (pública) | <https://unasgeorge.vaquita-hadar.ts.net> |
|
||||
| Repo de ejemplo | <https://unasgeorge.vaquita-hadar.ts.net/george/sap-legacy-webhook-emulator> |
|
||||
| Máquinas Tailscale (etiqueta Funnel) | <https://login.tailscale.com/admin/machines> |
|
||||
| Política de acceso (nodeAttrs funnel) | <https://login.tailscale.com/admin/acls> |
|
||||
| DNS / certificados HTTPS | <https://login.tailscale.com/admin/dns> |
|
||||
|
||||
---
|
||||
|
||||
## 5. Cambiar el `origin` de los proyectos
|
||||
|
||||
### 5.1 Un proyecto
|
||||
|
||||
```bash
|
||||
cd ruta/al/proyecto
|
||||
|
||||
# Ver el remoto actual
|
||||
git remote -v
|
||||
|
||||
# Cambiarlo
|
||||
git remote set-url origin https://unasgeorge.vaquita-hadar.ts.net/george/<repo>.git
|
||||
|
||||
# Verificar
|
||||
git remote -v
|
||||
git ls-remote origin
|
||||
git push
|
||||
```
|
||||
|
||||
Credenciales en el primer `push`:
|
||||
|
||||
- **Username:** `george`
|
||||
- **Password:** el **token** (al pegarlo no se ve nada, es normal)
|
||||
|
||||
### 5.2 Varios proyectos a la vez (macOS / Linux)
|
||||
|
||||
Desde la carpeta que contiene todos los proyectos. Sustituye cualquiera de las URLs antiguas (IP Tailscale, IP local o `ugdocker.link`) por la nueva:
|
||||
|
||||
```bash
|
||||
for d in */; do
|
||||
[ -d "$d/.git" ] || continue
|
||||
old=$(git -C "$d" remote get-url origin 2>/dev/null) || continue
|
||||
new=$(echo "$old" | sed -E 's#^https?://(100\.68\.242\.27|192\.168\.1\.145|app-30000-unasgeorge\.us15\.ugdocker\.link)(:30000)?#https://unasgeorge.vaquita-hadar.ts.net#')
|
||||
if [ "$old" != "$new" ]; then
|
||||
git -C "$d" remote set-url origin "$new"
|
||||
echo "$d $old -> $new"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
### 5.3 Varios proyectos a la vez (Windows PowerShell)
|
||||
|
||||
```powershell
|
||||
Get-ChildItem -Directory | ForEach-Object {
|
||||
if (Test-Path "$($_.FullName)\.git") {
|
||||
$old = git -C $_.FullName remote get-url origin 2>$null
|
||||
if ($old) {
|
||||
$new = $old -replace '^https?://(100\.68\.242\.27|192\.168\.1\.145|app-30000-unasgeorge\.us15\.ugdocker\.link)(:30000)?', 'https://unasgeorge.vaquita-hadar.ts.net'
|
||||
if ($old -ne $new) {
|
||||
git -C $_.FullName remote set-url origin $new
|
||||
Write-Host "$($_.Name) $old -> $new"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5.4 Guardar el token para no escribirlo cada vez
|
||||
|
||||
| Sistema | Comando / comportamiento |
|
||||
|---|---|
|
||||
| macOS | Se guarda solo en el Llavero (`git config --global credential.helper osxkeychain`) |
|
||||
| Windows | Git Credential Manager lo guarda automáticamente |
|
||||
| Linux | `git config --global credential.helper store` (guarda en texto plano en `~/.git-credentials`) |
|
||||
|
||||
### 5.5 Clonar en un equipo nuevo
|
||||
|
||||
```bash
|
||||
git clone https://unasgeorge.vaquita-hadar.ts.net/george/<repo>.git
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Seguridad (Gitea queda público en internet)
|
||||
|
||||
- [ ] Registro desactivado (`DISABLE_REGISTRATION = true`, verificado en variables de entorno **y** `app.ini`).
|
||||
- [ ] 2FA activado: **Configuración → Seguridad**.
|
||||
- [ ] Repositorios privados marcados como **privados**.
|
||||
- [ ] Un token por equipo; revocar el de un equipo perdido en **Configuración → Aplicaciones**.
|
||||
- [ ] Revisar que no exista otra variable `GITEA__...` que anule estos ajustes.
|
||||
|
||||
---
|
||||
|
||||
## 7. Problemas encontrados y solución
|
||||
|
||||
| Síntoma | Causa | Solución |
|
||||
|---|---|---|
|
||||
| `ssh` y `ping` a `100.68.242.27` hacen timeout | Esa IP es del contenedor de Tailscale, no del sistema del NAS | Usar la terminal del contenedor desde la app Docker de UGOS |
|
||||
| `Funnel is not enabled on your tailnet` | Falta permiso Funnel | Abrir el enlace que muestra el comando y aceptar |
|
||||
| `port 443 is not allowed for funnel` | El nodo aún no tiene el atributo `funnel` | Revisar `nodeAttrs` (paso 1.2) y reiniciar el contenedor de Tailscale |
|
||||
| HTTPS conecta pero no responde (`Request completely sent off` y nada más) | Funnel apuntaba a un destino inalcanzable (`:3000` o `192.168.1.145:30000`) | `tailscale serve reset` y Funnel a `http://172.17.0.1:30000` |
|
||||
| `Could not resolve host` sin Tailscale / `dig` vacío | DNS público de Funnel aún no publicado | Esperar (minutos a horas) y repetir `dig` |
|
||||
| Clone muestra `http://100.68.242.27:30000/...` o `ugdocker.link` | Variable `GITEA__server__ROOT_URL` antigua anulaba `app.ini` | Cambiar la variable y añadir `PUBLIC_URL_DETECTION = never` |
|
||||
| Aviso *detected web site URL ... unlikely matching* | Se entra por una dirección distinta de `ROOT_URL` | Informativo; entrar por la URL pública |
|
||||
Reference in new issue
Block a user