Implements tag/category system backend following microformats2 p-category specification. Database changes: - Migration 008: Add tags and note_tags tables - Normalized tag storage (case-insensitive lookup, display name preserved) - Indexes for performance New module: - starpunk/tags.py: Tag management functions - normalize_tag: Normalize tag strings - get_or_create_tag: Get or create tag records - add_tags_to_note: Associate tags with notes (replaces existing) - get_note_tags: Retrieve note tags (alphabetically ordered) - get_tag_by_name: Lookup tag by normalized name - get_notes_by_tag: Get all notes with specific tag - parse_tag_input: Parse comma-separated tag input Model updates: - Note.tags property (lazy-loaded, prefer pre-loading in routes) - Note.to_dict() add include_tags parameter CRUD updates: - create_note() accepts tags parameter - update_note() accepts tags parameter (None = no change, [] = remove all) Micropub integration: - Pass tags to create_note() (tags already extracted by extract_tags()) - Return tags in q=source response Per design doc: docs/design/v1.3.0/microformats-tags-design.md Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
4.2 KiB
INITIAL_SCHEMA_SQL Quick Reference
What You're Building
Implementing Phase 2 of the database migration system redesign (ADR-031/032) by adding INITIAL_SCHEMA_SQL to represent the v0.1.0 baseline schema.
Why It's Critical
Current system fails on production upgrades because SCHEMA_SQL represents current schema, not initial. This causes index creation on non-existent columns.
Key Files to Modify
-
/home/phil/Projects/starpunk/starpunk/database.py- Add INITIAL_SCHEMA_SQL constant (v0.1.0 schema)
- Rename SCHEMA_SQL to CURRENT_SCHEMA_SQL
- Add database_exists_with_tables() helper
- Update init_db() logic
-
/home/phil/Projects/starpunk/tests/test_migrations.py- Add test_fresh_database_initialization()
- Add test_existing_database_upgrade()
The INITIAL_SCHEMA_SQL Content
-- EXACTLY as it was in v0.1.0 (commit a68fd57)
-- Key differences from current:
-- 1. sessions: has 'session_token' not 'session_token_hash'
-- 2. tokens: plain text PRIMARY KEY, no token_hash column
-- 3. auth_state: no code_verifier column
-- 4. NO authorization_codes table at all
CREATE TABLE notes (...) -- with 4 indexes
CREATE TABLE sessions (...) -- with session_token (plain)
CREATE TABLE tokens (...) -- with token as PRIMARY KEY (plain)
CREATE TABLE auth_state (...) -- without code_verifier
The New init_db() Logic
def init_db(app=None):
if database_exists_with_tables(db_path):
# Existing DB: Skip schema, run migrations only
logger.info("Existing database found")
else:
# Fresh DB: Create v0.1.0 schema first
conn.executescript(INITIAL_SCHEMA_SQL)
logger.info("Created initial v0.1.0 schema")
# Always run migrations (brings everything current)
run_migrations(db_path, logger)
Migration Path from INITIAL_SCHEMA_SQL
- Start: v0.1.0 schema (INITIAL_SCHEMA_SQL)
- Migration 001: Adds code_verifier to auth_state
- Migration 002: Rebuilds tokens table (secure), adds authorization_codes
- Result: Current schema (CURRENT_SCHEMA_SQL)
Testing Commands
# Test fresh database
rm data/starpunk.db
uv run python app.py
# Should see: "Created initial v0.1.0 database schema"
# Should see: "Applied migration: 001_..."
# Should see: "Applied migration: 002_..."
# Test existing database
# (with backup of existing database)
uv run python app.py
# Should see: "Existing database found"
# Should see: "All migrations up to date"
# Verify schema
sqlite3 data/starpunk.db
.tables # Should show all tables including authorization_codes
SELECT * FROM schema_migrations; # Should show 2 migrations
Success Indicators
✅ Fresh database creates without errors ✅ Existing database upgrades without "no such column" errors ✅ No "index already exists" errors ✅ Both migrations show in schema_migrations table ✅ authorization_codes table exists after migrations ✅ tokens table has token_hash column after migrations ✅ All tests pass
Common Pitfalls to Avoid
❌ Don't use current schema for INITIAL_SCHEMA_SQL ❌ Don't forget to check database existence before schema creation ❌ Don't modify migration files (they're historical record) ❌ Don't skip testing both fresh and existing database paths
If Something Goes Wrong
- Check that INITIAL_SCHEMA_SQL matches commit
a68fd57exactly - Verify database_exists_with_tables() returns correct boolean
- Ensure migrations/ directory is accessible
- Check SQLite version supports all features
- Review logs for specific error messages
Time Estimate
- Implementation: 1-2 hours
- Testing: 2-3 hours
- Documentation updates: 1 hour
- Total: 4-6 hours
References
- Design: /home/phil/Projects/starpunk/docs/decisions/ADR-032-initial-schema-sql-implementation.md
- Context: /home/phil/Projects/starpunk/docs/decisions/ADR-031-database-migration-system-redesign.md
- Priority: /home/phil/Projects/starpunk/docs/projectplan/v1.1/priority-work.md
- Full Guide: /home/phil/Projects/starpunk/docs/design/initial-schema-implementation-guide.md
- Original Schema: Git commit
a68fd57
Remember: This is CRITICAL for v1.1.0. Without this fix, production databases cannot upgrade properly.