Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
98 lines
2.6 KiB
Python
98 lines
2.6 KiB
Python
"""Markdown + YAML frontmatter rendering for processed notes.
|
|
|
|
Renders:
|
|
- Frontmatter with title, date, tags, people, projects, source
|
|
- Body with wiki-links inserted
|
|
- Action Items section at the end
|
|
"""
|
|
|
|
import logging
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
from ingestion.enrichment.models import EnrichmentResult
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def render_note(
|
|
enrichment: EnrichmentResult, body_text: str, source_file: Path
|
|
) -> str:
|
|
"""Render a complete markdown note with YAML frontmatter.
|
|
|
|
Args:
|
|
enrichment: The enrichment result with metadata and entities.
|
|
body_text: The document body (with wiki-links already inserted).
|
|
source_file: Original source file path for provenance.
|
|
|
|
Returns:
|
|
Complete markdown string with frontmatter, body, and action items.
|
|
"""
|
|
# Build frontmatter data
|
|
frontmatter: dict = {
|
|
"title": enrichment.title,
|
|
}
|
|
|
|
# Extract date from entities or use today
|
|
date_entities = [e for e in enrichment.entities if e.type == "date"]
|
|
if date_entities:
|
|
frontmatter["date"] = date_entities[0].value
|
|
else:
|
|
frontmatter["date"] = datetime.now(timezone.utc).strftime("%Y-%m-%d")
|
|
|
|
if enrichment.tags:
|
|
frontmatter["tags"] = enrichment.tags
|
|
|
|
# People and projects from entities
|
|
people = list(
|
|
{e.value for e in enrichment.entities if e.type == "person"}
|
|
)
|
|
projects = list(
|
|
{e.value for e in enrichment.entities if e.type == "project"}
|
|
)
|
|
|
|
if people:
|
|
frontmatter["people"] = sorted(people)
|
|
if projects:
|
|
frontmatter["projects"] = sorted(projects)
|
|
|
|
frontmatter["source"] = {
|
|
"file": source_file.name,
|
|
"imported": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S"),
|
|
}
|
|
|
|
# Render YAML frontmatter
|
|
yaml_str = yaml.dump(
|
|
frontmatter,
|
|
default_flow_style=False,
|
|
allow_unicode=True,
|
|
sort_keys=False,
|
|
)
|
|
|
|
# Build the full document
|
|
parts = [
|
|
"---",
|
|
yaml_str.rstrip(),
|
|
"---",
|
|
"",
|
|
body_text.rstrip(),
|
|
]
|
|
|
|
# Add action items section if any
|
|
if enrichment.action_items:
|
|
parts.append("")
|
|
parts.append("## Action Items")
|
|
parts.append("")
|
|
for item in enrichment.action_items:
|
|
line = f"- [ ] {item.description}"
|
|
if item.assignee:
|
|
line += f" ({item.assignee})"
|
|
if item.deadline:
|
|
line += f" (deadline: {item.deadline})"
|
|
parts.append(line)
|
|
|
|
parts.append("") # trailing newline
|
|
return "\n".join(parts)
|