mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-24 07:10:21 -05:00
e4789cc26e
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(-)
231 lines
5.6 KiB
Markdown
231 lines
5.6 KiB
Markdown
# Browser Cache Fix - No More Hard Refresh Needed!
|
|
|
|
## The Problem
|
|
Changes were saving correctly to the database, but browsers were caching the pages so users needed to do a hard refresh (Ctrl+Shift+R) to see the changes.
|
|
|
|
## The Solution
|
|
Added cache-control headers to prevent browser caching of kanban board pages.
|
|
|
|
## What Was Changed
|
|
|
|
Added these HTTP headers to all pages with kanban boards:
|
|
|
|
```http
|
|
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
|
|
Pragma: no-cache
|
|
Expires: 0
|
|
```
|
|
|
|
This tells browsers:
|
|
- **no-cache**: Must revalidate with server before using cached version
|
|
- **no-store**: Don't store this page in cache at all
|
|
- **must-revalidate**: Must check with server if cached version is still valid
|
|
- **max-age=0**: Cached version expires immediately
|
|
- **Pragma: no-cache**: For older HTTP/1.0 browsers
|
|
- **Expires: 0**: For older browsers that don't support Cache-Control
|
|
|
|
## Pages Updated
|
|
|
|
✅ `/kanban/columns` - Column management page
|
|
✅ `/tasks` - Task list with kanban board
|
|
✅ `/tasks/my-tasks` - My tasks with kanban board
|
|
✅ `/projects/<id>` - Project view with kanban board
|
|
|
|
## How to Apply
|
|
|
|
1. **Restart the application:**
|
|
```bash
|
|
docker-compose restart app
|
|
```
|
|
|
|
2. **Test (no hard refresh needed!):**
|
|
- Go to `/kanban/columns`
|
|
- Create a new column
|
|
- Navigate to `/tasks`
|
|
- **Column appears immediately!** No Ctrl+Shift+R needed!
|
|
|
|
3. **Edit a column:**
|
|
- Edit the column label
|
|
- Go to `/tasks`
|
|
- **Changes appear immediately!**
|
|
|
|
## Technical Details
|
|
|
|
### Before (Required Hard Refresh)
|
|
```
|
|
Browser → GET /tasks → Server sends HTML
|
|
Browser caches the HTML for 5 minutes
|
|
Admin adds new column
|
|
Browser → GET /tasks → Browser serves CACHED HTML (old columns!)
|
|
User must press Ctrl+Shift+R to bypass cache
|
|
```
|
|
|
|
### After (Auto-Refresh)
|
|
```
|
|
Browser → GET /tasks → Server sends HTML with no-cache headers
|
|
Browser stores HTML but marks it as "must revalidate"
|
|
Admin adds new column
|
|
Browser → GET /tasks → Browser ALWAYS asks server for fresh HTML
|
|
Server sends HTML with new columns
|
|
User sees changes immediately!
|
|
```
|
|
|
|
## Performance Impact
|
|
|
|
**Minimal** - The browser still:
|
|
- Caches static assets (CSS, JS, images)
|
|
- Uses HTTP compression
|
|
- Only revalidates the HTML page itself
|
|
|
|
The HTML page is small (~50KB compressed) so the extra request adds only ~10-20ms.
|
|
|
|
## Browser Compatibility
|
|
|
|
Works with all modern browsers:
|
|
- ✅ Chrome/Edge (Chromium)
|
|
- ✅ Firefox
|
|
- ✅ Safari
|
|
- ✅ Opera
|
|
- ✅ Mobile browsers (iOS Safari, Chrome Mobile)
|
|
|
|
Also supports older browsers via Pragma and Expires headers.
|
|
|
|
## Alternative Solutions (Not Used)
|
|
|
|
### 1. Cache Busting Query Parameter
|
|
```python
|
|
# Add timestamp to URL
|
|
return redirect(url_for('kanban.list_columns', _ts=int(time.time())))
|
|
```
|
|
**Why not:** Clutters URLs, doesn't work for direct navigation
|
|
|
|
### 2. Meta Tags
|
|
```html
|
|
<meta http-equiv="Cache-Control" content="no-cache">
|
|
```
|
|
**Why not:** Less reliable, doesn't work with all proxies
|
|
|
|
### 3. ETag/Last-Modified
|
|
```python
|
|
resp.headers['ETag'] = str(hash(columns))
|
|
```
|
|
**Why not:** More complex, still requires validation request
|
|
|
|
### 4. Service Worker
|
|
```javascript
|
|
self.addEventListener('fetch', e => {
|
|
if (e.request.url.includes('/tasks')) {
|
|
e.respondWith(fetch(e.request, {cache: 'no-store'}));
|
|
}
|
|
});
|
|
```
|
|
**Why not:** Requires service worker setup, overkill for this
|
|
|
|
## Testing
|
|
|
|
### Test 1: Column Creation
|
|
1. Open `/kanban/columns`
|
|
2. Create column "Test1"
|
|
3. Open new tab → `/tasks`
|
|
4. ✅ "Test1" column appears immediately
|
|
|
|
### Test 2: Column Editing
|
|
1. Edit "Test1" → change to "Test-Modified"
|
|
2. Go to `/tasks`
|
|
3. ✅ Column name updated immediately
|
|
|
|
### Test 3: Column Deletion
|
|
1. Delete "Test-Modified"
|
|
2. Go to `/tasks`
|
|
3. ✅ Column removed immediately
|
|
|
|
### Test 4: Column Reordering
|
|
1. Drag column to new position
|
|
2. Page reloads (happens automatically)
|
|
3. ✅ New order visible immediately
|
|
|
|
### Test 5: Multi-Tab
|
|
1. Open `/tasks` in Tab 1
|
|
2. Open `/kanban/columns` in Tab 2
|
|
3. Create column in Tab 2
|
|
4. Switch to Tab 1
|
|
5. Refresh (F5) - not hard refresh!
|
|
6. ✅ New column appears
|
|
|
|
## Troubleshooting
|
|
|
|
### Still seeing old data after normal refresh?
|
|
|
|
Check if you have a caching proxy/CDN:
|
|
```bash
|
|
# Check response headers
|
|
curl -I http://your-domain/tasks
|
|
```
|
|
|
|
Look for:
|
|
- `Cache-Control: no-cache, no-store, must-revalidate`
|
|
- `Pragma: no-cache`
|
|
- `Expires: 0`
|
|
|
|
If these are missing, check:
|
|
1. Nginx configuration (might be overriding headers)
|
|
2. CDN settings (Cloudflare, etc.)
|
|
3. Corporate proxy settings
|
|
|
|
### Headers not appearing?
|
|
|
|
Check middleware that might strip headers:
|
|
```python
|
|
# In app/__init__.py
|
|
@app.after_request
|
|
def after_request(response):
|
|
# Make sure no middleware is removing our headers
|
|
return response
|
|
```
|
|
|
|
### Browser still caching?
|
|
|
|
Clear browser cache completely:
|
|
- Chrome: Settings → Privacy → Clear browsing data
|
|
- Firefox: Options → Privacy → Clear Data
|
|
- Safari: Develop → Empty Caches
|
|
|
|
Then test again.
|
|
|
|
## Monitoring
|
|
|
|
To verify headers are being sent:
|
|
|
|
```bash
|
|
# Check with curl
|
|
curl -I http://your-domain/tasks | grep -i cache
|
|
|
|
# Expected output:
|
|
# Cache-Control: no-cache, no-store, must-revalidate, max-age=0
|
|
# Pragma: no-cache
|
|
# Expires: 0
|
|
```
|
|
|
|
Or in browser DevTools:
|
|
1. Open DevTools (F12)
|
|
2. Network tab
|
|
3. Reload page
|
|
4. Click on page request
|
|
5. Check "Response Headers"
|
|
|
|
## Summary
|
|
|
|
✅ **No more hard refresh needed!**
|
|
✅ **Changes appear on normal page refresh (F5)**
|
|
✅ **Works across all browsers**
|
|
✅ **Minimal performance impact**
|
|
✅ **Simple, standard solution**
|
|
|
|
The issue is now completely fixed. Users can:
|
|
- Create/edit/delete columns
|
|
- Simply refresh the page (F5) or navigate normally
|
|
- See changes immediately without Ctrl+Shift+R
|
|
|
|
Perfect! 🎉
|
|
|