🧙‍♂️ Transform LifeRPG into The Wizard's Grimoire - Production-Ready Application

 Major Features Added:
- Complete magical theming and rebranding from LifeRPG to The Wizard's Grimoire
- Production-grade React frontend with Tailwind CSS v4 and magical aesthetics
- Comprehensive analytics dashboard with Recharts integration (ScryingPortal)
- Push notifications system with PWA service worker support
- Drag & drop functionality using @dnd-kit for habit reordering
- Social features with friends system and leaderboards
- Performance optimization tools and monitoring
- Mobile app enhancement with PWA installation support

🏗️ Technical Infrastructure:
- Advanced service worker with offline support and background sync
- Zustand state management for scalable application state
- Production-ready UI component system with enhanced Button, Card, Input
- Progressive Web App (PWA) with manifest and app installation
- FastAPI backend with comprehensive API endpoints
- Docker containerization and CI/CD pipeline setup

📱 Progressive Web App Features:
- Offline functionality with intelligent caching
- Push notification support for habit reminders
- App installation on mobile and desktop platforms
- Background sync for offline data management
- Performance monitoring and optimization tools

🎨 User Experience:
- Magical wizard/grimoire theming throughout application
- Responsive design optimized for all device sizes
- Drag & drop habit management with smooth animations
- Interactive analytics with multiple chart types
- Social connectivity with friends and competitive features
- Comprehensive notification and performance settings

🔧 Developer Experience:
- Modern development stack with Vite and React
- Comprehensive testing setup and CI/CD pipelines
- Code quality tools with pre-commit hooks
- Docker development environment
- Detailed documentation and implementation guides

This represents a complete transformation from prototype to production-ready application with enterprise-grade features and magical user experience.
This commit is contained in:
TLimoges33
2025-08-30 17:32:42 +00:00
committed by GitHub
parent 00ad1bd8d4
commit 7fe4ae5365
270 changed files with 46366 additions and 7824 deletions
+53
View File
@@ -0,0 +1,53 @@
# LifeRPG Ops Runbook
This runbook summarizes common operational signals and actions.
## Key metrics and dashboards
- HTTP: request rate (`http_requests_total`), p95 latency (`http_request_duration_seconds`), in-progress gauge.
- Jobs: `jobs_processed_total{status}`.
- Integrations: `integration_sync_total{provider,result}`, `integration_sync_by_integration_total{integration_id,result}`.
- Backpressure: `sync_enqueue_skips_total{reason}`, `sync_queue_depth{provider}`, `sync_inflight{provider}`.
- Logs: structured JSON logs for requests and jobs; ship via Promtail to Loki.
Grafana dashboard: `ops/grafana-dashboard.json` (import into Grafana and configure `PROM_DS` and `LOKI_DS`).
## Common symptoms
1) High enqueue skips
- Symptom: `sync_enqueue_skips_total` rate > 0.2 for >10m.
- Likely causes: provider concurrency cap, duplicate enqueues (guard), or downstream slowness.
- Actions:
- Check `sync_inflight{provider}` vs cap (env `SYNC_MAX_CONCURRENCY_PER_PROVIDER`).
- Temporarily raise the cap if safe, or reduce scheduler cadence (`sync_interval_seconds`).
- Inspect job logs in Loki for adapter errors or rate limits.
2) Queue depth rising
- Symptom: `increase(sync_queue_depth[15m]) > 50`.
- Actions:
- Scale workers or increase per-provider cap cautiously.
- Pause non-critical providers by increasing intervals.
- Check external API health/rate limits.
3) Elevated request latency
- Symptom: p95 > 500ms sustained.
- Actions:
- Inspect recent deployments, DB CPU/IO, and external dependencies.
- Enable sampling/profiling; consider caching.
## Configuration
- Concurrency cap per provider: `SYNC_MAX_CONCURRENCY_PER_PROVIDER` (default 4).
- Default scheduler interval: `DEFAULT_SYNC_INTERVAL_SECONDS` (default 900s). Per-integration override: `integration.config.sync_interval_seconds`.
- Close mode: `INTEGRATION_CLOSE_MODE` (`archive` default; `delete` opt-in).
## On-call checklist
- Confirm alerts and correlate with Grafana panels.
- Review recent logs for `event=enqueued|start|success|fail` in Loki.
- Take one mitigating action at a time; document in the incident log.
## Playbooks
- Raise provider cap:
- Set `SYNC_MAX_CONCURRENCY_PER_PROVIDER` and restart worker.
- Slow the scheduler:
- PATCH integration config `{"sync_interval_seconds": <value>}` for noisy integrations.
- Toggle close policy:
- POST `/api/v1/admin/settings` `{ "integration_close_mode": "archive|delete" }`.
+336
View File
@@ -0,0 +1,336 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": null,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"legend": {
"displayMode": "list"
},
"tooltip": {
"mode": "single"
}
},
"targets": [
{
"expr": "sum by (method, path, status) (rate(http_requests_total[5m]))",
"legendFormat": "{{method}} {{path}} {{status}}"
}
],
"title": "HTTP Requests (rate)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"legend": {
"displayMode": "list"
},
"tooltip": {
"mode": "single"
}
},
"targets": [
{
"expr": "histogram_quantile(0.95, sum by (le, method, path) (rate(http_request_duration_seconds_bucket[5m])))",
"legendFormat": "p95 {{method}} {{path}}"
}
],
"title": "Request Latency p95",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"targets": [
{
"expr": "sum(http_requests_in_progress)",
"legendFormat": "in-progress"
}
],
"title": "Requests In-Progress",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"targets": [
{
"expr": "sum by (status) (rate(jobs_processed_total[5m]))",
"legendFormat": "{{status}}"
}
],
"title": "Jobs Processed (rate)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 16
},
"id": 5,
"targets": [
{
"expr": "sum by (provider, result) (rate(integration_sync_total[5m]))",
"legendFormat": "{{provider}} {{result}}"
}
],
"title": "Integration Syncs (rate)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 16
},
"id": 6,
"targets": [
{
"expr": "sum by (provider, verified) (rate(webhook_events_total[5m]))",
"legendFormat": "{{provider}} {{verified}}"
}
],
"title": "Webhook Events (rate)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 24
},
"id": 7,
"targets": [
{
"expr": "sum by (integration_id, result) (rate(integration_sync_by_integration_total[5m]))",
"legendFormat": "id={{integration_id}} {{result}}"
}
],
"title": "Integration Syncs by Integration (rate)",
"type": "timeseries"
},
{
"datasource": {
"type": "loki",
"uid": "LOKI_DS"
},
"gridPos": {
"h": 10,
"w": 24,
"x": 0,
"y": 32
},
"id": 8,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": true,
"showCommonLabels": false,
"showLabels": true,
"sortOrder": "Descending"
},
"targets": [
{
"expr": "{job=\"liferpg\"} |= `\"type\":\"job\"`",
"queryType": "range"
}
],
"title": "Job Logs (structured)",
"type": "logs"
},
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 12,
"x": 0,
"y": 42
},
"id": 9,
"targets": [
{
"expr": "sum by (reason) (rate(sync_enqueue_skips_total[5m]))",
"legendFormat": "skip {{reason}}"
}
],
"title": "Sync Enqueue Skips (rate)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 12,
"x": 12,
"y": 42
},
"id": 10,
"targets": [
{
"expr": "sum by (provider) (sync_queue_depth)",
"legendFormat": "depth {{provider}}"
}
],
"title": "Sync Queue Depth",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "PROM_DS"
},
"fieldConfig": {
"defaults": {},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 12,
"x": 0,
"y": 48
},
"id": 11,
"targets": [
{
"expr": "sum by (provider) (sync_inflight)",
"legendFormat": "inflight {{provider}}"
}
],
"title": "Sync In-Flight",
"type": "stat"
}
],
"schemaVersion": 38,
"style": "dark",
"tags": [
"liferpg"
],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timezone": "browser",
"title": "LifeRPG Backend",
"version": 1
}
+49
View File
@@ -0,0 +1,49 @@
groups:
- name: liferpg.rules
interval: 1m
rules:
- alert: HighEnqueueSkips
expr: sum(rate(sync_enqueue_skips_total[5m])) > 0.2
for: 10m
labels:
severity: warning
annotations:
summary: High rate of sync enqueue skips
description: Enqueue skips ({{ $value }}) may indicate provider caps or guard contention.
- alert: ProviderAtConcurrencyCap
expr: max_over_time(sync_inflight[15m]) >= on(provider) (sync_provider_cap)
for: 10m
labels:
severity: warning
annotations:
summary: Provider at concurrency cap
description: In-flight syncs have been at the configured cap for 10m.
- alert: QueueDepthGrowing
expr: increase(sync_queue_depth[15m]) > 50
for: 10m
labels:
severity: warning
annotations:
summary: Queue depth increasing
description: Sync queue depth increased by >50 over 15m. Investigate worker capacity or provider health.
- alert: RQQueueBacklog
expr: max_over_time(rq_queue_length[10m]) > 100
for: 10m
labels:
severity: warning
annotations:
summary: RQ queue backlog
description: RQ queue length has exceeded 100 for 10 minutes.
- alert: SlowSyncsP95
expr: |
histogram_quantile(0.95, sum by (le, provider) (rate(sync_job_duration_seconds_bucket[5m]))) > 30
for: 10m
labels:
severity: warning
annotations:
summary: Slow syncs p95 over 30s
description: The 95th percentile of sync job durations is above 30 seconds for 10 minutes.
+11
View File
@@ -0,0 +1,11 @@
global:
scrape_interval: 15s
scrape_configs:
- job_name: liferpg-backend
static_configs:
- targets: ["localhost:8000"]
labels:
service: backend
env: dev
metrics_path: /metrics
+27
View File
@@ -0,0 +1,27 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: liferpg
static_configs:
- targets:
- localhost
labels:
job: liferpg
host: ${HOSTNAME}
__path__: /var/log/liferpg/*.log
- job_name: liferpg-stdout
static_configs:
- targets:
- localhost
labels:
job: liferpg
host: ${HOSTNAME}
__path__: /var/lib/docker/containers/*/*-json.log