Files
insertr/README.md
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

664 lines
22 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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**
```html
<!-- 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)
```yaml
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)
```yaml
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:**
```yaml
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):**
```bash
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
### **Quick Start (Recommended)**
```bash
# 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:
- **Demo sites**: http://localhost:8080/sites/demo/ (auto-enhanced for testing)
- **API server**: http://localhost:8080/api/* (with content persistence and version control)
### **Using NPM**
```bash
# Alternative using npm
npm run install:all
npm run build
npm run dev
```
### **Available Commands**
```bash
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
```bash
🔍 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**
```html
<!-- 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**
```bash
# 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**
```bash
# 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**
```bash
# 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**
```yaml
# .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**
```html
<!-- 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**
```bash
# 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**
```bash
# 🔥 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)**
```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
- **[Command Reference](COMMANDS.md)** - Complete command and configuration guide
- **[Development Guide](DEVELOPMENT.md)** - Setup and contribution workflow
- **[Research Document](RESEARCH.md)** - Strategic analysis and market positioning
- **[Integration Summary](INTEGRATION-SUMMARY.md)** - Complete architecture overview
## 🎯 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**
```bash
# 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:
```yaml
# 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)**
```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
#### **Authentication (Recommended for Production)**
- `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**
```bash
# 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](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**