Skip to content

Latest commit

 

History

History
916 lines (661 loc) · 35.2 KB

File metadata and controls

916 lines (661 loc) · 35.2 KB

Pulsefeed Project Guidelines

Import User Preferences: @~/.claude/CLAUDE.md

READ THIS ENTIRE FILE, EVERY TIME!!! DO NOT JUST SKIM!!! --- CRITICAL!!!


📚 Quick Reference Documents

New to the project? Start here:

This file (CLAUDE.md) contains critical constraints and gotchas. Reference the guides above for step-by-step workflows.


Environment

Database: App requires PostgreSQL. Start with docker-compose or set DATABASE_URL:

docker-compose up -d                    # Start PostgreSQL container
DATABASE_URL="postgresql://pulsefeed:localdev@localhost:5433/pulsefeed" python app.py

⚡ Common Commands

Development:

taskkill //F //IM python.exe && DATABASE_URL="postgresql://pulsefeed:localdev@localhost:5433/pulsefeed" python app.py  # Kill server and restart
pytest tests/ -v --tb=line                      # Run tests

Database:

alembic revision --autogenerate -m "Description"  # Create migration
alembic upgrade head                              # Apply migrations
alembic downgrade -1                              # Rollback one

Git (Solo Work):

git add -A && git commit -m "Description" && git push

Git (Collaborative Work with PRs):

git checkout -b feature/description      # Create branch
# ... make changes ...
git add -A && git commit -m "Description"
git push -u origin feature/description   # Push branch
gh pr create --title "Title" --body "Description"  # Create PR

🚨 CRITICAL RULES - READ BEFORE EVERY TASK 🚨

These are the most frequently violated constraints. Read this section COMPLETELY before starting any work.


🧠 Context & Confidence Protocol - MANDATORY

When Touching Files, Automatically Consider:

models.py → Also check:

  • Recent migrations in migrations/versions/
  • CHANGES_LOG.md (last 30 days)
  • docs/roadmaps/completed/ (especially Roadmap #4, #6)

routes/*.py → Also check:

  • Related repository in repositories/
  • Related service in services/
  • AJAX patterns if endpoint returns JSON

templates/*.html → Also check:

  • static/styles.css (for CSS classes being used)
  • docs/systems/unified-entry-display.md (for styling patterns)
  • Related route for data being rendered

entry_routes.py → Also check:

  • services/event_service.py, repositories/
  • templates/event_form.html (Event form)

Recurring patterns (RecurringEvent) → Also check:

  • utils/instance_resolver.py (RRULE computation)
  • services/recurrence_service.py
  • docs/systems/recurring-series-split.md

Permission/access logic → Also check:

  • utils/entry_access.py (centralized access control)
  • docs/security/entry-access-control.md
  • docs/security/data-security.md

Confidence Signaling - REQUIRED

When NOT 100% certain (didn't read the actual code), use qualifiers:

Correct:

  • "APPEARS to be duplication - let me verify by reading both files..."
  • "ASSUMING this follows events-only patterns (checking docs)..."
  • "I BELIEVE this is in the repository layer, but need to confirm..."

Wrong (overconfident):

  • "These are duplicates that should be merged"
  • "This is handled by X"
  • "This can be consolidated"

Before ANY architectural recommendation:

  1. Have I read the actual implementations?
  2. Have I checked CHANGES_LOG.md for recent refactorings?
  3. Have I checked docs/roadmaps/completed/?
  4. Am I pattern-matching or actually analyzing?

If answering "do you see X?" - INVESTIGATE FIRST:

  • Read actual code (not just function signatures)
  • Check CHANGES_LOG.md (recent changes)
  • Look for architecture docs explaining separation
  • Then answer with evidence citations

Recent Changes Reference

Check CHANGES_LOG.md before suggesting:

  • Consolidation (might be recently split)
  • New patterns (might already exist)
  • Architectural changes (might violate recent decisions)

Query Scoping & Data Security - CRITICAL

✅ ALWAYS use entry_access.py for determining what users can see

# ✅ CORRECT - Centralized access control (handles own + Pulse entries)
from utils.entry_access import get_accessible_event_ids

event_ids = get_accessible_event_ids(user.id, start_date, end_date)
events = Event.query.filter(Event.id.in_(event_ids)).all()

# ❌ WRONG - Manual filtering (misses Pulse subscriptions)
events = Event.query.filter(Event.user_id == user.id).all()

Critical: user_id means creator, NOT who can see it. Use entry_access.py for visibility.

Visibility Sources (3):

  1. User's own entries (user_id = user.id, NOT Pulse masters, NOT hidden)
  2. Controlled Pulse references (live updates from creator)
  3. Isolated Pulse copies (user's forked versions)

Permission helpers:

  • can_edit_entry(entry, user_id) - Check edit permission
  • is_pulse_reference(entry, user_id) - Check if read-only Pulse reference
  • get_entry_source_info(entry, user_id) - Get source for badges/UI

📚 Entry Access Control 📚 Data Security Guide


Repository Layer - MANDATORY (2025-10-20)

🚨 CRITICAL: NEVER use Model.query directly - ALWAYS use repositories 🚨

Before writing ANY route code, ask yourself:

  1. ❓ "Does a repository method exist for this query?"
  2. ✅ If YES → Use it
  3. ❌ If NO → CREATE the repository method FIRST, then use it

Why this matters:

  • Direct queries bypass access control (security vulnerability)
  • Creates N+1 query problems (performance issue)
  • Duplicates logic across routes (maintainability nightmare)
  • Misses Pulse subscriptions and shared calendar visibility

The pattern:

# ❌ WRONG - Direct Model.query (NEVER DO THIS)
event = Event.query.get(event_id)
events = Event.query.filter_by(user_id=user_id).all()

# ✅ CORRECT - Use repository layer
from repositories.event_repository import EventRepository

event = EventRepository.get(event_id)
events = EventRepository.get_for_homepage(user_id)

When creating new repository methods:

  1. Put them in the appropriate repository file (repositories/*.py)
  2. Follow the existing naming pattern: get_*, get_by_*, delete_*
  3. Include docstring with Args and Returns
  4. Use type hints
  5. Add permission checks where needed (user_id parameter)

Available Repositories: See repositories/ - includes EventRepository, RecurringRepository, PulseRepository, GroupRepository, ChatRepository, UserRepository, AdminRepository, and more.

Available Services: See services/ - includes EventService, PulseService, RecurrenceService, SocialService, GroupService, HomepageService, NotificationService, BroadcastService, and more.

📚 Repository Layer Documentation


Service Layer - NEW (2025-10-20)

✅ ALWAYS use services for business logic - NOT routes

Business logic layer orchestrates repositories and enforces business rules.

# ✅ CORRECT - Use service layer
from services.event_service import EventService

event = EventService.create_event(
    user_id=current_user.id,
    title="Team Meeting",
    start_date=date.today(),
    category='meeting'
)
db.session.commit()

# ❌ WRONG - Business logic in routes (scattered, hard to test)
event = Event(user_id=current_user.id, title="Team Meeting", start_date=date.today())
db.session.add(event)

Architecture:

Routes (HTTP handling) → Services (business logic) → Repositories (data access) → Models (database)

Service Exceptions (caught by routes):

  • PermissionError - User lacks permission (return 403)
  • NotFoundError - Resource not found (return 404)
  • ValidationError - Data validation failed (return 400)
  • AlreadyExistsError - Duplicate resource (return 409)
  • BusinessLogicError - Business rule violation (return 400)

Key Benefits:

  • Testable without HTTP overhead
  • Reusable across multiple routes
  • Clear separation of concerns
  • Consistent error handling

📚 Service Layer Examples


Activity Hooks & Helpers - NEW (2025-11-04, Roadmap #7)

Roadmap #7 added three new patterns for cleaner code:

1. Activity Hooks System

✅ ALWAYS use activity hooks for decoupled side effects

# ❌ WRONG - Side effects hardcoded in routes
@route('/create')
def create_event():
    event = EventService.create_event(...)
    db.session.commit()
    log_activity(...)
    # Manually update user stats
    current_user.event_count += 1
    # Manually send notification
    notify_user(...)
    return redirect(...)

# ✅ CORRECT - Side effects in hooks
@route('/create')
def create_event():
    event = EventService.create_event(...)
    db.session.commit()
    log_activity(...)  # Triggers all registered hooks automatically
    return redirect(...)

# Hook definition (in listeners/stats_hooks.py)
@on_activity('event.created')
def increment_event_count(activity_data):
    user_id = activity_data['user_id']
    # Update stats in background
    @run_in_background
    def update_count():
        user = User.query.get(user_id)
        user.event_count += 1
        db.session.commit()
    update_count()

Key Files:

  • utils/activity_hooks.py - Hook registry (on_activity(), trigger_hooks())
  • listeners/stats_hooks.py - Statistics tracking hooks
  • listeners/notification_hooks.py - Future notification hooks

Critical Rules:

  • ✅ Hooks triggered AFTER commit (transaction-safe)
  • ✅ Hook errors don't crash main flow
  • ✅ Use @run_in_background for DB operations in hooks
  • ❌ Hooks DON'T commit themselves

2. JSON Helpers (APIs Only)

✅ ALWAYS use json_helpers for API responses - NOT templates

# ✅ CORRECT - JSON helpers for APIs
@api_bp.route("/event/<int:event_id>/json")
@login_required
def get_event_json(event_id):
    from utils.json_helpers import event_to_json
    event = EventRepository.get(event_id)
    return jsonify({
        'success': True,
        'event': event_to_json(
            event,
            user_id=current_user.id,
            include_permissions=True
        )
    })

# ✅ CORRECT - Templates use models directly
@route('/')
@login_required
def index():
    events = EventRepository.get_for_homepage(...)
    return render_template('index.html', events=events)  # Pass models

Available Helpers:

  • event_to_json(), pulse_to_json(), recurring_event_to_json()
  • to_json_list() - Convert list of models

Key Features:

  • Reuses existing utils (date_utils, category_utils)
  • Integrates entry_access for permissions (can_edit, is_pulse_reference)
  • Optional fields (include_tasks, include_permissions)

3. WTForms Decorator (Optional)

✅ CAN use validate_with_form decorator to reduce boilerplate

# Before (manual validation)
@route('/create', methods=['POST'])
@login_required
def create_event():
    form = EventForm()
    if not form.validate_on_submit():
        for field, errors in form.errors.items():
            for error in errors:
                flash(f"{field}: {error}", 'error')
        return redirect(request.referrer or url_for('core.index'))
    # ... create event ...

# After (decorator)
from utils.form_decorators import validate_with_form

@route('/create', methods=['POST'])
@login_required
@validate_with_form(EventForm)
def create_event():
    form = request.validated_form  # Already validated!
    # ... create event ...

Key Features:

  • Wraps existing 13 WTForms (no duplication)
  • Handles JSON and form data
  • Smart error handling (AJAX returns JSON, forms flash/redirect)
  • CSRF kept for forms, disabled for JSON APIs

Migration Status:

  • Infrastructure ready, incremental migration (both patterns coexist)

📚 Roadmap #7 Details


Blueprint Routing - CRITICAL

All routes use Flask Blueprint pattern - centralized registration in routes/init.py

Critical Rules:

  • ✅ ALWAYS include blueprint prefix in url_for(): url_for('social.profile_view', ...)
  • ❌ NEVER omit prefix (causes BuildError): url_for('profile_view', ...)
  • WebSocket handlers require register_socketio_handlers(socketio)
  • All blueprints created at module level, NOT inside functions

Blueprint Prefixes: See routes/init.py for complete list - includes core., auth., admin., social., chat., sharing., oauth_calendar., calendar., event., entry., quick., series., entries., settings., guest., pulse., groups., hub., health., api.

📚 Blueprint Architecture Details


Database Migrations - CRITICAL

All schema changes MUST use Alembic migrations - NEVER manual SQL

alembic revision --autogenerate -m "Add user bio column"  # Create migration
alembic upgrade head                                      # Apply migration
alembic downgrade -1                                      # Rollback if needed

Critical Rules:

  • ✅ ALWAYS stop Flask server before running migrations (taskkill //F //IM python.exe)
  • ✅ ALWAYS review autogenerated migrations before applying (Alembic misses renames, custom constraints)
  • ✅ ALWAYS verify schema after migration (use inspection script)
  • ✅ ALWAYS test on database copy first
  • ❌ NEVER edit applied migrations (create new one instead)
  • ❌ NEVER run migrations without backup
  • ❌ NEVER run migrations while Flask server is running (database locks cause partial application)

Common Issue: Migrations may partially apply if server is running, leaving alembic version table out of sync with actual schema.

📚 Database Migrations Guide 📚 Migration Troubleshooting & Prevention


Database Integrity & CASCADE DELETE - CRITICAL

Zero tolerance for orphaned data. All 20 critical foreign keys have ondelete='CASCADE' in models.py. Database auto-deletes children when parents are deleted - no manual cleanup needed.

If integrity tests fail, you have a bug - don't schedule cleanup, fix the code.

📚 Database Integrity Guide - CASCADE implementation, testing, troubleshooting


Event Model Architecture - CRITICAL

As of Roadmap #12 (2025-12): Events-Only Architecture

# ✅ Calendar event (Event model)
event = Event(title="Doctor Appointment", start_date=date.today(), start_time=time(14, 30), category='event')

# ✅ Recurring event (RecurringEvent model)
recurring = RecurringEvent(title="Weekly Meeting", rrule='FREQ=WEEKLY;BYDAY=MO', start_date=date.today())

❌ CRITICAL Constraints:

  • Event model: start_date REQUIRED, category field
  • RecurringEvent: RRULE pattern for repetition
  • Pulses are curated collections of events

Before Modifying Complex Systems - MANDATORY READS

FIRST: Run the 📋 Before You Code Checklist - 10-step pre-flight protocol

If you're touching ANY of these systems, STOP and read the linked documentation FIRST:

🔒 Security-Critical (Read ALWAYS)

🏗️ Architecture-Critical (Read Before Major Changes)

🎨 UI/UX Patterns (Read Before UI Changes)

  • Unified Entry Display - 📚 Unified Entry Display System
    • WHY: Modular CSS classes for all entry types, no inline styles
  • Date/Time Selector - 📚 Date/Time Selector
    • WHY: Modular component used everywhere, don't duplicate logic
  • Time Picker - 📚 Time Picker System
    • WHY: Progressive disclosure time selection, lazy initialization prevents bugs
  • AJAX Patterns - 📚 AJAX Patterns
    • WHY: Specific timing, headers, double-click prevention required
  • Real-Time Updates (WebSockets) - 📚 Real-Time Updates System
    • WHY: Critical socket scoping gotcha, emit patterns, debugging checklist

🔧 Migration & Deployment (Read Before Schema Changes)

  • Database Migrations - 📚 Database Migrations
    • WHY: Production deployment has specific rollback procedures

Rule: If you're about to modify code in these areas, SAY "Reading [system] documentation first..." and actually read it.


📚 SYSTEM REFERENCE - Read When Relevant

The sections below contain detailed technical information about specific systems. Reference these when working on related features.


Entry System

Events-only architecture: All entries are events with dates, times, and categories. Recurring events use RRULE patterns for repetition.

📚 Entry Buttons System

Recurrence System

RFC5545 RRULE standard with on-demand computation (NO database storage). Use instance_resolver for RRULE-aware filtering with request-scoped caching (50-70% faster).

📚 RRULE Migration Summary 📚 Instance Resolver (Optimization)

Homepage Architecture

Philosophy: Command Center, Not Just a Feed The homepage is the primary workspace where users spend 90% of their time. Design for two use cases:

  • Monitoring users: Keep it open all day (project managers, team leads)
  • Check-in users: Quick visits to check schedules and upcoming events

Key Principles:

  • Information density is good IF intelligently organized
  • Every visual element must provide actionable information
  • Power users can parse complex information once they learn the visual language

Unified service layer: Use homepage_service.get_homepage_data() for all homepage data (NEVER duplicate logic in routes). Single source of truth prevents sync issues.

📚 Homepage Simplification Details

AJAX Architecture

TWO event endpoints (/api/events and /api/events_feed) MUST stay in sync. Task toggle requires specific headers and timing. See detailed patterns for implementation.

📚 AJAX Patterns Reference 📚 Entry Access Control

Form Validation

ALWAYS use WTForms validation (13 forms available). Global CSRF protection enabled. Eliminated ~410 lines of manual validation.

📚 Form Validation System

Mini-Calendar Component

Reusable calendar widget with date selection, month navigation, and theme-aware styling. Use mini_calendar() macro and initialize with new MiniCalendar({...}).

📚 Complete Mini-Calendar API & Examples

Date/Time Selector

Reusable radio button components for date/time selection. Use macros from components/form_fields.html and date_time_selector.js module. Never duplicate calendar HTML manually.

📚 Complete API & Examples

Category System

Database-driven (7 system + unlimited custom per user). NEVER hardcode categories. Jinja2 macros need explicit parameter passing (isolated scope).

📚 Category System Documentation

Unified Entry Display

Modular CSS system for all entry types. Three card classes (.entry-card, .entry-item, .task-card-nested). ALL styling in static/styles.css, use CSS variables, NEVER inline <style> tags.

Badge Evolution Strategy (Roadmap #10):

  • Moving toward intelligent combined badges instead of multiple separate badges
  • Example: [Work × Dev ↻] instead of [Recurring] [Pulse: Work] [Group: Dev Team]
  • Progressive disclosure: Simple badge by default, detailed on hover
  • User-customizable display preferences (future enhancement)

📚 Unified Entry Display System

Shared Calendars - DEPRECATED

REMOVED (Roadmap #10): SharedCalendars have been replaced by the Groups system.

All SharedCalendar models, routes, services, and shared_calendar_id columns have been removed. Use Groups for collaboration instead.

📚 Groups System

Groups System

Unified collaboration primitive (Roadmap #8 + #13 - COMPLETE). Groups are flat communities that own Pulses.

Architecture (Simplified in Roadmap #13):

  • Flat group model - NO hierarchical subgroups
  • Groups own Pulses directly (no intermediary)
  • Pulses are OFFERED to members, not forced
  • Members choose which Pulses to subscribe to

4-Tier Role System:

  • Owner - Full control
  • Co-Owner - Near-full control, can't transfer ownership
  • Admin - Manage Pulses and members
  • Member - View and subscribe

Ownership Model:

  • ✅ Users own entries (via user_id)
  • ✅ Pulses own entries (via pulse_id)
  • ✅ Groups own Pulses (via polymorphic owner_type/owner_user_id/owner_group_id)
  • ❌ Groups DON'T own entries directly (use Pulse ownership)

DO NOT Patterns:

  • DO NOT re-add hierarchical groups or subgroups
  • DO NOT add forced/automatic Pulse subscriptions
  • DO NOT add complex role inheritance between groups

📚 Groups System Roadmap 📚 Groups Simplification

User Customization System

Extensive appearance preferences (themes, buttons, badges, fonts, weights). Stored per-user in database, applied via CSS variables with real-time AJAX preview.

📚 Complete Customization System Documentation

Theme System

CSS Variable-based theming. NEVER hardcode colors. Use var(--bg-card), var(--text-primary), etc. for theme-aware styling.

📚 Theme System Details

Mobile Responsive Design

Comprehensive mobile support with hamburger menu. Breakpoints: 1024px (tablet), 992px (mobile), 480px (phone), 360px (tiny).

📚 Mobile Responsive Documentation

Notification System

Auto-dismissing toasts ONLY for banner notifications (use flash()). Persistent alerts OK for empty states and contextual info only.

📚 Notification System Details

Pulse System

Curated event collections with pure reference architecture. Events can belong to MULTIPLE Pulses (v2). Entry-level visibility, like/comment system.

📚 Multi-Pulse v2 Implementation - Phase 1-4 complete, UI pending 📚 Pulse System Details 📚 Visibility System

Admin System

User activity monitoring with real-time updates. Single admin level (is_admin flag). Dashboard displays activity feed, stats, filters, CSV/JSON export. Use log_activity() in routes to track actions.

Critical: Use current_app.extensions.get('socketio') to avoid circular imports when emitting events.

📚 Admin System Documentation

Social System

Real-time chat (WebSocket via Flask-SocketIO), friend management, profiles. Use friendship_utils.py helpers for N+1 prevention (90% query reduction).

📚 Social System Details 📚 Chat Implementation 📚 Real-Time Updates System - WebSocket architecture, gotchas, debugging

Calendar Import & OAuth

External calendar integration: iCal import (read-only auto-sync), OAuth calendars (Google/Microsoft). Tokens encrypted at rest with Fernet (requires DB_ENCRYPTION_KEY env var).

📚 Calendar Import Documentation 📚 Encrypted Field Implementation

Guest Mode System

Anonymous experience with session-based storage. Auto-converts to database on registration.

📚 Guest Mode Implementation

Calendar Performance

MUST remain lightning fast. FullCalendar lazy loading, minimal JavaScript, server-side filtering. Before modifying: ask "Will this slow down the calendar?" If yes, don't do it.

Testing & Production Libraries

Testing: Factory Boy for fixtures, pytest with coverage.

📚 Complete Testing Guide 📚 Production Libraries Guide 📚 Caching Strategy Guide


📋 PROJECT CONTEXT - Background Information

This section contains project structure, roadmap status, and historical context. Reference as needed.


About This File

  • Quick reference only - critical constraints, patterns, and gotchas
  • Detailed documentation lives in docs/systems/ - click through before modifying complex systems
  • Update when architecture or patterns change significantly
  • ❌ Avoid line number references - use function names, template conditions, or semantic descriptions

🚨 DOCUMENTATION UPDATE - MANDATORY AFTER SUBSTANTIAL CHANGES 🚨

Rule: If you modified code and didn't update docs, you didn't finish the task.

After substantial changes (schema, routes, workflows, patterns, security, performance, UI components):

  1. Update CHANGES_LOG.md - Add entry at TOP with date, what, why, files changed, "DO NOT" patterns
  2. Update CLAUDE.md - Add/update constraints, link to detailed docs (📚)
  3. Update/Create System Docs - Document in docs/systems/, explain WHY not just WHAT
  4. Update Roadmap - Mark completed items, move to completed/ if done
  5. Verify Links - All 📚 links work, no line number references

Specific CHANGES_LOG.md triggers (MANDATORY):

  • ✅ Completed roadmap phase/entire roadmap
  • ✅ Major refactoring (split models, consolidate routes, etc.)
  • ✅ New architectural pattern (repository layer, service layer, etc.)
  • ✅ Breaking changes (removed functions, changed model relationships)
  • ✅ Security changes (new permission model, access control updates)
  • ✅ Database migrations that affect multiple models

CHANGES_LOG.md format:

## YYYY-MM-DD - Brief Title

**What:** One sentence describing the change
**Why:** Why this was needed
**Impact:** Lines saved, performance improvement, or architectural benefit

**Files Added:**
- path/to/new/file.py

**Files Modified:**
- path/to/modified/file.py - What changed

**Key Changes:**
- Bullet point of important change
- Another important change

**DO NOT:**
- Pattern to avoid (e.g., "Suggest merging X and Y - intentionally split")

**Prevents:**
- What mistake this prevents

📋 PRE-COMMIT CHECKLIST - VERIFY BEFORE FINAL COMMIT

Before ANY commit that completes a roadmap/major feature, STOP and verify:

Step 1: Identify change type (pick ONE that applies):

  • ✅ Completed roadmap phase/entire roadmap → CHANGES_LOG.md MANDATORY
  • ✅ Major refactoring (split models, consolidate routes) → CHANGES_LOG.md MANDATORY
  • ✅ New architectural layer (repositories, services) → CHANGES_LOG.md MANDATORY
  • ✅ Breaking changes (removed functions, changed APIs) → CHANGES_LOG.md MANDATORY
  • ✅ Security changes (permissions, access control) → CHANGES_LOG.md MANDATORY
  • ✅ Database migrations affecting multiple models → CHANGES_LOG.md MANDATORY
  • ❌ None of above (minor bugfix/polish) → Documentation optional

Step 2: If you checked ANY box above, verify ALL of these:

  • CHANGES_LOG.md has new entry at TOP with date/what/why/impact
  • CHANGES_LOG.md entry includes "DO NOT" patterns
  • CHANGES_LOG.md entry includes "Prevents" section
  • CLAUDE.md updated with new patterns/constraints (if applicable)
  • Roadmap moved to completed/ folder (if roadmap complete)
  • All 📚 links in documentation verified

Step 3: Create final commit ONLY after all boxes checked

🚨 CRITICAL RULE: If you commit a completed roadmap/major change without updating CHANGES_LOG.md, you failed the task. No exceptions.


📚 Full Documentation Update Protocol

Roadmap System

Status tracking: 📚 Roadmap INDEX - Single source of truth for all roadmap status

Working on roadmaps:

  1. Check INDEX.md for current status (active vs completed roadmaps)
  2. Read the roadmap file for phase details
  3. Work on next item marked 🔜 NEXT or ❌
  4. Update roadmap file to mark progress (✅ + "Last Updated")
  5. When roadmap complete: move to completed/ folder and update INDEX.md

📚 Roadmap Architecture & Workflow

When to Update This Documentation

ALWAYS update CLAUDE.md when:

  • Model changes: Adding/removing database models, columns, or relationships
  • Workflow changes: Modifying how users create, edit, or delete entries
  • Critical constraints: Non-negotiable requirements (e.g., "ALWAYS use save_entry_data()")
  • Architecture decisions: New patterns that affect multiple systems

What to include in updates:

  1. The what: Clear description of the change
  2. The why: Reasoning and context
  3. The how: Link to detailed docs using 📚 notation
  4. The preserve: What must NOT change (❌/✅ examples if critical)

Housekeeping Workflow

When the user says "do housekeeping":

  1. Audit CLAUDE.md content:

    • Identify outdated information
    • Find content better suited for docs/systems/
    • Check for broken 📚 links
  2. Extract to separate docs (if needed):

    • Create/update docs in docs/systems/ for detailed content
    • Replace verbose sections with concise summaries + 📚 links
    • EXCEPTION: AI Assistant Behavior and Feature Implementation Protocol MUST stay in CLAUDE.md (meta-critical)
  3. Update CLAUDE.md:

    • Keep critical constraints and gotchas
    • Add/update 📚 links to detailed docs
    • Remove outdated patterns
  4. Standard workflow:

    • Start Flask server: taskkill //F //IM python.exe && python app.py
    • Commit changes: git add . && git commit -m "description"
    • Push to GitHub: git push
    • For collaborative work: Use branches and PRs (see Git commands above)

Development Workflow

  • Chat-enabled: python app.py (WebSocket support via Flask-SocketIO)
  • Standard dev: python -m flask run --port 5000 --debug (no WebSocket)
  • Flask auto-reloads on code changes in debug mode
  • ONLY ONE server at a time - kill existing Python processes first

Test Database Environment

Current database is TEST/DEVELOPMENT only - no production users. This means:

  • ✅ Aggressive schema changes allowed (DROP and recreate tables)
  • ✅ No complex migration scripts needed
  • ✅ Can recreate from scratch anytime
  • ✅ Test data via scripts, not careful preservation

When moving to production, migration strategy will need to change.

Project Structure

app.py                  - Main Flask application factory
models.py               - SQLAlchemy models with UserScopedMixin
extensions.py           - Flask extensions (db, login_manager, csrf)
routes/                 - Modular blueprints (see routes/__init__.py for complete list)
  __init__.py           - Centralized blueprint registration
repositories/           - Data access layer
services/               - Business logic layer
utils/                  - Utility functions (query_scoping, entry_access, date_utils, etc.)
forms/                  - WTForms validation schemas
templates/              - Jinja2 HTML templates
  partials/             - Reusable template components
  components/           - Reusable macros
static/                 - CSS, JS, assets
  js/                   - JavaScript modules
migrations/             - Alembic database migrations (PostgreSQL)
docs/                   - Documentation
  systems/              - System architecture docs
  roadmaps/             - Project roadmaps (active/ and completed/)
  security/             - Security documentation

Database - Key Models

User System

  • Flask-Login authentication with invite-only registration
  • Multi-user data isolation via UserScopedMixin
  • Theme and preferences stored in User model (NOT session)
  • UserActivity - Admin monitoring logs (action tracking, IP/user-agent, timestamps)
  • 📚 User System Details - User, AccountHistory, InviteCode, UserActivity models

Key Models

  • Event - Calendar items with dates/times/categories
  • RecurringEvent - RRULE patterns for recurring events
  • EventException - Tracks deleted/modified recurring event instances
  • Category - System + custom categories (database-driven)
  • Pulse - Curated event collections (subscription system)
  • PulseItem - Links events to Pulses (event_id OR recurring_event_id)
  • PulseSubscription - User subscriptions with fork-on-edit tracking
  • Group - Interest-based communities that own Pulses

📚 Instance Resolver (RRULE)

Completed Roadmaps

All 13 major roadmaps are complete! See 📚 Roadmap INDEX for full details.

Key architectural achievements:

  • Foundation & Security (#1), Production Readiness (#2), Pulse System (#3)
  • Event/Task Model Split (#4), Pulse Content Management (#5)
  • Repository/Service Layers (#6), Advanced Patterns (#7)
  • Groups System (#8), Permissions & Pulse Assignment (#9)
  • Vision Alignment & Core Experience Polish (#10)
  • PostgreSQL Migration (#11), Events-Only Pivot (#12)
  • Groups Simplification (#13) - Flat model, 4-tier roles, no forced subscriptions

📚 All Roadmap Details

Forward Looking

Potential future enhancements:

  • Content Pipeline (auto-curation with TMDB/sports APIs)
  • OAuth bidirectional sync (deferred from Roadmap #10)
  • LLM integration for natural language entry creation
  • Mobile app development
  • Advanced analytics and insights