# CLAUDE.md - Public Web Frontend ## Service Overview **Public Web Frontend** for Code of Conquest - Browser-based UI using Flask + Jinja2 + HTMX. **Tech Stack:** Flask + Jinja2 + HTMX + Vanilla CSS **Port:** 5001 (development), 8080 (production) **Location:** `/public_web` --- ## Architecture Role This web frontend is a **thin UI layer** that makes HTTP requests to the API backend: - ✅ Render HTML templates (Jinja2) - ✅ Form validation (UI only) - ✅ Make HTTP requests to API backend - ✅ Display API responses - ✅ Handle user input **What this service does NOT do:** - ❌ No business logic (all in `/api`) - ❌ No direct database access (use API) - ❌ No direct Appwrite calls (use API) - ❌ No game mechanics calculations (use API) **Communication:** ``` User Browser → Public Web (views) → HTTP Request → API Backend ↑ ↓ ←─────────── HTTP Response ─────────┘ ``` --- ## Documentation Index **Web Frontend Documentation:** - **[README.md](README.md)** - Setup and usage guide - **[docs/TEMPLATES.md](docs/TEMPLATES.md)** - Template structure and conventions - **[docs/HTMX_PATTERNS.md](docs/HTMX_PATTERNS.md)** - HTMX integration patterns - **[docs/TESTING.md](docs/TESTING.md)** - Manual testing guide - **[docs/MULTIPLAYER.md](docs/MULTIPLAYER.md)** - Multiplayer UI implementation **Project-Wide Documentation:** - **[../docs/ARCHITECTURE.md](../docs/ARCHITECTURE.md)** - System architecture overview - **[../api/docs/API_REFERENCE.md](../api/docs/API_REFERENCE.md)** - API endpoints to call - **[../docs/DEPLOYMENT.md](../docs/DEPLOYMENT.md)** - Deployment guide - **[../docs/WEB_VS_CLIENT_SYSTEMS.md](../docs/WEB_VS_CLIENT_SYSTEMS.md)** - Feature distribution between frontends **Documentation Guidelines:** - ✅ Place all public_web service documentation in `/public_web/docs/` - ✅ Each microservice maintains its own documentation - ❌ Do NOT add public_web-specific docs to `/docs/` (main repo docs are for cross-service architecture only) --- ## Development Guidelines ### Project Structure ``` public_web/ ├── app/ # Application code │ ├── views/ # View blueprints (Flask routes) │ └── utils/ # Utilities (logging, auth helpers, API client) ├── templates/ # Jinja2 HTML templates │ ├── auth/ # Authentication pages │ ├── character/ # Character pages │ ├── errors/ # Error pages (404, 500) │ └── base.html # Base template ├── static/ # CSS, JS, images │ └── css/ # Stylesheets ├── docs/ # Service-specific documentation ├── config/ # Configuration files └── README.md # Setup and usage guide ``` ### Coding Standards **Style & Structure** - Prefer longer, explicit code over compact one-liners - Always include docstrings for functions/classes + inline comments - Strong typing for view functions (type hints) - Keep views simple (delegate to API) **Templates & UI** - Don't mix large HTML/CSS blocks in Python code - Use Jinja2 templates for all HTML rendering - Clean CSS, minimal inline styles - Readable template logic (avoid complex Python in templates) - Use HTMX for dynamic interactions **Logging** - Use structlog (pip package) - Setup logging at app start: `logger = structlog.get_logger(__file__)` **Preferred Pip Packages** - Web Server: Flask - Templates: Jinja2 - HTTP Client: Requests - Logging: Structlog ### View Development Standards **View Functions (Flask Routes):** ```python from flask import Blueprint, render_template, request, redirect, url_for import requests from app.config import load_config character_bp = Blueprint('character', __name__, url_prefix='/characters') @character_bp.route('/') def list_characters(): """ Display list of user's characters. Makes HTTP request to API backend to fetch character data. """ config = load_config() # Make API request response = requests.get( f"{config.api.base_url}/api/v1/characters", timeout=config.api.timeout ) if response.status_code == 200: data = response.json() characters = data.get('result', []) return render_template('character/list.html', characters=characters) else: # Handle error return render_template('error.html', message="Failed to load characters"), 500 ``` **DO:** - ✅ Make HTTP requests to API backend - ✅ Pass data to templates - ✅ Handle errors gracefully - ✅ Validate form inputs (UI validation only) - ✅ Redirect to appropriate pages - ✅ Use flash messages for user feedback **DON'T:** - ❌ No business logic in views - ❌ No direct database access - ❌ No game mechanics calculations - ❌ No complex data transformations (keep it simple) ### Template Best Practices **Base Template (`templates/base.html`):** ```html {% block title %}Code of Conquest{% endblock %}
{% include 'components/navbar.html' %}
{% block content %}{% endblock %}
``` **Child Template:** ```html {% extends "base.html" %} {% block title %}Characters - Code of Conquest{% endblock %} {% block content %}

Your Characters

{% for character in characters %}

{{ character.name }}

{{ character.class_name }} - Level {{ character.level }}

{% endfor %}
{% endblock %} ``` **HTMX Usage:** ```html
``` ### CSS Standards **Organization:** - Use BEM naming convention (Block Element Modifier) - Group related styles together - Use CSS variables for colors/spacing - Mobile-first responsive design **Example:** ```css :root { --color-primary: #8b5cf6; --color-bg: #1a1a1a; --color-text: #e5e7eb; --spacing-unit: 1rem; } .character-card { background: var(--color-bg); color: var(--color-text); padding: calc(var(--spacing-unit) * 2); border-radius: 8px; } .character-card__title { font-size: 1.5rem; margin-bottom: var(--spacing-unit); } .character-card--highlighted { border: 2px solid var(--color-primary); } ``` ### Configuration - Environment-specific configs in `/config/*.yaml` - `development.yaml` - Local dev settings (API URL: http://localhost:5000) - `production.yaml` - Production settings (API URL from env var) - `.env` for secrets (never committed) - Typed config loaders using dataclasses **Configuration Structure:** ```yaml # config/development.yaml api: base_url: "http://localhost:5000" timeout: 30 verify_ssl: false server: host: "0.0.0.0" port: 5001 workers: 1 session: lifetime_hours: 24 cookie_secure: false cookie_httponly: true ``` ### Error Handling **View Error Handling:** ```python @character_bp.route('/') def character_detail(character_id): """Display character details.""" config = load_config() try: response = requests.get( f"{config.api.base_url}/api/v1/characters/{character_id}", timeout=config.api.timeout ) response.raise_for_status() data = response.json() character = data.get('result') return render_template('character/detail.html', character=character) except requests.exceptions.Timeout: logger.error("API timeout", character_id=character_id) return render_template('error.html', message="Request timed out"), 504 except requests.exceptions.HTTPError as e: if e.response.status_code == 404: return render_template('error.html', message="Character not found"), 404 logger.error("API error", status=e.response.status_code) return render_template('error.html', message="An error occurred"), 500 except Exception as e: logger.exception("Unexpected error", character_id=character_id) return render_template('error.html', message="An unexpected error occurred"), 500 ``` ### Dependency Management - Use `requirements.txt` in `/public_web` directory - Minimal dependencies (Flask, Jinja2, requests, structlog) - Use virtual environment: `python3 -m venv venv` - Activate venv before running: `source venv/bin/activate` ### Testing Standards **Manual Testing:** - Use the checklist in README.md - Test all user flows: - [ ] Login flow - [ ] Registration flow - [ ] Character creation wizard (all 4 steps) - [ ] Character list and detail views - [ ] Logout - [ ] Error handling **Browser Testing:** - Test in Chrome, Firefox, Safari - Test mobile responsive design - Test HTMX interactions --- ## Architecture Status ✅ **COMPLETE:** All views use the `APIClient` class for HTTP requests to the API backend. **What's Implemented:** - All views use `get_api_client()` from `app/utils/api_client.py` - Typed error handling with `APIError`, `APINotFoundError`, `APITimeoutError`, `APIAuthenticationError` - Session cookie forwarding for authentication - Proper JSON serialization/deserialization **Minor Improvements (Optional):** - Auth decorator could re-validate expired API sessions - Origin/class validation could use single-item lookups instead of fetching full lists --- ## Workflow for Web Frontend Development When implementing new pages: 1. **Design the page** - Sketch layout, user flow 2. **Create template** - Add Jinja2 template in `/templates` 3. **Create view** - Add Flask route in `/app/views` 4. **Make API calls** - Use requests library to call API backend 5. **Handle errors** - Graceful error handling with user feedback 6. **Add styles** - Update CSS in `/static/css` 7. **Test manually** - Check all user flows **Example Flow:** ```bash # 1. Create template # templates/quest/list.html # 2. Create view # app/views/quest_views.py @quest_bp.route('/') def list_quests(): # Make API request response = requests.get(f"{api_url}/api/v1/quests") quests = response.json()['result'] return render_template('quest/list.html', quests=quests) # 3. Register blueprint # app/__init__.py from .views.quest_views import quest_bp app.register_blueprint(quest_bp) # 4. Add styles # static/css/quest.css # 5. Test in browser # http://localhost:5001/quests ``` --- ## Running the Web Frontend ### Development **Prerequisites:** - Python 3.11+ - API backend running at http://localhost:5000 **Setup:** ```bash cd public_web python3 -m venv venv source venv/bin/activate pip install -r requirements.txt cp .env.example .env # Edit .env with your settings ``` **Run Development Server:** ```bash source venv/bin/activate export FLASK_ENV=development python wsgi.py # → http://localhost:5001 ``` ### Production **Run with Gunicorn:** ```bash gunicorn --bind 0.0.0.0:8080 --workers 4 wsgi:app ``` **Environment Variables:** ``` FLASK_ENV=production SECRET_KEY=... API_BASE_URL=https://api.codeofconquest.com ``` --- ## Git Standards **Commit Messages:** - Use conventional commit format: `feat:`, `fix:`, `docs:`, `style:`, etc. - Examples: - `feat(web): add quest list page` - `fix(views): handle API timeout errors` - `style(css): improve character card layout` **Branch Strategy:** - Branch off `dev` for features - Merge back to `dev` for testing - Promote to `master` for production --- ## Notes for Claude Code When working on the web frontend: 1. **Thin client only** - No business logic, just UI 2. **Always call API** - Use HTTP requests for all data operations 3. **Handle errors gracefully** - Show user-friendly error messages 4. **Keep templates clean** - Avoid complex logic in Jinja2 5. **Mobile responsive** - Design for all screen sizes 6. **HTMX for interactivity** - Use HTMX instead of heavy JavaScript 7. **Document refactoring needs** - Note any technical debt you encounter **Remember:** - This is a thin client - all logic lives in the API backend - The API serves multiple frontends (this web UI and Godot client) - Security validation happens in the API, but do basic UI validation for UX - Keep it simple - complicated logic belongs in the API