Skip to content

wkarbowski/email-management-system

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Email Management System

A professional Flask-based CRUD application for managing primary/secondary email record pairs. Exposes a versioned RESTful API backed by SQLite, ships a modern single-page web interface, and includes rate limiting, pagination, bulk operations, CSV export/import, and a full pytest test suite.

Features

  • Versioned REST API — all endpoints live under /api/v1/; legacy /api/ routes are retained for backward compatibility
  • Complete CRUD — Create, Read, Update, Delete individual records
  • Paginated listingGET /api/v1/email-records/list with configurable page size (max 100)
  • Bulk create — insert multiple records in a single JSON request
  • CSV export / import — download all records as CSV or upload a CSV to bulk-import
  • Rate limiting — per-IP limits via Flask-Limiter (configurable)
  • Advanced email validation — RFC-5321-inspired regex on both server and client
  • Health check endpoint/api/v1/health for load-balancer probes
  • Docker support — production-ready Dockerfile and docker-compose.yml
  • Test suite — pytest integration tests covering every endpoint and edge case
  • Structured logging — timestamped, levelled log output to stdout

Technology Stack

Layer Technology
Web framework Flask 2.3
Database SQLite (via stdlib sqlite3)
CORS Flask-CORS
Rate limiting Flask-Limiter
Frontend Vanilla JavaScript (ES6+), CSS3, HTML5
Containerisation Docker / Docker Compose
Testing pytest, pytest-flask, pytest-cov

Project Structure

email-management-system/
├── app.py                      # Application entry point and all route handlers
├── templates/
│   └── email_management.html   # Single-page web interface
├── tests/
│   ├── __init__.py
│   └── test_app.py             # pytest integration tests
├── docs/
│   └── API.md                  # Full API reference
├── Dockerfile                  # Production container image
├── docker-compose.yml          # Compose service definition
├── requirements.txt            # Python dependencies (runtime + dev)
├── .env.example                # Environment variable template
├── .gitignore
└── README.md

Quick Start

Prerequisites

  • Python 3.8 or higher
  • pip

Local Setup

# 1. Clone the repository
git clone https://github.com/Rosomak-002/email-management-system.git
cd email-management-system

# 2. Create and activate a virtual environment
python -m venv venv
source venv/bin/activate          # Windows: venv\Scripts\activate

# 3. Install dependencies
pip install -r requirements.txt

# 4. (Optional) configure environment
cp .env.example .env

# 5. Run the development server
python app.py

The application will be available at http://localhost:5002.

Docker

# Build and start
docker compose up --build

# Run in the background
docker compose up -d --build

# Stop
docker compose down

The SQLite database is persisted in a named Docker volume (db_data).

API Overview

Full reference: docs/API.md

Base URL: http://localhost:5002/api/v1

Method Path Description
GET /health Service health check
POST /email-records Create a single record
GET /email-records?primary_email=… Retrieve a single record
PUT /email-records Update a record's secondary email
DELETE /email-records Delete a record
GET /email-records/list Paginated list of all records
POST /email-records/bulk Bulk create from a JSON array
GET /email-records/export Download all records as CSV
POST /email-records/import Import records from a CSV file

Quick cURL Examples

# Create
curl -X POST http://localhost:5002/api/v1/email-records \
  -d "primary_email=alice@example.com&secondary_email=bob@example.com"

# Read
curl "http://localhost:5002/api/v1/email-records?primary_email=alice@example.com"

# Update  (JSON body)
curl -X PUT http://localhost:5002/api/v1/email-records \
  -H "Content-Type: application/json" \
  -d '{"primary_email":"alice@example.com","secondary_email":"new@example.com"}'

# Delete  (JSON body)
curl -X DELETE http://localhost:5002/api/v1/email-records \
  -H "Content-Type: application/json" \
  -d '{"primary_email":"alice@example.com"}'

# Paginated list
curl "http://localhost:5002/api/v1/email-records/list?page=1&per_page=10"

# Bulk create
curl -X POST http://localhost:5002/api/v1/email-records/bulk \
  -H "Content-Type: application/json" \
  -d '[{"primary_email":"u1@example.com","secondary_email":"s@example.com"}]'

# Export CSV
curl -o records.csv http://localhost:5002/api/v1/email-records/export

# Import CSV
curl -X POST http://localhost:5002/api/v1/email-records/import \
  -F "file=@records.csv"

Database Schema

CREATE TABLE email_records (
    primary_email   TEXT PRIMARY KEY,
    secondary_email TEXT NOT NULL,
    created_at      DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at      DATETIME DEFAULT CURRENT_TIMESTAMP
);

The database file is created automatically on first run. The path defaults to email_management.db in the project root and can be overridden via the DATABASE_PATH environment variable.

Configuration

Variable Default Description
DATABASE_PATH <project_root>/email_management.db Absolute or relative path to the SQLite file
FLASK_ENV production Set to development to enable the Flask debugger

Copy .env.example to .envpython-dotenv will load it automatically.

Running the Tests

# Run the full suite with coverage
pytest tests/ -v --cov=app --cov-report=term-missing

# Run a specific test file
pytest tests/test_app.py -v

Tests use an isolated temporary SQLite database and never touch the production file.

Rate Limits

Scope Limit
Global (per IP) 300 / day, 60 / hour
Create / Update / Delete 30 / minute
Read / List 60 / minute
Bulk create 10 / minute
Export / Import 10 / minute (export), 5 / minute (import)

Exceeding a limit returns 429 Too Many Requests.

Security Considerations

  • All queries use parameterised statements — no SQL injection risk
  • Input validation applied on both client (regex) and server (regex + length checks)
  • CORS is enabled globally; restrict origins in CORS(app, origins=[…]) for production
  • No authentication is implemented — add an auth layer (e.g. JWT) before exposing this publicly
  • Run behind a reverse proxy (nginx / Caddy) with TLS in production

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Commit your changes: git commit -m 'Add my feature'
  4. Push the branch: git push origin feature/my-feature
  5. Open a Pull Request

Please ensure pytest passes and flake8 reports no errors before submitting.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Author

rosomakgithub.com/Rosomak-002

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors