Files
personotes/docs/ARCHITECTURE_OVERVIEW.md
2025-11-12 17:16:13 +01:00

362 lines
8.3 KiB
Markdown

# Architecture Overview
## Hybrid Architecture
PersoNotes uses a **hybrid architecture** that combines the best of multiple paradigms:
### Core Components
- **Go Backend**: Fast, type-safe server handling file operations and indexing
- **HTMX**: "HTML over the wire" for dynamic interactions with minimal JavaScript
- **Modern JavaScript**: CodeMirror 6, drag-and-drop, and UI enhancements
- **Vite**: Modern build tool for efficient JavaScript bundling
### Key Design Principles
1. **Server renders HTML, not JSON** (simpler, faster)
2. **HTMX handles all AJAX and DOM updates** (consistent, reliable)
3. **JavaScript enhances UI** (editor, drag-and-drop, animations)
4. **Event-driven coordination** between HTMX and JavaScript
## Technology Stack
### Backend: Go
- **`net/http`**: Standard library for the web server
- **`github.com/fsnotify/fsnotify`**: For watching file system changes and re-indexing
- **`gopkg.in/yaml.v3`**: For parsing and marshaling YAML front matter
- **Chi Router**: Lightweight, fast HTTP router (implied by usage)
**Why Go?**
- Fast compilation and execution
- Excellent standard library
- Built-in concurrency
- Single binary deployment
- Cross-platform support (Linux, FreeBSD, macOS, Windows)
### Frontend: HTML, CSS, JavaScript
#### Core Technologies
- **[htmx](https://htmx.org/)**: For dynamic UI interactions without writing much JavaScript
- Declarative AJAX requests
- DOM swapping and updates
- WebSocket support
- Event-driven architecture
- **[CodeMirror 6](https://codemirror.net/6/)**: For the robust Markdown editor
- Extensible architecture
- Syntax highlighting
- Vim mode support
- Custom extensions (slash commands)
- **[Vite](https://vitejs.dev/)**: For bundling frontend JavaScript modules
- Fast development server
- Optimized production builds
- ES modules support
- Hot module replacement
#### Supporting Libraries
- **[marked.js](https://marked.js.org/)**: For client-side Markdown parsing in the preview
- **[DOMPurify](https://dompurpurify.com/)**: For sanitizing HTML output from Markdown to prevent XSS vulnerabilities
- **[Highlight.js](https://highlightjs.org/)**: For syntax highlighting in code blocks
- **Custom CSS theme**: Dark mode inspired by VS Code and GitHub Dark
**Why This Stack?**
- Minimal JavaScript complexity
- Progressive enhancement
- Fast page loads
- SEO-friendly (server-rendered HTML)
- Easy to understand and maintain
## Architecture Patterns
### Server-Side Rendering (SSR)
All HTML is rendered on the server using Go's `html/template` package:
- Initial page loads are fast
- No JavaScript required for basic functionality
- Better SEO and accessibility
### Progressive Enhancement
The application works without JavaScript but is enhanced with it:
1. **Base functionality**: Browse notes, view content (no JS)
2. **HTMX enhancement**: Dynamic updates without page reloads
3. **JavaScript enhancement**: Rich editor, drag-and-drop, animations
### File-Based Storage
Notes are stored as plain Markdown files with YAML front matter:
```markdown
---
title: My Note
date: 2025-11-11
last_modified: 2025-11-11:14:30
tags:
- example
- markdown
---
# My Note
Content here...
```
**Benefits**:
- No database setup required
- Easy backups (just copy files)
- Version control friendly (Git)
- Human-readable
- Portable (works with any Markdown tool)
### In-Memory Indexing
Notes are indexed in memory for fast search:
- Full-text search across title, tags, path, content
- Tag-based filtering
- Path-based navigation
- Real-time updates via file system watcher
**Trade-offs**:
- Memory usage scales with note count
- Index rebuilt on server restart
- Suitable for personal/small team use (< 10,000 notes)
## Request Flow
### Reading a Note
```
Browser → GET /editor?note=path/to/note.md
Go Handler
Read file from disk
Parse front matter
Render HTML template
Browser ← HTML response
CodeMirror initializes
User sees editable note
```
### Saving a Note
```
Browser → htmx POST /save
Go Handler
Update front matter (last_modified)
Write file to disk
File system watcher detects change
Re-index note
Browser ← Success response
htmx updates UI
```
### Search
```
Browser → htmx GET /search?q=query
Go Handler
Query in-memory index
Score and rank results
Render search results template
Browser ← HTML fragment
htmx swaps into DOM
```
## Data Flow
```
Filesystem (notes/) ←→ File Watcher (fsnotify)
Indexer (in-memory)
HTTP Handlers
Templates + HTMX
Browser
CodeMirror Editor
```
## Scalability Considerations
### Current Design (Suitable for)
- Personal use: 1-10,000 notes
- Small teams: 2-5 users
- Single server deployment
- Notes up to ~1MB each
### Limitations
- **No concurrent editing**: Last write wins
- **In-memory index**: Limited by server RAM
- **No authentication**: Requires reverse proxy
- **Single server**: No horizontal scaling
### Future Enhancements (if needed)
- SQLite for metadata indexing (larger note collections)
- WebSocket for real-time collaboration
- JWT authentication built-in
- Redis for distributed caching
- Object storage for large attachments
## Security Model
### Current State
- **No built-in authentication**: Designed for local/private networks
- **XSS protection**: DOMPurify sanitizes Markdown output
- **Path traversal prevention**: Input validation on file paths
- **CSRF**: Not needed (no session-based auth)
### Recommended Production Setup
```
Internet → Reverse Proxy (nginx/Caddy)
Basic Auth / OAuth
PersoNotes (Go)
Filesystem (notes/)
```
Example nginx config:
```nginx
location / {
auth_basic "PersoNotes";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:8080;
}
```
## Performance Characteristics
### Strengths
- **Fast page loads**: Server-rendered HTML
- **Low latency**: In-memory indexing
- **Efficient search**: Pre-indexed content
- **Small footprint**: ~10-20MB RAM for typical usage
### Benchmarks (approximate)
- Note load time: < 50ms
- Search query: < 10ms (1000 notes)
- Save operation: < 100ms
- Index rebuild: < 1s (1000 notes)
## Development Workflow
### Backend Development
```bash
# Run with auto-reload (using air or similar)
air
# Or manual reload
go run ./cmd/server
```
### Frontend Development
```bash
# Watch mode (auto-rebuild)
cd frontend
npm run build -- --watch
```
### Testing
```bash
# Run all tests
go test ./...
# With coverage
go test -cover ./...
# Specific package
go test -v ./internal/indexer
```
## Deployment Options
### 1. Simple Binary
```bash
# Build
go build -o server ./cmd/server
# Run
./server -addr :8080 -notes-dir ~/notes
```
### 2. Systemd Service (Linux)
See [FREEBSD_BUILD.md](./FREEBSD_BUILD.md) for service examples.
### 3. Docker (future)
```dockerfile
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o server ./cmd/server
FROM alpine:latest
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/server /server
COPY --from=builder /app/static /static
COPY --from=builder /app/templates /templates
EXPOSE 8080
CMD ["/server"]
```
### 4. Reverse Proxy
Always recommended for production:
- nginx, Caddy, Traefik
- TLS termination
- Authentication
- Rate limiting
- Caching
## Documentation
For more detailed information, see:
- **[ARCHITECTURE.md](../ARCHITECTURE.md)** - Complete system architecture, patterns, and best practices
- **[CLAUDE.md](../CLAUDE.md)** - Development guide and implementation details
- **[API.md](../API.md)** - REST API documentation
- **[DAILY_NOTES.md](./DAILY_NOTES.md)** - Daily notes feature guide
- **[FREEBSD_BUILD.md](./FREEBSD_BUILD.md)** - FreeBSD deployment guide
- **[CHANGELOG.md](../CHANGELOG.md)** - Version history
---
**Last updated**: November 11, 2025