# 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)