## Projects: apps, analysis y vaults bajo un tema comun

Un project agrupa apps, analyses y vaults relacionados. Vive en `projects/{nombre}/` con esta estructura:

```
projects/{nombre}/
  project.md                    # Frontmatter obligatorio (name, description, tags)
  apps/                         # Apps del proyecto (cada una con app.md)
    {app_name}/
      app.md
      ...
  analysis/                     # Analyses del proyecto (cada uno con analysis.md)
    {analysis_name}/
      analysis.md
      .venv/
      notebooks/
      run-jupyter-lab.sh
      ...
  vaults/                       # Datos del proyecto
    vault.yaml                  # Manifest de vaults (nombre, descripcion, path, tags)
    {vault_name} -> /abs/path   # Symlinks a directorios reales de datos
```

### Reglas

- `project.md` sigue el template de `docs/templates/project.md` — campos: `name`, `description`, `tags`, `repo_url`
- `analysis.md` sigue el template de `docs/templates/analysis.md` — `dir_path` debe apuntar a `projects/{nombre}/analysis/{tema}/`
- `vault.yaml` lista los vaults con nombre, descripcion, path absoluto y tags
- Los vaults reales viven fuera del repo (ej: `~/vaults/{nombre}/`) con symlinks en el proyecto
- `fn index` escanea `projects/*/` y setea `project_id` automaticamente en apps, analyses y vaults
- Apps y analyses sueltos (sin proyecto) siguen en `apps/` y `analysis/` en la raiz

### Raiz vs proyecto

| Ubicacion | Para que |
|-----------|---------|
| `apps/` | Apps independientes que no pertenecen a ningun proyecto |
| `analysis/` | Analyses independientes |
| `projects/{nombre}/apps/` | Apps de un proyecto — `project_id` se setea automaticamente |
| `projects/{nombre}/analysis/` | Analyses de un proyecto — `project_id` se setea automaticamente |

### Crear un proyecto nuevo

```bash
# 1. Crear estructura
mkdir -p projects/{nombre}/{apps,analysis,vaults}

# 2. Crear project.md con frontmatter
fn add -k project  # genera template

# 3. Crear vault (datos fuera del repo, symlink dentro)
mkdir -p ~/vaults/{vault_name}/{raw,processed,exports}
ln -s ~/vaults/{vault_name} projects/{nombre}/vaults/{vault_name}
# Crear vault.yaml con la entrada

# 4. Crear analysis dentro del proyecto
fn run init_jupyter_analysis {nombre_analysis} [paquetes...]
mv analysis/{nombre_analysis} projects/{nombre}/analysis/
# Crear analysis.md con dir_path correcto
# Regenerar launcher y kernel startup:
source bash/functions/infra/write_jupyter_launcher.sh && write_jupyter_launcher projects/{nombre}/analysis/{tema}
source bash/functions/infra/write_jupyter_registry_kernel.sh && write_jupyter_registry_kernel projects/{nombre}/analysis/{tema}

# 5. Indexar
fn index
fn show {nombre}  # verifica el project y sus componentes
```

### Consultas utiles

```sql
-- Listar proyectos
SELECT id, description FROM projects;

-- Analysis de un proyecto
SELECT id, name, dir_path FROM analysis WHERE project_id = 'app_turismo';

-- Vaults de un proyecto
SELECT id, name, path, symlink FROM vaults WHERE project_id = 'app_turismo';

-- Apps de un proyecto
SELECT id, name, dir_path FROM apps WHERE project_id = 'app_turismo';

-- Todo lo que pertenece a un proyecto
SELECT 'analysis' as tipo, id, name FROM analysis WHERE project_id = ?
UNION ALL
SELECT 'vault', id, name FROM vaults WHERE project_id = ?
UNION ALL
SELECT 'app', id, name FROM apps WHERE project_id = ?;
```
