Clement-coder/feg-power

FEG Power System Units — FastAPI backend + Next.js frontend for premium permanent magnet generator sales

★ 1Forks 0TypeScriptGitHub ↗Compare

Project website ↗

README

FEG Power Backend

Backend API for FEG Power System Units — premium permanent magnet generator sales.

Built with FastAPI, SQLAlchemy 2.0 async, PostgreSQL, Alembic, and Cloudinary.


Tech Stack

Layer Technology
Language Python 3.13
Framework FastAPI
Package manager uv
Database PostgreSQL 16
ORM SQLAlchemy 2.0 (async)
Migrations Alembic
Auth JWT (access + refresh)
Password hashing bcrypt
Image storage Cloudinary
Containerisation Docker + Docker Compose
Logging structlog

Project Structure

app/
├── api/
│   └── v1/
│       ├── router.py           # Aggregates all feature routers
│       ├── auth/router.py      # Register, login, refresh, logout, /me
│       ├── admin/router.py     # Admin stats dashboard
│       ├── customers/router.py # Customer profile + order history
│       ├── products/router.py  # Public catalog + admin CRUD
│       ├── cart/router.py      # Cart management (authenticated)
│       ├── checkout/router.py  # Checkout → order + Telegram URL
│       ├── orders/router.py    # Admin order management
│       ├── tracking/router.py  # Public tracking + admin updates
│       └── health/router.py    # Liveness + DB connectivity probe
│
├── core/
│   ├── config.py           # Pydantic-settings — all env vars
│   ├── constants.py        # App-wide magic values
│   ├── exceptions.py       # Domain exception hierarchy
│   ├── exception_handlers.py # Maps exceptions → HTTP responses
│   ├── security.py         # bcrypt password hashing
│   ├── jwt.py              # JWT creation and decoding
│   ├── logger.py           # structlog — JSON prod / colour dev
│   └── dependencies.py     # DI wiring — repos, services, auth, authz
│
├── db/
│   ├── base.py             # DeclarativeBase + TimestampMixin
│   ├── database.py         # Engine lifecycle (init / dispose)
│   └── session.py          # Session factory + get_db dependency
│
├── models/
│   ├── user.py
│   ├── product.py
│   ├── cart.py             # Cart + CartItem
│   ├── order.py            # Order + OrderItem
│   └── tracking.py
│
├── repositories/           # Database I/O only — no business logic
│   ├── base.py
│   ├── user.py
│   ├── product.py
│   ├── cart.py
│   ├── order.py
│   └── tracking.py
│
├── schemas/                # Pydantic v2 request/response schemas
│   ├── base.py
│   ├── response.py         # Standard { success, message, data } envelope
│   ├── user.py
│   ├── product.py
│   ├── cart.py
│   ├── order.py
│   └── tracking.py
│
├── services/               # All business logic
│   ├── auth_service.py
│   ├── product_service.py
│   ├── cart_service.py
│   ├── checkout_service.py
│   ├── order_service.py
│   └── tracking_service.py
│
├── integrations/
│   └── cloudinary.py       # Upload, delete, replace image
│
├── utils/
│   ├── identifiers.py      # Order number + tracking ID generators
│   ├── slugify.py          # URL-safe slug from product name
│   ├── telegram.py         # Pre-filled Telegram deep-link builder
│   └── pagination.py       # PaginationParams dependency + meta
│
└── main.py                 # FastAPI app factory + lifespan

Quick Start

Prerequisites

  • Python 3.13+
  • PostgreSQL 16
  • uv package manager
  • Cloudinary account

1. Install dependencies

uv sync

2. Configure environment

cp .env.example .env
# Fill in DATABASE_URL, JWT_SECRET_KEY, and Cloudinary credentials

3. Run migrations

uv run alembic upgrade head

4. Start the development server

uv run uvicorn app.main:app --reload

API: http://localhost:8000
Docs: http://localhost:8000/docs


Docker

docker compose up --build

Runs PostgreSQL 16 + API. Migrations execute automatically on container start.


API Endpoints

Authentication

Method Path Auth Description
POST /api/v1/auth/register — Register customer
POST /api/v1/auth/login — Login, get tokens
POST /api/v1/auth/refresh — Refresh token pair
POST /api/v1/auth/logout Bearer Logout (stateless)
GET /api/v1/auth/me Bearer Current user

Customers

Method Path Auth Description
GET /api/v1/customers/me Customer View profile
GET /api/v1/customers/me/orders Customer My orders
GET /api/v1/customers/me/orders/{id} Customer My order detail

Products

Method Path Auth Description
GET /api/v1/products — Browse catalog
GET /api/v1/products/{slug} — Product detail
POST /api/v1/products Admin Create product
PATCH /api/v1/products/{id} Admin Update product
POST /api/v1/products/{id}/image Admin Upload image
DELETE /api/v1/products/{id} Admin Delete product

Cart

Method Path Auth Description
GET /api/v1/cart Customer View cart
POST /api/v1/cart/items Customer Add item
PATCH /api/v1/cart/items/{product_id} Customer Set quantity
DELETE /api/v1/cart/items/{product_id} Customer Remove item
DELETE /api/v1/cart Customer Clear cart

Checkout

Method Path Auth Description
POST /api/v1/checkout Customer Place order from cart

Orders (Admin)

Method Path Auth Description
GET /api/v1/orders Admin All orders
GET /api/v1/orders/{id} Admin Any order
PATCH /api/v1/orders/{id}/status Admin Update status / ship
PATCH /api/v1/orders/{id}/notes Admin Admin notes

Tracking

Method Path Auth Description
GET /api/v1/tracking/{tracking_id} — Public shipment status
PATCH /api/v1/tracking/{tracking_id} Admin Update tracking

Health

Method Path Auth Description
GET /api/v1/health — Liveness + DB probe

Admin

Method Path Auth Description
GET /api/v1/admin/stats Admin Dashboard counts

Standard Response Format

Every endpoint returns the same envelope:

{
  "success": true,
  "message": "Product created successfully.",
  "data": { "..." }
}

Errors:

{
  "success": false,
  "message": "Product not found.",
  "data": null,
  "errors": null
}

Order Lifecycle

pending_payment → paid → preparing → packed → shipped → out_for_delivery → delivered

Setting status to shipped automatically generates: FEG-TRK-XXXXXXXXX


Order Numbers

Format: FEG-ORD-YYYYMMDD-XXXXXX
Example: FEG-ORD-20260702-000124


Migrations

# After modifying models
uv run alembic revision --autogenerate -m "describe_change"
uv run alembic upgrade head

Environment Variables

See .env.example. Key variables:

Variable Required Description
DATABASE_URL ✓ PostgreSQL async URL
JWT_SECRET_KEY ✓ Min 32 chars — use openssl rand -hex 32
CLOUDINARY_CLOUD_NAME ✓ Cloudinary account
CLOUDINARY_API_KEY ✓ Cloudinary API key
CLOUDINARY_API_SECRET ✓ Cloudinary API secret
ALLOWED_ORIGINS — JSON array: ["http://localhost:3000"]

Contributors

larisavlasceanu44-ship-it

Issues