# Bases

> Crea y edita archivos Obsidian Bases (.base) para vistas de base de datos sobre las notas del vault. Usar para dashboards, indices de proyecto, trackers de recursos y cualquier vista filtrada o calculada.

- Skill: `vasallo94/bases` (Agent Skill)
- Install (CLI): `npx skillmds@latest add vasallo94/bases`
- Raw SKILL.md: https://api.skillmd.com/api/skills/vasallo94/bases/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Vasallo94 (https://skillmd.com/u/vasallo94)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/vasallo94/bases

---


# Obsidian Bases

Skill para crear archivos `.base` que funcionan como vistas de base de datos sobre las notas del vault. Ideales para notas de tipo `indice` y dashboards.

## Cuando usar esta skill

Cuando el usuario quiera:
- Crear un dashboard o indice de proyecto
- Ver notas filtradas por tipo, estado, tags o fechas
- Montar un tracker de recursos o tareas
- Crear una vista calculada (dias hasta vencimiento, contadores, etc.)

> [!CAUTION]
> Antes de crear o editar notas, lee las [[.agents/REGLAS_GLOBALES|Reglas Globales]].

## Estructura de un archivo .base

Los archivos `.base` contienen YAML valido con esta estructura:

```yaml
filters:       # Filtros globales (aplican a TODAS las vistas)
formulas:      # Propiedades calculadas
properties:    # Nombres de visualizacion y configuracion
summaries:     # Formulas de resumen personalizadas
views:         # Una o mas vistas (table, cards, list, map)
```

## Filtros

Los filtros seleccionan que notas aparecen. Se pueden aplicar globalmente o por vista.

### Estructura de filtros

```yaml
# Filtro unico
filters: 'status == "completo"'

# AND: todas las condiciones deben cumplirse
filters:
  and:
    - 'status == "completo"'
    - 'type == "conocimiento"'

# OR: cualquier condicion vale
filters:
  or:
    - file.hasTag("python")
    - file.hasTag("java")

# NOT: excluir coincidencias
filters:
  not:
    - file.hasTag("archivo")

# Anidados
filters:
  and:
    - file.hasTag("proyecto")
    - or:
        - 'status == "en_proceso"'
        - 'status == "borrador"'
```

### Operadores

| Operador | Descripcion |
|----------|-------------|
| `==` | Igual |
| `!=` | Distinto |
| `>` | Mayor que |
| `<` | Menor que |
| `>=` | Mayor o igual |
| `<=` | Menor o igual |
| `&&` | Y logico |
| `\|\|` | O logico |
| `!` | Negacion |

## Propiedades

### Tres tipos de propiedades

1. **De la nota** — del frontmatter: `type`, `status`, `tags`, `created`
2. **Del archivo** — metadatos del fichero: `file.name`, `file.mtime`, etc.
3. **Formulas** — valores calculados: `formula.mi_formula`

### Propiedades de archivo

| Propiedad | Tipo | Descripcion |
|-----------|------|-------------|
| `file.name` | String | Nombre del archivo |
| `file.basename` | String | Nombre sin extension |
| `file.path` | String | Ruta completa |
| `file.folder` | String | Carpeta padre |
| `file.ext` | String | Extension |
| `file.size` | Number | Tamano en bytes |
| `file.ctime` | Date | Fecha de creacion |
| `file.mtime` | Date | Fecha de modificacion |
| `file.tags` | List | Tags del archivo |
| `file.links` | List | Enlaces internos |
| `file.backlinks` | List | Notas que enlazan a esta |

## Formulas

Las formulas calculan valores a partir de propiedades.

```yaml
formulas:
  # Aritmetica
  total: "precio * cantidad"

  # Condicional
  icono_estado: 'if(status == "completo", "OK", "Pendiente")'

  # Formato de fecha
  creado: 'file.ctime.format("YYYY-MM-DD")'

  # Dias desde creacion
  dias_antiguo: '(now() - file.ctime).days'

  # Dias hasta fecha limite
  dias_hasta_due: 'if(due_date, (date(due_date) - today()).days, "")'
```

### Funciones principales

| Funcion | Firma | Descripcion |
|---------|-------|-------------|
| `date()` | `date(string): date` | Parsear string a fecha (`YYYY-MM-DD HH:mm:ss`) |
| `now()` | `now(): date` | Fecha y hora actuales |
| `today()` | `today(): date` | Fecha actual (hora = 00:00:00) |
| `if()` | `if(cond, verdadero, falso?)` | Condicional |
| `duration()` | `duration(string): duration` | Parsear duracion |
| `file()` | `file(path): file` | Obtener objeto de archivo |
| `link()` | `link(path, display?): Link` | Crear enlace |

### Aritmetica de fechas

```yaml
# Unidades: y/year/years, M/month/months, d/day/days,
#           w/week/weeks, h/hour/hours, m/minute/minutes
"now() + \"1 day\""              # Manana
"today() + \"7d\""               # Dentro de una semana
"(now() - file.ctime).days"      # Dias desde creacion
```

> [!WARNING]
> Restar fechas devuelve un tipo Duration, no un numero. Siempre acceder a `.days`, `.hours`, etc. antes de aplicar `.round()`.

```yaml
# CORRECTO
"(now() - file.ctime).days.round(0)"

# INCORRECTO: Duration no soporta .round() directamente
"(now() - file.ctime).round(0)"
```

### Null checks

Las propiedades pueden no existir en todas las notas. Usar `if()` para proteger:

```yaml
# CORRECTO
'if(due_date, (date(due_date) - today()).days, "")'

# INCORRECTO: falla si due_date no existe
"(date(due_date) - today()).days"
```

## Tipos de vista

### Table

```yaml
views:
  - type: table
    name: "Mi Tabla"
    order:
      - file.name
      - status
      - created
    summaries:
      precio: Sum
```

### Cards

```yaml
views:
  - type: cards
    name: "Galeria"
    order:
      - file.name
      - cover
      - tags
```

### List

```yaml
views:
  - type: list
    name: "Lista Simple"
    order:
      - file.name
      - status
```

## Resumenes predefinidos

| Nombre | Tipo input | Descripcion |
|--------|-----------|-------------|
| `Average` | Number | Media |
| `Sum` | Number | Suma |
| `Min` / `Max` | Number | Minimo / Maximo |
| `Median` | Number | Mediana |
| `Earliest` / `Latest` | Date | Mas antigua / reciente |
| `Checked` / `Unchecked` | Boolean | Conteo de verdadero/falso |
| `Empty` / `Filled` | Any | Conteo de vacios/llenos |
| `Unique` | Any | Conteo de valores unicos |

## Incrustar bases en notas

```markdown
![[MiBase.base]]
![[MiBase.base#Nombre de Vista]]
```

## Reglas YAML

- Usar comillas simples para formulas con comillas dobles: `'if(done, "Si", "No")'`
- Usar comillas dobles para strings simples: `"Mi Vista"`
- Escapar comillas anidadas correctamente

---

## Ejemplos para nuestro vault

### Dashboard de proyecto

Ubicacion: `02_Proyectos/<proyecto>/Dashboard.base`

```yaml
filters:
  and:
    - file.inFolder("02_Proyectos/Alpha")
    - 'file.ext == "md"'

formulas:
  dias_sin_editar: '(now() - file.mtime).days.round(0)'
  tipo_label: 'if(type == "adr", "ADR", if(type == "doc-proyecto", "Doc", if(type == "reunion", "Reunion", type)))'

properties:
  formula.dias_sin_editar:
    displayName: "Dias sin editar"
  formula.tipo_label:
    displayName: "Tipo"

views:
  - type: table
    name: "Todas las notas"
    order:
      - file.name
      - status
      - formula.tipo_label
      - formula.dias_sin_editar
      - file.mtime
    groupBy:
      property: status
      direction: ASC

  - type: table
    name: "ADRs"
    filters:
      and:
        - 'type == "adr"'
    order:
      - file.name
      - status
      - created
```

### Tracker de recursos

Ubicacion: `04_Recursos/Tracker.base`

```yaml
filters:
  and:
    - 'type == "recurso"'
    - 'file.ext == "md"'

formulas:
  dias_desde_captura: '(now() - file.ctime).days.round(0)'
  procesado: 'if(status == "completo", "Si", if(status == "en_proceso", "En curso", "Pendiente"))'

properties:
  source_type:
    displayName: "Tipo de fuente"
  formula.procesado:
    displayName: "Procesado"
  formula.dias_desde_captura:
    displayName: "Dias"

views:
  - type: table
    name: "Pendientes de procesar"
    filters:
      and:
        - 'status == "borrador"'
    order:
      - file.name
      - source_type
      - formula.dias_desde_captura
      - tags

  - type: table
    name: "Todos los recursos"
    order:
      - file.name
      - formula.procesado
      - source_type
      - tags
    summaries:
      formula.dias_desde_captura: Average

  - type: cards
    name: "Galeria"
    order:
      - file.name
      - source_type
      - formula.procesado
```

### Indice de conocimiento

Ubicacion: `03_Conocimiento/Indice.base`

```yaml
filters:
  and:
    - file.inFolder("03_Conocimiento")
    - 'file.ext == "md"'

formulas:
  backlink_count: 'file.backlinks.length'
  dias_sin_editar: '(now() - file.mtime).days.round(0)'
  necesita_revision: 'if((now() - file.mtime).days > 180, "Revisar", "")'

properties:
  formula.backlink_count:
    displayName: "Backlinks"
  formula.necesita_revision:
    displayName: "Estado"

views:
  - type: table
    name: "Por popularidad"
    order:
      - file.name
      - tags
      - formula.backlink_count
      - formula.dias_sin_editar
      - formula.necesita_revision
    groupBy:
      property: file.folder
      direction: ASC

  - type: table
    name: "Necesitan revision"
    filters:
      and:
        - 'formula.necesita_revision != ""'
    order:
      - file.name
      - file.mtime
      - formula.dias_sin_editar
```

### Notas estancadas (para lint del organizador)

Ubicacion: `00_Sistema/Estancadas.base`

```yaml
filters:
  and:
    - 'file.ext == "md"'
    - or:
        - 'status == "borrador"'
        - 'status == "en_proceso"'

formulas:
  dias_sin_editar: '(now() - file.mtime).days.round(0)'
  urgencia: 'if((now() - file.mtime).days > 90, "Critico", if((now() - file.mtime).days > 30, "Revisar", "OK"))'

properties:
  formula.urgencia:
    displayName: "Urgencia"

views:
  - type: table
    name: "Notas estancadas"
    filters:
      and:
        - 'formula.dias_sin_editar > 30'
    order:
      - file.name
      - status
      - type
      - formula.dias_sin_editar
      - formula.urgencia
      - file.folder
    groupBy:
      property: formula.urgencia
      direction: DESC
```

