add readme and .env files
This commit is contained in:
31
.env.dev
Normal file
31
.env.dev
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# ===========================================
|
||||||
|
# Oil Customer Gateway - DEVELOPMENT Environment
|
||||||
|
# ===========================================
|
||||||
|
|
||||||
|
# Database Configuration
|
||||||
|
POSTGRES_USERNAME=postgres
|
||||||
|
POSTGRES_PASSWORD=password
|
||||||
|
POSTGRES_SERVER=192.168.1.204
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
POSTGRES_DBNAME=eamco
|
||||||
|
|
||||||
|
# JWT Configuration
|
||||||
|
# Generate with: python -c "import secrets; print(secrets.token_hex(32))"
|
||||||
|
JWT_SECRET_KEY=CHANGE_ME_GENERATE_A_SECURE_KEY
|
||||||
|
JWT_ALGORITHM=HS256
|
||||||
|
# Longer expiry for development convenience
|
||||||
|
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=525600
|
||||||
|
|
||||||
|
# Authorize.Net (Sandbox/Test credentials)
|
||||||
|
AUTH_NET_API_LOGIN_ID=9U6w96gZmX
|
||||||
|
AUTH_NET_TRANSACTION_KEY=94s6Qy458mMNJr7G
|
||||||
|
|
||||||
|
# SMTP Configuration
|
||||||
|
SMTP_SERVER=smtp.gmail.com
|
||||||
|
SMTP_PORT=587
|
||||||
|
SMTP_USERNAME=CHANGE_ME_TO_YOUR_EMAIL
|
||||||
|
SMTP_PASSWORD=CHANGE_ME_TO_YOUR_APP_PASSWORD
|
||||||
|
SMTP_FROM_EMAIL=CHANGE_ME_TO_YOUR_EMAIL
|
||||||
|
|
||||||
|
# Frontend URL
|
||||||
|
FRONTEND_URL=http://localhost:3000
|
||||||
58
.env.example
Normal file
58
.env.example
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# ===========================================
|
||||||
|
# Oil Customer Gateway - Environment Configuration
|
||||||
|
# ===========================================
|
||||||
|
# Copy this file to .env.dev, .env.local, or .env.prod
|
||||||
|
# and fill in the appropriate values for each environment.
|
||||||
|
#
|
||||||
|
# IMPORTANT: Never commit actual .env files to version control!
|
||||||
|
# ===========================================
|
||||||
|
|
||||||
|
# ===========================================
|
||||||
|
# DATABASE CONFIGURATION (Required)
|
||||||
|
# ===========================================
|
||||||
|
POSTGRES_USERNAME=postgres
|
||||||
|
POSTGRES_PASSWORD=your_database_password_here
|
||||||
|
POSTGRES_SERVER=192.168.1.204
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
POSTGRES_DBNAME=eamco
|
||||||
|
|
||||||
|
# ===========================================
|
||||||
|
# JWT CONFIGURATION (Required)
|
||||||
|
# ===========================================
|
||||||
|
# Generate a secure secret key using: python -c "import secrets; print(secrets.token_hex(32))"
|
||||||
|
# IMPORTANT: Use a unique, strong key for production (at least 32 characters)
|
||||||
|
JWT_SECRET_KEY=generate_a_secure_random_key_here_at_least_32_chars
|
||||||
|
JWT_ALGORITHM=HS256
|
||||||
|
# Token expiry in minutes (30 for production, can use longer for dev)
|
||||||
|
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||||
|
|
||||||
|
# ===========================================
|
||||||
|
# AUTHORIZE.NET PAYMENT GATEWAY (Required for payments)
|
||||||
|
# ===========================================
|
||||||
|
# Get these from your Authorize.Net merchant account
|
||||||
|
# Use sandbox credentials for development/testing
|
||||||
|
AUTH_NET_API_LOGIN_ID=your_api_login_id
|
||||||
|
AUTH_NET_TRANSACTION_KEY=your_transaction_key
|
||||||
|
|
||||||
|
# ===========================================
|
||||||
|
# SMTP EMAIL CONFIGURATION (Required for password reset)
|
||||||
|
# ===========================================
|
||||||
|
SMTP_SERVER=smtp.gmail.com
|
||||||
|
SMTP_PORT=587
|
||||||
|
SMTP_USERNAME=your_email@gmail.com
|
||||||
|
# For Gmail, use an App Password (not your regular password)
|
||||||
|
# Generate at: https://myaccount.google.com/apppasswords
|
||||||
|
SMTP_PASSWORD=your_app_password_here
|
||||||
|
SMTP_FROM_EMAIL=your_email@gmail.com
|
||||||
|
|
||||||
|
# ===========================================
|
||||||
|
# FRONTEND URL (Required for password reset links)
|
||||||
|
# ===========================================
|
||||||
|
FRONTEND_URL=http://localhost:3000
|
||||||
|
|
||||||
|
# ===========================================
|
||||||
|
# CORS ORIGINS (Optional - defaults based on MODE)
|
||||||
|
# ===========================================
|
||||||
|
# Comma-separated list of allowed origins
|
||||||
|
# Leave empty to use default origins for the current MODE
|
||||||
|
# CORS_ORIGINS=http://localhost:5173,http://localhost:8000
|
||||||
33
.env.prod
Normal file
33
.env.prod
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# ===========================================
|
||||||
|
# Oil Customer Gateway - PRODUCTION Environment
|
||||||
|
# ===========================================
|
||||||
|
# CRITICAL: Use strong, unique values for all secrets!
|
||||||
|
|
||||||
|
# Database Configuration
|
||||||
|
POSTGRES_USERNAME=postgres
|
||||||
|
POSTGRES_PASSWORD=CHANGE_ME_TO_YOUR_PROD_DB_PASSWORD
|
||||||
|
POSTGRES_SERVER=192.168.1.204
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
POSTGRES_DBNAME=auburnoil
|
||||||
|
|
||||||
|
# JWT Configuration
|
||||||
|
# Generate with: python -c "import secrets; print(secrets.token_hex(32))"
|
||||||
|
# IMPORTANT: Must be unique and at least 32 characters
|
||||||
|
JWT_SECRET_KEY=CHANGE_ME_GENERATE_A_SECURE_KEY_FOR_PRODUCTION
|
||||||
|
JWT_ALGORITHM=HS256
|
||||||
|
# Short expiry for production security (30 minutes)
|
||||||
|
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||||
|
|
||||||
|
# Authorize.Net (PRODUCTION credentials)
|
||||||
|
AUTH_NET_API_LOGIN_ID=CHANGE_ME_TO_YOUR_PROD_LOGIN_ID
|
||||||
|
AUTH_NET_TRANSACTION_KEY=CHANGE_ME_TO_YOUR_PROD_KEY
|
||||||
|
|
||||||
|
# SMTP Configuration
|
||||||
|
SMTP_SERVER=smtp.gmail.com
|
||||||
|
SMTP_PORT=587
|
||||||
|
SMTP_USERNAME=CHANGE_ME_TO_YOUR_EMAIL
|
||||||
|
SMTP_PASSWORD=CHANGE_ME_TO_YOUR_APP_PASSWORD
|
||||||
|
SMTP_FROM_EMAIL=CHANGE_ME_TO_YOUR_EMAIL
|
||||||
|
|
||||||
|
# Frontend URL
|
||||||
|
FRONTEND_URL=https://portal.auburnoil.com
|
||||||
47
.gitignore
vendored
47
.gitignore
vendored
@@ -119,4 +119,49 @@ helperfunctions/
|
|||||||
test.py
|
test.py
|
||||||
tools/
|
tools/
|
||||||
nginx.txt
|
nginx.txt
|
||||||
app/node_modules/
|
app/node_modules/
|
||||||
|
|
||||||
|
# Database files
|
||||||
|
*.db
|
||||||
|
*.sqlite
|
||||||
|
*.sqlite3
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Local development
|
||||||
|
.env.local
|
||||||
|
.env.development
|
||||||
|
.env.production
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# Coverage reports
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
coverage.xml
|
||||||
|
|
||||||
|
# Migrations (if using Alembic or similar)
|
||||||
|
alembic/versions/*.py
|
||||||
|
!alembic/versions/
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
.tox/
|
||||||
|
.cache/
|
||||||
|
.pytest_cache/
|
||||||
|
|||||||
299
README.md
299
README.md
@@ -1 +1,298 @@
|
|||||||
# API
|
# Auburn Oil Customer Gateway - API
|
||||||
|
|
||||||
|
A modern, high-performance REST API powering the Auburn Oil customer self-service portal. Built with FastAPI and designed for reliability, security, and ease of deployment.
|
||||||
|
|
||||||
|
```
|
||||||
|
___ __ ____ _ __
|
||||||
|
/ | __ __/ /_ __ ___________ / __ \(_) /
|
||||||
|
/ /| |/ / / / __ \/ / / / ___/ __ \ / / / / / /
|
||||||
|
/ ___ / /_/ / /_/ / /_/ / / / / / / / /_/ / / /
|
||||||
|
/_/ |_\__,_/_.___/\__,_/_/ /_/ /_/ \____/_/_/
|
||||||
|
|
||||||
|
Customer Gateway API
|
||||||
|
```
|
||||||
|
|
||||||
|
## What This Does
|
||||||
|
|
||||||
|
This API serves as the backbone for Auburn Oil's customer portal, enabling:
|
||||||
|
|
||||||
|
| Feature | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| **Customer Onboarding** | Multi-step registration for new customers with tank photo uploads |
|
||||||
|
| **Order Management** | Place heating oil delivery orders with real-time pricing |
|
||||||
|
| **Payment Processing** | Secure credit card handling via Authorize.net (PCI-compliant) |
|
||||||
|
| **Account Management** | Password reset, profile updates, delivery history |
|
||||||
|
| **Tank Inspections** | Upload and manage annual tank inspection photos |
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
- **Framework**: FastAPI 0.104 (async Python)
|
||||||
|
- **Database**: PostgreSQL with SQLAlchemy 2.0 (async)
|
||||||
|
- **Authentication**: JWT tokens with bcrypt password hashing
|
||||||
|
- **Payments**: Authorize.net CIM (tokenized card storage)
|
||||||
|
- **Server**: Uvicorn ASGI
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Docker & Docker Compose
|
||||||
|
- PostgreSQL database (can be remote)
|
||||||
|
- Authorize.net merchant account (sandbox for development)
|
||||||
|
|
||||||
|
### 1. Configure Environment
|
||||||
|
|
||||||
|
Copy the example environment file and customize:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env.dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `.env.dev` with your settings:
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Database
|
||||||
|
POSTGRES_SERVER=your-db-host
|
||||||
|
POSTGRES_PORT=5432
|
||||||
|
POSTGRES_DBNAME=auburnoil
|
||||||
|
POSTGRES_USERNAME=postgres
|
||||||
|
POSTGRES_PASSWORD=your-secure-password
|
||||||
|
|
||||||
|
# Security (generate a strong key!)
|
||||||
|
JWT_SECRET_KEY=your-256-bit-secret-key
|
||||||
|
JWT_ALGORITHM=HS256
|
||||||
|
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=1440
|
||||||
|
|
||||||
|
# Payments (use sandbox credentials for dev)
|
||||||
|
AUTH_NET_API_LOGIN_ID=your-login-id
|
||||||
|
AUTH_NET_TRANSACTION_KEY=your-transaction-key
|
||||||
|
|
||||||
|
# Email (for password resets)
|
||||||
|
SMTP_SERVER=smtp.gmail.com
|
||||||
|
SMTP_PORT=587
|
||||||
|
SMTP_USERNAME=your-email@gmail.com
|
||||||
|
SMTP_PASSWORD=your-app-password
|
||||||
|
SMTP_FROM_EMAIL=noreply@yourdomain.com
|
||||||
|
|
||||||
|
# Frontend URL (for password reset links)
|
||||||
|
FRONTEND_URL=http://localhost:3000
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Deploy with Docker
|
||||||
|
|
||||||
|
**Development** (with hot-reload):
|
||||||
|
```bash
|
||||||
|
cd deploy
|
||||||
|
docker compose -f docker-compose.dev.yml up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
**Local Network Testing**:
|
||||||
|
```bash
|
||||||
|
cd deploy
|
||||||
|
docker compose -f docker-compose.local.yml up --build
|
||||||
|
```
|
||||||
|
|
||||||
|
**Production**:
|
||||||
|
```bash
|
||||||
|
cd deploy
|
||||||
|
docker compose -f docker-compose.prod.yml up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Access the API
|
||||||
|
|
||||||
|
| Environment | API URL | Docs |
|
||||||
|
|-------------|---------|------|
|
||||||
|
| Development | http://localhost:8000 | http://localhost:8000/docs |
|
||||||
|
| Production | https://api.portal.auburnoil.com | https://api.portal.auburnoil.com/docs |
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
### Authentication (`/auth`)
|
||||||
|
|
||||||
|
| Method | Endpoint | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| `POST` | `/auth/login` | Login with email/password, returns JWT |
|
||||||
|
| `POST` | `/auth/register` | Register existing customer (requires account #) |
|
||||||
|
| `POST` | `/auth/new` | New customer single-step registration |
|
||||||
|
| `POST` | `/auth/step1` | New customer wizard - Step 1 (info) |
|
||||||
|
| `POST` | `/auth/step2` | New customer wizard - Step 2 (credentials) |
|
||||||
|
| `POST` | `/auth/step3` | New customer wizard - Step 3 (tank photos) |
|
||||||
|
| `GET` | `/auth/me` | Get current user profile |
|
||||||
|
| `POST` | `/auth/forgot-password` | Request password reset email |
|
||||||
|
| `POST` | `/auth/reset-password` | Complete password reset |
|
||||||
|
| `POST` | `/auth/change-password` | Change password (authenticated) |
|
||||||
|
| `POST` | `/auth/upload-tank-images` | Upload tank inspection photos |
|
||||||
|
| `GET` | `/auth/tank-images/{account}` | Get tank image history |
|
||||||
|
|
||||||
|
### Orders (`/order`)
|
||||||
|
|
||||||
|
| Method | Endpoint | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| `POST` | `/order/` | Place new delivery order (min 100 gallons) |
|
||||||
|
|
||||||
|
### Customer Info (`/info`)
|
||||||
|
|
||||||
|
| Method | Endpoint | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| `GET` | `/info/deliveries` | Get delivery history (last 20) |
|
||||||
|
| `GET` | `/info/pricing/current` | Get current oil price per gallon |
|
||||||
|
|
||||||
|
### Payments (`/payment`)
|
||||||
|
|
||||||
|
| Method | Endpoint | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| `POST` | `/payment/process` | Process payment (saved or new card) |
|
||||||
|
| `GET` | `/payment/cards` | List saved payment methods |
|
||||||
|
| `POST` | `/payment/cards` | Save new card (tokenize) |
|
||||||
|
| `PUT` | `/payment/cards/{id}` | Update card details |
|
||||||
|
| `DELETE` | `/payment/cards/{id}` | Remove saved card |
|
||||||
|
| `POST` | `/payment/cards/{id}/set-default` | Set default payment method |
|
||||||
|
| `POST` | `/payment/sync-billing-info` | Sync billing to Authorize.net |
|
||||||
|
|
||||||
|
## Database Setup
|
||||||
|
|
||||||
|
### Run Migrations
|
||||||
|
|
||||||
|
Apply database migrations in order:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Connect to your PostgreSQL database
|
||||||
|
psql -h your-host -U postgres -d auburnoil
|
||||||
|
|
||||||
|
# Run migrations
|
||||||
|
\i migrations/20240108_create_portal_user_table.sql
|
||||||
|
\i migrations/20240108_add_tank_image_upload_dates.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Tables
|
||||||
|
|
||||||
|
| Table | Purpose |
|
||||||
|
|-------|---------|
|
||||||
|
| `customer_customer` | Customer profiles and addresses |
|
||||||
|
| `portal_user` | Portal login credentials |
|
||||||
|
| `delivery_delivery` | Delivery orders and history |
|
||||||
|
| `card_card` | Saved payment methods (tokenized) |
|
||||||
|
| `transactions` | Payment transaction records |
|
||||||
|
| `customer_tank` | Tank inspection metadata |
|
||||||
|
| `pricing_oil_oil` | Daily oil pricing |
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
api/
|
||||||
|
├── main.py # FastAPI app entry point
|
||||||
|
├── config.py # Environment configuration
|
||||||
|
├── database.py # Database connection (async)
|
||||||
|
├── models.py # SQLAlchemy ORM models
|
||||||
|
├── schemas.py # Pydantic request/response schemas
|
||||||
|
├── routers/
|
||||||
|
│ ├── auth.py # Authentication endpoints
|
||||||
|
│ ├── info.py # Customer info endpoints
|
||||||
|
│ ├── order.py # Order management
|
||||||
|
│ └── payment.py # Payment processing
|
||||||
|
├── services/
|
||||||
|
│ └── authorizenet.py # Authorize.net integration
|
||||||
|
├── .env.example # Environment template
|
||||||
|
├── .env.dev # Development config
|
||||||
|
├── .env.local # Local network config
|
||||||
|
├── .env.prod # Production config
|
||||||
|
├── Dockerfile.dev # Development container
|
||||||
|
├── Dockerfile.local # Local network container
|
||||||
|
├── Dockerfile.prod # Production container
|
||||||
|
└── requirements.txt # Python dependencies
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Features
|
||||||
|
|
||||||
|
- **JWT Authentication**: Stateless token-based auth with configurable expiration
|
||||||
|
- **Password Hashing**: bcrypt with automatic truncation for compatibility
|
||||||
|
- **PCI Compliance**: Card data never stored locally (Authorize.net tokenization)
|
||||||
|
- **Image Sanitization**: Uploaded images resized, metadata stripped
|
||||||
|
- **CORS Protection**: Environment-specific allowed origins
|
||||||
|
- **Input Validation**: Pydantic schemas validate all inputs
|
||||||
|
|
||||||
|
## Environment Variables Reference
|
||||||
|
|
||||||
|
| Variable | Required | Description |
|
||||||
|
|----------|----------|-------------|
|
||||||
|
| `MODE` | Yes | `DEVELOPMENT`, `LOCAL`, or `PRODUCTION` |
|
||||||
|
| `POSTGRES_SERVER` | Yes | Database host |
|
||||||
|
| `POSTGRES_PORT` | Yes | Database port (usually 5432) |
|
||||||
|
| `POSTGRES_DBNAME` | Yes | Database name |
|
||||||
|
| `POSTGRES_USERNAME` | Yes | Database user |
|
||||||
|
| `POSTGRES_PASSWORD` | Yes | Database password |
|
||||||
|
| `JWT_SECRET_KEY` | Yes | Secret for signing tokens (use 256+ bits) |
|
||||||
|
| `JWT_ALGORITHM` | Yes | Algorithm (HS256 recommended) |
|
||||||
|
| `JWT_ACCESS_TOKEN_EXPIRE_MINUTES` | Yes | Token lifetime in minutes |
|
||||||
|
| `AUTH_NET_API_LOGIN_ID` | Yes | Authorize.net API Login ID |
|
||||||
|
| `AUTH_NET_TRANSACTION_KEY` | Yes | Authorize.net Transaction Key |
|
||||||
|
| `SMTP_SERVER` | Yes | SMTP server for emails |
|
||||||
|
| `SMTP_PORT` | Yes | SMTP port (587 for TLS) |
|
||||||
|
| `SMTP_USERNAME` | Yes | SMTP username |
|
||||||
|
| `SMTP_PASSWORD` | Yes | SMTP password/app password |
|
||||||
|
| `SMTP_FROM_EMAIL` | Yes | From address for emails |
|
||||||
|
| `FRONTEND_URL` | Yes | Frontend URL for reset links |
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
**Database connection failed**
|
||||||
|
```
|
||||||
|
Check POSTGRES_* environment variables
|
||||||
|
Ensure database is accessible from Docker network
|
||||||
|
Verify firewall allows connections on port 5432
|
||||||
|
```
|
||||||
|
|
||||||
|
**JWT token invalid**
|
||||||
|
```
|
||||||
|
Ensure JWT_SECRET_KEY is the same across restarts
|
||||||
|
Check token hasn't expired
|
||||||
|
Verify JWT_ALGORITHM matches what was used to sign
|
||||||
|
```
|
||||||
|
|
||||||
|
**Authorize.net errors**
|
||||||
|
```
|
||||||
|
Sandbox vs Production: Use correct credentials for each
|
||||||
|
Test cards: Use Authorize.net test card numbers in sandbox
|
||||||
|
Check API Login ID and Transaction Key are correct
|
||||||
|
```
|
||||||
|
|
||||||
|
**Image upload fails**
|
||||||
|
```
|
||||||
|
Max file size: 20MB per image
|
||||||
|
Supported formats: JPEG, PNG
|
||||||
|
Check /images volume is mounted correctly
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Running Locally (without Docker)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create virtual environment
|
||||||
|
python -m venv venv
|
||||||
|
source venv/bin/activate # Windows: venv\Scripts\activate
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
export MODE=DEVELOPMENT
|
||||||
|
# ... set other variables
|
||||||
|
|
||||||
|
# Run with hot-reload
|
||||||
|
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Documentation
|
||||||
|
|
||||||
|
FastAPI auto-generates interactive documentation:
|
||||||
|
|
||||||
|
- **Swagger UI**: http://localhost:8000/docs
|
||||||
|
- **ReDoc**: http://localhost:8000/redoc
|
||||||
|
- **OpenAPI JSON**: http://localhost:8000/openapi.json
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Auburn Oil Customer Gateway** - Built with reliability in mind for New Hampshire and Massachusetts heating oil customers.
|
||||||
|
|||||||
Reference in New Issue
Block a user