# Knowledge Base Templates

This directory contains Tera templates for generating and exporting knowledge base documents.

## Overview

Templates are divided into two categories:

1. **Document Templates** - Generate new KOGRAL documents with proper frontmatter
2. **Export Templates** - Export KOGRAL data to various formats (Logseq, JSON, reports)

## Document Templates

Located in the root `templates/` directory. Used to create new knowledge base entries.

### Available Templates

| Template | Purpose | Node Type |
|----------|---------|-----------|
| `note.md.tera` | General notes and observations | note |
| `decision.md.tera` | Architectural Decision Records (ADR) | decision |
| `guideline.md.tera` | Code guidelines and best practices | guideline |
| `pattern.md.tera` | Design patterns and solutions | pattern |
| `journal.md.tera` | Daily notes and journal entries | journal |
| `execution.md.tera` | Agent execution records (from Vapora) | execution |

### Template Variables

All document templates receive these common variables:

```rust
{
  id: String,              // UUID
  title: String,           // Node title
  created: DateTime,       // ISO 8601 timestamp
  modified: DateTime,      // ISO 8601 timestamp
  tags: Vec<String>,       // Tags
  status: NodeStatus,      // draft, active, superseded, archived
  content: String,         // Markdown content
  relates_to: Vec<String>, // Related node IDs
  depends_on: Vec<String>, // Dependency node IDs
  implements: Vec<String>, // Pattern/guideline node IDs
  extends: Vec<String>,    // Extension node IDs
  project: Option<String>, // Project identifier
}
```

### Type-Specific Variables

**Decision (ADR):**
```rust
{
  context: String,           // Problem context
  decision: String,          // Decision made
  consequences: Vec<String>, // Impacts
  alternatives: Vec<{        // Alternatives considered
    name: String,
    description: String,
    pros: Vec<String>,
    cons: Vec<String>,
  }>,
}
```

**Guideline:**
```rust
{
  language: String,     // Programming language
  category: String,     // Category (error-handling, testing, etc.)
  overview: String,     // Brief overview
  rules: Vec<{          // Guideline rules
    title: String,
    description: String,
    rationale: String,
  }>,
  examples: Vec<{       // Code examples
    title: String,
    good: String,       // Good practice
    bad: String,        // Bad practice
    explanation: String,
  }>,
  exceptions: Vec<String>,
}
```

**Pattern:**
```rust
{
  problem: String,           // Problem statement
  solution: String,          // Solution description
  forces: Vec<String>,       // Constraints/forces
  context: String,           // When to use
  structure: String,         // Pattern structure
  implementation: Vec<{      // Implementation steps
    title: String,
    description: String,
    code: String,
    language: String,
  }>,
  consequences: {
    benefits: Vec<String>,
    drawbacks: Vec<String>,
  },
}
```

**Journal:**
```rust
{
  date: String,             // Date (YYYY-MM-DD)
  tasks: Vec<{              // Tasks for the day
    description: String,
    completed: bool,
  }>,
  highlights: Vec<String>,  // Daily highlights
  learnings: Vec<String>,   // Things learned
  links: Vec<String>,       // Related node IDs
}
```

**Execution:**
```rust
{
  task_type: String,        // Type of task
  agent: String,            // Agent name
  outcome: String,          // success, failure, etc.
  duration_ms: u64,         // Execution time
  steps: Vec<{              // Execution steps
    description: String,
    duration_ms: u64,
    result: String,
  }>,
  errors: Vec<{             // Errors encountered
    type: String,
    message: String,
    details: String,
  }>,
  metrics: Vec<{            // Performance metrics
    name: String,
    value: f64,
    unit: String,
  }>,
}
```

## Export Templates

Located in `templates/export/`. Used to export KOGRAL data to external formats.

### Available Export Templates

| Template | Format | Purpose |
|----------|--------|---------|
| `logseq-page.md.tera` | Logseq Markdown | Export single node to Logseq page |
| `logseq-journal.md.tera` | Logseq Markdown | Export journal to Logseq daily note |
| `summary.md.tera` | Markdown Report | Generate KOGRAL summary report |
| `graph.json.tera` | JSON | Export entire graph to JSON |

### Export Template Variables

**Logseq Export:**
```rust
{
  node: Node,  // Full node object
}
```

**Summary Export:**
```rust
{
  graph: {
    name: String,
    version: String,
    description: String,
  },
  timestamp: DateTime,
  stats: {
    total_nodes: usize,
    total_edges: usize,
    nodes_by_type: HashMap<NodeType, usize>,
    nodes_by_status: HashMap<NodeStatus, usize>,
    top_tags: Vec<(String, usize)>,
  },
  nodes: Vec<Node>,
}
```

**JSON Export:**
```rust
{
  graph: Graph,
  nodes: Vec<Node>,
  edges: Vec<Edge>,
  stats: Statistics,
}
```

## Usage Examples

### Generate a New Note

```rust
use kb_core::export::tera::TeraEngine;
use kb_core::models::{Node, NodeType};

let tera = TeraEngine::new(Path::new("templates"))?;
let mut node = Node::new(NodeType::Note, "My Note".to_string());
node.content = "This is my note content".to_string();
node.tags = vec!["rust".to_string(), "kogral".to_string()];

let markdown = tera.render_node(&node)?;
```

### Export to Logseq

```rust
let logseq_md = tera.export_logseq(&node)?;
std::fs::write(".logseq/pages/my-note.md", logseq_md)?;
```

### Generate Summary Report

```rust
use tera::Context;

let mut context = Context::new();
context.insert("graph", &graph);
context.insert("timestamp", &Utc::now());
context.insert("stats", &statistics);
context.insert("nodes", &nodes);

let summary = tera.render_custom("export/summary.md.tera", &context)?;
```

## Customization

### Override Default Templates

Copy a template and modify it:

```bash
cp templates/note.md.tera my-templates/custom-note.md.tera
# Edit my-templates/custom-note.md.tera
```

Update configuration:

```nickel
{
  templates = {
    templates_dir = "my-templates",
    templates = {
      note = "custom-note.md.tera",
    },
  },
}
```

### Create Custom Templates

Add to `templates/custom/`:

```jinja2
---
id: {{ id }}
title: {{ title }}
custom_field: {{ my_custom_field }}
---

# {{ title }}

Custom template content here.
```

Register in config:

```nickel
{
  templates = {
    custom = {
      my-template = "custom/my-template.md.tera",
    },
  },
}
```

## Template Syntax

Templates use Tera syntax (similar to Jinja2):

### Variables
```jinja2
{{ variable }}
{{ object.field }}
{{ array.0 }}
```

### Filters
```jinja2
{{ text | upper }}
{{ date | date(format="%Y-%m-%d") }}
{{ content | truncate(length=100) }}
{{ json_data | json_encode | safe }}
```

### Conditionals
```jinja2
{% if condition %}
  ...
{% elif other_condition %}
  ...
{% else %}
  ...
{% endif %}
```

### Loops
```jinja2
{% for item in items %}
  {{ item }}
{% endfor %}

{% for key, value in map %}
  {{ key }}: {{ value }}
{% endfor %}
```

### Comments
```jinja2
{# This is a comment #}
```

## YAML Frontmatter

All document templates generate YAML frontmatter compatible with:

- **Logseq** - Wikilinks, properties
- **kogral-core parser** - Full schema validation
- **Git** - Human-readable diffs

Example:

```yaml
---
id: abc-123
type: note
title: My Note
created: 2026-01-17T10:30:00Z
modified: 2026-01-17T10:30:00Z
tags: ["rust", "kogral"]
status: draft
relates_to:
  - other-note-id
---
```

## Best Practices

1. **Keep Templates Simple** - Focus on structure, not complex logic
2. **Use Defaults** - Provide sensible defaults with `| default(value="...")`
3. **Indent Consistently** - Use `| indent(width=2)` for nested content
4. **Escape User Content** - Use `| escape` for user-provided text in HTML/JSON
5. **Document Custom Fields** - Add comments explaining custom template variables

## Troubleshooting

### Template Not Found

Ensure `templates_dir` in config points to the correct directory:

```nickel
templates = {
  templates_dir = "templates",  // Relative to project root
}
```

### Variable Not Found

Check that the variable is provided in the template context. Add a default:

```jinja2
{{ variable | default(value="") }}
```

### Rendering Errors

Enable debug mode to see detailed error messages:

```rust
let tera = Tera::new("templates/**/*.tera")?;
tera.autoescape_on(vec![]); // Disable autoescaping for markdown
```

## References

- [Tera Documentation](https://keats.github.io/tera/)
- [Logseq Markdown Format](https://docs.logseq.com/)
- kogral-core models: `crates/kogral-core/src/models.rs`
- Template engine: `crates/kogral-core/src/export/tera.rs`
