chore(uniweb): make pnpm dev usable after the same-origin switch

Same-origin (Caddy) means the SPA reaches /api and /nats through its own
origin in production, but those relative paths do not exist on the bare Vite
dev server, so `pnpm dev` no longer connects. busService already reads
VITE_BUS_HTTP / VITE_BUS_WS as overrides of the same-origin defaults — this
documents that path (Option A, no proxy code) and moves the dev server off the
port reserved by an unrelated local app.

- vite.config: dev server port 5173 -> 5174 (5173 is in use by another local
  app). strictPort left off so Vite falls back to the next free port. Comment
  explains the same-origin/dev split and the env-var override.
- app.md: Ejemplo and the CORS gotcha document the exact dev command
  (VITE_BUS_HTTP/WS pointing at a cluster node) on :5174 and the same-origin
  production model.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-14 15:32:12 +02:00
parent 5fbf319172
commit 6c4baf1397
2 changed files with 24 additions and 13 deletions
+15 -8
View File
@@ -62,14 +62,18 @@ total.
## Ejemplo ## Ejemplo
```bash ```bash
# El bus ya corre (cluster unibus con WebSocket habilitado, --ws-port). Apunta la SPA a un # Producción: SPA same-origin detrás de Caddy, que sirve la SPA + /api + /nats.
# nodo y arráncala en dev (puerto 5173, que coincide con la CORS allowlist del cluster): # Build estático y despliegue de web/dist:
cd web && pnpm install cd web && pnpm install
VITE_BUS_HTTP=https://<nodo>:8470 VITE_BUS_WS=wss://<nodo>:8480 pnpm dev pnpm build # genera web/dist (se despliega a magnus:/opt/uniweb/dist)
# Navegador: http://localhost:5173
# Producción: build estático y sirve web/dist con cualquier static server. # Dev (`pnpm dev`): el dev server NO tiene el proxy de Caddy, así que /api y /nats no
cd web && pnpm build # genera web/dist # existen en localhost. Apunta la SPA a un nodo real del cluster con las env vars
# (overrides del default same-origin). El dev server corre en el puerto 5174:
VITE_BUS_HTTP=https://<nodo>:8470 VITE_BUS_WS=wss://<nodo>:8480 pnpm dev
# Navegador: http://localhost:5174
# (Añade http://localhost:5174 a la --cors-origins del nodo, o el control-plane
# rechazará la petición por CORS.)
``` ```
## Cuándo usarla ## Cuándo usarla
@@ -87,8 +91,11 @@ programáticos) ve a `unibus`; `uniweb` es el cliente web encima.
*mockeaba*). En `enforce`, una identidad nueva debe ser autorizada por un admin *mockeaba*). En `enforce`, una identidad nueva debe ser autorizada por un admin
(`membershipd user add`) antes de poder abrir sesión; el flujo de Join muestra la clave (`membershipd user add`) antes de poder abrir sesión; el flujo de Join muestra la clave
pública del usuario para que un admin la autorice. pública del usuario para que un admin la autorice.
- **CORS**: el dev server corre en `http://localhost:5173` para coincidir con la - **CORS / same-origin**: en producción la SPA es same-origin detrás de Caddy (`/api` y
`--cors-origins` del cluster. Otro origen necesita añadirse a esa allowlist. `/nats` proxyados), así que no hay CORS. En dev (`pnpm dev`, puerto 5174) esos paths
relativos no existen: hay que apuntar a un nodo con `VITE_BUS_HTTP`/`VITE_BUS_WS` y
añadir `http://localhost:5174` a la `--cors-origins` del nodo. El puerto 5173 está
reservado a otra app local; si 5174 está ocupado, Vite usa el siguiente libre.
- La passphrase del wallet nunca se guarda ni se envía; perderla en un dispositivo sin la - La passphrase del wallet nunca se guarda ni se envía; perderla en un dispositivo sin la
mnemónica BIP39 = identidad irrecuperable en ese dispositivo (recuperable en otro con las 12 mnemónica BIP39 = identidad irrecuperable en ese dispositivo (recuperable en otro con las 12
palabras). palabras).
+9 -5
View File
@@ -3,12 +3,16 @@ import react from "@vitejs/plugin-react";
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],
// The SPA talks DIRECTLY to the bus (signed HTTPS control plane + nats.ws data // In production the SPA is served same-origin behind Caddy, which proxies /api and
// plane), so there is no gateway and no /api proxy. The dev server runs on 5173 to // /nats to the cluster; those relative paths do not exist on the bare dev server, so
// match the bus CORS allowlist (--cors-origins http://localhost:5173). Point the // `pnpm dev` must be pointed at a real cluster node with VITE_BUS_HTTP / VITE_BUS_WS
// SPA at a cluster node with VITE_BUS_HTTP / VITE_BUS_WS (see busService.ts). // (busService.ts uses them as overrides of the same-origin defaults). Example:
// VITE_BUS_HTTP=https://<node>:8470 VITE_BUS_WS=wss://<node>:8480 pnpm dev
// The dev server runs on 5174 (5173 is reserved for an unrelated local app). Add the
// dev origin (http://localhost:5174) to the node's --cors-origins allowlist. strictPort
// is left off, so Vite falls back to the next free port if 5174 is busy.
server: { server: {
host: true, host: true,
port: 5173, port: 5174,
}, },
}); });