Skip to content

Latest commit

 

History

History
483 lines (421 loc) · 18.8 KB

File metadata and controls

483 lines (421 loc) · 18.8 KB

scribbl-py Development Plan

Completed

Phase 1: Project Setup

  • Project scaffolding (pyproject.toml, Makefile, CI workflows)
  • Pre-commit hooks, ruff, ty configuration
  • Documentation structure (Sphinx + shibuya)

Phase 2: Core API + Models

  • Domain models: Canvas, Stroke, Shape, Text, Point, ElementStyle
  • Type enums: ElementType, ShapeType
  • Storage layer: StorageProtocol, InMemoryStorage
  • Service layer: CanvasService
  • REST API: Canvas CRUD, Element CRUD
  • Litestar plugin: ScribblPlugin, ScribblConfig
  • Tests: 114 passing

Phase 3: WebSocket Real-time

  • WebSocket handler for canvas sessions (CanvasWebSocketHandler)
  • Connection manager for tracking users (ConnectionManager)
  • Broadcast element changes to connected clients
  • Cursor position sync
  • Conflict resolution strategy (last-write-wins with version tracking)
  • Message types: join, leave, element_add/update/delete, cursor_move
  • Tests: 137 passing

Phase 4: Database Persistence

  • SQLAlchemy models (CanvasModel, ElementModel with JSON columns)
  • Alembic migrations (001_initial_schema)
  • DatabaseStorage implementing StorageProtocol
  • [db] optional extra (advanced-alchemy, alembic, asyncpg)
  • Lazy imports to avoid errors when db extra not installed
  • Tests: 164 passing

Phase 5: Canvas Operations

  • Element layers with z-index ordering (z_index field on Element)
  • Z-ordering operations: bring_to_front, send_to_back, move_forward, move_backward
  • Command pattern for undo/redo (CommandHistory, CommandHistoryManager)
  • Command types: Add, Delete, Update, Move, Reorder, Group, Ungroup
  • Element grouping with Group element type and group_id field
  • Group operations: group_elements, ungroup_elements
  • Copy/paste elements with per-user clipboard
  • Database migration for z_index and group_id (002_add_z_index_and_group)
  • Tests: 207 passing

Phase 6: Export

  • ExportService for canvas rendering to multiple formats
  • Export canvas as JSON (dict/string)
  • Export canvas as SVG (strokes, shapes, text with full styling)
  • Export canvas as PNG (via cairosvg, optional [export] extra)
  • REST API endpoints: /export/json, /export/svg, /export/png
  • Tests: 237 passing

API Endpoints

REST API

Method Endpoint Description
POST /api/canvases Create canvas
GET /api/canvases List canvases
GET /api/canvases/{id} Get canvas with elements
PATCH /api/canvases/{id} Update canvas
DELETE /api/canvases/{id} Delete canvas
GET /api/canvases/{id}/elements List elements
POST /api/canvases/{id}/elements/strokes Add stroke
POST /api/canvases/{id}/elements/shapes Add shape
POST /api/canvases/{id}/elements/texts Add text
DELETE /api/canvases/{id}/elements/{eid} Delete element
GET /api/canvases/{id}/export/json Export as JSON
GET /api/canvases/{id}/export/svg Export as SVG
GET /api/canvases/{id}/export/png Export as PNG

WebSocket API

Endpoint Description
ws://.../ws/canvas/{id} Real-time canvas collaboration

Message Types (Client -> Server):

  • join - Join canvas session with user_id/user_name
  • element_add - Add stroke/shape/text element
  • element_update - Update element properties
  • element_delete - Delete an element
  • cursor_move - Update cursor position

Message Types (Server -> Client):

  • sync - Full canvas state on join
  • user_joined / user_left - User presence
  • element_added / element_updated / element_deleted - Element changes
  • cursor_moved - Other users' cursor positions
  • error - Error responses

Next Up

Phase 10: Persistence & Deployment ✅

  • Docker deployment (Dockerfile + docker-compose.yml)
  • SQLite storage backend for persistence
    • Create SQLite storage implementation (storage/db/auth_storage.py)
    • User, Session, UserStats models (storage/db/auth_models.py)
    • Database setup and session factory (storage/db/setup.py)
    • Wire up DATABASE_URL environment variable
  • Wire up stats recording to game events
    • TelemetryService with tracking for connections, games, rounds, guesses, drawings
    • Room created/closed tracking
    • Game started/ended tracking with winner
    • Round started tracking with drawer
    • Guess tracking (correct/wrong, time)
    • Drawing completed tracking
    • Player join/leave tracking
  • Telemetry & Analytics
    • Stats API endpoint (/stats)
    • Optional Sentry integration (SENTRY_DSN env var)
    • Optional PostHog integration (POSTHOG_API_KEY env var)
    • Custom callback support for external integrations

Phase 11: Developer Experience & Tooling ✅

  • Swap to Scalar default + Swagger OpenAPI plugin
    • ScalarRenderPlugin at /schema/ (primary)
    • SwaggerRenderPlugin at /schema/swagger (secondary)
    • Custom Scalar theme CSS (frontend/dist/css/scalar-theme.css)
  • Database CLI commands via advanced-alchemy SQLAlchemyPlugin
    • litestar database upgrade - Run migrations
    • litestar database downgrade - Rollback migrations
    • litestar database make-migrations - Autogenerate migrations from models
    • litestar database show-current-revision - Check current state
  • Custom query CLI commands (litestar query)
    • litestar query users - List users with search
    • litestar query stats - Show user statistics
    • litestar query sessions - List sessions (with --active flag)
    • litestar query leaderboard - Show leaderboard (by wins/games/accuracy)
    • litestar query tables - List all tables with row counts
    • litestar query sql "SELECT ..." - Execute raw SELECT queries
  • Environment configuration
    • .env.example with all environment variables documented
    • LITESTAR_APP for CLI discovery
    • DATABASE_URL support in migrations
  • Database migrations
    • 001_initial_schema - Canvas and Element tables
    • 002_add_z_index_and_group - Z-index and grouping (SQLite batch mode)
    • 003_auth_tables - Users, UserStats, Sessions tables

Phase 12: Production Hardening ✅

  • Request/response validation error handling
    • Structured error responses with ErrorResponse dataclass
    • Per-field validation error details
    • Exception handlers for all custom exceptions
    • HTTP exception handler with appropriate error codes
  • Health check endpoints (/health, /ready)
    • /health - Liveness probe with component health status
    • /ready - Readiness probe checking dependencies
    • Database health check with latency measurement
  • Structured logging with correlation IDs
    • CorrelationIdMiddleware for request tracking
    • RequestLoggingMiddleware for request/response logging
    • X-Correlation-ID header propagation
    • Structlog integration with context variables
    • JSON logging option for production
  • Rate limiting
    • RateLimitConfig using Litestar's built-in middleware
    • Configurable via environment variables (RATE_LIMIT_*)
    • Default: 100 requests/minute, excludes health checks
    • Returns 429 Too Many Requests with RateLimit-* headers
  • Task queue with Huey (SQLite backend)
    • SqliteHuey configuration with environment variables (TASK_QUEUE_*)
    • Periodic tasks: session cleanup, weekly stats reset, canvas cleanup, telemetry aggregation
    • CLI commands: litestar tasks run, litestar tasks status, litestar tasks list
    • Manual task runners: cleanup-sessions, cleanup-canvases, reset-weekly
    • [tasks] optional extra for Huey dependency

Phase 9.2: Collaborative Mode ✅

Free-form collaborative whiteboard where everyone draws simultaneously.

Features:

  • All users can draw at same time
  • Real-time cursor positions
  • Layer management (visibility, lock, reorder, delete)
  • Export to PNG/SVG

Future Phases

Phase 13: Canvas Editor Enhancements

Advanced drawing tools and capabilities.

  • Image Upload & Manipulation (upload, resize, rotate, crop, opacity)
  • Advanced Shape Tools (polygon, star, arrows, speech bubbles, Bezier curves)
  • Text Formatting (font selection, bold/italic/underline, alignment, text-along-path)
  • Layer opacity sliders
  • Blend modes for layers
  • Infinite canvas with pan/zoom

Phase 14: Additional Game Modes

New Canvas Clash variations.

  • Speed Draw - Rapid-fire 15-30 second rounds
  • Blind Contour - Can't see strokes until time's up
  • Telephone Game - Alternating draw/guess, each sees only previous entry
  • Multiplayer Canvas - Everyone draws simultaneously, layer per user, time-lapse export

Phase 15: Social Features

Community and engagement features.

  • User Profiles (public gallery, achievements, badges)
  • Drawing Gallery (browse, like, comment, share community art)
  • Drawing Challenges (daily/weekly prompts with voting)
  • Following/followers system
  • Sticky notes and annotations for collaborative mode

Phase 16: Print & Merchandise

Monetization and physical products.

  • Image to T-Shirt (print-on-demand integration: Printful, Printify)
  • Sticker Sheets (print-ready PDF with cut lines)
  • Canvas Prints (high-res export, standard print sizes)
  • Design marketplace
  • NFT Minting (optional blockchain integration)

Phase 17: Mobile & Desktop Apps

Native applications.

  • Progressive Web App (PWA) with offline support
  • Native iOS app with Apple Pencil support
  • Native Android app with stylus support
  • Desktop apps (Electron or Tauri)
  • Tablet-optimized interface

Phase 18: API & Integrations

Third-party connectivity.

  • Webhooks (canvas updates, game events, Discord/Slack integration)
  • Public API with OAuth2 and rate limiting
  • Embed Widget (customizable canvas for external sites)
  • AI Assistance (auto-complete strokes, style transfer, background removal, upscaling)
  • Video/voice chat integration

Phase 19: Infrastructure Scaling

Production-grade deployment.

  • Redis session storage for horizontal scaling
  • WebSocket message broker (Redis Pub/Sub) for multi-instance
  • CDN integration for static assets
  • S3/GCS storage backend for large canvases
  • Kubernetes Helm chart
  • Terraform modules for cloud deployment

Completed

Phase 9.1: CanvasClash Mode ✅

Pictionary-style drawing game - fully implemented with:

  • Game lobby with room codes, public/private rooms
  • Round system with drawer rotation, word selection, timer
  • Drawing tools: pen, shapes, line, fill, eraser, 24 colors, brush sizes
  • Chat system with guessing, close guess hints, correct guess celebrations
  • Spectator mode, custom word lists, content moderation
  • All UI components: lobby, game screen, word selection, round end, final scoreboard

Phase 8: Auth & Permissions ✅

  • OAuth2 authentication (Google, Discord, GitHub)
  • User profiles with avatars and stats
  • Global leaderboards (wins, fastest, drawer, games played)
  • Room permissions (kick, ban, transfer host)
  • 38 auth + permissions tests passing

Phase 7: Bug Fixes & Polish ✅

  • WebSocket reconnection with exponential backoff
  • Real-time stroke streaming (no delay until mouse release)
  • All drawing tools working (shapes, text, eraser, fill)
  • Undo/redo functionality
  • PNG export with Pillow (no system dependencies)

Phase 8: Frontend UI

Modern, interactive frontend using HTMX + Tailwind CSS + DaisyUI with Bun for build tooling.

8.1 Project Structure & Build Setup

  • Create frontend/ directory structure:
    frontend/
    ├── package.json          # Bun package manifest
    ├── bunfig.toml           # Bun configuration
    ├── tailwind.config.js    # Tailwind + DaisyUI config
    ├── src/
    │   ├── css/
    │   │   └── main.css      # Tailwind directives + custom styles
    │   └── js/
    │       └── main.js       # HTMX extensions, Alpine.js, custom JS
    └── dist/                 # Built assets (gitignored)
    
  • Initialize Bun project: bun init
  • Install dependencies:
    bun add tailwindcss @tailwindcss/cli daisyui
    bun add -d bun-plugin-tailwind
  • Configure tailwind.config.js with DaisyUI plugin and scribbl theme
  • Add build scripts to package.json:
    • bun run build - Production build
    • bun run dev - Watch mode for development
  • Add [ui] optional extra to pyproject.toml

8.2 Litestar Integration

  • Install litestar-htmx: uv add litestar-htmx
  • Configure HTMXPlugin in Litestar app
  • Set up Jinja2 template engine with JinjaTemplateEngine
  • Configure static files router for built assets:
    from litestar.static_files import create_static_files_router
    
    static_router = create_static_files_router(
        path="/static",
        directories=["frontend/dist"]
    )
  • Create template directory: src/scribbl/templates/
  • Add HTMXRequest type for HTMX-aware request handling

8.3 Base Templates & Layout

  • Create base.html template with:
    • DaisyUI theme support (light/dark toggle)
    • HTMX script include (<script src="https://unpkg.com/htmx.org@2"></script>)
    • Alpine.js for client-side interactivity
    • Tailwind CSS built stylesheet
    • Navigation component with DaisyUI navbar
    • Flash message/toast container for HTMX responses
  • Create partials/ directory for HTMX partial templates
  • Implement DaisyUI theme switcher (localStorage persistence)

8.4 Canvas List & Dashboard Views

  • GET / - Dashboard/landing page
    • Recent canvases grid (DaisyUI cards)
    • Create new canvas button
    • Quick stats (total canvases, recent activity)
  • GET /canvases - Canvas list view
    • Responsive grid layout with DaisyUI cards
    • Search/filter with HTMX (hx-get, hx-trigger="keyup changed delay:300ms")
    • Pagination with HTMX (hx-get, hx-target, hx-swap="outerHTML")
    • Delete canvas with confirmation modal
  • Partial templates for HTMX responses:
    • partials/canvas_card.html - Single canvas card
    • partials/canvas_list.html - Canvas list container
    • partials/canvas_grid.html - Grid of canvas cards

8.5 Canvas Editor View

  • GET /canvases/{id}/edit - Full canvas editor page
  • Canvas toolbar component (DaisyUI button groups):
    • Tool selection (pen, shapes, text, eraser)
    • Color picker
    • Stroke width slider
    • Undo/redo buttons
    • Layer controls
  • Canvas area with HTML5 <canvas> element
  • Side panel for:
    • Element properties (HTMX updates)
    • Layer list with drag-to-reorder
    • Export options
  • WebSocket connection indicator (DaisyUI badge)
  • User presence indicators (avatars, cursor positions)

8.6 HTMX-Powered Interactions

  • Canvas CRUD with HTMX:
    • Create: hx-post="/api/canvases" with form
    • Update: hx-patch="/api/canvases/{id}" inline editing
    • Delete: hx-delete with hx-confirm or DaisyUI modal
  • Element operations via HTMX:
    • Add element: POST with HTMXTemplate response
    • Update element: PATCH with partial swap
    • Delete element: DELETE with hx-swap="delete"
  • Use litestar-htmx response classes:
    from litestar_htmx.response import HTMXTemplate, Reswap, Retarget, TriggerEvent
    
    @get("/canvases/{id}/elements")
    async def get_elements(id: UUID) -> Template:
        return HTMXTemplate(
            template_name="partials/element_list.html",
            context={"elements": elements},
            trigger_event="elementsLoaded"
        )
  • Implement HXLocation for client-side redirects without full reload
  • Use TriggerEvent for toast notifications

8.7 Real-time Features (WebSocket + HTMX)

  • WebSocket connection management with reconnection
  • HTMX WebSocket extension for real-time updates:
    <div hx-ext="ws" ws-connect="/ws/canvas/{id}">
      <div id="canvas-elements" hx-swap-oob="true">
        <!-- Elements updated via WebSocket -->
      </div>
    </div>
  • Cursor position broadcasting
  • Live element updates from other users
  • Connection status indicator with DaisyUI badge states

8.8 UI Components (DaisyUI)

  • Navigation: navbar, menu, breadcrumbs
  • Canvas cards: card, card-body, card-actions
  • Forms: input, select, range, toggle
  • Buttons: btn, btn-primary, btn-group
  • Feedback: toast, alert, loading, progress
  • Modals: modal for confirmations, settings
  • Drawers: drawer for mobile navigation
  • Tooltips: tooltip for toolbar hints
  • Theme: Custom scribbl theme extending DaisyUI

8.9 Frontend Controller

  • Create UIController class:
    from litestar import Controller, get
    from litestar_htmx import HTMXRequest
    from litestar.response import Template
    
    class UIController(Controller):
        path = "/ui"
    
        @get("/")
        async def index(self, request: HTMXRequest) -> Template:
            return Template("index.html", context={...})
    
        @get("/canvases")
        async def canvas_list(self, request: HTMXRequest) -> Template:
            if request.htmx:
                return HTMXTemplate("partials/canvas_list.html", ...)
            return Template("canvas_list.html", ...)
  • Route handlers for all UI pages
  • HTMX-aware responses (full page vs partial)

8.10 Development Workflow

  • Makefile targets:
    • make frontend-install - Install frontend dependencies with Bun
    • make frontend-build - Build production assets
    • make frontend-dev - Watch mode for development
    • make serve-dev - Run Litestar with frontend watch
  • Hot reload setup for templates
  • Browser-sync or similar for CSS changes

Dependencies

# pyproject.toml additions
[project.optional-dependencies]
ui = [
    "litestar[jinja]",
    "litestar-htmx>=0.4.0",
]
// frontend/package.json
{
  "dependencies": {
    "tailwindcss": "^4.0",
    "daisyui": "^5.0"
  },
  "devDependencies": {
    "bun-plugin-tailwind": "^0.1"
  }
}

Reference Patterns

  • litestar-workflows: Tailwind CDN + Alpine.js base template pattern
  • litestar-pydotorg: DaisyUI theming, Lucide icons, theme persistence
  • litestar-htmx: HTMXPlugin, HTMXRequest, HTMXTemplate responses

Quick Start

make dev              # Install Python dependencies
make frontend-install # Install frontend dependencies (Bun)
make frontend-build   # Build frontend assets
make serve            # Run app at http://127.0.0.1:8000 (includes UI)
make serve-dev        # Run with hot reload (run make frontend-dev in another terminal)
make serve-api        # Run API only (no UI)
make lint             # Run linters
make ci               # Run all CI checks