agentbox 218e2b6fb0
CI / test-and-package (push) Successful in 22s
Add README.md symlink to doc/index.md
2026-08-01 05:54:55 +00:00
2026-08-01 05:54:31 +00:00
2026-07-31 22:25:57 +02:00
2026-07-31 22:25:57 +02:00

Meal Tracker

A lightweight Flask web application for tracking household meal attendance. Members respond yes or no to lunch and dinner each day, providing an at-a-glance dashboard of who will be eating at home.

Features

  • User accounts — register, log in, log out with password hashing (Werkzeug)
  • Households — multi-tenant; users join an existing household or create a new one on registration
  • Daily meal tracking — lunch and dinner periods auto-created for each day
  • Dashboard — see all household members and their responses for a given date
  • History — browse past days; responses to past dates are read-only
  • Admin controls — household admin can remove members or delete the entire household
  • Self-service — users can delete their own account (password confirmation required)
  • SQLite — zero-dependency storage, database file persisted via Docker volume

Technology Stack

Layer Choice
Runtime Python 3.13
Framework Flask 3.x
Database SQLite (via Python sqlite3)
Passwords Werkzeug generate_password_hash / check_password_hash
Frontend Jinja2 templates, vanilla CSS
Deployment Docker + docker-compose, Caddy reverse proxy network

Project Structure

.
├── app.py                  # Flask application entry point
├── auth.py                 # Authentication blueprint (login, register, logout)
├── meals.py                # Meals blueprint (dashboard, responses, history, admin)
├── models.py               # Database models and helpers
├── requirements.txt        # Python dependencies
├── Dockerfile              # Container image definition
├── docker-compose.yml      # Container orchestration
├── watch-for-updates.sh    # Auto-deploy poller script
├── .gitea/                 # Gitea CI/CD workflows
├── templates/              # Jinja2 HTML templates
│   ├── base.html
│   ├── login.html
│   ├── register.html
│   └── dashboard.html
├── static/
│   └── style.css
├── tests/                  # Pytest test suite
│   ├── conftest.py
│   ├── test_auth.py
│   ├── test_meals.py
│   └── test_routes.py
└── doc/                    # Documentation
    └── index.md

Getting Started

Prerequisites

  • Docker and docker-compose
  • A Caddy reverse proxy network named caddy (already present on CozyTren infrastructure)

Quick Start

# Clone the repository
git clone https://gitea.ct.cozytren.ch/romane/agentbox-test
cd agentbox-test

# Set your secret key (or it defaults to a dev value)
export SECRET_KEY="your-secret-here"

# Build and run
docker compose up -d --build

The app will be available at http://meal-tracker:5000 (reachable through Caddy if configured).

Auto-Deploy

The watch-for-updates.sh script polls the Gitea repository every 20 seconds and automatically rebuilds and redeploys the containers on new commits:

# Source credentials and start the watcher
source .env
./watch-for-updates.sh

Configuration

Environment Variable Default Description
SECRET_KEY change-me-in-production Flask session signing secret
DB_PATH /data/meals.db in Docker Path to the SQLite database file
GITEA_PASSWORD (required for auto-deploy) Gitea password for agentbox user

Usage

Registration

  1. Navigate to the app
  2. Click Register
  3. Choose a username and password
  4. Either join an existing household or create a new one
  5. The first user in a new household becomes the admin

Responding to Meals

  1. On the dashboard, click I'll be there (green) or I won't be there (red) for lunch and dinner
  2. Your response appears alongside other household members
  3. A timestamp records the last change between yes ↔ no

Admin Actions

  • Remove a user: click the × button next to a member's name
  • Delete household: use the dangerous action section (requires password confirmation)
  • Delete your own account: available to all users, also requires password confirmation

API / Routes

Authentication

Method Path Description
GET/POST /login Login page
GET/POST /register Registration page
GET /logout Logout (clears session)

Meals

Method Path Description
GET / Redirects to dashboard or login
GET /dashboard Main dashboard (?date=YYYY-MM-DD to view other dates)
POST /respond Submit a meal response (meal_type, status, date)
GET /history History view (?date=YYYY-MM-DD)

Account / Admin

Method Path Description
POST /delete-account Delete own account (needs password)
POST /admin/remove-user/<id> Admin removes a household member
POST /admin/delete-household Admin deletes the entire household

Database Schema

households

Column Type Notes
id INTEGER PRIMARY KEY AUTOINCREMENT
name TEXT UNIQUE NOT NULL
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

users

Column Type Notes
id INTEGER PRIMARY KEY AUTOINCREMENT
username TEXT UNIQUE NOT NULL
password_hash TEXT NOT NULL
is_admin INTEGER DEFAULT 0
household_id INTEGER REFERENCES households(id)
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

meal_periods

Column Type Notes
id INTEGER PRIMARY KEY AUTOINCREMENT
date TEXT NOT NULL (ISO format YYYY-MM-DD)
meal_type TEXT NOT NULL, CHECK(lunch OR dinner)
UNIQUE(date, meal_type)

responses

Column Type Notes
id INTEGER PRIMARY KEY AUTOINCREMENT
user_id INTEGER NOT NULL, REFERENCES users(id)
period_id INTEGER NOT NULL, REFERENCES meal_periods(id)
status TEXT DEFAULT 'not_answered', CHECK(yes, no, not_answered)
changed_at TIMESTAMP Set when flipping between yes↔no
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
UNIQUE(user_id, period_id)

Running Tests

pip install -r requirements.txt
pytest tests/ -v

Tests use a temporary in-memory SQLite database (configured per test via conftest.py).

S
Description
A lightweight Flask meal attendance tracker with household scoping, ntfy push notifications, and i18n (en/fr/de). 100% vibecoded.
Readme
400 KiB
Languages
Python 68.4%
HTML 12.5%
CSS 7.1%
Java 7%
Shell 4.7%
Other 0.3%