← Memory
demo-mode-beetools.md
# Demo Mode BEE Tools - Estado y Directrices
> **Fecha**: 05/04/2026 | **Estado**: EN CURSO - Fase exploratoria completada, nada escrito aun
## Objetivo
Modo demo con datos ficticios de **NovaTech Solutions** (SaaS Barcelona).
URL landing: `hub.beepeek.com/demo` con cards a cada tool con `?demo=true`.
Competidores ficticios: InnoSoft Labs, CloudPeak Systems, DataVista AI.
## Tools a implementar (7 fases)
1. DemoBanner + utilidad `isDemo()` (compartido)
2. Sentinel (hub tool, el mas facil — ya tiene `?shared=1`)
3. BEE Newz (React app separada en `/tools/news/`)
4. BEE LLM (React app separada en `/tools/llm/`)
5. BEE Local (hub tool en `/tools/local-premium`)
6. Invoice (FastAPI separado en `invoice.beepeek.com`)
7. Landing `/demo` + server bypass auth
---
## Hallazgos de la exploracion (lo que ya se leyo)
### Hub (`apps/hub/`)
#### `server/index.js`
- Express, puerto 3000 en produccion
- Middleware `verifySupabaseToken` para auth
- Rutas API: `/api/sentinel/*`, `/api/cron/*`, etc.
- Health check sin auth en `/health`
- **Para demo**: Anadir middleware que permita servir SPA sin auth cuando `?demo=true` en ruta
#### `src/App.tsx`
- React Router con lazy loading
- Rutas tools: `/tools/sentinel`, `/tools/local-premium`, `/tools/local`, etc.
- Session state via `supabase.auth.getSession()` + `onAuthStateChange`
- Sentinel y Local NO tienen guard de session (acceden directo)
- Admin routes SI requieren `<AdminRoute session={session}>`
- **Para demo**: Anadir `<Route path="/demo" element={<Demo />} />` — NO necesita session guard
#### `src/pages/tools/Sentinel.tsx` (798 lineas)
- Usa `useSelectedClient('sentinel')` para obtener clientId
- `apiFetch()` helper que detecta `shared=1` para bypass auth
- State: brands, dashboard, timeline, results, alerts, config
- Tabs: Overview, Results, Alerts, Settings
- **Para demo**: Detectar `?demo=true` en `apiFetch()` y en useEffect inicial. Return mock data sin llamar API. Modelo similar al shared mode existente.
#### `src/pages/tools/Local/LocalApp.jsx`
- JSX (no TSX), clase `ScanErrorBoundary`
- Session via `supabase.auth.getSession()`, si no hay session muestra `<Login />`
- State: session, gridPoints, center, clients, keywords, clientHistory, scanStats
- Carga clientes de Supabase, luego keywords, luego history
- GridMap component para mapa de rankings locales
- **Para demo**: Detectar `?demo=true`, setear session falsa, cargar mock clients/keywords/gridPoints. Mock center Barcelona (41.3874, 2.1686).
#### `src/pages/tools/Local/index.tsx`
- Simple wrapper: `export default function LocalPremium() { return <LocalApp />; }`
### News (`apps/news/`)
#### `src/components/AccessGuard.tsx`
- Usa `useAuth()` + `useUserRole()` + edge function `access-status`
- Si no hay user → redirige al Hub
- Si acceso denegado/pendiente → redirige al Hub
- **Para demo**: Detectar `?demo=true` al inicio, si demo → return children directamente sin checks
#### `src/hooks/useOrganization.ts`
- Query a Supabase `user_roles` + `organizations`
- Admin puede ver todas las orgs
- Sync con Hub via `localStorage` key `hub-selected-client-data`
- **Para demo**: Si `?demo=true`, return mock org `{ id: 'demo-org', name: 'NovaTech Solutions', slug: 'novatech' }` sin queries
#### Hooks a mockear en News:
- `useOrganization.ts` — org ficticia
- `useCompanies.ts` — empresas monitorizadas (NovaTech + competidores)
- `useFeeds.ts` — feeds RSS ficticios
- `useTopics.ts` — topics ficticios
- `src/pages/Index.tsx` — articulos mock
#### `src/App.tsx` — NO LEIDO AUN, leerlo antes de implementar
### LLM (`apps/llm/`)
#### `src/components/BeeLLMProtectedRoute.tsx`
- Usa `useAuth()` + `useCurrentUser()` + query a `profiles.is_active`
- Si no hay user → redirige al Hub
- Bypass para `marketing@blueseo.es` sin perfil
- **Para demo**: Detectar `?demo=true`, si demo → return children directamente
#### Hooks a mockear en LLM:
- `useMyCompany.ts` — empresa del usuario
- `useOverviewMetrics.ts` — metricas de visibilidad LLM
- `useBeeLLMPrompts.ts` — prompts monitorizados
- `useBeeLLMTags.ts` — tags
- `useBeeLLMCompetitors.ts` — competidores
#### `src/App.tsx` — NO LEIDO AUN, leerlo antes de implementar
### Invoice (`/home/ubuntu/proyectos-cloud/factura-ocr/`)
- FastAPI + Jinja2 templates
- **Para demo**: Anadir ruta `/demo` en `app/main.py` que sirva `dashboard.html` con flag demo
- JS del template detecta demo mode y muestra mock extractions sin llamar API
---
## Patron de implementacion (copiar en cada tool)
### 1. Utilidad `isDemo()`
```typescript
// En cada app, simple helper
export const isDemo = () => new URLSearchParams(window.location.search).get('demo') === 'true';
```
### 2. DemoBanner component
```tsx
// Banner amarillo fijo arriba
export default function DemoBanner() {
return (
<div style={{background:'#f59e0b',color:'#000',textAlign:'center',padding:'8px 16px',fontSize:'14px',fontWeight:600}}>
Demo Mode — Datos de ejemplo de NovaTech Solutions
</div>
);
}
```
### 3. Patron en hooks (ejemplo generico)
```typescript
export const useSomething = () => {
if (isDemo()) {
return { data: MOCK_DATA, isLoading: false, error: null };
}
// ... logica real existente
};
```
### 4. Patron en guards (AccessGuard, BeeLLMProtectedRoute)
```typescript
// Al inicio del componente:
if (isDemo()) return <>{children}</>;
```
### 5. Server bypass (hub server/index.js)
```javascript
// Antes del middleware auth, para rutas SPA:
// No necesario realmente porque Sentinel y Local ya no tienen auth guard en el router
// Solo asegurar que el SPA se sirve sin problemas
```
---
## Mock Data NovaTech Solutions
### Empresa
- **Nombre**: NovaTech Solutions
- **Sector**: SaaS / Software
- **Ciudad**: Barcelona
- **Web**: novatech-solutions.com (ficticia)
- **Competidores**: InnoSoft Labs, CloudPeak Systems, DataVista AI
### Sentinel mock
- Brand: NovaTech Solutions, keywords: ["novatech solutions", "novatech software", "novatech saas"]
- Reputation score: 78/100
- Sentiment: 45% positive, 40% neutral, 15% negative
- 5 alertas mock (2 high, 1 medium, 2 low)
- Timeline: 30 dias de datos generados
- Results: 20 resultados SERP con mix de sentimientos
### News mock
- 3 companies monitorizadas: NovaTech, InnoSoft, CloudPeak
- 15-20 articulos ficticios de noticias tech
- 4 feeds: TechCrunch, El Referente, Business Insider, Xataka
- 5 topics: AI, SaaS, Cloud, Funding, Product Launch
### LLM mock
- Company: NovaTech Solutions
- 10 prompts monitorizados (ej: "best saas tools", "project management software", etc.)
- Visibility score: 72%
- Trend: subiendo ultimos 30 dias
- Sources: ChatGPT, Gemini, Perplexity, Claude
- Competidores con scores diferentes
### Local mock
- Business: NovaTech Solutions Barcelona
- Keyword: "software empresa barcelona"
- Grid 5x5 centrado en Barcelona (41.3874, 2.1686)
- Rankings mixtos: 1-20 en distintos puntos
- Avg rank: 4.2, Visibility: 68%
- 5 competidores locales ficticios
### Invoice mock
- 8-10 facturas ficticias extraidas
- Mix de proveedores: AWS, Google Cloud, GitHub, Figma, Slack
- Totales variados, fechas ultimo mes
- Accuracy scores: 92-99%
---
## Orden de implementacion recomendado
1. **DemoBanner + isDemo()** en hub (5 min)
2. **Sentinel** — el mas facil, ya tiene patron `?shared=1` (30 min)
3. **BEE Local** — segundo mas facil, todo en un archivo (45 min)
4. **Landing /demo** — cards con links a cada tool (20 min)
5. **BEE Newz** — mas hooks que mockear (1h)
6. **BEE LLM** — similar a Newz (1h)
7. **Invoice** — FastAPI separado (30 min)
## Archivos NO leidos que hay que leer antes de tocar
- `apps/news/src/App.tsx` — routing de News
- `apps/news/src/pages/Index.tsx` — pagina principal de News
- `apps/news/src/hooks/useCompanies.ts`
- `apps/news/src/hooks/useFeeds.ts`
- `apps/news/src/hooks/useTopics.ts`
- `apps/llm/src/App.tsx` — routing de LLM
- `apps/llm/src/hooks/useMyCompany.ts`
- `apps/llm/src/hooks/useOverviewMetrics.ts`
- `apps/llm/src/hooks/useBeeLLMPrompts.ts`
- `apps/llm/src/pages/` — ver que paginas hay
- `factura-ocr/app/main.py` — rutas FastAPI
- `factura-ocr/app/templates/dashboard.html` — template del dashboard
## Deploy
Tras implementar cada fase:
- Hub: `cd /home/ubuntu/proyectos-cloud/hub-beepeek && npm run build --filter=hub && sudo systemctl restart hub-beepeek`
- News: `cd /home/ubuntu/proyectos-cloud/hub-beepeek && npm run build --filter=news && sudo systemctl restart hub-beepeek`
- LLM: `cd /home/ubuntu/proyectos-cloud/hub-beepeek && npm run build --filter=llm && sudo systemctl restart hub-beepeek`
- Invoice: `sudo systemctl restart factura-ocr`
## Notas
- NO se ha escrito ni una linea de codigo aun. Solo exploracion.
- El patron `?shared=1` de Sentinel es la referencia perfecta para el demo mode.
- Sentinel y Local no tienen session guard en App.tsx routes, asi que el SPA se sirve sin auth. Solo los datos requieren session.
- News y LLM SI tienen guards (AccessGuard y BeeLLMProtectedRoute) que hay que bypassear.