feat: add billing module with usage tracking, invoice generation, and stripe integration
This commit is contained in:
@@ -1,5 +1,153 @@
|
||||
PYTHON=".venv/bin/python3"
|
||||
RBOX=".venv/bin/rbox"
|
||||
.PHONY: help install dev test test-billing test-e2e test-coverage e2e-setup lint format clean run migrate init-db reset-db all
|
||||
|
||||
PYTHON := .venv/bin/python3
|
||||
PIP := .venv/bin/pip
|
||||
PYTEST := .venv/bin/pytest
|
||||
BLACK := .venv/bin/black
|
||||
RUFF := .venv/bin/ruff
|
||||
RBOX := .venv/bin/rbox
|
||||
|
||||
all:
|
||||
$(RBOX) --port 9004
|
||||
|
||||
help:
|
||||
@echo "RBox Development Makefile"
|
||||
@echo ""
|
||||
@echo "Available commands:"
|
||||
@echo " make all Run the application on port 9004"
|
||||
@echo " make install Install all dependencies"
|
||||
@echo " make dev Install development dependencies"
|
||||
@echo " make run Run the application locally"
|
||||
@echo " make test Run all tests"
|
||||
@echo " make test-billing Run billing tests only"
|
||||
@echo " make test-e2e Run end-to-end tests (visible browser)"
|
||||
@echo " make test-coverage Run tests with coverage report"
|
||||
@echo " make e2e-setup Install Playwright and browsers"
|
||||
@echo " make lint Run linting checks"
|
||||
@echo " make format Format code with black"
|
||||
@echo " make migrate Run database migrations"
|
||||
@echo " make init-db Initialize database with default data"
|
||||
@echo " make reset-db Reset database (WARNING: deletes all data)"
|
||||
@echo " make clean Clean up temporary files"
|
||||
@echo " make setup Complete setup (env + install + init-db)"
|
||||
|
||||
install:
|
||||
@echo "Installing dependencies..."
|
||||
$(PIP) install -r requirements.txt
|
||||
@echo "Dependencies installed successfully"
|
||||
|
||||
dev:
|
||||
@echo "Installing development dependencies..."
|
||||
$(PIP) install pytest pytest-asyncio pytest-cov httpx black ruff stripe apscheduler dataset
|
||||
@echo "Development dependencies installed successfully"
|
||||
|
||||
run:
|
||||
@echo "Starting RBox application..."
|
||||
@echo "Access the application at http://localhost:8000"
|
||||
$(PYTHON) -m rbox.main
|
||||
|
||||
test:
|
||||
@echo "Running all tests..."
|
||||
$(PYTEST) tests/ -v
|
||||
|
||||
test-billing:
|
||||
@echo "Running billing tests..."
|
||||
$(PYTEST) tests/billing/ -v
|
||||
|
||||
test-e2e:
|
||||
@echo "Running end-to-end tests with visible browser..."
|
||||
@echo "Make sure the application is running (make run in another terminal)"
|
||||
$(PYTEST) tests/e2e/ -v -s --tb=short
|
||||
|
||||
e2e-setup:
|
||||
@echo "Installing Playwright and browsers..."
|
||||
$(PIP) install playwright
|
||||
.venv/bin/playwright install chromium
|
||||
@echo "Playwright setup complete"
|
||||
|
||||
test-coverage:
|
||||
@echo "Running tests with coverage..."
|
||||
$(PYTEST) tests/ -v --cov=rbox --cov-report=html --cov-report=term
|
||||
@echo "Coverage report generated in htmlcov/index.html"
|
||||
|
||||
lint:
|
||||
@echo "Running linting checks..."
|
||||
$(RUFF) check rbox/
|
||||
@echo "Linting complete"
|
||||
|
||||
format:
|
||||
@echo "Formatting code..."
|
||||
$(BLACK) rbox/ tests/
|
||||
@echo "Code formatting complete"
|
||||
|
||||
migrate:
|
||||
@echo "Running database migrations..."
|
||||
@echo "Tortoise ORM auto-generates schemas on startup"
|
||||
$(PYTHON) -c "from rbox.main import app; print('Database schema will be created on first run')"
|
||||
|
||||
init-db:
|
||||
@echo "Initializing database with default data..."
|
||||
$(PYTHON) -c "import asyncio; \
|
||||
from tortoise import Tortoise; \
|
||||
from rbox.settings import settings; \
|
||||
from rbox.billing.models import PricingConfig; \
|
||||
from decimal import Decimal; \
|
||||
async def init(): \
|
||||
await Tortoise.init(db_url=settings.DATABASE_URL, modules={'models': ['rbox.models', 'rbox.billing.models']}); \
|
||||
await Tortoise.generate_schemas(); \
|
||||
count = await PricingConfig.all().count(); \
|
||||
if count == 0: \
|
||||
await PricingConfig.create(config_key='storage_per_gb_month', config_value=Decimal('0.0045'), description='Storage cost per GB per month', unit='per_gb_month'); \
|
||||
await PricingConfig.create(config_key='bandwidth_egress_per_gb', config_value=Decimal('0.009'), description='Bandwidth egress cost per GB', unit='per_gb'); \
|
||||
await PricingConfig.create(config_key='bandwidth_ingress_per_gb', config_value=Decimal('0.0'), description='Bandwidth ingress cost per GB (free)', unit='per_gb'); \
|
||||
await PricingConfig.create(config_key='free_tier_storage_gb', config_value=Decimal('15'), description='Free tier storage in GB', unit='gb'); \
|
||||
await PricingConfig.create(config_key='free_tier_bandwidth_gb', config_value=Decimal('15'), description='Free tier bandwidth in GB per month', unit='gb'); \
|
||||
await PricingConfig.create(config_key='tax_rate_default', config_value=Decimal('0.0'), description='Default tax rate (0 = no tax)', unit='percentage'); \
|
||||
print('Default pricing configuration created'); \
|
||||
else: \
|
||||
print('Pricing configuration already exists'); \
|
||||
await Tortoise.close_connections(); \
|
||||
asyncio.run(init())"
|
||||
@echo "Database initialized successfully"
|
||||
|
||||
reset-db:
|
||||
@echo "WARNING: This will delete all data!"
|
||||
@read -p "Are you sure? (yes/no): " confirm && [ "$$confirm" = "yes" ] || exit 1
|
||||
@rm -f rbox.db app/rbox.db storage/rbox.db
|
||||
@echo "Database reset complete. Run 'make init-db' to reinitialize"
|
||||
|
||||
clean:
|
||||
@echo "Cleaning up temporary files..."
|
||||
find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
|
||||
find . -type f -name "*.pyc" -delete
|
||||
find . -type f -name "*.pyo" -delete
|
||||
find . -type f -name "*.pyd" -delete
|
||||
find . -type d -name "*.egg-info" -exec rm -rf {} + 2>/dev/null || true
|
||||
find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true
|
||||
find . -type d -name ".ruff_cache" -exec rm -rf {} + 2>/dev/null || true
|
||||
rm -rf htmlcov/
|
||||
rm -rf .coverage
|
||||
@echo "Cleanup complete"
|
||||
|
||||
setup-env:
|
||||
@echo "Setting up environment file..."
|
||||
@if [ ! -f .env ]; then \
|
||||
cp .env.example .env 2>/dev/null || \
|
||||
echo "DATABASE_URL=sqlite:///app/rbox.db\nSECRET_KEY=$$(openssl rand -hex 32)\nSTRIPE_SECRET_KEY=\nSTRIPE_PUBLISHABLE_KEY=\nSTRIPE_WEBHOOK_SECRET=" > .env; \
|
||||
echo ".env file created. Please update with your configuration."; \
|
||||
else \
|
||||
echo ".env file already exists"; \
|
||||
fi
|
||||
|
||||
setup: setup-env install dev init-db
|
||||
@echo ""
|
||||
@echo "Setup complete!"
|
||||
@echo "Next steps:"
|
||||
@echo " 1. Update .env with your configuration (especially Stripe keys)"
|
||||
@echo " 2. Run 'make run' or 'make all' to start the application"
|
||||
@echo " 3. Access the application at http://localhost:8000"
|
||||
|
||||
docs:
|
||||
@echo "Generating API documentation..."
|
||||
@echo "API documentation available at http://localhost:8000/docs when running"
|
||||
@echo "ReDoc available at http://localhost:8000/redoc when running"
|
||||
|
||||
Reference in New Issue
Block a user