Development
===========
.. note::
**This guide is for local development only.**
Local Python/Poetry installation is only supported for development purposes.
For production deployments, Docker is the only supported method.
See :doc:`deployment` for production setup instructions.
System Requirements
-------------------
Before setting up the development environment, ensure you have the following
system dependencies installed:
* **Python 3.13+**: Required for the Flask backend
* **Node.js 18+ and npm**: Required for frontend development
* **ffmpeg/ffprobe**: Required for automatic video duration detection
**Installing ffmpeg:**
.. code-block:: bash
# ArchLinux
sudo pacman -S ffmpeg
# Ubuntu/Debian
sudo apt install ffmpeg
# Fedora
sudo dnf install ffmpeg
# macOS (with Homebrew)
brew install ffmpeg
**Verifying ffprobe installation:**
.. code-block:: bash
ffprobe -version
# Should output version information
Setting up Development Environment
----------------------------------
1. Clone the repository:
.. code-block:: bash
git clone https://github.com/jantman/kiosk-show-replacement.git
cd kiosk-show-replacement
2. Install Poetry (if not already installed):
.. code-block:: bash
curl -sSL https://install.python-poetry.org | python3 -
3. Install dependencies and activate environment:
.. code-block:: bash
poetry install
eval $(poetry env activate)
4. Set up the development environment:
.. code-block:: bash
nox -s dev-setup
Development Workflow
--------------------
This project uses `nox `_ for development automation.
Available Commands
~~~~~~~~~~~~~~~~~~
**Important**: First activate your Poetry environment in any new terminal session:
.. code-block:: bash
eval $(poetry env activate)
Then run the development commands:
.. code-block:: bash
# Format code with black and isort
nox -s format
# Run linting (flake8, pycodestyle)
nox -s lint
# Run type checking with mypy
nox -s type_check
# Run unit tests
nox -s test
# Run integration tests
nox -s test-integration
# Run all tests
nox -s test-comprehensive
# Build documentation
nox -s docs
# Serve documentation locally
nox -s docs-serve
# Clean build artifacts
nox -s clean
# Check for security vulnerabilities
nox -s safety
Default Development Session
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Running ``nox`` without arguments will run the default development session (format, lint, test):
.. code-block:: bash
# After activating environment
nox
Code Style
----------
This project uses several tools to maintain code quality:
* **Black**: Code formatting
* **isort**: Import sorting
* **flake8**: Linting and style checking
* **mypy**: Type checking
Configuration files:
* ``.flake8``: flake8 configuration
* ``pyproject.toml``: Black, isort, and mypy configuration
Testing
-------
The project uses pytest for testing with two types of tests:
1. **Unit Tests** (``tests/unit/``): Test individual functions and classes in isolation
2. **Integration Tests** (``tests/integration/``): Full-stack browser tests of React frontend + Flask backend
**Important**: First activate your Poetry environment in any new terminal session:
.. code-block:: bash
eval $(poetry env activate)
Unit Tests
~~~~~~~~~~
Located in ``tests/unit/``, these test individual functions and classes in isolation.
.. code-block:: bash
nox -s test
Integration Tests
~~~~~~~~~~~~~~~~~
Located in ``tests/integration/``, these test the complete React frontend + Flask backend integration through a real browser using Playwright.
**What Integration Tests Cover:**
* **Full-Stack Integration**: React frontend communicating with Flask backend through real HTTP requests
* **Real Browser Testing**: Uses Playwright to control system Chrome/Chromium browser
* **Complete User Workflows**: Full user journeys from login to dashboard interaction
* **Authentication Integration**: Tests session-based authentication across frontend and backend
* **API Communication**: Validates REST API endpoints work correctly with React frontend
* **Database Integration**: Tests data persistence across the full application stack
**Key Characteristics:**
* Use Playwright to automate a real Chrome/Chromium browser
* Start both Flask backend (port 5000) and Vite frontend (port 3001) servers
* Test actual user interactions (clicking, typing, form submission)
* Verify complete authentication workflows and dashboard functionality
* Include multi-step user journeys that span multiple application components
* Test real-world scenarios that users actually experience
**Examples:**
* Complete login workflow (visit frontend → authenticate → access dashboard → see content)
* Frontend-backend authentication integration (session cookies, API calls)
* Dashboard data loading from Flask backend APIs
* User interface responsiveness and error handling
.. code-block:: bash
nox -s test-integration
**Integration Test Server Logs:**
Integration tests automatically capture comprehensive logs from both Flask and Vite servers during test execution. These logs are saved for debugging purposes and can be found in:
* **Log File Location**: ``test-results/integration-server-logs.txt`` (created in project root)
* **Log Contents**:
- Flask server startup, requests, and error messages
- Vite development server output and build information
- Timestamped entries for easy debugging
- Complete server lifecycle from startup to shutdown
* **Automatic Capture**: Logs are automatically saved after each integration test session
* **Debug Access**: Server logs are also dumped to console when tests fail for immediate debugging
**Example log file structure:**
.. code-block:: text
=== INTEGRATION TEST SERVER LOGS ===
=== FLASK SERVER LOGS ===
[14:32:15.123] Flask: Starting development server...
[14:32:15.456] Flask: * Running on http://localhost:5000
[14:32:16.789] Flask: GET /api/v1/auth/login - 200
=== VITE SERVER LOGS ===
[14:32:20.123] Vite: Local: http://localhost:3001/
[14:32:20.456] Vite: ready in 1.2s
=== END OF LOGS ===
**System Requirements for Integration Tests:**
Integration tests require a system-installed Chrome or Chromium browser and Node.js for the frontend development server. The test framework automatically detects and uses the first available browser from these common locations:
* ``/usr/bin/google-chrome-stable`` (Google Chrome on most Linux distributions)
* ``/usr/bin/chromium-browser`` (Chromium on Ubuntu/Debian)
* ``/usr/bin/google-chrome`` (Alternative Chrome location)
* ``/usr/bin/chromium`` (Chromium on Arch/Fedora)
**Debugging Integration Test Failures:**
When integration tests fail, several debugging resources are automatically generated:
1. **Server Logs**: Check ``test-results/integration-server-logs.txt`` for detailed Flask and Vite server output
2. **Screenshots**: Failed tests capture screenshots in ``test-results/`` directory
3. **Console Output**: Server logs are also dumped to the terminal on test failures
4. **Real-time Debugging**: Run tests with ``-s`` flag to see live server output
**Common Integration Test Issues:**
* **Server Startup Failures**: Check server logs for port conflicts or missing dependencies
* **Authentication Issues**: Look for API authentication errors in Flask logs
* **Frontend Build Issues**: Check Vite logs for compilation errors or missing assets
* **Network Timeouts**: Increase timeouts or check server health in logs
**Example debugging workflow:**
.. code-block:: bash
# Run integration tests with verbose output
nox -s test-integration -- -s -v
# If tests fail, check the server logs
cat test-results/integration-server-logs.txt
# Run specific test for focused debugging
nox -s test-integration -- -k "test_user_login" -s
Test Configuration
~~~~~~~~~~~~~~~~~~
* ``pytest.ini``: Pytest configuration
* ``tests/conftest.py``: Shared test fixtures
Coverage
~~~~~~~~
Code coverage is measured using pytest-cov. Coverage reports are generated in:
* Terminal output (with ``--cov-report=term-missing``)
* HTML report in ``htmlcov/`` directory
* XML report as ``coverage.xml``
Database Testing
~~~~~~~~~~~~~~~~
**Test Database Isolation:**
Tests use completely isolated databases that are separate from your development database:
* **Unit tests**: Use a temporary SQLite database in a pytest temp directory
* **Integration tests**: Use a fresh SQLite database per test session
* **Your development database**: Located at ``kiosk_show.db`` (default) is never touched by tests
This means running tests will **never** affect your development database or its data.
**How it works:**
The test fixtures in ``tests/conftest.py`` override ``SQLALCHEMY_DATABASE_URI`` to point
to a temporary file, ensuring complete isolation from your development environment.
Test Type Summary
~~~~~~~~~~~~~~~~~
**When to use each test type:**
* **Unit Tests** (``nox -s test``): Testing individual functions, classes, or small components in isolation. Fast and focused.
* **Integration Tests** (``nox -s test-integration``): Testing the complete React + Flask application stack through a real browser. Use for validating user experiences and frontend-backend integration.
**Test execution speed:** Unit < Integration (Integration tests are slowest due to starting both servers)
Troubleshooting Browser Tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Playwright Browser Dependencies on Arch Linux**
Playwright browser tests (integration tests) may encounter issues on Arch Linux due to browser dependency conflicts. This section documents the successful solution.
**Problem:** Playwright fails with browser executable errors:
.. code-block:: text
playwright._impl._errors.Error: Executable doesn't exist at
/home/user/.cache/ms-playwright/chromium_headless_shell-1179/chrome-linux/headless_shell
**Root Cause:** Playwright's bundled browsers don't work properly on Arch Linux due to:
* Missing system library versions (libicudata.so.66, libicui18n.so.66, etc.)
* Arch Linux has newer library versions than Playwright expects
* Playwright doesn't officially support Arch Linux
**Failed Solutions to Avoid:**
* **Playwright Version Downgrade**: Attempting to downgrade Playwright to 1.30.0 fails due to Python 3.13 incompatibility with older dependency versions (greenlet, etc.)
* **System Library Symlinks**: Creating global symlinks pollutes the system and is not recommended
* **Playwright Install Commands**: ``playwright install`` fails due to missing library versions
**✅ Working Solution: System Chrome Integration**
Configure Playwright to use the system-installed Google Chrome instead of bundled browsers:
1. **Install Google Chrome:**
.. code-block:: bash
# Install Google Chrome on Arch Linux
yay -S google-chrome
# or using AUR helper of choice
2. **Configure Playwright:** Update ``playwright.config.js`` to use system Chrome:
.. code-block:: javascript
projects: [
{
name: 'chromium',
use: {
...require('@playwright/test').devices['Desktop Chrome'],
channel: 'chrome', // Use system Chrome
executablePath: '/usr/bin/google-chrome-stable' // Explicit path
},
},
],
3. **Verify Installation:**
.. code-block:: bash
# Confirm Chrome is installed
which google-chrome-stable
# Should output: /usr/bin/google-chrome-stable
4. **Run Tests:**
.. code-block:: bash
eval $(poetry env activate)
nox -s test-integration
nox -s test-e2e
**Alternative Browser Paths:**
If ``google-chrome-stable`` is not available, try these alternatives:
.. code-block:: bash
# Check available browsers
which chromium
which google-chrome
which chromium-browser
Update ``executablePath`` in ``playwright.config.js`` accordingly:
.. code-block:: javascript
executablePath: '/usr/bin/chromium' // For Chromium
executablePath: '/usr/bin/google-chrome' // Alternative Chrome path
**Testing the Fix:**
After configuration, verify browser tests work:
.. code-block:: bash
# Test with verbose output
eval $(poetry env activate)
nox -s test-integration -- -v
# Should see browser startup without executable errors
# Look for: "Browser launched successfully" in logs
**Success Indicators:**
* No more "Executable doesn't exist" errors
* Browser tests launch Chrome successfully
* Tests can navigate to React frontend and Flask backend
* Screenshots and videos are captured properly on test failures
**What This Solution Provides:**
* ✅ **Browser tests work on Arch Linux**
* ✅ **Uses stable, system-managed Chrome**
* ✅ **No global system modifications required**
* ✅ **Easy to maintain and update**
* ✅ **Works with automatic browser updates**
Project Structure
-----------------
.. code-block:: text
kiosk-show-replacement/
├── kiosk_show_replacement/ # Main package
│ ├── __init__.py
│ ├── app.py # Flask application factory
│ ├── api/ # REST API blueprints
│ ├── auth/ # Authentication (future)
│ ├── cli/ # Command-line interface
│ ├── config/ # Configuration management
│ ├── display/ # Display/kiosk blueprints
│ ├── models/ # Database models
│ ├── slideshow/ # Slideshow management
│ ├── static/ # Static files
│ ├── templates/ # Jinja2 templates
│ └── utils/ # Utility functions
├── tests/ # Test suite
│ ├── unit/ # Unit tests
│ └── integration/ # Integration tests
├── docs/ # Documentation
├── scripts/ # Utility scripts
├── noxfile.py # Development automation
├── pyproject.toml # Poetry configuration
└── README.md
Adding New Features
-------------------
1. Create a new branch for your feature
2. Write tests first (TDD approach)
3. Implement the feature
4. Run the full test suite
5. Update documentation
6. Submit a pull request
Database Migrations
-------------------
This project uses Flask-Migrate for database migrations.
**Important**: First activate your Poetry environment in any new terminal session:
.. code-block:: bash
eval $(poetry env activate)
Then run migration commands:
.. code-block:: bash
# Create a new migration
flask db migrate -m "Description of changes"
# Apply migrations
flask db upgrade
# Rollback migrations
flask db downgrade
Frontend Development
--------------------
The kiosk-show-replacement project includes a modern React-based admin interface alongside the Flask backend. This section covers everything you need to know about developing and maintaining the frontend.
Frontend Technology Stack
~~~~~~~~~~~~~~~~~~~~~~~~~~
The frontend uses modern web technologies:
**Core Technologies:**
* **React 18**: Modern React with hooks and functional components
* **TypeScript**: Type-safe JavaScript for better development experience
* **Vite**: Fast build tool and development server
* **React Router**: Client-side routing for single-page application
**UI Framework:**
* **React Bootstrap**: Bootstrap 5 components for React
* **Bootstrap 5**: CSS framework for responsive design
* **React Router Bootstrap**: Integration between React Router and Bootstrap
**Development Tools:**
* **npm**: Package manager for JavaScript dependencies
* **ESLint**: JavaScript/TypeScript linting (future enhancement)
* **Prettier**: Code formatting (future enhancement)
Frontend Project Structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: text
frontend/ # Frontend application root
├── package.json # npm dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── vite.config.ts # Vite build configuration
├── index.html # HTML entry point
└── src/ # Source code
├── main.tsx # Application entry point
├── App.tsx # Main app component
├── components/ # Reusable UI components
│ ├── common/ # Common components (buttons, forms)
│ ├── layout/ # Layout components (header, sidebar)
│ └── ui/ # Basic UI elements
├── pages/ # Page components
│ ├── Dashboard.tsx # Admin dashboard
│ ├── Login.tsx # Login page
│ ├── Slideshows.tsx # Slideshow management
│ └── Displays.tsx # Display management
├── contexts/ # React contexts
│ └── AuthContext.tsx # Authentication state
├── hooks/ # Custom React hooks
│ ├── useAuth.ts # Authentication hook
│ ├── useApi.ts # API client hook
│ └── useLocalStorage.ts # Local storage hook
└── types/ # TypeScript type definitions
├── api.ts # API response types
├── auth.ts # Authentication types
└── slideshow.ts # Slideshow data types
Running the Application Locally
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. important::
**In development mode, you MUST run BOTH Flask and Vite servers.**
Flask redirects ``/admin/`` requests to the Vite dev server on port 3000.
If Vite is not running, the admin interface will not load.
**Port Summary:**
+------+---------+------------------------------------------------+
| Port | Service | Purpose |
+======+=========+================================================+
| 5000 | Flask | Backend API, redirects /admin/ to Vite in dev |
+------+---------+------------------------------------------------+
| 3000 | Vite | React frontend with hot reload (dev only) |
+------+---------+------------------------------------------------+
**First-time Setup:**
1. Initialize the database:
.. code-block:: bash
FLASK_APP=kiosk_show_replacement.app poetry run flask cli init-db
# Default credentials: admin / admin
**Starting for Development:**
1. Start Flask backend (Terminal 1):
.. code-block:: bash
# From project root
poetry run python run.py
# API available at http://localhost:5000/api/
2. Start Vite frontend (Terminal 2):
.. code-block:: bash
cd frontend
npm run dev
# Admin interface at http://localhost:3000/admin/
3. Access the admin interface at http://localhost:3000/admin/ (or http://localhost:5000/admin/ which redirects to port 3000)
Setting Up Frontend Development
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Prerequisites:**
* Node.js 18+ and npm (for frontend development)
* Python 3.13+ and Poetry (for backend integration)
**Initial Setup:**
1. Navigate to the frontend directory:
.. code-block:: bash
cd frontend
2. Install frontend dependencies:
.. code-block:: bash
npm install
The frontend development server runs on http://localhost:3000 and proxies API requests to the Flask backend on http://localhost:5000.
Frontend Development Commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Development Server:**
.. code-block:: bash
cd frontend
npm run dev # Start development server with hot reload
**Building for Production:**
.. code-block:: bash
cd frontend
npm run build # Build optimized production assets
npm run preview # Preview production build locally
**Package Management:**
.. code-block:: bash
cd frontend
npm install # Install dependencies
npm install # Add new dependency
npm install --save-dev # Add development dependency
npm update # Update dependencies
npm audit # Check for security vulnerabilities
**TypeScript:**
.. code-block:: bash
cd frontend
npx tsc --noEmit # Type check without building
npx tsc --watch # Watch mode type checking
Frontend-Backend Integration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The frontend integrates with the Flask backend through several mechanisms:
**Development Mode:**
* Vite dev server runs on port 3000
* API requests are proxied to Flask backend on port 5000
* Hot reload for immediate feedback during development
**Production Mode:**
* Frontend builds to ``kiosk_show_replacement/static/dist/``
* Flask serves the built React app at ``/admin`` routes
* All assets served through Flask for single-server deployment
**API Communication:**
* REST API endpoints at ``/api/v1/*``
* Session-based authentication shared between frontend and backend
* Axios client with automatic authentication handling
**Configuration in vite.config.ts:**
.. code-block:: typescript
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
proxy: {
'/api': 'http://localhost:5000',
'/auth': 'http://localhost:5000',
'/uploads': 'http://localhost:5000'
}
},
build: {
outDir: '../kiosk_show_replacement/static/dist'
}
})
Authentication Integration
~~~~~~~~~~~~~~~~~~~~~~~~~~
The frontend uses the same session-based authentication as the Flask backend:
**Login Flow:**
1. User submits credentials to ``/api/v1/auth/login``
2. Flask creates session and returns user data
3. Frontend stores authentication state in React context
4. Subsequent API requests include session cookies automatically
**Protected Routes:**
* React Router guards routes requiring authentication
* Redirects to login page if not authenticated
* Preserves intended destination for post-login redirect
**API Client (useApi hook):**
.. code-block:: typescript
const api = useApi();
// Authenticated requests automatically include session
const slideshows = await api.get('/api/v1/slideshows');
const newSlideshow = await api.post('/api/v1/slideshows', data);
Adding New Frontend Features
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**1. Adding a New Page:**
.. code-block:: typescript
// src/pages/NewPage.tsx
import React from 'react';
import { Container } from 'react-bootstrap';
const NewPage: React.FC = () => {
return (
New Page
{/* Page content */}
);
};
export default NewPage;
**2. Adding to Navigation:**
.. code-block:: typescript
// src/components/layout/Sidebar.tsx
import { LinkContainer } from 'react-router-bootstrap';
import { Nav } from 'react-bootstrap';
New Page
**3. Adding Route:**
.. code-block:: typescript
// src/App.tsx
import { Routes, Route } from 'react-router-dom';
import NewPage from './pages/NewPage';
} />
**4. Adding API Integration:**
.. code-block:: typescript
// Custom hook for API operations
const useNewFeature = () => {
const api = useApi();
const fetchData = async () => {
return await api.get('/api/v1/new-endpoint');
};
const createItem = async (data: NewItemType) => {
return await api.post('/api/v1/new-endpoint', data);
};
return { fetchData, createItem };
};
Common Frontend Development Tasks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Managing State:**
* Use React Context for global state (authentication, settings)
* Use useState for local component state
* Use useEffect for side effects and API calls
**Handling Forms:**
.. code-block:: typescript
const [formData, setFormData] = useState({ name: '', description: '' });
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
await api.post('/api/v1/endpoint', formData);
// Handle success
} catch (error) {
// Handle error
}
};
**Error Handling:**
.. code-block:: typescript
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
const handleApiCall = async () => {
setLoading(true);
setError(null);
try {
const result = await api.get('/api/v1/data');
// Handle success
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
} finally {
setLoading(false);
}
};
**Responsive Design:**
Use Bootstrap classes and React Bootstrap components for responsive layouts:
.. code-block:: typescript
Content
TypeScript Best Practices
~~~~~~~~~~~~~~~~~~~~~~~~~~
**Define Types for API Responses:**
.. code-block:: typescript
// src/types/api.ts
export interface ApiResponse {
success: boolean;
data: T;
message?: string;
}
export interface Slideshow {
id: number;
name: string;
description: string;
active: boolean;
items: SlideshowItem[];
}
**Use Proper Component Props Types:**
.. code-block:: typescript
interface SlideshowCardProps {
slideshow: Slideshow;
onEdit: (slideshow: Slideshow) => void;
onDelete: (id: number) => void;
}
const SlideshowCard: React.FC = ({
slideshow,
onEdit,
onDelete
}) => {
// Component implementation
};
**Custom Hook Type Safety:**
.. code-block:: typescript
interface UseApiResult {
get: (url: string) => Promise;
post: (url: string, data: any) => Promise;
put: (url: string, data: any) => Promise;
delete: (url: string) => Promise;
}
const useApi = (): UseApiResult => {
// Hook implementation
};
Troubleshooting Frontend Issues
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Common Issues:**
1. **Build Errors:**
- Check TypeScript errors: ``npx tsc --noEmit``
- Verify all dependencies are installed: ``npm install``
- Clear node_modules and reinstall: ``rm -rf node_modules package-lock.json && npm install``
2. **API Connection Issues:**
- Ensure Flask backend is running on port 5000
- Check Vite proxy configuration in ``vite.config.ts``
- Verify CORS is enabled in Flask app
3. **Authentication Problems:**
- Check browser cookies and session storage
- Verify API endpoints return proper status codes
- Test authentication flow in browser dev tools
4. **Hot Reload Not Working:**
- Restart Vite dev server: ``npm run dev``
- Check file permissions and paths
- Clear browser cache
5. **Database Not Initialized:**
- The login page will show a clear error if the database is not initialized
- Run: ``FLASK_APP=kiosk_show_replacement.app poetry run flask cli init-db``
- Check the health endpoint: ``curl http://localhost:5000/health/ready``
- The ``/health/ready`` endpoint returns ``"reason": "database_not_initialized"`` if setup is needed
**Debugging Tools:**
* Browser DevTools for inspecting network requests and React components
* React Developer Tools browser extension
* TypeScript compiler for type checking
* Flask debug toolbar for backend API issues
Frontend Testing (Future Enhancement)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When adding frontend tests, consider:
* **Unit Tests**: Jest and React Testing Library for component testing
* **Integration Tests**: Testing API integration and user workflows
* **E2E Tests**: Playwright or Cypress for full application testing
**Example test structure:**
.. code-block:: typescript
// src/components/__tests__/SlideshowCard.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import SlideshowCard from '../SlideshowCard';
test('renders slideshow name', () => {
const slideshow = { id: 1, name: 'Test Slideshow' };
render();
expect(screen.getByText('Test Slideshow')).toBeInTheDocument();
});
Deployment Considerations
~~~~~~~~~~~~~~~~~~~~~~~~~
**Production Build:**
.. code-block:: bash
cd frontend
npm run build
This creates optimized assets in ``kiosk_show_replacement/static/dist/`` that Flask serves in production.
**Environment Variables:**
Create ``.env`` files for different environments:
.. code-block:: bash
# frontend/.env.development
VITE_API_BASE_URL=http://localhost:5000
# frontend/.env.production
VITE_API_BASE_URL=
**Build Optimization:**
* Vite automatically optimizes bundle size
* Tree shaking removes unused code
* Assets are fingerprinted for caching
* Source maps available for debugging
Contributing
------------
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new functionality
5. Run the test suite
6. Update documentation
7. Submit a pull request
Code Review Process
~~~~~~~~~~~~~~~~~~~
All contributions go through code review:
1. Automated checks (linting, testing, type checking)
2. Manual review by maintainers
3. Discussion and iteration
4. Approval and merge
Release Process
---------------
1. Update version in ``pyproject.toml``
2. Update ``CHANGELOG.md``
3. Create a Git tag
4. Build and publish to PyPI
5. Create GitHub release