🧙‍♂️ 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
@@ -0,0 +1,32 @@
"""add integration item map with unique constraint
Revision ID: 0001_add_integration_item_map
Revises:
Create Date: 2025-08-28 00:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '0001_add_integration_item_map'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
'integration_item_map',
sa.Column('id', sa.Integer(), primary_key=True),
sa.Column('integration_id', sa.Integer(), nullable=False),
sa.Column('external_id', sa.String(), nullable=False),
sa.Column('entity_type', sa.String(), nullable=False),
sa.Column('entity_id', sa.Integer(), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP')),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP')),
sa.UniqueConstraint('integration_id', 'external_id', 'entity_type', name='uq_integration_item'),
)
def downgrade():
op.drop_table('integration_item_map')
@@ -0,0 +1,25 @@
"""add status/due_date/labels to habit
Revision ID: 0002_add_habit_fields
Revises: 0001_add_integration_item_map
Create Date: 2025-08-28 00:10:00.000000
"""
from alembic import op
import sqlalchemy as sa
revision = '0002_add_habit_fields'
down_revision = '0001_add_integration_item_map'
branch_labels = None
depends_on = None
def upgrade():
op.add_column('habits', sa.Column('status', sa.String(), server_default='active'))
op.add_column('habits', sa.Column('due_date', sa.DateTime(), nullable=True))
op.add_column('habits', sa.Column('labels', sa.Text(), nullable=True))
def downgrade():
op.drop_column('habits', 'labels')
op.drop_column('habits', 'due_date')
op.drop_column('habits', 'status')
@@ -0,0 +1,33 @@
"""add public_tokens table
Revision ID: 0004_add_public_tokens
Revises: 0002_add_habit_fields
Create Date: 2025-08-28 00:30:00.000000
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '0004_add_public_tokens'
down_revision = '0002_add_habit_fields'
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
'public_tokens',
sa.Column('id', sa.Integer(), primary_key=True),
sa.Column('user_id', sa.Integer(), sa.ForeignKey('users.id'), nullable=False),
sa.Column('name', sa.String(), nullable=False),
sa.Column('scope', sa.String(), server_default='read:widgets'),
sa.Column('token_hash', sa.String(), nullable=False, unique=True),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP')),
sa.Column('last_used_at', sa.DateTime(), nullable=True),
)
def downgrade():
op.drop_table('public_tokens')
@@ -0,0 +1,32 @@
"""add oidc_login_state table
Revision ID: 0005_add_oidc_login_state
Revises: 0004_add_public_tokens
Create Date: 2025-08-28 00:40:00.000000
"""
from alembic import op
import sqlalchemy as sa
revision = '0005_add_oidc_login_state'
down_revision = '0004_add_public_tokens'
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
'oidc_login_state',
sa.Column('id', sa.Integer(), primary_key=True),
sa.Column('state', sa.String(), unique=True, nullable=False),
sa.Column('provider', sa.String(), nullable=False),
sa.Column('code_verifier', sa.String(), nullable=False),
sa.Column('redirect_to', sa.String(), nullable=True),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP')),
sa.Column('expires_at', sa.DateTime(), nullable=True),
)
def downgrade():
op.drop_table('oidc_login_state')
@@ -0,0 +1,27 @@
"""add totp fields to users
Revision ID: 0006_add_totp_fields
Revises: 0005_add_oidc_login_state
Create Date: 2025-08-28 01:05:00.000000
"""
from alembic import op
import sqlalchemy as sa
revision = '0006_add_totp_fields'
down_revision = '0005_add_oidc_login_state'
branch_labels = None
depends_on = None
def upgrade():
op.add_column('users', sa.Column('totp_secret', sa.String(), nullable=True))
op.add_column('users', sa.Column('totp_enabled', sa.Integer(), server_default='0'))
op.add_column('users', sa.Column('recovery_codes', sa.Text(), nullable=True))
def downgrade():
op.drop_column('users', 'recovery_codes')
op.drop_column('users', 'totp_enabled')
op.drop_column('users', 'totp_secret')