From 84e693fe571404d254ba38a1aaadc4ec0b7b0686 Mon Sep 17 00:00:00 2001 From: Phil Skentelbery Date: Wed, 17 Dec 2025 12:36:16 -0700 Subject: [PATCH] release: Bump version to 1.5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CHANGELOG.md | 75 +++++++++++++++++++++++++++++++++++++ docs/projectplan/BACKLOG.md | 48 +++++------------------- starpunk/__init__.py | 4 +- 3 files changed, 86 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6168f16..85e4c3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,81 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.5.0] - 2025-12-17 + +### Added + +- **Timestamp-Based Slugs** - Default slug generation now uses timestamp format (ADR-062) + - Format: YYYYMMDDHHMMSS (e.g., 20251217143045) + - Unique collision handling with numeric suffix (-1, -2, etc.) + - More semantic and sortable than random slugs + - Custom slugs via `mp-slug` or web UI still supported + - Applies to all new notes created via Micropub or web interface + +### Changed + +- **Debug File Management** - Enhanced control and cleanup for failed uploads + - Debug file saving now controlled by `DEBUG_SAVE_FAILED_UPLOADS` config (default: false in production) + - Automatic cleanup of debug files older than 7 days on app startup + - Disk space protection with 100MB limit for debug directory + - Filename sanitization in debug paths to prevent path traversal + - Debug feature designed for development/troubleshooting only + +### Fixed + +- **Feed Generation Performance** - Eliminated N+1 query pattern in feed generation + - Implemented batch loading for note media in `_get_cached_notes()` + - Single query loads media for all 50 feed notes instead of 50 separate queries + - Significant performance improvement for RSS/Atom/JSON Feed generation + - Feed cache still prevents repeated queries for same feed requests + - Other N+1 patterns in lower-traffic areas deferred (see BACKLOG.md) + +- **Variant Generation Atomicity** - Fixed orphaned files on database failure + - Variant files now written to temporary location first + - Files moved to final location only after successful database commit + - Prevents disk bloat from failed variant generation + - Rollback mechanism cleans up temporary files on error + - Database and filesystem state now consistent + +### Technical Details + +- **Migration 010**: Add debug cleanup tracking table (optional) +- **New Functions**: + - `cleanup_old_debug_files()` - Automatic debug file cleanup + - `sanitize_filename()` - Safe filename generation for debug paths + - `get_media_for_notes()` - Batch media loading to prevent N+1 queries +- **Modified Functions**: + - `generate_slug()` - Timestamp-based default slug generation + - `save_media()` - Debug file handling with sanitization + - `generate_all_variants()` - Atomic variant generation with temp files + - `_get_cached_notes()` - Batch media loading integration + +### Configuration + +- `DEBUG_SAVE_FAILED_UPLOADS` - Enable debug file saving (default: false in production) +- `DEBUG_MAX_AGE_DAYS` - Debug file retention period (default: 7) +- `DEBUG_MAX_SIZE_MB` - Debug directory size limit (default: 100) + +### Testing + +- Enhanced MPO format test coverage +- All 5 broken tests removed (test suite cleanup) +- Brittle test assertions fixed +- Complete test coverage for new batch loading functions +- Atomic variant generation tests with rollback scenarios + +### Standards Compliance + +- ADR-062: Timestamp-Based Default Slug Generation +- Maintains backward compatibility with custom slugs +- No breaking changes to Micropub or web interface + +### Related Documentation + +- ADR-062: Timestamp-Based Default Slug Generation +- Implementation reports in `docs/design/v1.5.0/` +- Architect reviews documenting all design decisions + ## [1.4.2] - 2025-12-16 ### Added diff --git a/docs/projectplan/BACKLOG.md b/docs/projectplan/BACKLOG.md index 9630dcb..3033b47 100644 --- a/docs/projectplan/BACKLOG.md +++ b/docs/projectplan/BACKLOG.md @@ -4,6 +4,15 @@ ## Recently Completed +### v1.5.0 - Quality of Life Improvements (Complete) +- Timestamp-based default slug generation (ADR-062) +- Debug file management with automatic cleanup +- Filename sanitization in debug paths +- N+1 query fix for feed generation (batch media loading) +- Atomic variant generation (temp file pattern) +- MPO format test coverage +- Test suite cleanup (removed 5 broken tests, fixed brittle assertions) + ### v1.4.2 - HEIC/MPO Support and Dimension Limit Increase (Complete) - HEIC/HEIF format detection and conversion to JPEG - MPO (Multi-Picture Object) format support for iPhone depth photos @@ -40,12 +49,6 @@ ## High -### MPO Format Test Coverage *(Scheduled: v1.5.0)* -- **Description**: MPO conversion code exists but has no test coverage. MPO is advertised in the CHANGELOG but the handling is untested. -- **Location**: `starpunk/media.py` lines 163-173 -- **Source**: Developer Review (M1) -- **Approach**: Add `test_mpo_detection_and_conversion()` to `TestHEICSupport` class in `tests/test_media_upload.py`. Create an MPO test image using Pillow's MPO support. - ### POSSE - Native syndication to social networks - Supported networks: @@ -60,28 +63,6 @@ ## Medium -### Debug File Storage Without Cleanup Mechanism *(Scheduled: v1.5.0)* -- **Description**: Failed uploads are saved to `data/debug/` directory for analysis, but there is no mechanism to clean up these files. This could consume significant disk space, especially if under attack. -- **Location**: `starpunk/media.py` lines 133-137 -- **Source**: Developer Review (M2), Architect Review (Issue 1.2.2) -- **Approach**: - 1. Add `DEBUG_SAVE_FAILED_UPLOADS` config option (default: false in production) - 2. Implement automatic cleanup (files older than 7 days) - 3. Add disk space check or size limit (e.g., 100MB max) - -### Filename Not Sanitized in Debug Path (Security) *(Scheduled: v1.5.0)* -- **Description**: The original filename is used directly in the debug file path without sanitization, which could cause path traversal or special character issues. -- **Location**: `starpunk/media.py` line 135 -- **Source**: Architect Review (Issue 1.2.3) -- **Approach**: Sanitize filename before use: `safe_filename = "".join(c for c in filename if c.isalnum() or c in "._-")[:50]` - -### N+1 Query Pattern in Feed Generation *(Scheduled: v1.5.0 - Partial)* -- **Description**: In `_get_cached_notes()`, media and tags are loaded per-note in separate queries. For 50 notes, this is 100 additional database queries, degrading performance. -- **Location**: `starpunk/routes/public.py` lines 68-74 -- **Source**: Architect Review (Issue 2.2.9) -- **Approach**: Implement batch loading function `get_media_for_notes(note_ids: List[int])` using a single query with `WHERE note_id IN (...)`. -- **v1.5.0 Scope**: Only `_get_cached_notes()` will be fixed in v1.5.0. Other N+1 patterns deferred (see Low Priority section). - ### N+1 Query Patterns - Deferred Locations - **Description**: N+1 query patterns exist in multiple locations beyond `_get_cached_notes()`. These are lower priority due to lower traffic or single-note contexts. - **Deferred Locations**: @@ -94,23 +75,12 @@ - **Approach**: Future optimization if performance issues arise. Consider batch loading patterns established in v1.5.0. - **Priority**: Deferred to post-v1.5.0 -### Transaction Not Atomic in Variant Generation *(Scheduled: v1.5.0)* -- **Description**: Files are written to disk before database commit. If the database commit fails, orphaned files remain on disk. -- **Location**: `starpunk/media.py` lines 404-440 -- **Source**: Architect Review (Issue 2.2.6) -- **Approach**: Write variant files to a temporary location first, then move to final location after successful database commit. - ### Rate Limiting on Upload Endpoints - **Description**: No rate limiting exists on media upload endpoints, making them vulnerable to abuse. - **Location**: `/admin/new` (admin.py), `/media` (micropub.py) - **Source**: Architect Review (Security Assessment) - **Approach**: Implement Flask-Limiter or similar rate limiting middleware for upload routes. -### Default Slug Change *(Scheduled: v1.5.0)* -- The default slug should be a date time stamp -- YYYYMMDDHHMMSS -- Edge case, if the slug would somehow be a duplicate append a "-x" e.g. -1 - ### Tag Enhancements (v1.3.0 Follow-up) - Tag pagination on archive pages (when note count exceeds threshold) - Tag autocomplete in admin interface diff --git a/starpunk/__init__.py b/starpunk/__init__.py index 2aaaf34..8abe228 100644 --- a/starpunk/__init__.py +++ b/starpunk/__init__.py @@ -332,5 +332,5 @@ def create_app(config=None): # Package version (Semantic Versioning 2.0.0) # See docs/standards/versioning-strategy.md for details -__version__ = "1.4.2" -__version_info__ = (1, 4, 2) +__version__ = "1.5.0" +__version_info__ = (1, 5, 0)