ResQTrack is a small, friendly tool to help people, NGOs, volunteers, and hospitals coordinate animal rescues. A citizen can report an injured animal (with an optional photo/video), responders can pick it up from there, and you can track things end‑to‑end. Donors can chip in too.
Under the hood it’s a Flask API with a simple static frontend (HTML/JS/CSS). It’s easy to run locally, and it comes with production basics like JWT auth, database migrations, CORS, upload validation, logging, and optional Docker.
- Report animal cases (optionally attach media)
- Sign in with roles: ADMIN / NGO / VOLUNTEER (JWT)
- Register NGOs and Volunteers
- Hospitals directory and donation records
- Centralized JSON error responses (no HTML error pages)
- Sensible rate limiting (login/registration)
- CORS that you can control via environment variables
- Logging to console (and file if you want)
- Tests via pytest and CI via GitHub Actions
- Install dependencies
python -m venv .venv
".venv\\Scripts\\Activate.ps1" # Windows
# source .venv/bin/activate # macOS/Linux
pip install -r requirements.txt
- Configure environment
cp .env.example .env # or copy manually on Windows
Defaults use the MySQL connector URI in .env.example; set ALLOWED_ORIGINS=http://localhost:8000.
- Initialize the database
set FLASK_APP=backend/wsgi.py # Windows
flask db upgrade
# macOS/Linux: export FLASK_APP=backend/wsgi.py && flask db upgrade
- Run the app
python backend/wsgi.py # API at http://localhost:5000
cd frontend && python -m http.server 8000 # Frontend at http://localhost:8000
That’s it. If you want containers, use docker-compose up --build instead.
ResQTrack/
backend/
app/
routes/ # API blueprints (auth, cases, uploads, etc.)
models.py # SQLAlchemy models
extensions.py # Flask extensions (db, jwt, cors, limiter, mail)
utils.py # Helpers
mailer.py # Email utilities
data_integration.py# Bulk data import/export utilities
config.py # App configuration
logging_config.py # Logging setup (RotatingFileHandler + console)
wsgi.py # App entrypoint for Gunicorn/Flask
frontend/
assets/css/ # Styles (includes toasts, spinners, theme)
assets/js/ # API client + UI helpers (toasts, loading overlay)
*.html # Static pages (index, report, register, donate, admin, data-dashboard)
docs/ # Docs, SQL schema, ERD/DFD
migrations/ # Alembic migration scripts
tests/ # Pytest suite
.github/workflows/ci.yml
.env.example # Example environment file
Dockerfile
docker-compose.yml
requirements.txt
README.md
- Python 3.11+
- Optional: MySQL 8+ (uses MySQL connector URI)
- Optional: Docker and Docker Compose
Windows (PowerShell):
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txtmacOS/Linux (bash/zsh):
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtCopy the example env and adjust:
cp .env.example .env # Windows PowerShell: cp .env.example .envImportant variables:
SECRET_KEY,JWT_SECRET_KEYDATABASE_URL(set to a MySQL connector URI, e.g.mysql+mysqlconnector://root:1234@localhost/resqtrack)MAIL_*for SMTPALLOWED_ORIGINSfor CORS in production (comma‑separated list)UPLOAD_FOLDER,MAX_CONTENT_LENGTH(bytes)- Optional S3:
AWS_S3_BUCKET,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION - Optional rate limit storage:
RATELIMIT_STORAGE_URI(e.g.,redis://redis:6379)
Using the DATABASE_URL from your .env (MySQL connector URI):
set FLASK_APP=backend/wsgi.py # Windows
flask db upgradeexport FLASK_APP=backend/wsgi.py # macOS/Linux
flask db upgradeFor MySQL, set DATABASE_URL to e.g. mysql+mysqlconnector://user:password@localhost:3306/resqtrack and run flask db upgrade.
python backend/wsgi.pyBackend: http://localhost:5000
Frontend (static):
cd frontend
python -m http.server 8000Visit http://localhost:8000/index.html
Build and start the full stack (Flask + MySQL + Redis):
docker-compose up --build- API: http://localhost:5000
- MySQL: localhost:3306
- Redis: localhost:6379
Notes:
- By default, the app uses
DATABASE_URLfrom your.env(use a MySQL connector URI, e.g.mysql+mysqlconnector://root:1234@localhost/resqtrack). - Volumes persist uploads and logs.
- CORS can be controlled via
ALLOWED_ORIGINSenv (comma‑separated).
Login:
curl -X POST http://localhost:5000/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "admin@resqtrack.com", "password": "admin123", "role": "ADMIN"}'Report a case (JSON):
curl -X POST http://localhost:5000/cases \
-H "Content-Type: application/json" \
-d '{"reporter_phone":"9999999999","location":"MG Road","animal_type":"Dog","urgency":"Low"}'Report a case with media (multipart):
curl -X POST http://localhost:5000/cases \
-F file=@/path/to/photo.jpg \
-F reporter_phone=9999999999 -F location="MG Road"Upload file directly:
curl -X POST http://localhost:5000/uploads -F file=@/path/to/photo.jpg| Role | Who | Notes |
|---|---|---|
| ADMIN | Platform admin | Can access admin endpoints, manage resources |
| NGO | NGO member | Can access NGO workflows |
| VOLUNTEER | Volunteer | Can access volunteer workflows |
JWT identity payload includes id, email, and role.
- CORS restricted via
ALLOWED_ORIGINS(production) - Upload validation: extension whitelist, MIME type check, file size limit, sanitized filename
- Global JSON error handlers for all exceptions (no HTML error pages)
- Rate limiting:
5/minfor/auth/login,10/hourfor registrations
- Run tests:
pytest -q- Lint:
flake8 backendCI (GitHub Actions) runs on push/PR: Python 3.11, installs deps, runs flake8 and pytest.
- 401 Unauthorized: Ensure
Authorization: Bearer <token>header is set for protected endpoints. - CORS errors in browser: set
ALLOWED_ORIGINSto include your frontend origin (e.g.,http://localhost:8000). - File upload fails: verify extension/MIME type and that
MAX_CONTENT_LENGTHisn’t exceeded. - MySQL connection errors in Docker: wait for db to be healthy, or check
DATABASE_URLand credentials. - Emails not sent: verify SMTP credentials and allow provider‑specific requirements (e.g., Gmail App Passwords).
- Rate limit exceeded: API returns 429; reduce frequency or configure
RATELIMIT_STORAGE_URI.