Skip to content

Brands

The page at /admin/brands manages brand identity rows: name, primary and secondary hex colors, and an optional logo file.

Data source

The admin page is a thin HTML shell. Alpine.js loads brands via GET /api/brands (optional q search) and saves with multipart POST /api/brands or PATCH /api/brands/{brand_id}. Deletes use DELETE /api/brands/{brand_id}.

This is database configuration. Logos are objects in AWS_S3_DEFAULT_BUCKET at brands/<brand_id>/<filename>. That prefix is publicly readable (anonymous GetObject); list/get responses include a stable public logo_url for display.

Fields

Field Column / storage Notes
Name name Unique, whitespace trimmed
Primary color primary_color #RRGGBB (stored uppercase)
Secondary color secondary_color #RRGGBB (stored uppercase)
Logo logo_filename + S3 object png / jpeg / svg / webp, max 2 MiB

Each field label has a ? help modal.

Workflow

  1. Open Manage → Brands. Brand name labels elsewhere in admin (match cards, Play/History sponsor pills, Brand Sponsorships, match details) deep-link here as /admin/brands?q=<name> and prefill Search.
  2. Use Search to call GET /api/brands?q=… (debounced). Matches name, hex color, logo filename, or id (case-insensitive). Click Name, Primary, or Secondary column headers to sort the loaded results (click again to reverse). Choose Per page (10 / 25 / 50 / 100; default 25) and use Previous/Next to page through results.
  3. New Brand or Edit opens a modal; set name, colors, and optional logo.
  4. Save sends one multipart request (metadata + optional file).
  5. On edit, Remove current logo clears the S3 object and logo_filename.
  6. Delete removes the row and any logo object.

Code map

Concern Location
REST CRUD GET/POST/PATCH/DELETE /api/brands, src/api/routes/brands.py
Ops + schemas src/lib/brands/
Model src/lib/db/models/brand.py
Admin HTML shell src/api/admin/routes/brands.py
Template src/api/admin/templates/brands/index.jinja2
Alpine app src/api/admin/static/js/brands_app.js
CSS src/api/admin/static/css/brands.css
Tests src/api/tests/admin/test_brands.py, src/api/tests/test_brands_api.py

Common failures

  • Duplicate name (409): another brand already uses that name.
  • Invalid color (422): must be # + six hex digits.
  • Invalid logo (400): wrong MIME type, empty file, or over 2 MiB.
  • S3 not configured (503): AWS_S3_DEFAULT_BUCKET unset when uploading, clearing, or deleting a logo.