Restructure project for Docker: move app to src/, add Helm chart and Fleet config

This commit is contained in:
eka
2026-03-01 10:32:26 +05:00
parent b8b822e578
commit 649ec54886
17 changed files with 240 additions and 61 deletions

123
AGENTS.md
View File

@@ -2,49 +2,60 @@
## Project Overview
This is a simple Flask web application - a "Jeopardy-style" quiz game about the Russian short story "Уроки французского" by Valentin Rasputin. The project uses:
- **Backend**: Python 3.13 with Flask
- **Frontend**: HTML, CSS, JavaScript (vanilla)
- **Data Storage**: JSON file (`data/questions.json`)
- **State**: Browser localStorage (client-side)
This is a Flask web application - a "Jeopardy-style" quiz game about the Russian short story "Уроки французского" by Valentin Rasputin.
**Tech Stack:**
- Backend: Python 3.13 with Flask
- Frontend: HTML, CSS, JavaScript (vanilla)
- Data Storage: JSON file (`data/questions.json`)
- State: Browser localStorage (client-side)
- Container: Docker
## Build/Test Commands
### Running the Application
### Running Locally (without Docker)
```bash
# Activate virtual environment
source venv/bin/activate
# Run Flask app (default port 5000)
python app.py
python src/app.py
# Run on specific port
python -c "from app import app; app.run(port=5002)"
python -c "from src.app import app; app.run(port=5002)"
```
### No Formal Tests
### Running with Docker
```bash
# Build image
./build.sh
# Run container
./run.sh
# Stop container
docker stop sigra && docker rm sigra
```
**Note:** Dockerfile copies only `src/` directory into the container (app.py, data/, templates/, static/).
### Manual Testing
This project does not have a formal test suite. For manual testing:
- Use `curl` to test API endpoints
- Test in browser at http://localhost:5000 (or configured port)
### Linting/Type Checking
No formal linter is configured. The codebase uses basic Python and JavaScript.
- Test in browser at http://localhost:5000
## Code Style Guidelines
### Python (app.py)
**Imports**
- Standard library first, then third-party
- Use absolute imports
- Example:
```python
import json
from flask import Flask, render_template, request, redirect, url_for, make_response
```
**Imports** - Standard library first, then third-party:
```python
import json
from flask import Flask, render_template, request, redirect, url_for, make_response
```
**Formatting**
- Use 4 spaces for indentation
@@ -71,20 +82,18 @@ No formal linter is configured. The codebase uses basic Python and JavaScript.
**General**
- Use vanilla JavaScript (no frameworks)
- Prefer `var` over `let/const` for compatibility
- Use `function` keyword instead of arrow functions where possible
- Use `function` keyword instead of arrow functions
**Event Handling**
- Use `onclick` directly in HTML or `element.onclick = function()`
- Use `onclick` directly in HTML or `element.onclick = function()`
- Avoid `addEventListener` for simplicity
**DOM Manipulation**
- Use `document.getElementById` and `document.querySelector`
- Template literals for dynamic content: `` `string ${variable}` ``
- Template literals for dynamic content
- Use `JSON.parse()` and `JSON.stringify()` for localStorage
**Naming**
- camelCase for variables and functions
- Descriptive names (e.g., `currentTeam`, `selectAnswer`)
**Naming** - camelCase for variables and functions
### HTML/CSS (templates/*.html)
@@ -99,57 +108,65 @@ No formal linter is configured. The codebase uses basic Python and JavaScript.
- Keep responsive design in mind
**Structure**
- Inline CSS in `<style>` tags (simple project)
- Inline CSS in `<style>` tags
- Inline JS in `<script>` tags at end of body
## File Organization
```
/home/eof/dev/roma/sigra/
├── app.py # Flask application
├── data/
│ └── questions.json # Game questions data
├── templates/
│ ├── index.html # Main game page
│ ├── admin.html # Admin panel (edit questions)
│ ├── edit.html # Question editor
│ └── login.html # Admin login
├── static/ # Static assets (empty currently)
├── venv/ # Virtual environment
├── SPEC.md # Project specification
└── AGENTS.md # This file
├── Dockerfile # Docker image definition
├── build.sh # Build script
├── run.sh # Run script
├── .dockerignore # Docker ignore
├── src/ # Application source (copied to container)
│ ├── app.py # Flask application
│ ├── data/
│ └── questions.json # Game questions
│ ├── templates/ # Jinja2 templates
│ └── static/ # Static assets
├── helm/ # Kubernetes Helm chart
├── venv/ # Virtual environment
├── SPEC.md # Project specification
├── AGENTS.md # This file
└── .gitignore # Git ignore rules
```
## Common Patterns
### Adding a New Question
1. Edit `data/questions.json` manually or via admin panel at `/admin`
2. Follow existing structure:
2. Structure:
```json
{
"cost": 600,
"question": "Question text?",
"options": ["Option 1", "Option 2", "Option 3", "Option 4"],
"answer": 0 // 0-3 index of correct answer
"answer": 0
}
```
### Adding a New Route
1. Add route in `app.py` using `@app.route()`
2. Return `render_template()` or `jsonify()`
3. For API routes, use proper HTTP methods
### Modifying Game Logic
- Game state stored in browser's localStorage
### Game State (localStorage)
- Key: `francuzskiy_game`
- Structure: `{ score: 0, answered: [], userAnswers: {}, teams: [] }`
- `answered`: array of "cat_q" keys (e.g., ["0_0", "1_2"])
- `userAnswers`: object with keys and `{team, answer}` values
### Multi-team Support
- Teams: 1-3 teams supported
- Questions: 30 (always, regardless of team count)
- Auto-switch to next team after answering
## Security Notes
- Admin panel is password-protected (password in `app.py`)
- No database - data is in JSON file
- No SQL injection risk (no database)
- XSS: Be careful with `innerHTML` - user input in questions is trusted
- Admin panel password: stored in `app.py` (`ADMIN_PASSWORD`)
- No database - data in JSON file
- No SQL injection risk
- XSS: user input in questions is trusted (admin-only)
## Dependencies
@@ -159,6 +176,8 @@ Jinja2==3.1.6
Werkzeug==3.1.6
```
## Contact
## Git Conventions
For questions about this codebase, refer to SPEC.md or the original requirements.
- Do NOT commit without explicit user request
- Run lint/typecheck before committing if available
- Keep commits focused and descriptive