Joakim bb5ea6f873 Complete library cleanup and documentation overhaul
## Library Code Cleanup (~1,200+ lines removed)
- Remove legacy markdown system (markdown.js, previewer.js)
- Delete unused EditContext code from ui/editor.js (~400 lines)
- Remove version history UI components from form-renderer.js (~180 lines)
- Clean unused CSS styles from insertr.css (~120 lines)
- Update package.json dependencies (remove marked, turndown)

## Documentation Updates
- README.md: Update from markdown to HTML-first approach
- AGENTS.md: Add current architecture guidance and HTML-first principles
- TODO.md: Complete rewrite with realistic roadmap and current status
- demos/README.md: Update for development demo server usage

## System Reality Alignment
- All documentation now reflects current working system
- Removed aspirational features in favor of actual capabilities
- Clear separation between development and production workflows
- Accurate description of style-aware editor with HTML preservation

## Code Cleanup Benefits
- Simplified codebase focused on HTML-first approach
- Removed markdown conversion complexity
- Cleaner build process without unused dependencies
- Better alignment between frontend capabilities and documentation

Ready for Phase 3a server updates with clean foundation.
2025-09-20 00:02:03 +02:00

Insertr

The Tailwind of CMS - Zero-configuration content editing for any static site

Insertr adds editing capabilities to any HTML website by simply adding class="insertr" to elements. No complex setup, no architectural changes, no framework dependencies. Just mark what should be editable and get a production-ready CMS.

Zero Configuration Philosophy

Just Add a Class

<!-- Individual elements -->
<h1 class="insertr">Main Title</h1>
<p class="insertr">Description text</p>  
<a href="/contact" class="insertr">Contact Us</a>

<!-- Container expansion -->
<section class="insertr">
  <h1>Hero Title</h1>
  <p>Hero description</p>
  <button>Call to Action</button>
</section>

That's it! No manual IDs, no configuration files, no schema definitions.

Container Expansion

Containers with class="insertr" automatically make their viable children editable:

  • Viable children: Elements containing only text (h1-h6, p, span, a, button)
  • Automatic detection: Skip complex nested elements
  • Semantic convenience: One class enables section-wide editing

🎯 Three User Experiences

1. Regular Visitors (99% of traffic)

  • Pure static HTML performance
  • Zero editor assets loaded
  • No runtime overhead

2. Content Editors (Authenticated users)

  • Style-aware editing interface loads on demand
  • Click-to-edit any marked element
  • Rich text editor with style preservation and formatting toolbar
  • Link editor with popup configuration for complex elements
  • Changes saved to database with version history

3. Developers (You)

  • Add class="insertr" to any element
  • Use HTML id attributes for complex cases
  • Never see or manage generated content IDs
  • Works with any static site generator

🔐 Authentication & Security

Insertr provides enterprise-grade authentication with multiple provider support for secure content editing.

Authentication Providers

Mock Authentication (Development)

auth:
  provider: "mock"
  • Zero setup - Works immediately for development
  • Automatic login - No credentials needed
  • Perfect for testing - Focus on content editing workflow

Authentik OIDC (Production)

auth:
  provider: "authentik"
  oidc:
    endpoint: "https://auth.example.com/application/o/insertr/"
    client_id: "insertr-client"
    client_secret: "your-secret"  # or use AUTHENTIK_CLIENT_SECRET env var

Enterprise-grade security features:

  • OIDC Discovery - Automatic endpoint configuration
  • PKCE Flow - Proof Key for Code Exchange security
  • JWT Verification - RSA/ECDSA signature validation via JWKS
  • Secure Sessions - HTTP-only cookies with CSRF protection
  • Multi-tenant - Per-site authentication configuration

Authentication Flow

1. Editor clicks gate → Popup opens to Authentik
2. User authenticates → Authentik returns authorization code  
3. Backend exchanges code for JWT → Validates with OIDC provider
4. Editor UI loads → Full editing capabilities enabled

Authentik Setup Guide

  1. Create OIDC Provider in Authentik:

    Applications → Providers → Create → OAuth2/OIDC Provider
    - Name: "Insertr CMS"
    - Authorization flow: default-authorization-flow
    - Client type: Confidential
    - Client ID: insertr-client
    - Redirect URIs: https://your-domain.com/auth/callback
    
  2. Create Application:

    Applications → Applications → Create
    - Name: "Insertr CMS"
    - Slug: insertr
    - Provider: (select the provider created above)
    
  3. Configure Insertr:

    auth:
      provider: "authentik"
      oidc:
        endpoint: "https://auth.example.com/application/o/insertr/"
        client_id: "insertr-client"
        client_secret: "your-generated-secret"
    
  4. Environment Variables (Recommended):

    export AUTHENTIK_CLIENT_SECRET="your-secret"
    export AUTHENTIK_ENDPOINT="https://auth.example.com/application/o/insertr/"
    

Security Best Practices

  • Environment Variables: Store secrets in env vars, not config files
  • HTTPS Only: Always use HTTPS in production for OAuth flows
  • Restricted Access: Use Authentik groups/policies to limit editor access
  • Token Validation: All JWTs verified against provider's public keys
  • Session Security: Secure cookie settings prevent XSS/CSRF attacks

🚀 Current Status

Complete Full-Stack CMS

  • Style-Aware Editor: Rich text editor with automatic style detection and formatting toolbar
  • HTML Preservation: Perfect fidelity editing that maintains all element attributes and styling
  • Enterprise Authentication: Production-ready OIDC integration with Authentik, PKCE security
  • Content Persistence: SQLite/PostgreSQL database with REST API, complete version control
  • Version History: Complete edit history with user attribution and one-click rollback
  • Build Enhancement: Parse HTML, inject database content, build-time optimization
  • Smart Detection: Auto-detects content types and generates style-based formatting options
  • Link Management: Popup-based link configuration for complex multi-property elements
  • Full Integration: Seamless development workflow with hot reload

🚀 Production Ready

  • Full HTTP API server with authentication and version control
  • Build-time enhancement for static site generators
  • PostgreSQL and SQLite database support
  • Authentik OIDC integration for enterprise authentication
  • Deploy enhanced static files to any CDN or host
  • Run content API server on separate infrastructure

🛠️ Quick Start

# Clone and setup
git clone <repository-url>
cd insertr

# Install dependencies and build everything
just install build

# Start full-stack development
just dev

This starts:

Using NPM

# Alternative using npm
npm run install:all
npm run build
npm run dev

Available Commands

just --list        # Show all available commands

# Development (Full-Stack by Default)
just dev           # Start full-stack development (recommended)
just demo [site]   # Start specific demo site (default, dan-eden)
just list-demos    # Show all available demo sites
just demo-only     # Demo site only (no content persistence)
just serve         # API server only (localhost:8080)

# Building  
just build         # Build library + unified binary (complete stack)
just build-lib     # Build JavaScript library only

# Utilities
just check         # Validate project setup
just status        # Show project status
just clean         # Clean build artifacts

🎯 Complete Development Experience

Running just dev gives you the complete Insertr CMS:

  • Style-Aware Editor - Rich text editing with automatic style detection and formatting
  • HTML Preservation - Perfect fidelity editing that maintains all styling and attributes
  • Real-Time Persistence - SQLite database with REST API and authentication
  • Version Control - Complete edit history with user attribution and rollback
  • Content Management - Create, read, update content via browser with popup-based link editing
  • Build Integration - Binary enhances HTML with database content
  • Hot Reload - Changes reflected immediately

📚 Version Control Features

Complete Edit History

Every content change is automatically tracked with:

  • User Attribution - Who made each change
  • Timestamps - When changes were made
  • Content Snapshots - Full content preserved for each version

Easy Rollback

  • View History button in any content editor
  • One-Click Restore to any previous version
  • Version Comparison - See what changed between versions
  • Safe Rollback - Current content is preserved before restoration

Example Workflow

1. Editor clicks on any element with class="insertr"
2. Professional editing modal opens
3. Click "View History" to see all previous versions
4. Each version shows: timestamp, author, content preview
5. Click "Restore" on any version to rollback instantly
6. All changes are tracked automatically

📊 Parser Output Example

🔍 Parsing HTML files in: ../demo-site/

📊 Parse Results:
   Files processed: 2
   Elements found: 40
   Container expansions: 3
   Generated IDs: 34

📝 Content Types:
   text: 19      # Headlines, short content
   markdown: 19  # Rich content, paragraphs  
   link: 2       # Buttons, navigation

🎯 Container Expansions:
   hero-section → 3 children (h1, p, button)
   services-grid → 6 children (3×h3, 3×p)

🏗️ Architecture: Unified Binary

Enhancement Pipeline

Static Site Build → insertr enhance → Enhanced Deployment
     ↓                       ↓                 ↓
  Pure HTML            Parse + Inject        Smart Loading
                       Database Content      (Auth-dependent)
                              ↓
Runtime Content API ← insertr serve ← Database (SQLite/PostgreSQL)

Unified Commands:

  • insertr enhance - Build-time content injection
  • insertr serve - Runtime API server
  • Single binary handles both development and production workflows

Smart Loading Strategy

<!-- Regular visitors: zero overhead -->
<h1 class="insertr">Welcome to Our Site</h1>

<!-- Authenticated editors: rich editing -->
<h1 class="insertr" data-content-id="hero-title-abc123" 
    data-editor-loaded="true">Latest Content From Database</h1>

Benefits:

  • Performance: Zero runtime cost for regular visitors
  • Framework agnostic: Works with Hugo, Next.js, Jekyll, etc.
  • Zero configuration: No schema files or content mappings
  • Developer friendly: Stay in HTML markup, no context switching

🔧 Unified Binary Commands

Build-Time Enhancement

# Production build with remote API
./insertr enhance src/ --output ./dist --api https://cms.example.com --api-key xyz

# Development build with local database
./insertr enhance demo-site/ --output ./dist --db ./content.db

# Development build with mock data
./insertr enhance demo-site/ --output ./dist --mock

# Use justfile shortcuts
just enhance                     # Default: demo-site/ → dist/ with mock data
just enhance input="src" output="public"  # Custom paths

Runtime API Server

# Development server with automatic site enhancement
./insertr serve --dev-mode --port 8080

# Production server with PostgreSQL
./insertr serve --db "postgresql://user:pass@host:5432/dbname" --config production.yaml

# Production server with custom config and Authentik
./insertr --config ./production.yaml serve

# Use justfile shortcuts
just serve                       # Development server on :8080 with auto-enhanced demo sites
just dev                         # Full development stack (recommended)

Configuration Options

# YAML configuration file
./insertr --config ./custom.yaml [command]

# Environment variables
export INSERTR_DB_PATH="./content.db"
export INSERTR_API_URL="https://api.example.com"
export INSERTR_API_KEY="your-api-key"
export INSERTR_SITE_ID="production"

# Command-line flags (highest priority)
./insertr --db ./custom.db --site-id staging serve --port 3000

# Show all options
./insertr --help
./insertr enhance --help
./insertr serve --help

📚 Integration Examples

GitHub Actions Workflow

# .github/workflows/deploy.yml
- name: Build static site
  run: hugo --minify

- name: Enhance with Insertr
  run: insertr enhance ./public --output ./dist

- name: Deploy enhanced site
  uses: peaceiris/actions-gh-pages@v3
  with:
    publish_dir: ./dist

Container vs Individual Elements

<!-- Semantic convenience: entire section editable -->
<section id="hero" class="insertr">
  <h1>Dynamic Title</h1>           <!-- → text input -->
  <p>Dynamic description</p>       <!-- → textarea -->  
  <button>Dynamic CTA</button>     <!-- → link editor -->
</section>

<!-- Granular control: specific elements -->
<nav>
  <h1 class="insertr">Site Name</h1>
  <ul>
    <li><a href="/" class="insertr">Home</a></li>
    <li><a href="/about" class="insertr">About</a></li>
  </ul>
</nav>

Content Type Detection

  • Headlines (h1-h6) → Rich text editor with style-aware formatting
  • Paragraphs (p) → Rich text editor with detected style options from CSS
  • Links/Buttons (a, button) → Popup-based link editor with text + URL configuration
  • Containers (div, section) → Expand to viable children with automatic style detection

🔌 API Reference

Simple Content Management

# Create or update content (single endpoint for both)
curl -X POST http://localhost:8080/api/content?site_id=demo \
  -H "Content-Type: application/json" \
  -d '{"value": "New content", "type": "text"}'

# Get all content for a site
curl http://localhost:8080/api/content?site_id=demo

# Get specific content by ID
curl http://localhost:8080/api/content/content-id?site_id=demo

# View edit history
curl http://localhost:8080/api/content/content-id/versions?site_id=demo

# Rollback to previous version
curl -X POST http://localhost:8080/api/content/content-id/rollback \
  -d '{"version_id": 123}'

Key Features:

  • Single POST endpoint handles both create and update (upsert)
  • Automatic ID generation from element context if no ID provided
  • Version control preserves all changes with user attribution
  • Auto-enhancement updates static files when content changes

🔧 Development Workflow

Live Development with Hot Reload

# 🔥 Hot Reload: watches BOTH library AND unified binary
just air

# Alternative: Watch library only
just watch
# or: cd lib && npm run dev

# Library changes: lib/src/**/*.js → Auto rebuild library + binary
# Binary changes: cmd/**/*.go, internal/**/*.go → Auto rebuild binary
# Both trigger server restart with latest embedded assets
# Visit localhost:3000 → Refresh to see changes

What Gets Hot Reloaded:

  • JavaScript library changes (lib/src/)
  • Go unified binary changes (cmd/, internal/)
  • Enhanced HTML output (real-time content injection)

Content ID Management

Development Phase:

  • Generated IDs are disposable and change freely
  • Focus on markup, ignore content persistence
  • Use HTML id attributes for complex cases

Production Phase:

  • Preserve existing content mappings for stability
  • Binary warns about orphaned content
  • Simple migration tools for structural changes

⚙️ Configuration

YAML Configuration (insertr.yaml)

# Database configuration
database:
  path: "./insertr.db"        # SQLite file or PostgreSQL connection string

# API configuration (for remote content API)
api:
  url: ""                     # Content API URL (leave empty to use local database)
  key: ""                     # API authentication key

# Server configuration  
server:
  port: 8080                  # HTTP server port
  dev_mode: false             # Enable development mode features

# Build configuration
build:
  input: "./src"              # Default input directory
  output: "./dist"            # Default output directory

# Global settings
site_id: "demo"              # Site ID for content lookup
mock_content: false          # Use mock content instead of real data

Configuration Precedence

  1. CLI flags (highest priority) - ./insertr --db ./custom.db serve
  2. Environment variables - INSERTR_DB_PATH=./custom.db
  3. YAML config file - insertr.yaml or --config custom.yaml
  4. Smart defaults (lowest priority)

Environment Variables

  • INSERTR_DB_PATH - Database path
  • INSERTR_API_URL - Remote API URL
  • INSERTR_API_KEY - API authentication key
  • INSERTR_SITE_ID - Site identifier

📖 Documentation

🎯 Market Position: "The Tailwind of CMS"

Tailwind CSS Approach:

  • Utility-first classes: class="text-lg font-bold"
  • Zero configuration, build-time optimization
  • Framework agnostic, developer workflow integration

Insertr CMS Approach:

  • Content-first classes: class="insertr"
  • Zero configuration, build-time enhancement
  • Framework agnostic, developer workflow integration

Shared Principles:

  • Stay in markup, don't context switch
  • Build-time optimization, zero runtime overhead
  • Works with any framework or generator
  • Developer experience focused

🚀 Production Deployment Workflow

Build-time enhancement + Runtime API for content management.

Production Architecture

The production workflow separates content management from site hosting:

1. Static Site Build → `insertr enhance` → Enhanced Static Files → Deploy to CDN/Host
2. Content Editing → `insertr serve` API → Database → Triggers rebuild

Two-Server Architecture

  • Content API Server: Runs insertr serve for content management and authentication
  • Static Site Host: Serves enhanced static files (CDN, GitHub Pages, Netlify, etc.)

Production Workflow

# 1. Build-time enhancement
./insertr enhance ./src --output ./dist --api https://cms.example.com

# 2. Deploy enhanced static files
rsync ./dist/ user@cdn:/var/www/site/

# 3. Run content API server (separate infrastructure)
./insertr serve --config production.yaml --db "postgresql://..."

Benefits

  • Performance: Static files served from CDN with zero CMS overhead
  • Scalability: Content API and static hosting scale independently
  • Reliability: Static site works even if CMS server is down
  • Security: Content editing isolated from public site hosting
  • Framework Agnostic: Works with any static site generator or CDN

Development Server (Current Multi-Site Feature)

For development convenience, insertr serve --dev-mode can host multiple demo sites:

# insertr.yaml (development only)
server:
  sites:
    - site_id: "demo"
      path: "./demos/demo_enhanced"
      source_path: "./demos/demo"
      auto_enhance: true

This serves sites at http://localhost:8080/sites/demo/ for testing the editor interface.

⚙️ Configuration

YAML Configuration (insertr.yaml)

# Global settings
dev_mode: false          # Development mode features

# Database configuration
database:
  path: "./insertr.db"   # SQLite file or PostgreSQL connection string

# Server configuration (multi-site hosting)
server:
  port: 8080            # HTTP server port
  sites:                # Server-hosted static sites
    - site_id: "mysite"
      path: "/var/www/mysite_enhanced"      # Enhanced site output directory
      source_path: "/var/www/mysite"        # Original static site files
      auto_enhance: true                    # Auto-enhance on startup and content changes
      discovery:
        enabled: false    # Use explicit class="insertr" markings (true = auto-discover)
        aggressive: false # Aggressive element discovery

# CLI enhancement configuration  
cli:
  site_id: "default"    # Default site ID for CLI operations
  output: "./dist"      # Default output directory for enhanced files
  inject_demo_gate: true  # Inject demo editing gate if none exist

# API configuration (for CLI remote mode)
api:
  url: ""               # Content API URL (empty = use local database)
  key: ""               # API authentication key

# Authentication configuration
auth:
  provider: "mock"      # "mock" for development, "authentik" for production
  jwt_secret: ""        # JWT signing secret (auto-generated in dev mode)
  # Authentik OIDC configuration (production)
  oidc:
    endpoint: ""        # https://auth.example.com/application/o/insertr/
    client_id: ""       # insertr-client (OAuth2 client ID)
    client_secret: ""   # OAuth2 client secret (or use AUTHENTIK_CLIENT_SECRET env var)

Environment Variables

Core Configuration

  • INSERTR_DB_PATH - Database path override
  • INSERTR_API_URL - Remote API URL override
  • INSERTR_API_KEY - API authentication key
  • INSERTR_SITE_ID - Site identifier override
  • AUTHENTIK_CLIENT_SECRET - OIDC client secret (overrides config file)
  • AUTHENTIK_ENDPOINT - OIDC endpoint URL (overrides config file)

Configuration Precedence

  1. CLI flags (highest priority)
  2. Environment variables
  3. YAML config file
  4. Smart defaults (lowest priority)

Database Options

# SQLite (development)
./insertr serve --db "./content.db"

# PostgreSQL (production)
./insertr serve --db "postgresql://user:pass@host:5432/insertr"

# Environment-based
export INSERTR_DB_PATH="postgresql://prod-host/insertr"
./insertr serve

🤝 Contributing

This project follows the "Tailwind philosophy" of developer-first design:

  1. Zero configuration - Markup-driven approach
  2. Build-time optimization - No runtime performance cost
  3. Framework agnostic - Works with any tech stack
  4. Developer friendly - Minimal cognitive overhead

See DEVELOPMENT.md for technical setup and contribution guidelines.

📄 License

MIT License - see LICENSE file for details.


Built with ❤️ for developers who want powerful editing without the complexity

Description
No description provided
Readme 29 MiB
Languages
JavaScript 48%
Go 40.9%
CSS 7.1%
PLpgSQL 2.3%
Just 1.4%
Other 0.3%