# Secure E-commerce API MVP FastAPI + SQLite MVP for a retail order-payment flow with modular architecture, JWT authentication, RBAC (client/shop roles), object-level authorization, strict validation, and secure logging. The project also includes a browser UI at `/` for the complete client flow: registration, login, catalog browsing, cart checkout, order viewing, mock payment confirmation, and shop-only product creation. ## Features - Customer registration and login with short-lived JWT access tokens - Product catalog browsing - Shop-only product creation - Order creation from cart-style line items - Object-level authorization for viewing and paying only your own orders - Mock payment confirmation that updates order status - Secure audit logging that avoids passwords, JWTs, and sensitive identifiers - Static frontend served by FastAPI with same-origin API calls ## Roles - **`client`** — default role, assigned on registration. Can browse products, create orders, view own orders, make payments. - **`shop`** — privileged role. Can create products. Assigned to the default shop account. ## Project Structure ```text app/ api/ core/ db/ models/ schemas/ services/ main.py ``` ## Requirements - Python 3.12 recommended ## Setup 1. Create and activate a virtual environment. 2. Install dependencies: ```bash pip install -r requirements.txt ``` 3. Optional: create a local environment file from the example and adjust secrets: ```bash cp .env.example .env ``` ## Initialize the SQLite Database The application creates tables automatically on startup. You can also initialize the database explicitly: ```bash python -m app.db.init_db ``` ### Create a Shop Account A shop account is **not** created by default. Run the dedicated script to create one: ```bash python -m app.db.create_shop_account ``` For safer bootstrap, the script no longer prints generated credentials to stdout. Use one of these approaches: 1. Interactive mode: the script securely asks for a strong password via `getpass()`. 2. Non-interactive mode: set `SHOP_ACCOUNT_PASSWORD` before running the script. Example output: ``` ============================================================ SHOP ACCOUNT CREATED SUCCESSFULLY ============================================================ Username: shop ============================================================ Password was accepted and hashed without being printed to stdout. ============================================================ ``` ## Run the Server ```bash uvicorn app.main:app --reload ``` Open: - Frontend: `http://127.0.0.1:8000/` - API docs: `http://127.0.0.1:8000/docs` - Health check: `http://127.0.0.1:8000/health` ## Docker ```bash docker build -t secure-online-shop . docker run -d --name secure-online-shop \ -p 80:8000 \ -e JWT_SECRET_KEY="replace-with-a-strong-32-plus-char-random-secret-value" \ -e SHOP_ACCOUNT_PASSWORD="StrongShopPassword1!" \ -e DEMO_SEED_PRODUCTS=true \ secure-online-shop ``` `SHOP_ACCOUNT_PASSWORD` is optional, but setting it creates the `shop` account at container startup. `DEMO_SEED_PRODUCTS=true` fills the catalog with demo rows for MVP presentation. ## Example Flow 1. Register a client with `POST /api/v1/auth/register` 2. Log in with `POST /api/v1/auth/login` 3. Log in as shop and create products with `POST /api/v1/products` 4. Browse products with `GET /api/v1/products` 5. Create an order with `POST /api/v1/orders` 6. View your orders with `GET /api/v1/orders` 7. Confirm payment with `POST /api/v1/payments/orders/{order_id}/confirm`