1253 lines
40 KiB
Markdown
1253 lines
40 KiB
Markdown
# StarPunk V1 Implementation Plan
|
|
|
|
## Overview
|
|
|
|
This document provides a comprehensive, dependency-ordered implementation plan for StarPunk V1, taking the project from its current state (basic infrastructure complete) to a fully functional IndieWeb CMS.
|
|
|
|
**Current State**: Core infrastructure complete (database schema, config, basic Flask app)
|
|
**Target State**: Working V1 with all features implemented, tested, and documented
|
|
**Estimated Total Effort**: ~40-60 hours of focused development
|
|
|
|
## Implementation Strategy
|
|
|
|
1. **Bottom-up approach**: Build foundation modules before features that depend on them
|
|
2. **Feature completeness**: Implement each feature fully (code + tests + docs) before moving to the next
|
|
3. **Continuous validation**: Test integration points as we build
|
|
4. **Documentation alongside code**: Update docs as implementation progresses
|
|
|
|
---
|
|
|
|
## Phase 1: Core Utilities and Models (Foundation)
|
|
|
|
These utilities are used by all other features. Must be implemented first.
|
|
|
|
### 1.1 Utility Functions (`starpunk/utils.py`)
|
|
|
|
**Priority**: CRITICAL - Required by all other features
|
|
**Estimated Effort**: 2-3 hours
|
|
**Dependencies**: None
|
|
|
|
- [ ] Implement slug generation function
|
|
- Extract first 5 words from content
|
|
- Normalize to lowercase with hyphens
|
|
- Remove special characters, preserve alphanumeric + hyphens
|
|
- Fallback to timestamp-based slug if content too short
|
|
- Check uniqueness against database
|
|
- Add random suffix if slug exists
|
|
- **References**: ADR-004 (File-Based Storage), project-structure.md
|
|
- **Acceptance Criteria**: Generates valid, unique, URL-safe slugs
|
|
|
|
- [ ] Implement content hash calculation
|
|
- Use SHA-256 algorithm
|
|
- Return hex digest string
|
|
- Handle UTF-8 encoding properly
|
|
- **Acceptance Criteria**: Consistent hashes for same content
|
|
|
|
- [ ] Implement file path helpers
|
|
- Generate year/month directory structure from timestamp
|
|
- Build file paths: `data/notes/YYYY/MM/slug.md`
|
|
- Validate paths (prevent directory traversal)
|
|
- Ensure paths stay within DATA_PATH
|
|
- **References**: ADR-004, architecture/security.md
|
|
- **Acceptance Criteria**: Safe path generation and validation
|
|
|
|
- [ ] Implement atomic file operations
|
|
- Write to temp file first (`.tmp` suffix)
|
|
- Atomic rename to final destination
|
|
- Handle errors with rollback
|
|
- Create parent directories if needed
|
|
- **References**: ADR-004
|
|
- **Acceptance Criteria**: Files written safely without corruption risk
|
|
|
|
- [ ] Implement date/time utilities
|
|
- RFC-822 date formatting (for RSS)
|
|
- ISO 8601 formatting (for timestamps)
|
|
- Timezone handling (UTC)
|
|
- **Acceptance Criteria**: Correct date formatting for all use cases
|
|
|
|
- [ ] Write comprehensive tests (`tests/test_utils.py`)
|
|
- Test slug generation with various inputs
|
|
- Test uniqueness enforcement
|
|
- Test content hash consistency
|
|
- Test path validation (including security tests)
|
|
- Test atomic file operations
|
|
- Test date formatting
|
|
|
|
**Completion Criteria**: All utility functions implemented and tested with >90% coverage
|
|
|
|
---
|
|
|
|
### 1.2 Data Models (`starpunk/models.py`)
|
|
|
|
**Priority**: CRITICAL - Used by all feature modules
|
|
**Estimated Effort**: 3-4 hours
|
|
**Dependencies**: `utils.py`
|
|
|
|
- [ ] Implement `Note` model class
|
|
- Properties: id, slug, file_path, published, created_at, updated_at, content_hash
|
|
- Method: `from_row()` - Create Note from database row
|
|
- Method: `to_dict()` - Serialize to dictionary
|
|
- Property: `content` - Lazy load from file
|
|
- Property: `html` - Render markdown to HTML (cached)
|
|
- Method: `permalink()` - Generate public URL
|
|
- **References**: ADR-004, architecture/overview.md
|
|
- **Acceptance Criteria**: Clean interface for note data access
|
|
|
|
- [ ] Implement `Session` model class
|
|
- Properties: id, session_token, me, created_at, expires_at, last_used_at
|
|
- Method: `from_row()` - Create Session from database row
|
|
- Property: `is_expired` - Check if session expired
|
|
- Method: `is_valid()` - Comprehensive validation
|
|
- **References**: ADR-005
|
|
- **Acceptance Criteria**: Session validation works correctly
|
|
|
|
- [ ] Implement `Token` model class (Micropub)
|
|
- Properties: token, me, client_id, scope, created_at, expires_at
|
|
- Method: `from_row()` - Create Token from database row
|
|
- Property: `is_expired` - Check if token expired
|
|
- Method: `has_scope()` - Check if token has required scope
|
|
- **References**: Micropub spec
|
|
- **Acceptance Criteria**: Token scope checking works
|
|
|
|
- [ ] Implement `AuthState` model class
|
|
- Properties: state, created_at, expires_at
|
|
- Method: `from_row()` - Create AuthState from database row
|
|
- Property: `is_expired` - Check if state expired
|
|
- **References**: ADR-005
|
|
- **Acceptance Criteria**: State token validation works
|
|
|
|
- [ ] Write model tests (`tests/test_models.py`)
|
|
- Test all model creation methods
|
|
- Test property access
|
|
- Test expiration logic
|
|
- Test serialization/deserialization
|
|
- Test edge cases (None values, invalid data)
|
|
|
|
**Completion Criteria**: All models implemented with clean interfaces and full test coverage
|
|
|
|
---
|
|
|
|
## Phase 2: Notes Management (Core Feature)
|
|
|
|
This is the heart of the application. File operations + database sync.
|
|
|
|
### 2.1 Notes Module (`starpunk/notes.py`)
|
|
|
|
**Priority**: CRITICAL - Core functionality
|
|
**Estimated Effort**: 6-8 hours
|
|
**Dependencies**: `utils.py`, `models.py`, `database.py`
|
|
|
|
- [ ] Implement `create_note()` function
|
|
- Accept: content (markdown), published (boolean), created_at (optional)
|
|
- Generate unique slug using utils
|
|
- Determine file path (year/month from timestamp)
|
|
- Create directory structure if needed
|
|
- Write markdown file atomically
|
|
- Calculate content hash
|
|
- Begin database transaction
|
|
- Insert note record with metadata
|
|
- If DB insert fails: delete file, raise error
|
|
- If successful: commit transaction, return Note object
|
|
- **References**: ADR-004, architecture/data-flow.md
|
|
- **Acceptance Criteria**: Note created with file + database entry in sync
|
|
|
|
- [ ] Implement `get_note()` function
|
|
- Accept: slug (string) or id (int)
|
|
- Query database for note metadata
|
|
- If not found: return None
|
|
- Read file content from disk
|
|
- Verify content hash (optional, log if mismatch)
|
|
- Return Note object with content loaded
|
|
- **References**: ADR-004
|
|
- **Acceptance Criteria**: Note retrieved with content from file
|
|
|
|
- [ ] Implement `list_notes()` function
|
|
- Accept: published_only (boolean), limit (int), offset (int)
|
|
- Query database with filters and sorting (created_at DESC)
|
|
- Return list of Note objects (metadata only, no content)
|
|
- Support pagination
|
|
- **References**: ADR-004
|
|
- **Acceptance Criteria**: Efficient listing with proper filtering
|
|
|
|
- [ ] Implement `update_note()` function
|
|
- Accept: slug or id, new content, published status
|
|
- Query database for existing note
|
|
- Create backup of original file (optional)
|
|
- Write new content to file atomically
|
|
- Calculate new content hash
|
|
- Update database record (updated_at, content_hash, published)
|
|
- If DB update fails: restore backup, raise error
|
|
- Return updated Note object
|
|
- **References**: ADR-004
|
|
- **Acceptance Criteria**: Note updated safely with sync maintained
|
|
|
|
- [ ] Implement `delete_note()` function
|
|
- Accept: slug or id, hard_delete (boolean, default False)
|
|
- Query database for note
|
|
- If soft delete: update deleted_at timestamp, optionally move file to .trash/
|
|
- If hard delete: delete database record, delete file
|
|
- **References**: ADR-004
|
|
- **Acceptance Criteria**: Note deleted (soft or hard) correctly
|
|
|
|
- [ ] Implement `search_notes()` function (optional for V1)
|
|
- Accept: query string
|
|
- Search file content using grep or Python search
|
|
- Return matching Note objects
|
|
- **Priority**: LOW - Can defer to V2
|
|
- **Acceptance Criteria**: Basic text search works
|
|
|
|
- [ ] Handle edge cases
|
|
- Orphaned files (file exists, no DB record)
|
|
- Orphaned records (DB record exists, no file)
|
|
- File read/write errors
|
|
- Permission errors
|
|
- Disk full errors
|
|
- **References**: architecture/security.md
|
|
|
|
- [ ] Write comprehensive tests (`tests/test_notes.py`)
|
|
- Test create with various content
|
|
- Test slug uniqueness enforcement
|
|
- Test file/database sync
|
|
- Test get by slug and id
|
|
- Test list with filters and pagination
|
|
- Test update operations
|
|
- Test delete (soft and hard)
|
|
- Test error handling (DB failure, file failure)
|
|
- Test edge cases (empty content, very long content, special characters)
|
|
- Integration test: create → read → update → delete cycle
|
|
|
|
**Completion Criteria**: Full CRUD operations working with file+database sync, comprehensive tests passing
|
|
|
|
---
|
|
|
|
## Phase 3: Authentication (IndieLogin)
|
|
|
|
Implements the IndieLogin OAuth flow for admin access.
|
|
|
|
### 3.1 Authentication Module (`starpunk/auth.py`)
|
|
|
|
**Priority**: HIGH - Required for admin interface
|
|
**Estimated Effort**: 5-6 hours
|
|
**Dependencies**: `models.py`, `database.py`, `httpx` library
|
|
|
|
- [ ] Implement state token management
|
|
- `generate_state()` - Create random CSRF token (32 bytes)
|
|
- `store_state()` - Save to database with 5-minute expiry
|
|
- `verify_state()` - Check validity and delete (single-use)
|
|
- `cleanup_expired_states()` - Remove old tokens
|
|
- **References**: ADR-005
|
|
- **Acceptance Criteria**: State tokens prevent CSRF attacks
|
|
|
|
- [ ] Implement session token management
|
|
- `generate_session_token()` - Create random token (32 bytes)
|
|
- `create_session()` - Store session with user 'me' URL
|
|
- `get_session()` - Retrieve session by token
|
|
- `validate_session()` - Check if valid and not expired
|
|
- `update_session_activity()` - Update last_used_at
|
|
- `delete_session()` - Logout
|
|
- `cleanup_expired_sessions()` - Remove old sessions
|
|
- **References**: ADR-005, architecture/security.md
|
|
- **Acceptance Criteria**: Sessions work for 30 days, extend on use
|
|
|
|
- [ ] Implement IndieLogin OAuth flow
|
|
- `initiate_login()` - Build authorization URL, store state, redirect
|
|
- Validate 'me' URL format
|
|
- Generate state token
|
|
- Build indielogin.com authorization URL with params
|
|
- Return redirect response
|
|
- `handle_callback()` - Exchange code for identity
|
|
- Verify state token (CSRF check)
|
|
- POST to indielogin.com/auth with code
|
|
- Verify HTTP response (200 OK)
|
|
- Extract 'me' from JSON response
|
|
- Verify 'me' matches ADMIN_ME config
|
|
- Create session if authorized
|
|
- Set secure HttpOnly cookie
|
|
- Redirect to admin dashboard
|
|
- **References**: ADR-005, IndieLogin API docs
|
|
- **Acceptance Criteria**: Full OAuth flow works with indielogin.com
|
|
|
|
- [ ] Implement authentication decorator
|
|
- `require_auth()` - Decorator for protected routes
|
|
- Check session cookie
|
|
- Validate session
|
|
- Store user info in Flask `g` context
|
|
- Redirect to login if not authenticated
|
|
- **Acceptance Criteria**: Protects admin routes correctly
|
|
|
|
- [ ] Implement logout
|
|
- `logout()` - Delete session from database
|
|
- Clear session cookie
|
|
- Redirect to homepage
|
|
- **Acceptance Criteria**: Logout works completely
|
|
|
|
- [ ] Error handling
|
|
- Invalid state token
|
|
- IndieLogin API errors
|
|
- Network timeouts
|
|
- Unauthorized users (wrong 'me' URL)
|
|
- Expired sessions
|
|
- **References**: architecture/security.md
|
|
|
|
- [ ] Write comprehensive tests (`tests/test_auth.py`)
|
|
- Test state token generation and validation
|
|
- Test session creation and validation
|
|
- Test session expiry
|
|
- Mock IndieLogin API responses
|
|
- Test full OAuth flow (integration test with mocked API)
|
|
- Test CSRF protection (invalid state)
|
|
- Test unauthorized user rejection (wrong 'me')
|
|
- Test session cookie security (HttpOnly, Secure flags)
|
|
- Test logout functionality
|
|
- Test decorator on protected routes
|
|
|
|
**Completion Criteria**: Authentication works end-to-end, all security measures tested
|
|
|
|
---
|
|
|
|
## Phase 4: Web Routes and Templates
|
|
|
|
User-facing interface (public site + admin interface).
|
|
|
|
### 4.1 Public Routes Blueprint (`starpunk/routes/public.py`)
|
|
|
|
**Priority**: HIGH - Public interface
|
|
**Estimated Effort**: 3-4 hours
|
|
**Dependencies**: `notes.py`, `models.py`
|
|
|
|
Note: Create `starpunk/routes/` directory first
|
|
|
|
- [ ] Create routes module structure
|
|
- Create `starpunk/routes/__init__.py`
|
|
- Create `starpunk/routes/public.py`
|
|
- Create `starpunk/routes/admin.py`
|
|
- Create `starpunk/routes/api.py`
|
|
|
|
- [ ] Implement homepage route (`/`)
|
|
- GET handler
|
|
- List published notes (limit 20, newest first)
|
|
- Render `templates/index.html`
|
|
- Pass notes to template
|
|
- **Acceptance Criteria**: Homepage displays recent published notes
|
|
|
|
- [ ] Implement note permalink route (`/note/<slug>`)
|
|
- GET handler
|
|
- Retrieve note by slug
|
|
- Check if published (404 if not published)
|
|
- Render `templates/note.html`
|
|
- Pass note with rendered HTML content
|
|
- **Acceptance Criteria**: Individual notes display correctly
|
|
|
|
- [ ] Register blueprint in `starpunk/__init__.py`
|
|
- Import public blueprint
|
|
- Register with app
|
|
- **Acceptance Criteria**: Routes are accessible
|
|
|
|
- [ ] Write route tests
|
|
- Test homepage returns 200
|
|
- Test homepage lists published notes only
|
|
- Test note permalink returns 200 for published note
|
|
- Test note permalink returns 404 for unpublished note
|
|
- Test note permalink returns 404 for non-existent note
|
|
|
|
**Completion Criteria**: Public routes work, return correct content
|
|
|
|
---
|
|
|
|
### 4.2 Admin Routes Blueprint (`starpunk/routes/admin.py`)
|
|
|
|
**Priority**: HIGH - Admin interface
|
|
**Estimated Effort**: 4-5 hours
|
|
**Dependencies**: `auth.py`, `notes.py`
|
|
|
|
- [ ] Implement login routes
|
|
- GET `/admin/login` - Display login form
|
|
- POST `/admin/login` - Initiate IndieLogin flow
|
|
- GET `/auth/callback` - Handle IndieLogin callback
|
|
- POST `/admin/logout` - Logout and clear session
|
|
- **References**: ADR-005
|
|
- **Acceptance Criteria**: Authentication flow works
|
|
|
|
- [ ] Implement admin dashboard (`/admin`)
|
|
- GET handler (protected with `@require_auth`)
|
|
- List all notes (published and drafts)
|
|
- Show note count, recent activity
|
|
- Render `templates/admin/dashboard.html`
|
|
- **Acceptance Criteria**: Dashboard shows all notes
|
|
|
|
- [ ] Implement create note routes (`/admin/new`)
|
|
- GET handler - Display note creation form
|
|
- POST handler - Create note from form data
|
|
- Extract content and published status
|
|
- Call `create_note()`
|
|
- Redirect to dashboard on success
|
|
- Show errors on failure
|
|
- **Acceptance Criteria**: Can create notes via web form
|
|
|
|
- [ ] Implement edit note routes (`/admin/edit/<slug>`)
|
|
- GET handler - Display edit form with existing content
|
|
- POST handler - Update note
|
|
- Call `update_note()`
|
|
- Redirect to dashboard on success
|
|
- Show errors on failure
|
|
- **Acceptance Criteria**: Can edit notes via web form
|
|
|
|
- [ ] Implement delete note route (`/admin/delete/<slug>`)
|
|
- POST handler - Delete note
|
|
- Confirm deletion (soft delete by default)
|
|
- Call `delete_note()`
|
|
- Redirect to dashboard
|
|
- **Acceptance Criteria**: Can delete notes
|
|
|
|
- [ ] Register blueprint in `starpunk/__init__.py`
|
|
- Import admin blueprint
|
|
- Register with app
|
|
- **Acceptance Criteria**: Admin routes accessible
|
|
|
|
- [ ] Write route tests
|
|
- Test login flow (with mocked IndieLogin)
|
|
- Test authentication required for admin routes
|
|
- Test dashboard displays notes
|
|
- Test create note form submission
|
|
- Test edit note form submission
|
|
- Test delete note
|
|
- Test logout
|
|
|
|
**Completion Criteria**: Admin interface fully functional, authentication working
|
|
|
|
---
|
|
|
|
### 4.3 HTML Templates
|
|
|
|
**Priority**: HIGH - Required for web interface
|
|
**Estimated Effort**: 6-8 hours
|
|
**Dependencies**: None (can be done in parallel with routes)
|
|
|
|
#### Base Templates
|
|
|
|
- [ ] Implement `templates/base.html`
|
|
- HTML5 semantic structure
|
|
- Meta tags (charset, viewport)
|
|
- Link to stylesheet (`/static/css/style.css`)
|
|
- Navigation (home, admin)
|
|
- Content block (`{% block content %}`)
|
|
- Footer with attribution
|
|
- **Microformats**: h-card for site author
|
|
- **References**: ADR-003, architecture/overview.md
|
|
- **Acceptance Criteria**: Clean, semantic HTML base template
|
|
|
|
- [ ] Implement `templates/admin/base.html`
|
|
- Extends base or separate admin layout
|
|
- Admin navigation (dashboard, new note, logout)
|
|
- Admin-specific styling
|
|
- Flash message display
|
|
- **Acceptance Criteria**: Consistent admin layout
|
|
|
|
#### Public Templates
|
|
|
|
- [ ] Implement `templates/index.html`
|
|
- Extends `base.html`
|
|
- Display list of notes
|
|
- Each note: title (first line), excerpt, timestamp, permalink
|
|
- Pagination controls (if >20 notes)
|
|
- **Microformats**: h-feed with h-entry for each note
|
|
- **References**: Microformats2 spec
|
|
- **Acceptance Criteria**: Homepage displays notes with proper markup
|
|
|
|
- [ ] Implement `templates/note.html`
|
|
- Extends `base.html`
|
|
- Display full note content (rendered HTML)
|
|
- Timestamp, permalink
|
|
- **Microformats**: h-entry with e-content, dt-published
|
|
- **References**: Microformats2 h-entry spec
|
|
- **Acceptance Criteria**: Note displays with proper semantic markup
|
|
|
|
#### Admin Templates
|
|
|
|
- [ ] Implement `templates/admin/login.html`
|
|
- Simple form asking for website URL
|
|
- Input for 'me' URL
|
|
- Submit button
|
|
- Explanation of IndieLogin
|
|
- **Acceptance Criteria**: Clean login form
|
|
|
|
- [ ] Implement `templates/admin/dashboard.html`
|
|
- Extends `admin/base.html`
|
|
- Table of all notes (published + drafts)
|
|
- Columns: title, status, created, updated, actions (edit, delete)
|
|
- "New Note" button
|
|
- Summary stats (total notes, published count)
|
|
- **Acceptance Criteria**: Dashboard shows all notes with actions
|
|
|
|
- [ ] Implement `templates/admin/new.html`
|
|
- Extends `admin/base.html`
|
|
- Form with markdown textarea
|
|
- Published checkbox
|
|
- Submit button
|
|
- Optional: markdown preview (if JS enabled)
|
|
- **Acceptance Criteria**: Form for creating notes
|
|
|
|
- [ ] Implement `templates/admin/edit.html`
|
|
- Extends `admin/base.html`
|
|
- Form pre-filled with existing content
|
|
- Markdown textarea
|
|
- Published checkbox
|
|
- Save and Cancel buttons
|
|
- Optional: markdown preview
|
|
- **Acceptance Criteria**: Form for editing notes
|
|
|
|
**Completion Criteria**: All templates implemented with proper HTML5 and Microformats2 markup
|
|
|
|
---
|
|
|
|
### 4.4 CSS Styling (`static/css/style.css`)
|
|
|
|
**Priority**: MEDIUM - Functional without, better with
|
|
**Estimated Effort**: 4-5 hours
|
|
**Dependencies**: None
|
|
|
|
- [ ] Implement CSS custom properties (variables)
|
|
- Colors (background, text, accent, borders)
|
|
- Typography (font families, sizes, line heights)
|
|
- Spacing scale
|
|
- **References**: ADR-003
|
|
- **Acceptance Criteria**: Consistent design tokens
|
|
|
|
- [ ] Implement base styles
|
|
- CSS reset/normalize
|
|
- Typography (readable font sizes, line heights)
|
|
- Links and buttons
|
|
- Forms and inputs
|
|
- **Acceptance Criteria**: Clean, readable defaults
|
|
|
|
- [ ] Implement layout
|
|
- Centered content container (max-width: 800px)
|
|
- Header and footer
|
|
- Navigation
|
|
- Grid for note lists
|
|
- **Acceptance Criteria**: Responsive layout works
|
|
|
|
- [ ] Implement component styles
|
|
- Note cards
|
|
- Note content (markdown rendering)
|
|
- Forms (admin interface)
|
|
- Tables (dashboard)
|
|
- Buttons and inputs
|
|
- **Acceptance Criteria**: Components look consistent
|
|
|
|
- [ ] Implement responsive design
|
|
- Mobile-first approach
|
|
- Breakpoints for tablet and desktop
|
|
- Touch-friendly targets
|
|
- Readable on all screen sizes
|
|
- **References**: ADR-003 (Progressive Enhancement)
|
|
- **Acceptance Criteria**: Works on mobile, tablet, desktop
|
|
|
|
- [ ] Keep total CSS under 300 lines
|
|
- Minimal styling philosophy
|
|
- No fancy animations or effects
|
|
- Focus on readability and usability
|
|
- **References**: ADR-003
|
|
- **Acceptance Criteria**: CSS is simple and maintainable
|
|
|
|
**Completion Criteria**: Site is usable and looks clean on all devices
|
|
|
|
---
|
|
|
|
### 4.5 Optional JavaScript Enhancement (`static/js/preview.js`)
|
|
|
|
**Priority**: LOW - Optional enhancement only
|
|
**Estimated Effort**: 2-3 hours
|
|
**Dependencies**: None
|
|
|
|
This is OPTIONAL for V1. Can be deferred.
|
|
|
|
- [ ] Implement markdown preview (optional)
|
|
- Load marked.js from CDN
|
|
- Listen to textarea input
|
|
- Render markdown in real-time
|
|
- Display preview beside textarea
|
|
- Degrades gracefully if JS disabled
|
|
- **References**: ADR-003 (Progressive Enhancement)
|
|
- **Acceptance Criteria**: Preview works, form works without it
|
|
|
|
**Completion Criteria**: Preview enhances editing experience but isn't required
|
|
|
|
---
|
|
|
|
## Phase 5: RSS Feed Generation
|
|
|
|
Syndication for published notes.
|
|
|
|
### 5.1 Feed Module (`starpunk/feed.py`)
|
|
|
|
**Priority**: HIGH - Core feature
|
|
**Estimated Effort**: 3-4 hours
|
|
**Dependencies**: `notes.py`, `feedgen` library
|
|
|
|
- [ ] Implement `generate_rss_feed()` function
|
|
- Create FeedGenerator instance
|
|
- Set feed metadata (title, link, description, language)
|
|
- Set feed author from config
|
|
- Query published notes (limit 50, newest first)
|
|
- For each note:
|
|
- Add feed entry
|
|
- Set entry title (first line or slug)
|
|
- Set entry link (permalink)
|
|
- Set entry description/content (rendered HTML, CDATA-wrapped)
|
|
- Set entry published date (RFC-822 format)
|
|
- Set entry GUID (permalink)
|
|
- Generate RSS 2.0 XML string
|
|
- Return XML
|
|
- **References**: ADR-002 (feedgen), RSS 2.0 spec, architecture/overview.md
|
|
- **Acceptance Criteria**: Valid RSS 2.0 feed generated
|
|
|
|
- [ ] Implement feed caching (optional)
|
|
- Cache generated feed for 5 minutes
|
|
- Invalidate on note create/update/delete
|
|
- **Priority**: MEDIUM - Can defer to V2
|
|
- **Acceptance Criteria**: Feed generation is performant
|
|
|
|
- [ ] Write tests (`tests/test_feed.py`)
|
|
- Test feed generation with notes
|
|
- Test feed metadata is correct
|
|
- Test entry format
|
|
- Test date formatting (RFC-822)
|
|
- Test HTML content in CDATA
|
|
- Validate XML structure
|
|
- Test empty feed (no published notes)
|
|
- Test W3C Feed Validator compliance (manual test)
|
|
|
|
**Completion Criteria**: RSS feed generates valid XML, passes W3C validator
|
|
|
|
---
|
|
|
|
### 5.2 Feed Route (`/feed.xml`)
|
|
|
|
**Priority**: HIGH - Part of RSS feature
|
|
**Estimated Effort**: 1 hour
|
|
**Dependencies**: `feed.py`
|
|
|
|
- [ ] Add feed route to public blueprint
|
|
- GET `/feed.xml`
|
|
- Call `generate_rss_feed()`
|
|
- Return XML with correct Content-Type (`application/rss+xml`)
|
|
- Set Cache-Control header (5 minutes)
|
|
- **Acceptance Criteria**: Feed accessible at /feed.xml
|
|
|
|
- [ ] Add feed auto-discovery to templates
|
|
- Add `<link rel="alternate" type="application/rss+xml">` to base.html
|
|
- **Acceptance Criteria**: RSS readers auto-discover feed
|
|
|
|
- [ ] Write route tests
|
|
- Test feed returns 200
|
|
- Test Content-Type is correct
|
|
- Test feed contains published notes
|
|
- Test feed is valid XML
|
|
|
|
**Completion Criteria**: Feed is accessible and discoverable
|
|
|
|
---
|
|
|
|
## Phase 6: Micropub API
|
|
|
|
Micropub endpoint for publishing from external clients.
|
|
|
|
### 6.1 Token Management (for Micropub)
|
|
|
|
**Priority**: HIGH - Required for Micropub
|
|
**Estimated Effort**: 2-3 hours
|
|
**Dependencies**: `models.py`, `database.py`
|
|
|
|
Note: Micropub clients will obtain tokens via external IndieAuth flow. StarPunk just validates tokens.
|
|
|
|
- [ ] Implement token validation in `starpunk/auth.py`
|
|
- `validate_micropub_token()` - Check if token exists and valid
|
|
- Query tokens table
|
|
- Check expiration
|
|
- Return Token object with 'me' and scope
|
|
- **References**: IndieAuth spec, Micropub spec
|
|
- **Acceptance Criteria**: Token validation works
|
|
|
|
- [ ] Implement token creation (for testing)
|
|
- `create_token()` - Manually create token (for development/testing)
|
|
- Store token with 'me', client_id, scope
|
|
- **Priority**: For testing only, real tokens come from IndieAuth server
|
|
- **Acceptance Criteria**: Can create test tokens
|
|
|
|
- [ ] Implement Micropub authentication decorator
|
|
- `require_micropub_auth()` - Decorator for Micropub endpoint
|
|
- Extract Bearer token from Authorization header
|
|
- Validate token
|
|
- Check scope (must have 'create' or 'post')
|
|
- Store token info in Flask `g`
|
|
- Return 401 if invalid
|
|
- **Acceptance Criteria**: Protects Micropub endpoint
|
|
|
|
**Completion Criteria**: Token validation works for Micropub
|
|
|
|
---
|
|
|
|
### 6.2 Micropub Endpoint (`starpunk/micropub.py`)
|
|
|
|
**Priority**: HIGH - Core IndieWeb feature
|
|
**Estimated Effort**: 6-8 hours
|
|
**Dependencies**: `auth.py`, `notes.py`, Micropub spec knowledge
|
|
|
|
- [ ] Implement Micropub POST handler (create)
|
|
- Handle `application/json` content type
|
|
- Handle `application/x-www-form-urlencoded` content type
|
|
- Parse Micropub payload
|
|
- Validate h-entry structure
|
|
- Extract content from properties.content[0]
|
|
- Extract name from properties.name[0] (if present)
|
|
- Call `create_note()` with content
|
|
- Return 201 Created with Location header (note URL)
|
|
- Handle errors (400, 500)
|
|
- **References**: Micropub spec, ADR-005
|
|
- **Acceptance Criteria**: Can create notes via Micropub
|
|
|
|
- [ ] Implement Micropub GET handler (query)
|
|
- Handle `q=config` query - Return supported config
|
|
- Handle `q=source` query - Return note source by URL
|
|
- Handle `q=syndicate-to` query - Return empty (no syndication targets in V1)
|
|
- Return JSON responses
|
|
- **References**: Micropub spec
|
|
- **Acceptance Criteria**: Query endpoints return correct data
|
|
|
|
- [ ] Implement Micropub media endpoint (optional for V1)
|
|
- Handle file uploads
|
|
- Store in `data/media/`
|
|
- Return media URL
|
|
- **Priority**: LOW - Defer to V2
|
|
- **Acceptance Criteria**: Media uploads work (if implemented)
|
|
|
|
- [ ] Implement error responses
|
|
- 400 Bad Request - Invalid payload
|
|
- 401 Unauthorized - Missing/invalid token
|
|
- 403 Forbidden - Insufficient scope
|
|
- 500 Server Error - Internal errors
|
|
- Return JSON error responses with Micropub error codes
|
|
- **References**: Micropub spec error handling
|
|
- **Acceptance Criteria**: Errors return proper Micropub responses
|
|
|
|
- [ ] Write comprehensive tests (`tests/test_micropub.py`)
|
|
- Test POST with JSON payload
|
|
- Test POST with form-encoded payload
|
|
- Test authentication (valid token, invalid token, missing token)
|
|
- Test scope checking
|
|
- Test content extraction from h-entry
|
|
- Test error responses
|
|
- Test query endpoints (config, source)
|
|
- Integration test: Full Micropub create flow
|
|
|
|
**Completion Criteria**: Micropub endpoint fully implements spec, passes micropub.rocks tests
|
|
|
|
---
|
|
|
|
### 6.3 Micropub Route
|
|
|
|
**Priority**: HIGH - Part of Micropub feature
|
|
**Estimated Effort**: 1 hour
|
|
**Dependencies**: `micropub.py`
|
|
|
|
- [ ] Add Micropub route to API blueprint
|
|
- POST `/api/micropub` - Create entry
|
|
- GET `/api/micropub` - Query endpoint
|
|
- Apply `@require_micropub_auth` decorator
|
|
- **Acceptance Criteria**: Micropub endpoint accessible
|
|
|
|
- [ ] Add Micropub endpoint discovery
|
|
- Add `<link rel="micropub">` to base template
|
|
- Point to `/api/micropub`
|
|
- **References**: Micropub spec
|
|
- **Acceptance Criteria**: Clients can discover endpoint
|
|
|
|
- [ ] Write route tests
|
|
- Test endpoint returns 401 without auth
|
|
- Test endpoint accepts authenticated requests
|
|
- Test both POST and GET methods
|
|
|
|
**Completion Criteria**: Micropub endpoint discoverable and functional
|
|
|
|
---
|
|
|
|
## Phase 7: API Routes (CRUD API)
|
|
|
|
Optional REST API for notes (in addition to Micropub).
|
|
|
|
### 7.1 Notes API Blueprint (`starpunk/routes/api.py`)
|
|
|
|
**Priority**: MEDIUM - Nice to have, not critical
|
|
**Estimated Effort**: 3-4 hours
|
|
**Dependencies**: `auth.py`, `notes.py`
|
|
|
|
This is OPTIONAL for V1. The admin interface uses forms, Micropub handles external publishing. This JSON API is a bonus.
|
|
|
|
- [ ] Implement notes CRUD API
|
|
- GET `/api/notes` - List published notes (JSON)
|
|
- POST `/api/notes` - Create note (requires auth)
|
|
- GET `/api/notes/<slug>` - Get single note (JSON)
|
|
- PUT `/api/notes/<slug>` - Update note (requires auth)
|
|
- DELETE `/api/notes/<slug>` - Delete note (requires auth)
|
|
- Use session auth for write operations
|
|
- Return JSON responses
|
|
- **Acceptance Criteria**: JSON API works for notes
|
|
|
|
- [ ] Register API blueprint
|
|
- Import in `starpunk/__init__.py`
|
|
- Register with app
|
|
- **Acceptance Criteria**: API routes accessible
|
|
|
|
- [ ] Write API tests
|
|
- Test list notes
|
|
- Test get single note
|
|
- Test create requires auth
|
|
- Test update requires auth
|
|
- Test delete requires auth
|
|
- Test JSON serialization
|
|
|
|
**Completion Criteria**: REST API provides JSON access to notes (if implemented)
|
|
|
|
---
|
|
|
|
## Phase 8: Testing and Quality Assurance
|
|
|
|
Comprehensive testing to ensure reliability.
|
|
|
|
### 8.1 Integration Tests
|
|
|
|
**Priority**: HIGH - Ensure components work together
|
|
**Estimated Effort**: 4-5 hours
|
|
**Dependencies**: All features implemented
|
|
|
|
- [ ] Write end-to-end tests (`tests/test_integration.py`)
|
|
- Test complete user journey: login → create note → view note → edit → delete
|
|
- Test complete Micropub flow: authenticate → publish → view on site
|
|
- Test RSS feed updates when notes created
|
|
- Test file/database sync integrity
|
|
- Test error recovery (DB failure, file failure)
|
|
- **Acceptance Criteria**: All major user flows tested
|
|
|
|
- [ ] Test data consistency
|
|
- Create note, verify file exists
|
|
- Create note, verify DB record exists
|
|
- Update note, verify file content changes
|
|
- Update note, verify DB timestamp changes
|
|
- Delete note, verify file and DB record handled correctly
|
|
- **Acceptance Criteria**: File and database stay in sync
|
|
|
|
- [ ] Test edge cases
|
|
- Very long content (>10k characters)
|
|
- Special characters in content (unicode, emoji)
|
|
- Concurrent requests (if applicable)
|
|
- Low disk space scenarios
|
|
- **Acceptance Criteria**: Edge cases handled gracefully
|
|
|
|
**Completion Criteria**: Integration tests pass, coverage >80%
|
|
|
|
---
|
|
|
|
### 8.2 Standards Validation
|
|
|
|
**Priority**: HIGH - Ensure compliance
|
|
**Estimated Effort**: 2-3 hours
|
|
**Dependencies**: All features implemented
|
|
|
|
- [ ] Validate HTML output
|
|
- Run W3C HTML Validator on templates
|
|
- Fix any validation errors
|
|
- **Tool**: https://validator.w3.org/
|
|
- **Acceptance Criteria**: Valid HTML5
|
|
|
|
- [ ] Validate RSS feed
|
|
- Run W3C Feed Validator on /feed.xml
|
|
- Fix any validation errors
|
|
- **Tool**: https://validator.w3.org/feed/
|
|
- **Acceptance Criteria**: Valid RSS 2.0
|
|
|
|
- [ ] Validate Microformats
|
|
- Use IndieWebify.me to check h-entry markup
|
|
- Verify h-card, h-feed, h-entry parsing
|
|
- **Tool**: https://indiewebify.me/
|
|
- **Acceptance Criteria**: Microformats2 properly parsed
|
|
|
|
- [ ] Validate Micropub
|
|
- Use micropub.rocks to test endpoint
|
|
- Pass all required tests
|
|
- **Tool**: https://micropub.rocks/
|
|
- **Acceptance Criteria**: Micropub spec compliant
|
|
|
|
**Completion Criteria**: All standards validators pass
|
|
|
|
---
|
|
|
|
### 8.3 Security Testing
|
|
|
|
**Priority**: HIGH - Critical for production
|
|
**Estimated Effort**: 3-4 hours
|
|
**Dependencies**: All features implemented
|
|
|
|
- [ ] Test authentication security
|
|
- CSRF protection (state tokens)
|
|
- Session hijacking prevention
|
|
- Cookie security (HttpOnly, Secure, SameSite)
|
|
- Session expiry
|
|
- **References**: architecture/security.md
|
|
- **Acceptance Criteria**: Authentication is secure
|
|
|
|
- [ ] Test input validation
|
|
- SQL injection prevention (parameterized queries)
|
|
- XSS prevention (markdown sanitization)
|
|
- Path traversal prevention
|
|
- File upload security (if media implemented)
|
|
- **References**: architecture/security.md
|
|
- **Acceptance Criteria**: All inputs validated
|
|
|
|
- [ ] Test authorization
|
|
- Only ADMIN_ME can login
|
|
- Unauthorized users rejected
|
|
- Protected routes require auth
|
|
- Token scope enforcement
|
|
- **Acceptance Criteria**: Authorization works correctly
|
|
|
|
- [ ] Security headers
|
|
- Content-Security-Policy
|
|
- X-Frame-Options
|
|
- X-Content-Type-Options
|
|
- Referrer-Policy
|
|
- **References**: architecture/security.md
|
|
- **Acceptance Criteria**: Security headers set
|
|
|
|
**Completion Criteria**: No security vulnerabilities found
|
|
|
|
---
|
|
|
|
### 8.4 Manual Testing
|
|
|
|
**Priority**: HIGH - Real-world validation
|
|
**Estimated Effort**: 3-4 hours
|
|
**Dependencies**: All features implemented
|
|
|
|
- [ ] Test with real IndieLogin
|
|
- Authenticate with actual indielogin.com
|
|
- Verify session persistence
|
|
- Test logout
|
|
- **Acceptance Criteria**: Real IndieLogin works
|
|
|
|
- [ ] Test with real Micropub client
|
|
- Use Quill or Indigenous app
|
|
- Publish a note
|
|
- Verify it appears on site
|
|
- **Tools**: Quill (https://quill.p3k.io/)
|
|
- **Acceptance Criteria**: Real clients work
|
|
|
|
- [ ] Test in multiple browsers
|
|
- Chrome/Chromium
|
|
- Firefox
|
|
- Safari (if available)
|
|
- Mobile browsers
|
|
- **Acceptance Criteria**: Works in all major browsers
|
|
|
|
- [ ] Test responsive design
|
|
- Mobile phone (320px width)
|
|
- Tablet (768px width)
|
|
- Desktop (1200px width)
|
|
- **Acceptance Criteria**: Responsive on all sizes
|
|
|
|
- [ ] Test accessibility
|
|
- Keyboard navigation
|
|
- Screen reader (if available)
|
|
- Color contrast
|
|
- **Acceptance Criteria**: Basic accessibility works
|
|
|
|
**Completion Criteria**: Manual testing reveals no critical issues
|
|
|
|
---
|
|
|
|
## Phase 9: Documentation and Deployment
|
|
|
|
Final documentation and deployment preparation.
|
|
|
|
### 9.1 User Documentation
|
|
|
|
**Priority**: HIGH - Required for V1 release
|
|
**Estimated Effort**: 3-4 hours
|
|
**Dependencies**: All features complete
|
|
|
|
- [ ] Update README.md
|
|
- Verify all sections accurate
|
|
- Update installation instructions
|
|
- Add screenshots (optional)
|
|
- Update configuration examples
|
|
- **Acceptance Criteria**: README is complete and accurate
|
|
|
|
- [ ] Create deployment guide (`docs/architecture/deployment.md`)
|
|
- Production setup instructions
|
|
- Systemd service configuration
|
|
- Nginx/Caddy reverse proxy setup
|
|
- SSL/TLS configuration
|
|
- Backup procedures
|
|
- **References**: architecture/overview.md
|
|
- **Acceptance Criteria**: Deployment guide is comprehensive
|
|
|
|
- [ ] Create user guide (`docs/user-guide.md`)
|
|
- How to login
|
|
- How to create notes
|
|
- How to use Micropub clients
|
|
- How to backup data
|
|
- Troubleshooting common issues
|
|
- **Acceptance Criteria**: Users can self-serve
|
|
|
|
- [ ] Create API documentation (`docs/api.md`)
|
|
- REST API endpoints
|
|
- Micropub endpoint
|
|
- Authentication methods
|
|
- Example requests/responses
|
|
- **Acceptance Criteria**: API is documented
|
|
|
|
**Completion Criteria**: Documentation is complete and helpful
|
|
|
|
---
|
|
|
|
### 9.2 Developer Documentation
|
|
|
|
**Priority**: MEDIUM - Helpful for maintenance
|
|
**Estimated Effort**: 2-3 hours
|
|
**Dependencies**: All features complete
|
|
|
|
- [ ] Create contributing guide (`CONTRIBUTING.md`)
|
|
- Development setup
|
|
- Running tests
|
|
- Code style
|
|
- Pull request process
|
|
- **Acceptance Criteria**: Contributors can get started
|
|
|
|
- [ ] Create architecture diagram
|
|
- Visual representation of system
|
|
- Component interactions
|
|
- Data flow
|
|
- Save to `docs/architecture/diagrams/`
|
|
- **Acceptance Criteria**: Architecture is visualized
|
|
|
|
- [ ] Update ADRs if needed
|
|
- Document any architectural changes made during implementation
|
|
- Add new ADRs for new decisions
|
|
- **Acceptance Criteria**: All decisions documented
|
|
|
|
**Completion Criteria**: Developer documentation is complete
|
|
|
|
---
|
|
|
|
### 9.3 Deployment Testing
|
|
|
|
**Priority**: HIGH - Verify production readiness
|
|
**Estimated Effort**: 2-3 hours
|
|
**Dependencies**: Deployment guide complete
|
|
|
|
- [ ] Test production deployment
|
|
- Deploy to test server
|
|
- Use gunicorn (not Flask dev server)
|
|
- Configure reverse proxy
|
|
- Enable HTTPS
|
|
- Test performance under load
|
|
- **Acceptance Criteria**: Runs in production environment
|
|
|
|
- [ ] Test backup and restore
|
|
- Create backup of data/
|
|
- Restore to new instance
|
|
- Verify all notes accessible
|
|
- **Acceptance Criteria**: Backup/restore works
|
|
|
|
- [ ] Performance testing
|
|
- Test response times (< 300ms target)
|
|
- Test with 100+ notes
|
|
- Test RSS generation time
|
|
- Check memory usage
|
|
- **References**: architecture/overview.md (performance targets)
|
|
- **Acceptance Criteria**: Meets performance targets
|
|
|
|
**Completion Criteria**: Production deployment verified
|
|
|
|
---
|
|
|
|
## Phase 10: Release Preparation
|
|
|
|
Final steps before V1 release.
|
|
|
|
### 10.1 Final Quality Checks
|
|
|
|
**Priority**: CRITICAL - No release without this
|
|
**Estimated Effort**: 2-3 hours
|
|
**Dependencies**: Everything complete
|
|
|
|
- [ ] Run full test suite
|
|
- All unit tests pass
|
|
- All integration tests pass
|
|
- Test coverage >80%
|
|
- **Acceptance Criteria**: All tests green
|
|
|
|
- [ ] Code quality checks
|
|
- Run black (code formatting)
|
|
- Run flake8 (linting)
|
|
- Run mypy (type checking)
|
|
- Fix any issues
|
|
- **Acceptance Criteria**: Code passes all quality checks
|
|
|
|
- [ ] Final security review
|
|
- Review security checklist
|
|
- Verify all secrets in .env (not code)
|
|
- Verify data/ is gitignored
|
|
- Check for any hardcoded credentials
|
|
- **Acceptance Criteria**: No security issues
|
|
|
|
- [ ] Final documentation review
|
|
- All docs accurate
|
|
- All links working
|
|
- All code examples correct
|
|
- **Acceptance Criteria**: Documentation complete
|
|
|
|
**Completion Criteria**: Ready for release
|
|
|
|
---
|
|
|
|
### 10.2 Release
|
|
|
|
**Priority**: CRITICAL - V1 milestone
|
|
**Estimated Effort**: 1-2 hours
|
|
**Dependencies**: All quality checks pass
|
|
|
|
- [ ] Version tagging
|
|
- Update version in `starpunk/__init__.py` to `1.0.0`
|
|
- Create git tag `v1.0.0`
|
|
- Write release notes
|
|
- **Acceptance Criteria**: Version tagged
|
|
|
|
- [ ] Release announcement
|
|
- Post to IndieWeb wiki
|
|
- Share on personal site
|
|
- Optional: Announce on social media
|
|
- **Acceptance Criteria**: V1 announced
|
|
|
|
- [ ] Archive project state
|
|
- Create release branch `release/v1.0.0`
|
|
- Tag in git
|
|
- **Acceptance Criteria**: Release archived
|
|
|
|
**Completion Criteria**: StarPunk V1 released!
|
|
|
|
---
|
|
|
|
## Summary Checklist
|
|
|
|
### Core Features (Must Have)
|
|
- [ ] Notes CRUD operations (file + database sync)
|
|
- [ ] IndieLogin authentication
|
|
- [ ] Admin web interface
|
|
- [ ] Public web interface
|
|
- [ ] RSS feed generation
|
|
- [ ] Micropub endpoint
|
|
- [ ] All tests passing
|
|
- [ ] Standards compliance (HTML, RSS, Microformats, Micropub)
|
|
- [ ] Documentation complete
|
|
|
|
### Optional Features (Nice to Have)
|
|
- [ ] Markdown preview (JavaScript)
|
|
- [ ] Notes search
|
|
- [ ] Media uploads (Micropub)
|
|
- [ ] JSON REST API
|
|
- [ ] Feed caching
|
|
|
|
### Quality Gates
|
|
- [ ] Test coverage >80%
|
|
- [ ] All validators pass (HTML, RSS, Microformats, Micropub)
|
|
- [ ] Security tests pass
|
|
- [ ] Manual testing complete
|
|
- [ ] Performance targets met (<300ms responses)
|
|
- [ ] Production deployment tested
|
|
|
|
---
|
|
|
|
## Estimated Timeline
|
|
|
|
**Total Effort**: 40-60 hours of focused development work
|
|
|
|
**Breakdown by Phase**:
|
|
- Phase 1 (Utilities & Models): 5-7 hours
|
|
- Phase 2 (Notes Management): 6-8 hours
|
|
- Phase 3 (Authentication): 5-6 hours
|
|
- Phase 4 (Web Interface): 13-17 hours
|
|
- Phase 5 (RSS Feed): 4-5 hours
|
|
- Phase 6 (Micropub): 9-12 hours
|
|
- Phase 7 (REST API): 3-4 hours (optional)
|
|
- Phase 8 (Testing): 9-12 hours
|
|
- Phase 9 (Documentation): 5-7 hours
|
|
- Phase 10 (Release): 3-5 hours
|
|
|
|
**Recommended Schedule**:
|
|
- Week 1: Phases 1-3 (foundation and auth)
|
|
- Week 2: Phase 4 (web interface)
|
|
- Week 3: Phases 5-6 (RSS and Micropub)
|
|
- Week 4: Phases 8-10 (testing, docs, release)
|
|
|
|
---
|
|
|
|
## Development Notes
|
|
|
|
### Working Incrementally
|
|
1. Complete each phase before moving to next
|
|
2. Run tests after each feature
|
|
3. Keep commits small and focused
|
|
4. Document as you go (don't defer to end)
|
|
|
|
### When Stuck
|
|
1. Review relevant ADRs and architecture docs
|
|
2. Check IndieWeb specs (Micropub, Microformats)
|
|
3. Look at reference implementations
|
|
4. Ask for architectural guidance
|
|
|
|
### Testing Strategy
|
|
1. Write tests alongside features (not after)
|
|
2. Test happy path AND error cases
|
|
3. Integration tests for cross-component features
|
|
4. Manual testing for user experience
|
|
|
|
### Quality Over Speed
|
|
- Don't skip tests
|
|
- Don't skip documentation
|
|
- Don't compromise security
|
|
- Simple implementations are better than clever ones
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
### Project Documentation
|
|
- [Architecture Overview](/home/phil/Projects/starpunk/docs/architecture/overview.md)
|
|
- [Technology Stack](/home/phil/Projects/starpunk/docs/architecture/technology-stack.md)
|
|
- [ADR-001: Python Web Framework](/home/phil/Projects/starpunk/docs/decisions/ADR-001-python-web-framework.md)
|
|
- [ADR-002: Flask Extensions](/home/phil/Projects/starpunk/docs/decisions/ADR-002-flask-extensions.md)
|
|
- [ADR-003: Frontend Technology](/home/phil/Projects/starpunk/docs/decisions/ADR-003-frontend-technology.md)
|
|
- [ADR-004: File-Based Storage](/home/phil/Projects/starpunk/docs/decisions/ADR-004-file-based-note-storage.md)
|
|
- [ADR-005: IndieLogin Authentication](/home/phil/Projects/starpunk/docs/decisions/ADR-005-indielogin-authentication.md)
|
|
- [ADR-006: Python Virtual Environment](/home/phil/Projects/starpunk/docs/decisions/ADR-006-python-virtual-environment-uv.md)
|
|
- [Project Structure](/home/phil/Projects/starpunk/docs/design/project-structure.md)
|
|
- [Python Coding Standards](/home/phil/Projects/starpunk/docs/standards/python-coding-standards.md)
|
|
|
|
### External Standards
|
|
- [Micropub Specification](https://micropub.spec.indieweb.org/)
|
|
- [IndieAuth Specification](https://indieauth.spec.indieweb.org/)
|
|
- [Microformats2](http://microformats.org/wiki/microformats2)
|
|
- [RSS 2.0 Specification](https://www.rssboard.org/rss-specification)
|
|
- [IndieLogin API](https://indielogin.com/api)
|
|
|
|
### Testing Tools
|
|
- [W3C HTML Validator](https://validator.w3.org/)
|
|
- [W3C Feed Validator](https://validator.w3.org/feed/)
|
|
- [IndieWebify.me](https://indiewebify.me/)
|
|
- [Micropub.rocks](https://micropub.rocks/)
|
|
|
|
---
|
|
|
|
**This implementation plan is a living document. Update as implementation progresses and new insights emerge.**
|