Add multi-tier subscription system (Starter, Professional, Enterprise) with per-tier storage and bandwidth pricing, replace static free-tier limits with nullable usage-based fields in SubscriptionPlan model, introduce subscribe/unsubscribe API endpoints with plan validation, update invoice generator to calculate costs based on user's active plan tier, and refactor pricing page to load plans dynamically from backend API instead of hardcoded HTML.
158 lines
6.7 KiB
Makefile
158 lines
6.7 KiB
Makefile
.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
|
|
MYWEBDAV := .venv/bin/mywebdav
|
|
|
|
all:
|
|
$(MYWEBDAV) --port 9004
|
|
|
|
help:
|
|
@echo "MyWebdav 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..."
|
|
python -m venv .venv
|
|
$(PIP) install -e .
|
|
$(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 MyWebdav application..."
|
|
@echo "Access the application at http://localhost:9004"
|
|
$(PYTHON) -m mywebdav.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=mywebdav --cov-report=html --cov-report=term
|
|
@echo "Coverage report generated in htmlcov/index.html"
|
|
|
|
lint:
|
|
@echo "Running linting checks..."
|
|
$(RUFF) check mywebdav/
|
|
@echo "Linting complete"
|
|
|
|
format:
|
|
@echo "Formatting code..."
|
|
$(BLACK) mywebdav/ tests/
|
|
@echo "Code formatting complete"
|
|
|
|
migrate:
|
|
@echo "Running database migrations..."
|
|
@echo "Tortoise ORM auto-generates schemas on startup"
|
|
$(PYTHON) -c "from mywebdav.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 mywebdav.settings import settings; \
|
|
from mywebdav.billing.models import PricingConfig; \
|
|
from decimal import Decimal; \
|
|
async def init(): \
|
|
await Tortoise.init(db_url=settings.DATABASE_URL, modules={'models': ['mywebdav.models', 'mywebdav.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.005'), description='Storage cost per GB per month (Starter tier)', unit='per_gb_month'); \
|
|
await PricingConfig.create(config_key='storage_per_gb_month_pro', config_value=Decimal('0.004'), description='Storage cost per GB per month (Professional tier)', unit='per_gb_month'); \
|
|
await PricingConfig.create(config_key='storage_per_gb_month_enterprise', config_value=Decimal('0.003'), description='Storage cost per GB per month (Enterprise tier, 10TB+)', unit='per_gb_month'); \
|
|
await PricingConfig.create(config_key='bandwidth_egress_per_gb', config_value=Decimal('0.008'), description='Bandwidth egress cost per GB (Starter tier)', unit='per_gb'); \
|
|
await PricingConfig.create(config_key='bandwidth_egress_per_gb_pro', config_value=Decimal('0.007'), description='Bandwidth egress cost per GB (Professional tier)', unit='per_gb'); \
|
|
await PricingConfig.create(config_key='bandwidth_egress_per_gb_enterprise', config_value=Decimal('0.005'), description='Bandwidth egress cost per GB (Enterprise tier)', 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='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 mywebdav.db app/mywebdav.db storage/mywebdav.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/mywebdav.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:9004"
|
|
|
|
docs:
|
|
@echo "Generating API documentation..."
|
|
@echo "API documentation available at http://localhost:9004/docs when running"
|
|
@echo "ReDoc available at http://localhost:9004/redoc when running"
|