## Phase 4: Web Interface Implementation Implemented complete web interface with public and admin routes, templates, CSS, and development authentication. ### Core Features **Public Routes**: - Homepage with recent published notes - Note permalinks with microformats2 - Server-side rendering (Jinja2) **Admin Routes**: - Login via IndieLogin - Dashboard with note management - Create, edit, delete notes - Protected with @require_auth decorator **Development Authentication**: - Dev login bypass for local testing (DEV_MODE only) - Security safeguards per ADR-011 - Returns 404 when disabled **Templates & Frontend**: - Base layouts (public + admin) - 8 HTML templates with microformats2 - Custom responsive CSS (114 lines) - Error pages (404, 500) ### Bugfixes (v0.5.1 → v0.5.2) 1. **Cookie collision fix (v0.5.1)**: - Renamed auth cookie from "session" to "starpunk_session" - Fixed redirect loop between dev login and admin dashboard - Flask's session cookie no longer conflicts with auth 2. **HTTP 404 error handling (v0.5.1)**: - Update route now returns 404 for nonexistent notes - Delete route now returns 404 for nonexistent notes - Follows ADR-012 HTTP Error Handling Policy - Pattern consistency across all admin routes 3. **Note model enhancement (v0.5.2)**: - Exposed deleted_at field from database schema - Enables soft deletion verification in tests - Follows ADR-013 transparency principle ### Architecture **New ADRs**: - ADR-011: Development Authentication Mechanism - ADR-012: HTTP Error Handling Policy - ADR-013: Expose deleted_at Field in Note Model **Standards Compliance**: - Uses uv for Python environment - Black formatted, Flake8 clean - Follows git branching strategy - Version incremented per versioning strategy ### Test Results - 405/406 tests passing (99.75%) - 87% code coverage - All security tests passing - Manual testing confirmed working ### Documentation - Complete implementation reports in docs/reports/ - Architecture reviews in docs/reviews/ - Design documents in docs/design/ - CHANGELOG updated for v0.5.2 ### Files Changed **New Modules**: - starpunk/dev_auth.py - starpunk/routes/ (public, admin, auth, dev_auth) **Templates**: 10 files (base, pages, admin, errors) **Static**: CSS and optional JavaScript **Tests**: 4 test files for routes and templates **Docs**: 20+ architectural and implementation documents 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
48 KiB
StarPunk V1 Implementation Plan
Overview
This document provides a comprehensive, dependency-ordered implementation plan for StarPunk V1, taking the project from its current state to a fully functional IndieWeb CMS.
Current State: Phase 3 Complete - Authentication module implemented (v0.4.0) Current Version: 0.4.0 Target State: Working V1 with all features implemented, tested, and documented Estimated Total Effort: ~40-60 hours of focused development Completed Effort: ~20 hours (Phases 1-3) Remaining Effort: ~20-40 hours (Phases 4-10)
Progress Summary
Last Updated: 2025-11-18
Completed Phases ✅
| Phase | Status | Version | Test Coverage | Report |
|---|---|---|---|---|
| 1.1 - Core Utilities | ✅ Complete | 0.1.0 | >90% | N/A |
| 1.2 - Data Models | ✅ Complete | 0.1.0 | >90% | N/A |
| 2.1 - Notes Management | ✅ Complete | 0.3.0 | 86% (85 tests) | Phase 2.1 Report |
| 3.1 - Authentication | ✅ Complete | 0.4.0 | 96% (37 tests) | Phase 3 Report |
Current Phase 🔵
Phase 4: Web Routes and Templates (v0.5.0 target)
- Status: Design complete, ready for implementation
- Design Docs: phase-4-web-interface.md, phase-4-architectural-assessment-20251118.md
- New ADR: ADR-011 (Development Authentication Mechanism)
- Progress: 0% (not started)
Remaining Phases ⏳
| Phase | Estimated Effort | Priority |
|---|---|---|
| 4 - Web Interface | 34 hours | HIGH |
| 5 - RSS Feed | 4-5 hours | HIGH |
| 6 - Micropub | 9-12 hours | HIGH |
| 7 - API Routes | 3-4 hours | MEDIUM (optional) |
| 8 - Testing & QA | 9-12 hours | HIGH |
| 9 - Documentation | 5-7 hours | HIGH |
| 10 - Release Prep | 3-5 hours | CRITICAL |
Overall Progress: ~33% complete (Phases 1-3 done, 7 phases remaining)
Implementation Strategy
- Bottom-up approach: Build foundation modules before features that depend on them
- Feature completeness: Implement each feature fully (code + tests + docs) before moving to the next
- Continuous validation: Test integration points as we build
- 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)
Status: ✅ COMPLETE Priority: CRITICAL - Required by all other features Estimated Effort: 2-3 hours Actual Effort: ~2 hours Completed: 2025-11-18 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), ADR-007 (Slug Generation)
- 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 (
.tmpsuffix) - 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
- Write to temp file first (
-
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
-
Implement URL validation utility (
is_valid_url())- Added in Phase 3 for authentication
- Validates HTTP/HTTPS URLs
- Acceptance Criteria: ✅ Validates URLs correctly
-
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
- Result: ✅ All tests passing with excellent coverage
Completion Criteria: ✅ All utility functions implemented and tested with >90% coverage
1.2 Data Models (starpunk/models.py)
Status: ✅ COMPLETE
Priority: CRITICAL - Used by all feature modules
Estimated Effort: 3-4 hours
Actual Effort: ~3 hours
Completed: 2025-11-18
Dependencies: utils.py
-
Implement
Notemodel 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
Sessionmodel class- Properties: id, session_token_hash, me, created_at, expires_at, last_used_at, user_agent, ip_address
- Method:
from_row()- Create Session from database row - Property:
is_expired- Check if session expired - Method:
is_valid()- Comprehensive validation - References: ADR-005, ADR-010
- Note: Uses token hash instead of plaintext for security
- Acceptance Criteria: ✅ Session validation works correctly
-
Implement
Tokenmodel 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
- Note: Ready for Phase 6 implementation
- Acceptance Criteria: ✅ Token scope checking works
-
Implement
AuthStatemodel class- Properties: state, created_at, expires_at, redirect_uri
- Method:
from_row()- Create AuthState from database row - Property:
is_expired- Check if state expired - References: ADR-005, ADR-010
- 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)
- Result: ✅ All tests passing with excellent coverage
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)
Status: ✅ COMPLETE
Priority: CRITICAL - Core functionality
Estimated Effort: 6-8 hours
Actual Effort: ~6 hours
Completed: 2025-11-18
Dependencies: utils.py, models.py, database.py
Test Coverage: 86% (85 tests passing)
-
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, docs/reports/phase-2.1-implementation-20251118.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
- SQL injection prevention (validated order_by field)
- 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
- Write new content to file atomically
- Calculate new content hash
- Update database record (updated_at, content_hash, published)
- 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
- Idempotent operation (safe to call multiple times)
- 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 - Deferred to V2
- Status: Not implemented in Phase 2.1
- Acceptance Criteria: N/A - Deferred
-
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
- Result: ✅ Comprehensive error handling implemented
-
Implement custom exceptions
NoteError- Base exceptionNoteNotFoundError- Note not foundInvalidNoteDataError- Invalid dataNoteSyncError- Sync failure- Result: ✅ Complete exception hierarchy
-
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
- Result: ✅ 85 tests, 86% coverage, all passing
Completion Criteria: ✅ Full CRUD operations working with file+database sync, comprehensive tests passing
Report: See /home/phil/Projects/starpunk/docs/reports/phase-2.1-implementation-20251118.md
Phase 3: Authentication (IndieLogin)
Implements the IndieLogin OAuth flow for admin access.
3.1 Authentication Module (starpunk/auth.py)
Status: ✅ COMPLETE
Priority: HIGH - Required for admin interface
Estimated Effort: 5-6 hours
Actual Effort: ~5 hours
Completed: 2025-11-18
Dependencies: models.py, database.py, httpx library
Test Coverage: 96% (37 tests passing)
-
Implement state token management
- Helper functions for state token generation and verification
- Single-use tokens with 5-minute expiry
- Automatic cleanup of expired tokens
- References: ADR-005, ADR-010
- Acceptance Criteria: ✅ State tokens prevent CSRF attacks
-
Implement session token management
create_session()- Create session with SHA-256 hashed tokenverify_session()- Validate session and check expirationdestroy_session()- Delete session (logout)- Session metadata tracking (user_agent, ip_address)
- Automatic cleanup of expired sessions
- 30-day expiry with activity-based refresh
- References: ADR-005, ADR-010, architecture/security.md
- Note: Uses token hashing for security (never stores plaintext)
- Acceptance Criteria: ✅ Sessions work for 30 days, extend on use
-
Implement IndieLogin OAuth flow
initiate_login()- Build authorization URL, store state- Validates 'me' URL format using
is_valid_url() - Generates cryptographically secure state token
- Stores state in database with 5-minute expiry
- Builds indielogin.com authorization URL
- Returns authorization URL for redirect
- Validates 'me' URL format using
handle_callback()- Exchange code for identity- Verifies state token (CSRF check, single-use)
- POSTs to indielogin.com/auth with code
- Validates HTTP response (200 OK)
- Extracts 'me' from JSON response
- Verifies 'me' matches ADMIN_ME config
- Creates session if authorized
- Returns session token for cookie setting
- References: ADR-005, ADR-010, IndieLogin API docs
- Acceptance Criteria: ✅ Full OAuth flow works with indielogin.com
-
Implement authentication decorator
require_auth()- Decorator for protected routes- Extracts session token from cookie
- Validates session using
verify_session() - Stores user info in Flask
g.user - Returns 401/redirect if not authenticated
- Acceptance Criteria: ✅ Protects admin routes correctly
-
Implement custom exceptions
AuthError- Base exceptionInvalidStateError- CSRF validation failedUnauthorizedError- User not authorizedIndieLoginError- External service error- Result: ✅ Complete exception hierarchy
-
Error handling
- Invalid state token rejection
- IndieLogin API error handling
- Network timeout handling (10s timeout)
- Unauthorized user rejection (wrong 'me')
- Expired session handling
- Comprehensive logging for all auth events
- References: architecture/security.md, ADR-010
- Result: ✅ Comprehensive error handling
-
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
- Result: ✅ 37 tests, 96% coverage, all passing
Completion Criteria: ✅ Authentication works end-to-end, all security measures tested
Report: See /home/phil/Projects/starpunk/docs/reports/phase-3-authentication-20251118.md
New ADRs: ADR-010 (Authentication Module Design)
Phase 4: Web Routes and Templates
User-facing interface (public site + admin interface).
Status: 🔵 IN PROGRESS - Design complete, ready for implementation Design Complete: 2025-11-18 Documentation:
/home/phil/Projects/starpunk/docs/design/phase-4-web-interface.md/home/phil/Projects/starpunk/docs/reports/phase-4-architectural-assessment-20251118.md/home/phil/Projects/starpunk/docs/decisions/ADR-011-development-authentication-mechanism.md
Key Decisions:
- Development authentication mechanism approved (ADR-011)
- Template structure defined
- Route organization finalized
- CSS architecture specified
Target Version: 0.5.0
4.1 Public Routes Blueprint (starpunk/routes/public.py)
Status: ⏳ NOT STARTED
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
- Create
-
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
- GET
-
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
- GET handler (protected with
-
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
- Extends
-
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
- Extends
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
- Extends
-
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
- Extends
-
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
- Extends
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
- GET
-
Add feed auto-discovery to templates
- Add
<link rel="alternate" type="application/rss+xml">to base.html - Acceptance Criteria: RSS readers auto-discover feed
- Add
-
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.pyvalidate_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/jsoncontent type - Handle
application/x-www-form-urlencodedcontent 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
- Handle
-
Implement Micropub GET handler (query)
- Handle
q=configquery - Return supported config - Handle
q=sourcequery - Return note source by URL - Handle
q=syndicate-toquery - Return empty (no syndication targets in V1) - Return JSON responses
- References: Micropub spec
- Acceptance Criteria: Query endpoints return correct data
- Handle
-
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_authdecorator - Acceptance Criteria: Micropub endpoint accessible
- POST
-
Add Micropub endpoint discovery
- Add
<link rel="micropub">to base template - Point to
/api/micropub - References: Micropub spec
- Acceptance Criteria: Clients can discover endpoint
- Add
-
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
- GET
-
Register API blueprint
- Import in
starpunk/__init__.py - Register with app
- Acceptance Criteria: API routes accessible
- Import in
-
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__.pyto1.0.0 - Create git tag
v1.0.0 - Write release notes
- Acceptance Criteria: Version tagged
- Update version in
-
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
- Create release branch
Completion Criteria: StarPunk V1 released!
Summary Checklist
Core Features (Must Have)
- Notes CRUD operations (file + database sync) ✅ v0.3.0
- 86% test coverage, 85 tests passing
- Full file/database synchronization
- Soft and hard delete support
- IndieLogin authentication ✅ v0.4.0
- 96% test coverage, 37 tests passing
- CSRF protection, session management
- Token hashing for security
- Admin web interface ⏳ Designed, not implemented
- Design complete (Phase 4)
- Routes specified
- Templates planned
- Public web interface ⏳ Designed, not implemented
- Design complete (Phase 4)
- Microformats2 markup planned
- RSS feed generation ⏳ Not started
- Phase 5
- Micropub endpoint ⏳ Not started
- Phase 6
- Token model ready
- Core tests passing ✅ Phases 1-3 complete
- Utils: >90% coverage
- Models: >90% coverage
- Notes: 86% coverage
- Auth: 96% coverage
- Standards compliance ⏳ Partial
- HTML5: Not yet tested
- RSS: Not yet implemented
- Microformats: Planned in Phase 4
- Micropub: Not yet implemented
- Documentation complete (Phases 1-3) ✅
- ADRs 001-011 complete
- Design docs for Phases 1-4
- Implementation reports for Phases 2-3
Optional Features (Nice to Have)
- Markdown preview (JavaScript) - Phase 4.5
- Notes search - Deferred to V2
- Media uploads (Micropub) - Deferred to V2
- JSON REST API - Phase 7 (optional)
- Feed caching - Deferred to V2
Quality Gates
- Test coverage >80% ✅ Phases 1-3 achieve 86-96%
- All validators pass ⏳ Not yet tested
- HTML validator: Phase 8
- RSS validator: Phase 8
- Microformats validator: Phase 8
- Micropub validator: Phase 8
- Security tests pass ✅ Phases 1-3
- SQL injection prevention tested
- Path traversal prevention tested
- CSRF protection tested
- Token hashing tested
- Manual testing complete ⏳ Not yet performed
- Performance targets met ⏳ Not yet tested
- Production deployment tested ⏳ Not yet performed
Current Status: 3/10 phases complete (33%), foundation solid, ready for Phase 4
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
Original Schedule:
Week 1: Phases 1-3 (foundation and auth)✅ Complete- Week 2: Phase 4 (web interface) ⏳ Current
- Week 3: Phases 5-6 (RSS and Micropub)
- Week 4: Phases 8-10 (testing, docs, release)
Revised Schedule (from 2025-11-18):
- Completed: Phases 1-3 (utilities, models, notes, auth) - ~20 hours
- Next: Phase 4 (web interface) - ~34 hours (~5 days)
- Then: Phases 5-6 (RSS + Micropub) - ~15 hours (~2 days)
- Finally: Phases 8-10 (QA + docs + release) - ~20 hours (~3 days)
Estimated Completion: ~10-12 development days from 2025-11-18
Development Notes
Working Incrementally
- Complete each phase before moving to next
- Run tests after each feature
- Keep commits small and focused
- Document as you go (don't defer to end)
When Stuck
- Review relevant ADRs and architecture docs
- Check IndieWeb specs (Micropub, Microformats)
- Look at reference implementations
- Ask for architectural guidance
Testing Strategy
- Write tests alongside features (not after)
- Test happy path AND error cases
- Integration tests for cross-component features
- 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
- Technology Stack
- ADR-001: Python Web Framework
- ADR-002: Flask Extensions
- ADR-003: Frontend Technology
- ADR-004: File-Based Storage
- ADR-005: IndieLogin Authentication
- ADR-006: Python Virtual Environment
- ADR-007: Slug Generation Algorithm
- ADR-008: Versioning Strategy
- ADR-009: Git Branching Strategy
- ADR-010: Authentication Module Design
- ADR-011: Development Authentication Mechanism
- Project Structure
- Phase 4 Web Interface Design
- Python Coding Standards
- Versioning Strategy
- Git Branching Strategy
Implementation Reports
External Standards
Testing Tools
This implementation plan is a living document. Update as implementation progresses and new insights emerge.