This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Kiosk Show Replacement is a self-hosted digital signage solution with a Flask backend and React frontend admin interface. It serves as a replacement for the defunct kiosk.show service.
Note: This file documents local development setup. Local Python/Poetry installation is only supported for development purposes. For production deployments, Docker is the only supported method. See
docs/deployment.rst.
Use poetry run -- prefix to run commands in the Poetry environment. The -- after run prevents poetry from interpreting nox arguments (like -s) as its own. Do not use eval $(poetry env activate).
# Format code (always run before lint)
poetry run -- nox -s format
# Lint code
poetry run -- nox -s lint
# Run unit tests
poetry run -- nox -s test-3.14
# Run a single test file (note the second -- before the file path)
poetry run -- nox -s test-3.14 -- tests/unit/test_specific.py
# Run a single test function
poetry run -- nox -s test-3.14 -- tests/unit/test_file.py::test_function_name
# Type checking
poetry run -- nox -s type_check
# Integration tests (React + Flask with Playwright)
poetry run -- nox -s test-integrationcd frontend
# Development server with hot reload
npm run dev
# Build for production
npm run build
# Run tests
npm run test:run
# Type checking
npm run type-check
# Lint
npm run lint# 1. Install Python dependencies (if not already done)
poetry install
# 2. Install frontend dependencies
cd frontend && npm install && cd ..
# 3. Initialize the database (creates SQLite DB and admin user)
poetry run flask cli init-db
# Default admin credentials: admin / admin (change in production!)The database is stored at instance/kiosk_show_dev.db in development mode.
IMPORTANT: In development mode, you must run BOTH Flask and Vite:
- Flask (port 5000): Backend API server
- Vite (port 3000): Frontend dev server with hot reload
Flask redirects /admin/ to port 3000 in development mode, so Vite must be running.
# Terminal 1: Start Flask backend (API server)
poetry run python run.py
# API available at http://localhost:5000/api/
# Terminal 2: Start Vite dev server (React frontend)
cd frontend && npm run dev
# Admin interface at http://localhost:3000/admin/
# (or http://localhost:5000/admin/ which redirects to port 3000)If you see "Database not initialized" errors:
# Re-initialize the database
poetry run flask cli init-dbTo check database health:
# Via curl
curl http://localhost:5000/health/db
# Or check the health endpoint
curl http://localhost:5000/health/readyThe React frontend also displays helpful error messages when the database is not initialized.
| Port | Service | Purpose |
|---|---|---|
| 5000 | Flask | Backend API, redirects /admin/ to Vite in dev mode |
| 3000 | Vite | React frontend with hot reload (dev only) |
After making changes to frontend code, rebuild for production:
cd frontend
npm run build
# This outputs to kiosk_show_replacement/static/dist/
# Flask serves this automatically at /admin/ in production modeThe application uses session-based authentication with password hashing:
- Default admin user:
admin/admin(username/password) - Admin users can create/edit/deactivate other users and reset passwords
- Users can update their own email and password via Profile Settings
- Inactive users cannot log in
When creating a new user or resetting a password, a temporary password is generated and displayed once. The user should change it after first login.
- app.py: Flask application factory with
create_app() - api/: RESTful API blueprints for slideshows, slides, displays
- auth/: Authentication blueprint and session management
- models/: SQLAlchemy models (Slideshow, Slide, Display, User)
- sse.py: Server-Sent Events for real-time updates
- storage.py: File upload and storage handling
- config/: Configuration classes (DevelopmentConfig, ProductionConfig, TestingConfig)
- static/dist/: Built React admin interface (generated by
npm run build)
- src/components/: Reusable React components
- src/pages/: Page-level components (Dashboard, Slideshows, Displays, History)
- src/contexts/: React contexts (AuthContext, SSEContext)
- src/hooks/: Custom React hooks
- src/types/: TypeScript type definitions
- Built with Vite, React 18, TypeScript, Bootstrap 5
- unit/: Backend unit tests (pytest)
- integration/: React frontend + Flask backend tests (Playwright)
- Never suppress warnings/errors without explicit approval - Fix root causes, not symptoms
- Always run
nox -s formatbeforenox -s lint - Always run tests via nox, not directly with pytest
- Never run lint/format with uncommitted git changes - Commit first
- Use proper type annotations on all new Python code
- Close resources explicitly - Use context managers or try/finally
- Database sessions: Close with
db.session.close(), dispose engines withdb.engine.dispose() - Git commits: Use detailed commit messages beginning with a concise one-sentence summary, followed by a blank line and detailed explanation of changes
- Command output: When running commands that may be long-running and/or produce a lot of output, such as tests, do not pipe the command directly to grep/head/tail/etc. Rather, tee the output to a scratchpad file and read from there as needed.
| Session | Purpose | Location |
|---|---|---|
test-3.14 |
Backend unit tests | tests/unit/ |
test-integration |
React + Flask through browser | tests/integration/ |
Integration tests require the React admin interface to be built (npm run build in frontend/).
Tests use separate databases and will NOT affect your development database.
- Unit tests: Use a temporary SQLite database in pytest's temp directory
- Integration tests: Use a separate temporary database with
DATABASE_URLoverride
All test databases are automatically created and destroyed during test runs. Your development database at instance/kiosk_show_dev.db is never touched by tests.
- mypy: Zero type errors (using SQLAlchemy mypy plugin and proper Mapped types)
- ResourceWarnings in tests: ~28 expected from Flask-SQLAlchemy, pytest fixtures, Werkzeug
- Zero tolerance for application code ResourceWarnings