Instructivo — Desarrollador¶
Trabajás directamente sobre el server. Tu laptop solo corre VS Code (o Cursor) y Tailscale. El código vive en mm-testserver y nunca se copia a tu máquina.
Qué vas a poder hacer¶
- Editar el código de
MercadoMayor(leyendo + escribiendo) desde VS Code como si fuera local. - Correr backend, frontend y ai-service (reiniciarlos cuando hagas cambios).
- Ejecutar tests, migraciones, scripts.
- Git: pull/push contra el remoto desde el mismo server, con tu propia identidad de GitHub.
Qué NO vas a hacer¶
- Clonar el repo a tu laptop.
- Levantar servicios en tu máquina.
- Exponer tus credenciales de Tailscale o tu clave SSH privada a nadie.
- Tocar archivos del user admin (
mercadomayormacmini) ni instalar software global — no tenés permisos.
Paso 1 — Instalar Tailscale en tu laptop¶
Tailscale es una VPN privada: te da acceso al server sin abrir puertos al internet.
- Descargá el cliente desde https://tailscale.com/download (Mac, Windows o Linux, ~15 MB).
- Abrilo y aceptá el link de invitación que te mandó el admin (o Share si te tocó esa vía).
- Verificá que aparezca
mm-testserveren tu lista de dispositivos.
Paso 2 — Generar clave SSH (si no tenés una)¶
Abrí una terminal en tu laptop:
```bash ssh-keygen -t ed25519 -C "tu-nombre@mercadomayor"
Aceptá el path default (~/.ssh/id_ed25519). Poné passphrase si querés.¶
```
Copiá la clave pública:
```bash
Mac / Linux¶
cat ~/.ssh/id_ed25519.pub
Windows (PowerShell)¶
Get-Content $HOME.ssh\id_ed25519.pub ```
Mandale al admin por el canal del equipo:
1. El texto completo de la clave pública (una línea que empieza con ssh-ed25519 AAAA...).
2. El username que querés tener en el server (ej. juan-dev, maria-dev).
La clave privada (id_ed25519 sin .pub) NUNCA se comparte. Esperá a que el admin confirme.
Paso 3 — Primer SSH al server¶
Desde tu laptop, usando tu username (NO mercadomayormacmini):
```bash
ssh
o, si el nombre corto no resuelve:¶
ssh
Si es la primera vez, te va a preguntar por el fingerprint del host: respondé yes.
Deberías entrar al prompt del server. Para salir: exit.
Datos de conexión del server: - Hostname:
mm-testserver- IP Tailscale:100.116.16.34- MagicDNS:mm-testserver.tail52b275.ts.net- Proyecto:/Users/Shared/MercadoMayor(alias disponible:mm-cdya te lleva ahí)
Paso 4 — Instalar VS Code + extensión Remote-SSH¶
- Instalá VS Code: https://code.visualstudio.com/ (o Cursor si preferís).
- En la pestaña de extensiones, buscá Remote - SSH (publisher Microsoft) e instalala.
Paso 5 — Abrir el proyecto remoto¶
- En VS Code:
Cmd/Ctrl + Shift + P→ "Remote-SSH: Connect to Host" → "Add New SSH Host". - Pegá:
ssh <tu-username>@mm-testservery guardalo en el config default. - "Connect to Host" → elegí
mm-testserver. VS Code abre una ventana nueva conectada al server. File → Open Folder→/Users/Shared/MercadoMayor
Las extensiones se instalan del lado del server la primera vez (tarda un poco). Desde acá, todo (terminal integrada, tests, debug) corre en el server, no en tu laptop.
Paso 6 — Configurar git con tu identidad¶
El repo ya está clonado en /Users/Shared/MercadoMayor. Pero el git config global del server es del admin. Configurá tu identidad en este repo:
bash
cd /Users/Shared/MercadoMayor
git config user.name "Tu Nombre"
git config user.email "tu-email@mercadomayor.com"
Paso 7 — SSH key para pushear a GitHub (la tuya, no la del server)¶
Para que tus commits se pusheen bajo tu cuenta de GitHub, generá una key tuya en el server y subila a GitHub:
bash
ssh-keygen -t ed25519 -C "tu-email@mercadomayor.com" -f ~/.ssh/id_github
Mostrá la pública:
bash
cat ~/.ssh/id_github.pub
Copiá ese texto → https://github.com/settings/keys → "New SSH key" → pegá y guardá.
Configurá el repo para usar esa key:
bash
cd /Users/Shared/MercadoMayor
git config core.sshCommand "ssh -i ~/.ssh/id_github -o IdentitiesOnly=yes"
Alternativa más limpia — SSH agent forwarding: si no querés mantener una key del lado del server, podés forwardear el agente SSH de tu laptop:
En ~/.ssh/config de tu laptop agregá:
Host mm-testserver
HostName mm-testserver
User <tu-username>
ForwardAgent yes
Así git push usa las keys que ya tenés en tu laptop. Ninguna key tuya queda en el server.
Paso 8 — Levantar / revisar los servicios¶
Los servicios corren como LaunchAgents del admin: arrancan solos al login de la Mac y se reinician solos si crashean.
```bash
Ver si están corriendo¶
curl -s http://localhost:3002/api/health curl -s http://localhost:8010/health curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000
Ver logs en vivo (alias: mm-logs)¶
tail -f /Users/Shared/MercadoMayor/logs/backend.log tail -f /Users/Shared/MercadoMayor/logs/frontend.log tail -f /Users/Shared/MercadoMayor/logs/ai.log
Reiniciar un servicio después de cambiar código (o .env)¶
sudo mm-restart-backend # o mm-restart-frontend / mm-restart-ai ```
Los sudo mm-restart-* son wrappers especiales: no te van a pedir password (están en sudoers con NOPASSWD para el grupo dev). Solo funcionan para esos 3 comandos puntuales.
El venv de Python del ai-service vive en
~mercadomayormacmini/Library/Application Support/MercadoMayor/venv. No podés modificarlo vos, pero para instalar paquetes nuevos pedile al admin que corra:bash "$HOME/Library/Application Support/MercadoMayor/venv/bin/pip" install <paquete>
Para ver la UI en tu navegador (solo con Tailscale prendido):
- http://mm-testserver:3000
- http://100.116.16.34:3000
Paso 9 — Workflow diario¶
```bash
Empezá el día¶
mm-cd # alias para: cd /Users/Shared/MercadoMayor git pull --rebase
Rama nueva¶
git checkout -b feature/tu-cambio
Trabajás, commiteás, pusheás¶
git add . git commit -m "feat: descripción del cambio" git push -u origin feature/tu-cambio ```
Reglas puntuales¶
- No borres la BD local (
cargo_db) sin avisar al admin. Si se corrompe, se regenera con un script del admin. - Los
.envdel server tienen secretos random para testing (JWT, cert keys). No los copies a ningún otro lado. - No podés hacer
sudode nada que no sea los 3mm-restart-*. Si necesitás instalar algo global (brew, npm global, apt), pedile al admin. - Si tenés que agregar un secreto nuevo (API key, token), actualizá
MercadoMayor/SECRETS.mdcon qué es y dónde conseguirlo, y dejá el valor solo en el.envdel server. - Si te trabás, leé
CLAUDE.mden el proyecto — ahí está el contexto del stack y las convenciones.
Comandos útiles¶
```bash
Tail logs¶
mm-logs # alias para seguir los 3 a la vez
Restart¶
sudo mm-restart-backend sudo mm-restart-frontend sudo mm-restart-ai ```
Acceso a la base de datos¶
Tu user Unix no tiene acceso directo a docker (es admin-only). Para queries usás psql contra el puerto del host:
```bash
User con R/W para testing (SELECT/INSERT/UPDATE/DELETE, NO DDL)¶
PGPASSWORD=mmdev_rw_local psql -h localhost -p 5433 -U mmdev_rw -d cargo_db
Read-only (mismo que pentesters)¶
PGPASSWORD=pentest_ro_local psql -h localhost -p 5433 -U pentest_ro -d cargo_db
Ejemplo: contar productos activos¶
PGPASSWORD=mmdev_rw_local psql -h localhost -p 5433 -U mmdev_rw -d cargo_db \ -c "SELECT count(*) FROM mm_productos WHERE estado='activo'" ```
Lo que podés hacer con mmdev_rw: SELECT, INSERT, UPDATE, DELETE sobre cualquier tabla. Útil para poblar datos de test, corregir seeds, debuggear.
Lo que NO podés: CREATE TABLE, DROP TABLE, ALTER TABLE, crear extensions, etc. Los cambios de schema van siempre por migrations (knex) — nunca SQL manual en prod ni en testing.
Si necesitás hacer algo que requiere DDL (agregar columna, crear tabla nueva), escribí la migration, la mergeás, y el admin la corre. Alternativamente, pedile al admin un one-off con docker exec mercado-mayor-db psql -U postgres -d cargo_db.
Problemas comunes¶
- "Permission denied" editando un archivo → el file quedó owned por otro user/grupo. Avisale al admin para que ajuste permisos o hacé
chmod g+w <archivo>si vos sos owner. - Cambios en
.envno se reflejan → hay que reiniciar el servicio:sudo mm-restart-backend. - "Cannot GET /api/..." → el backend está caído.
tail /Users/Shared/MercadoMayor/logs/backend.logpara ver el error. Si ya pasaste 3sudo mm-restart-backendsin suerte, avisale al admin. - VS Code "cannot connect" al volver del almuerzo → probablemente Tailscale se desconectó. Abrí el app, "Reconnect".