413 lines
10 KiB
Markdown
413 lines
10 KiB
Markdown
# StarPunk - Minimal IndieWeb CMS
|
|
|
|
## Project Overview
|
|
|
|
StarPunk is a minimalist, single-user CMS for publishing IndieWeb-compatible notes with RSS syndication. It emphasizes simplicity, elegance, and standards compliance.
|
|
|
|
**Core Philosophy**: Every line of code must justify its existence. When in doubt, leave it out.
|
|
|
|
## V1 Scope
|
|
|
|
### Must Have
|
|
- Publish notes (https://indieweb.org/note)
|
|
- IndieAuth authentication (https://indieauth.spec.indieweb.org)
|
|
- Micropub server endpoint (https://micropub.spec.indieweb.org)
|
|
- RSS feed generation
|
|
- API-first architecture
|
|
- Markdown support
|
|
- Self-hostable deployment
|
|
|
|
### Won't Have (V1)
|
|
- Webmentions
|
|
- POSSE (beyond RSS)
|
|
- Multiple users
|
|
- Comments
|
|
- Analytics
|
|
- Themes/customization
|
|
- Media uploads
|
|
- Other post types (articles, photos, replies)
|
|
|
|
## System Architecture
|
|
|
|
### Core Components
|
|
|
|
1. **Data Layer**
|
|
- Notes storage (content, HTML rendering, timestamps, slugs)
|
|
- Authentication tokens for IndieAuth sessions
|
|
- Simple schema with minimal relationships
|
|
- Persistence with backup capability
|
|
|
|
2. **API Layer**
|
|
- RESTful endpoints for note management
|
|
- Micropub endpoint for external clients
|
|
- IndieAuth implementation
|
|
- RSS feed generation
|
|
- JSON responses for all APIs
|
|
|
|
3. **Web Interface**
|
|
- Minimal public interface displaying notes
|
|
- Admin interface for creating/managing notes
|
|
- Single elegant theme
|
|
- Proper microformats markup (h-entry, h-card)
|
|
- No client-side complexity
|
|
|
|
### Data Model
|
|
|
|
```
|
|
Notes:
|
|
- id: unique identifier
|
|
- content: raw markdown text
|
|
- content_html: rendered HTML
|
|
- slug: URL-friendly identifier
|
|
- published: boolean flag
|
|
- created_at: timestamp
|
|
- updated_at: timestamp
|
|
|
|
Tokens:
|
|
- token: unique token string
|
|
- me: user identity URL
|
|
- client_id: micropub client identifier
|
|
- scope: permission scope
|
|
- created_at: timestamp
|
|
- expires_at: optional expiration
|
|
```
|
|
|
|
### URL Structure
|
|
|
|
```
|
|
/ # Homepage with recent notes
|
|
/note/{slug} # Individual note permalink
|
|
/admin # Admin dashboard
|
|
/admin/new # Create new note
|
|
/api/micropub # Micropub endpoint
|
|
/api/notes # Notes CRUD API
|
|
/api/auth # IndieAuth endpoints
|
|
/feed.xml # RSS feed
|
|
/.well-known/oauth-authorization-server # IndieAuth metadata
|
|
```
|
|
|
|
## Implementation Requirements
|
|
|
|
### Phase 1: Foundation
|
|
|
|
**Data Storage**
|
|
- Implement note storage with CRUD operations
|
|
- Support markdown content with HTML rendering
|
|
- Generate unique slugs for URLs
|
|
- Track creation and update timestamps
|
|
|
|
**Configuration**
|
|
- Site URL (required for absolute URLs)
|
|
- Site title and author information
|
|
- IndieAuth endpoint configuration
|
|
- Environment-based configuration
|
|
|
|
### Phase 2: Core APIs
|
|
|
|
**Notes API**
|
|
- GET /api/notes - List published notes
|
|
- POST /api/notes - Create new note (authenticated)
|
|
- GET /api/notes/{id} - Get single note
|
|
- PUT /api/notes/{id} - Update note (authenticated)
|
|
- DELETE /api/notes/{id} - Delete note (authenticated)
|
|
|
|
**RSS Feed**
|
|
- Generate valid RSS 2.0 feed
|
|
- Include all published notes
|
|
- Proper date formatting (RFC-822)
|
|
- CDATA wrapping for HTML content
|
|
- Cache appropriately (5 minute minimum)
|
|
|
|
### Phase 3: IndieAuth Implementation
|
|
|
|
**Authorization Endpoint**
|
|
- Validate client_id parameter
|
|
- Verify redirect_uri matches registered client
|
|
- Generate authorization codes
|
|
- Support PKCE flow
|
|
|
|
**Token Endpoint**
|
|
- Exchange authorization codes for access tokens
|
|
- Validate code verifier for PKCE
|
|
- Return token with appropriate scope
|
|
- Store token with expiration
|
|
|
|
**Token Verification**
|
|
- Validate bearer tokens in Authorization header
|
|
- Check token expiration
|
|
- Verify scope for requested operation
|
|
|
|
### Phase 4: Micropub Implementation
|
|
|
|
**POST Endpoint**
|
|
- Support JSON format (Content-Type: application/json)
|
|
- Support form-encoded format (Content-Type: application/x-www-form-urlencoded)
|
|
- Handle h-entry creation for notes
|
|
- Return 201 Created with Location header
|
|
- Validate authentication token
|
|
|
|
**GET Endpoint**
|
|
- Support q=config query (return supported features)
|
|
- Support q=source query (return note source)
|
|
- Return appropriate JSON responses
|
|
|
|
**Micropub Request Structure (JSON)**
|
|
```json
|
|
{
|
|
"type": ["h-entry"],
|
|
"properties": {
|
|
"content": ["Note content here"]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Micropub Response**
|
|
```
|
|
HTTP/1.1 201 Created
|
|
Location: https://example.com/note/abc123
|
|
```
|
|
|
|
### Phase 5: Web Interface
|
|
|
|
**Homepage Requirements**
|
|
- Display notes in reverse chronological order
|
|
- Include proper h-entry microformats
|
|
- Show note content (e-content class)
|
|
- Include permalink (u-url class)
|
|
- Display publish date (dt-published class)
|
|
- Clean, readable typography
|
|
- Mobile-responsive design
|
|
|
|
**Note Permalink Page**
|
|
- Full note display with microformats
|
|
- Author information (h-card)
|
|
- Timestamp and permalink
|
|
- Link back to homepage
|
|
|
|
**Admin Interface**
|
|
- Simple markdown editor
|
|
- Preview capability
|
|
- Publish/Draft toggle
|
|
- List of existing notes
|
|
- Edit existing notes
|
|
- Protected by authentication
|
|
|
|
**Microformats Example**
|
|
```html
|
|
<article class="h-entry">
|
|
<div class="e-content">
|
|
<p>Note content goes here</p>
|
|
</div>
|
|
<footer>
|
|
<a class="u-url" href="/note/abc123">
|
|
<time class="dt-published" datetime="2024-01-01T12:00:00Z">
|
|
January 1, 2024
|
|
</time>
|
|
</a>
|
|
</footer>
|
|
</article>
|
|
```
|
|
|
|
### Phase 6: Deployment
|
|
|
|
**Requirements**
|
|
- Self-hostable package
|
|
- Single deployment unit
|
|
- Persistent data storage
|
|
- Environment-based configuration
|
|
- Backup-friendly data format
|
|
|
|
**Configuration Variables**
|
|
- SITE_URL - Full URL of the site
|
|
- SITE_TITLE - Site name for RSS feed
|
|
- SITE_AUTHOR - Default author name
|
|
- INDIEAUTH_ENDPOINT - IndieAuth provider URL
|
|
- DATA_PATH - Location for persistent storage
|
|
|
|
### Phase 7: Testing
|
|
|
|
**Unit Tests Required**
|
|
- Data layer operations
|
|
- Micropub request parsing
|
|
- IndieAuth token validation
|
|
- Markdown rendering
|
|
- Slug generation
|
|
|
|
**Integration Tests**
|
|
- Complete Micropub flow
|
|
- IndieAuth authentication flow
|
|
- RSS feed generation
|
|
- API endpoint responses
|
|
|
|
**Test Coverage Areas**
|
|
- Note creation via web interface
|
|
- Note creation via Micropub
|
|
- Authentication flows
|
|
- Feed validation
|
|
- Error handling
|
|
|
|
## Standards Compliance
|
|
|
|
### IndieWeb Standards
|
|
|
|
**Microformats2**
|
|
- h-entry for notes
|
|
- h-card for author information
|
|
- e-content for note content
|
|
- dt-published for timestamps
|
|
- u-url for permalinks
|
|
|
|
**IndieAuth**
|
|
- OAuth 2.0 compatible flow
|
|
- Support for authorization code grant
|
|
- PKCE support recommended
|
|
- Token introspection endpoint
|
|
|
|
**Micropub**
|
|
- JSON and form-encoded content types
|
|
- Location header on creation
|
|
- Configuration endpoint
|
|
- Source endpoint for queries
|
|
|
|
### Web Standards
|
|
|
|
**HTTP**
|
|
- Proper status codes (200, 201, 400, 401, 404)
|
|
- Content-Type headers
|
|
- Cache-Control headers where appropriate
|
|
- CORS headers for API endpoints
|
|
|
|
**RSS 2.0**
|
|
- Valid XML structure
|
|
- Required channel elements
|
|
- Proper date formatting
|
|
- GUID for each item
|
|
- CDATA for HTML content
|
|
|
|
**HTML**
|
|
- Semantic HTML5 elements
|
|
- Valid markup
|
|
- Accessible forms
|
|
- Mobile-responsive design
|
|
|
|
## Security Considerations
|
|
|
|
### Authentication
|
|
- Validate all tokens before operations
|
|
- Implement token expiration
|
|
- Use secure token generation
|
|
- Protect admin routes
|
|
|
|
### Input Validation
|
|
- Sanitize markdown input
|
|
- Validate Micropub payloads
|
|
- Prevent SQL injection
|
|
- Escape HTML appropriately
|
|
|
|
### HTTP Security
|
|
- Use HTTPS in production
|
|
- Set secure headers
|
|
- Implement CSRF protection
|
|
- Rate limit API endpoints
|
|
|
|
## Performance Guidelines
|
|
|
|
### Response Times
|
|
- API responses < 100ms
|
|
- Page loads < 200ms
|
|
- RSS feed generation < 300ms
|
|
|
|
### Caching Strategy
|
|
- Cache RSS feed (5 minutes)
|
|
- Cache static assets
|
|
- Database query optimization
|
|
- Minimize external dependencies
|
|
|
|
### Resource Usage
|
|
- Efficient database queries
|
|
- Minimal memory footprint
|
|
- Optimize HTML/CSS delivery
|
|
- Compress responses
|
|
|
|
## Testing Checklist
|
|
|
|
- [ ] Create notes via web interface
|
|
- [ ] Create notes via Micropub JSON
|
|
- [ ] Create notes via Micropub form-encoded
|
|
- [ ] RSS feed validates (W3C validator)
|
|
- [ ] IndieAuth login flow works
|
|
- [ ] Micropub client authentication
|
|
- [ ] Notes display with proper microformats
|
|
- [ ] API returns correct status codes
|
|
- [ ] Markdown renders correctly
|
|
- [ ] Slugs generate uniquely
|
|
- [ ] Timestamps record accurately
|
|
- [ ] Token expiration works
|
|
- [ ] Rate limiting functions
|
|
- [ ] All unit tests pass
|
|
|
|
## Validation Tools
|
|
|
|
**IndieWeb**
|
|
- https://indiewebify.me/ - Verify microformats
|
|
- https://indieauth.com/validate - Test IndieAuth
|
|
- https://micropub.rocks/ - Micropub test suite
|
|
|
|
**Web Standards**
|
|
- https://validator.w3.org/feed/ - RSS validator
|
|
- https://validator.w3.org/ - HTML validator
|
|
- https://jsonlint.com/ - JSON validator
|
|
|
|
## Resources
|
|
|
|
### Specifications
|
|
- IndieWeb Notes: https://indieweb.org/note
|
|
- Micropub Spec: https://micropub.spec.indieweb.org
|
|
- IndieAuth Spec: https://indieauth.spec.indieweb.org
|
|
- Microformats2: http://microformats.org/wiki/h-entry
|
|
- RSS 2.0 Spec: https://www.rssboard.org/rss-specification
|
|
|
|
### Testing & Validation
|
|
- Micropub Test Suite: https://micropub.rocks/
|
|
- IndieAuth Testing: https://indieauth.com/
|
|
- Microformats Parser: https://pin13.net/mf2/
|
|
|
|
### Example Implementations
|
|
- IndieWeb Examples: https://indieweb.org/examples
|
|
- Micropub Clients: https://indieweb.org/Micropub/Clients
|
|
|
|
## Development Principles
|
|
|
|
1. **Minimal Code**: Every feature must justify its complexity
|
|
2. **Standards First**: Follow specifications exactly
|
|
3. **User Control**: User owns their data completely
|
|
4. **No Lock-in**: Data must be portable and exportable
|
|
5. **Progressive Enhancement**: Core functionality works without JavaScript
|
|
6. **Documentation**: Code should be self-documenting
|
|
7. **Test Coverage**: Critical paths must have tests
|
|
|
|
## Future Considerations (Post-V1)
|
|
|
|
Potential V2 features:
|
|
- Webmentions support
|
|
- Media uploads (photos)
|
|
- Additional post types (articles, replies)
|
|
- POSSE to Mastodon/ActivityPub
|
|
- Full-text search
|
|
- Draft/scheduled posts
|
|
- Multiple IndieAuth providers
|
|
- Backup/restore functionality
|
|
- Import from other platforms
|
|
- Export in multiple formats
|
|
|
|
## Success Criteria
|
|
|
|
The project is successful when:
|
|
- A user can publish notes from any Micropub client
|
|
- Notes appear in RSS readers immediately
|
|
- The system runs on minimal resources
|
|
- Code is readable and maintainable
|
|
- All IndieWeb validators pass
|
|
- Setup takes less than 5 minutes
|
|
- System runs for months without intervention
|