This commit resolves all documentation issues identified in the comprehensive review: CRITICAL FIXES: - Renumbered duplicate ADRs to eliminate conflicts: * ADR-022-migration-race-condition-fix → ADR-037 * ADR-022-syndication-formats → ADR-038 * ADR-023-microformats2-compliance → ADR-040 * ADR-027-versioning-strategy-for-authorization-removal → ADR-042 * ADR-030-CORRECTED-indieauth-endpoint-discovery → ADR-043 * ADR-031-endpoint-discovery-implementation → ADR-044 - Updated all cross-references to renumbered ADRs in: * docs/projectplan/ROADMAP.md * docs/reports/v1.0.0-rc.5-migration-race-condition-implementation.md * docs/reports/2025-11-24-endpoint-discovery-analysis.md * docs/decisions/ADR-043-CORRECTED-indieauth-endpoint-discovery.md * docs/decisions/ADR-044-endpoint-discovery-implementation.md - Updated README.md version from 1.0.0 to 1.1.0 - Tracked ADR-021-indieauth-provider-strategy.md in git DOCUMENTATION IMPROVEMENTS: - Created comprehensive INDEX.md files for all docs/ subdirectories: * docs/architecture/INDEX.md (28 documents indexed) * docs/decisions/INDEX.md (55 ADRs indexed with topical grouping) * docs/design/INDEX.md (phase plans and feature designs) * docs/standards/INDEX.md (9 standards with compliance checklist) * docs/reports/INDEX.md (57 implementation reports) * docs/deployment/INDEX.md (deployment guides) * docs/examples/INDEX.md (code samples and usage patterns) * docs/migration/INDEX.md (version migration guides) * docs/releases/INDEX.md (release documentation) * docs/reviews/INDEX.md (architectural reviews) * docs/security/INDEX.md (security documentation) - Updated CLAUDE.md with complete folder descriptions including: * docs/migration/ * docs/releases/ * docs/security/ VERIFICATION: - All ADR numbers now sequential and unique (50 total ADRs) - No duplicate ADR numbers remain - All cross-references updated and verified - Documentation structure consistent and well-organized These changes improve documentation discoverability, maintainability, and ensure proper version tracking. All index files follow consistent format with clear navigation guidance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
233 lines
6.7 KiB
Markdown
233 lines
6.7 KiB
Markdown
# Syndication Architecture
|
|
|
|
## Overview
|
|
StarPunk's syndication architecture provides multiple feed formats for content distribution, ensuring broad compatibility with feed readers and IndieWeb tools while maintaining simplicity.
|
|
|
|
## Current State (v1.1.0)
|
|
```
|
|
┌─────────────┐
|
|
│ Database │
|
|
│ (Notes) │
|
|
└──────┬──────┘
|
|
│
|
|
┌──────▼──────┐
|
|
│ feed.py │
|
|
│ (RSS 2.0) │
|
|
└──────┬──────┘
|
|
│
|
|
┌──────▼──────┐
|
|
│ /feed.xml │
|
|
│ endpoint │
|
|
└─────────────┘
|
|
```
|
|
|
|
## Target Architecture (v1.1.2+)
|
|
```
|
|
┌─────────────┐
|
|
│ Database │
|
|
│ (Notes) │
|
|
└──────┬──────┘
|
|
│
|
|
┌──────▼──────────────────┐
|
|
│ Feed Generation Layer │
|
|
├──────────┬───────────────┤
|
|
│ feed.py │ json_feed.py │
|
|
│ RSS/ATOM│ JSON │
|
|
└──────────┴───────────────┘
|
|
│
|
|
┌──────▼──────────────────┐
|
|
│ Feed Endpoints │
|
|
├─────────┬───────────────┤
|
|
│/feed.xml│ /feed.atom │
|
|
│ (RSS) │ (ATOM) │
|
|
├─────────┼───────────────┤
|
|
│ /feed.json │
|
|
│ (JSON Feed) │
|
|
└─────────────────────────┘
|
|
```
|
|
|
|
## Design Principles
|
|
|
|
### 1. Format Independence
|
|
Each syndication format operates independently:
|
|
- No shared state between formats
|
|
- Failures in one don't affect others
|
|
- Can be enabled/disabled individually
|
|
|
|
### 2. Shared Data Access
|
|
All formats read from the same data source:
|
|
- Single query pattern for notes
|
|
- Consistent ordering (newest first)
|
|
- Same publication status filtering
|
|
|
|
### 3. Library Leverage
|
|
Maximize use of existing libraries:
|
|
- `feedgen` for RSS and ATOM
|
|
- Native Python `json` for JSON Feed
|
|
- No custom XML generation
|
|
|
|
## Component Design
|
|
|
|
### Feed Generation Module (`feed.py`)
|
|
**Current Responsibility**: RSS 2.0 generation
|
|
**Future Enhancement**: Add ATOM generation function
|
|
|
|
```python
|
|
# Pseudocode structure
|
|
def generate_rss_feed(notes, config) -> str
|
|
def generate_atom_feed(notes, config) -> str # New
|
|
```
|
|
|
|
### JSON Feed Module (`json_feed.py`)
|
|
**New Component**: Dedicated JSON Feed generation
|
|
|
|
```python
|
|
# Pseudocode structure
|
|
def generate_json_feed(notes, config) -> str
|
|
def format_json_item(note) -> dict
|
|
```
|
|
|
|
### Route Handlers
|
|
Simple pass-through to generation functions:
|
|
```python
|
|
@app.route('/feed.xml') # Existing
|
|
@app.route('/feed.atom') # New
|
|
@app.route('/feed.json') # New
|
|
```
|
|
|
|
## Data Flow
|
|
|
|
1. **Request**: Client requests feed at endpoint
|
|
2. **Query**: Fetch published notes from database
|
|
3. **Transform**: Convert notes to format-specific structure
|
|
4. **Serialize**: Generate final output (XML/JSON)
|
|
5. **Response**: Return with appropriate Content-Type
|
|
|
|
## Microformats2 Architecture
|
|
|
|
### Template Layer Enhancement
|
|
Microformats2 operates at the HTML template layer:
|
|
|
|
```
|
|
┌──────────────┐
|
|
│ Data Model │
|
|
│ (Notes) │
|
|
└──────┬───────┘
|
|
│
|
|
┌──────▼───────┐
|
|
│ Templates │
|
|
│ + mf2 markup│
|
|
└──────┬───────┘
|
|
│
|
|
┌──────▼───────┐
|
|
│ HTML Output │
|
|
│ (Semantic) │
|
|
└──────────────┘
|
|
```
|
|
|
|
### Markup Strategy
|
|
- **Progressive Enhancement**: Add classes without changing structure
|
|
- **CSS Independence**: Use mf2-specific classes, not styling classes
|
|
- **Validation First**: Test with parsers during development
|
|
|
|
## Configuration Requirements
|
|
|
|
### New Configuration Variables
|
|
```ini
|
|
# Author information for h-card
|
|
AUTHOR_NAME = "Site Author"
|
|
AUTHOR_URL = "https://example.com"
|
|
AUTHOR_PHOTO = "/static/avatar.jpg" # Optional
|
|
|
|
# Feed settings
|
|
FEED_LIMIT = 50
|
|
FEED_FORMATS = "rss,atom,json" # Comma-separated
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
### Caching Strategy
|
|
- Feed generation is read-heavy, write-light
|
|
- Consider caching generated feeds (5-minute TTL)
|
|
- Invalidate cache on note creation/update
|
|
|
|
### Resource Usage
|
|
- RSS/ATOM: ~O(n) memory for n notes
|
|
- JSON Feed: Similar memory profile
|
|
- Microformats2: No additional server resources
|
|
|
|
## Security Considerations
|
|
|
|
### Content Sanitization
|
|
- HTML in feeds must be properly escaped
|
|
- CDATA wrapping for RSS/ATOM
|
|
- JSON string encoding for JSON Feed
|
|
- No script injection vectors
|
|
|
|
### Rate Limiting
|
|
- Apply same limits as HTML endpoints
|
|
- Consider aggressive caching for feeds
|
|
- Monitor for feed polling abuse
|
|
|
|
## Testing Architecture
|
|
|
|
### Unit Tests
|
|
```
|
|
tests/
|
|
├── test_feed.py # Enhanced for ATOM
|
|
├── test_json_feed.py # New test module
|
|
└── test_microformats.py # Template parsing tests
|
|
```
|
|
|
|
### Integration Tests
|
|
- Validate against external validators
|
|
- Test feed reader compatibility
|
|
- Verify IndieWeb tool parsing
|
|
|
|
## Backwards Compatibility
|
|
|
|
### URL Structure
|
|
- `/feed.xml` remains RSS 2.0 (no breaking change)
|
|
- New endpoints are additive only
|
|
- Auto-discovery links updated in templates
|
|
|
|
### Database
|
|
- No schema changes required
|
|
- All features use existing Note model
|
|
- No migration needed
|
|
|
|
## Future Extensibility
|
|
|
|
### Potential Enhancements
|
|
1. Content negotiation on `/feed`
|
|
2. WebSub (PubSubHubbub) support
|
|
3. Custom feed filtering (by tag, date)
|
|
4. Feed pagination for large sites
|
|
|
|
### Format Support Matrix
|
|
| Format | v1.1.0 | v1.1.2 | v1.2.0 |
|
|
|--------|--------|--------|--------|
|
|
| RSS 2.0 | ✅ | ✅ | ✅ |
|
|
| ATOM | ❌ | ✅ | ✅ |
|
|
| JSON Feed | ❌ | ✅ | ✅ |
|
|
| Microformats2 | Partial | Partial | ✅ |
|
|
|
|
## Decision Rationale
|
|
|
|
### Why Multiple Formats?
|
|
1. **No Universal Standard**: Different ecosystems prefer different formats
|
|
2. **Low Maintenance**: Feed formats are stable, rarely change
|
|
3. **User Choice**: Let users pick their preferred format
|
|
4. **IndieWeb Philosophy**: Embrace plurality and interoperability
|
|
|
|
### Why This Architecture?
|
|
1. **Simplicity**: Each component has single responsibility
|
|
2. **Testability**: Isolated components are easier to test
|
|
3. **Maintainability**: Changes to one format don't affect others
|
|
4. **Performance**: Can optimize each format independently
|
|
|
|
## References
|
|
- [RSS 2.0 Specification](https://www.rssboard.org/rss-specification)
|
|
- [ATOM RFC 4287](https://tools.ietf.org/html/rfc4287)
|
|
- [JSON Feed Specification](https://www.jsonfeed.org/)
|
|
- [Microformats2](https://microformats.org/wiki/microformats2) |