Files
TimeTracker/docs/implementation-notes/SESSION_CLOSE_ERROR_FIX.md
Dries Peeters e4789cc26e feat: Add telemetry and analytics infrastructure with observability stack
Implement comprehensive analytics and monitoring system with PostHog integration,
complete observability stack (Prometheus, Grafana, Loki, Promtail), and CI/CD
workflows for automated builds.

Features:
- Add PostHog telemetry integration with privacy-focused event tracking
- Implement installation flow for opt-in telemetry configuration
- Add telemetry management UI in admin panel with detailed transparency
- Track key user events across all major features (projects, tasks, timer, etc.)

Infrastructure:
- Set up Prometheus for metrics collection
- Configure Grafana for visualization dashboards
- Integrate Loki and Promtail for log aggregation
- Add separate analytics docker-compose configuration

CI/CD:
- Add GitHub Actions workflows for building and publishing Docker images
- Implement separate dev and production build pipelines
- Configure automated image publishing to registry

Documentation:
- Restructure documentation into organized docs/ directory
- Add comprehensive guides for telemetry, analytics, and local development
- Create transparency documentation for tracked events
- Add CI/CD and build configuration guides

Code improvements:
- Integrate telemetry hooks across all route handlers
- Add feature flags and configuration management
- Refactor test suite for analytics functionality
- Clean up root directory by moving docs and removing test artifacts

Breaking changes:
- Requires new environment variables for PostHog configuration
- Docker compose setup now supports analytics stack

Changes: 73 files changed, 955 insertions(+), 14126 deletions(-)
2025-10-20 14:38:57 +02:00

2.9 KiB

Session Close Error - Fixed

Errors Encountered

Error 1: DetachedInstanceError

sqlalchemy.orm.exc.DetachedInstanceError: Instance <User at 0x7e0c6e7fa450> is not bound to a Session; attribute refresh operation cannot proceed

Cause: Using db.session.close() detached ALL objects from the session, including the current_user object needed by Flask-Login.

Solution: Removed db.session.close() calls and kept only db.session.expire_all().

Error 2: NameError

NameError: name 'make_response' is not defined

Cause: make_response was not imported in the module imports.

Solution: Added make_response to the Flask imports at the top of each file.

Files Fixed

1. app/routes/kanban.py

  • Added make_response to imports
  • Removed db.session.close() (kept expire_all())

2. app/routes/tasks.py

  • Added make_response to imports
  • Removed inline from flask import make_response statements

3. app/routes/projects.py

  • Added make_response to imports
  • Removed inline from flask import make_response statements

Why This Works

The Right Way: expire_all()

# Force fresh data from database
db.session.expire_all()  # ✅ Marks all objects as stale
columns = KanbanColumn.get_all_columns()  # Fetches fresh data

# Prevent browser caching
response = render_template('kanban/columns.html', columns=columns)
resp = make_response(response)  # Works because make_response is imported
resp.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate, max-age=0'
return resp

What happens:

  1. expire_all() marks all cached objects as "needs refresh"
  2. Next time an object is accessed, SQLAlchemy fetches fresh data
  3. current_user stays bound to the session and works normally
  4. Fresh kanban columns are loaded from database

The Wrong Way: close()

# This was the problem:
db.session.expire_all()
db.session.close()  # ❌ Detaches ALL objects including current_user!
columns = KanbanColumn.get_all_columns()  # Works fine

# But later in base.html:
# {{ current_user.is_authenticated }}  # ❌ CRASHES! User detached!

Testing Checklist

  • No import errors
  • No session detachment errors
  • /kanban/columns loads without error
  • Create column works
  • Edit column works
  • Delete modal shows (Bootstrap modal)
  • Reorder columns works
  • Changes reflected with normal refresh
  • /tasks page works
  • /projects/<id> page works
  • current_user accessible in all templates

Summary

Problem: Too aggressive session management (closing session) broke Flask-Login.

Solution: Use expire_all() without close() to get fresh data while keeping session objects intact.

Result:

  • Fresh data loaded from database
  • No browser caching
  • Flask-Login still works
  • All pages render correctly
  • Changes reflected immediately

The application now works correctly! 🎉