Offline-friendly web app for logging daily asthma medication usage and exporting a CSV history.
codex/
├── frontend/ # Web application
│ ├── index.html
│ ├── app.js
│ ├── styles.css
│ ├── service-worker.js
│ └── manifest.webmanifest
└── backend/ # Flask API
├── app/
└── tests/
The web application allows users to track medication usage offline.
- Open
frontend/index.html(or deploy the contents) at/codex/. - Pick a date, adjust the counter with the plus/minus buttons, and Save count.
- Use Reset day to clear a date and Export CSV to download your history.
Data is stored locally in the browser and works offline via the included service worker.
A Flask backend with token authentication, rate limiting, and CORS support.
See backend/README.md for details and DEPLOY.md for production deployment.
- ✅ Token-based authentication
- ✅ Rate limiting per IP (prevents abuse)
- ✅ CORS configuration
- ✅ Docker support with automated builds
- ✅ 90 tests with 96.60% coverage
Option 1: Run both frontend and backend together (recommended)
./dev.shThis starts:
- Backend at http://localhost:5001
- Frontend at http://localhost:8000
Note: Port 5001 is used for the backend because macOS uses port 5000 for AirPlay.
Press Ctrl+C to stop both services.
Option 2: Run backend only
cd backend
uv sync
uv run flask --app app.main run --debugAutomated deployment with Docker and GitHub Container Registry:
- Push code to GitHub → Image builds automatically
- Deploy on server:
# Install Docker (if needed)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# Logout/login for group to take effect
# Create application directory
sudo mkdir -p /var/www/codex/backend
sudo chown -R $USER:$USER /var/www/codex
cd /var/www/codex/backend
# Download production compose file
curl -O https://raw.githubusercontent.com/FredrikMeyer/codex/main/backend/docker-compose.prod.yml
# Create environment file
cat > .env << 'EOF'
ALLOWED_ORIGINS=https://fredrikmeyer.github.io
EOF
# Create data directory with correct permissions
mkdir -p data
sudo chown -R 1000:1000 data
# Pull and start container
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
# Verify it's running
docker compose -f docker-compose.prod.yml ps
curl -X POST http://localhost:5000/generate-code- Configure nginx to proxy to
localhost:5000:
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Host $host;
}
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
}Updates:
# When you push new code, update with:
cd /var/www/codex/backend
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -dSee DEPLOY.md for complete deployment guide with troubleshooting.
POST /generate-code→ Generate access code (5/hour limit)POST /login→ Validate code (10/minute limit)POST /generate-token→ Exchange code for token (10/minute limit)POST /logs→ Store log entry (100/minute limit, requires auth)GET /test-protected→ Test token authentication