Invoice Generation Service
This is a FastAPI application for generating and managing invoices. It allows users to register, login, and manage their invoices with full authentication and user-specific data access.
Features
- User registration and authentication with JWT
- Generate invoices with automatic invoice number generation
- Store invoice details in SQLite database
- Retrieve invoice information by ID or invoice number
- Update invoice details and status
- Delete invoices
- User-specific invoice management (users can only access their own invoices)
- Advanced search and filtering options
- Web-based user interface for invoice management
- Health check endpoint
Technical Stack
- Framework: FastAPI
- Database: SQLite with SQLAlchemy ORM
- Migrations: Alembic
- Validation: Pydantic
- Authentication: JWT (JSON Web Tokens)
- Password Hashing: Bcrypt
- Frontend: Jinja2 Templates, HTML, CSS, JavaScript
- Linting: Ruff
Project Structure
.
├── alembic.ini # Alembic configuration file
├── app # Application package
│ ├── api # API routes
│ │ └── routes # API route modules
│ │ ├── __init__.py # Routes initialization
│ │ ├── invoices.py # Invoice API routes
│ │ └── frontend.py # Frontend routes
│ ├── core # Core functionality
│ │ ├── config.py # Application settings
│ │ ├── database.py # Database connection setup
│ │ └── utils.py # Utility functions
│ ├── models # SQLAlchemy models
│ │ ├── __init__.py # Models initialization
│ │ └── invoice.py # Invoice and InvoiceItem models
│ ├── schemas # Pydantic schemas
│ │ ├── __init__.py # Schemas initialization
│ │ └── invoice.py # Invoice-related schemas
│ ├── static # Static files
│ │ ├── css # CSS styles
│ │ │ └── styles.css # Main stylesheet
│ │ └── js # JavaScript files
│ │ └── main.js # Main JavaScript file
│ └── templates # Jinja2 templates
│ ├── base.html # Base template with layout
│ ├── home.html # Home page
│ ├── create_invoice.html # Invoice creation form
│ ├── search_invoice.html # Search for invoices
│ └── invoice_details.html # Invoice details page
├── main.py # Application entry point
├── migrations # Alembic migrations
│ ├── env.py # Alembic environment
│ ├── script.py.mako # Migration script template
│ └── versions # Migration scripts
│ └── ef0aaab3a275_initial_database_tables.py # Initial migration
├── requirements.txt # Project dependencies
└── pyproject.toml # Ruff configuration
API Endpoints
Health Check
GET /health
: Check if the service is running
Authentication API
POST /api/v1/auth/register
: Register a new user- Request body: User registration details (email, username, password, etc.)
- Returns: User details (without password)
POST /api/v1/auth/login
: Login and get an access token- Request body: Form data with username/email and password
- Returns: JWT access token
GET /api/v1/auth/me
: Get current user details- Headers:
Authorization: Bearer {token}
- Returns: Current user details
- Headers:
Invoice Management API
All invoice endpoints require authentication with a valid JWT token in the Authorization header: Authorization: Bearer {token}
POST /api/v1/invoices
: Create a new invoice (associated with the authenticated user)GET /api/v1/invoices
: List invoices belonging to the authenticated user (with pagination)- Query parameters:
skip
: Number of records to skip (default: 0)limit
: Maximum number of records to return (default: 100)fields
: Comma-separated list of fields to include in the response (e.g., "id,invoice_number,total_amount")status
: Filter invoices by status (e.g., "PENDING", "PAID", "CANCELLED")sort_order
: Sort by creation date, either "asc" (oldest first) or "desc" (newest first, default)- Many more filtering options available (see Advanced Filtering section)
- Query parameters:
GET /api/v1/invoices/{invoice_id}
: Get a specific invoice by ID (must belong to the authenticated user)- Query parameters:
fields
: Comma-separated list of fields to include in the response (e.g., "id,invoice_number,total_amount")
- Query parameters:
GET /api/v1/invoices/find
: Find an invoice by invoice number (must belong to the authenticated user)- Query parameters:
invoice_number
: Invoice number to search for (required)fields
: Comma-separated list of fields to include in the response (e.g., "id,invoice_number,total_amount")
- Query parameters:
PATCH /api/v1/invoices/{invoice_id}
: Update an invoice (must belong to the authenticated user)PATCH /api/v1/invoices/{invoice_id}/status
: Update invoice status (must belong to the authenticated user)DELETE /api/v1/invoices/{invoice_id}
: Delete an invoice (must belong to the authenticated user)
Frontend Routes
GET /
: Home page with list of recent invoicesGET /create
: Form to create a new invoicePOST /create
: Process invoice creation formGET /search
: Form to search for invoices by numberPOST /search
: Process invoice searchGET /invoice/{invoice_id}
: View invoice detailsPOST /invoice/{invoice_id}/status
: Update invoice status
Setup and Installation
- Clone the repository
- Install dependencies:
pip install -r requirements.txt
- Run migrations:
alembic upgrade head
- Start the application:
uvicorn main:app --reload
Authentication
The application uses JWT (JSON Web Tokens) for authentication. Here's how to use it:
User Registration
To create a new user account:
POST /api/v1/auth/register
Request body:
{
"email": "user@example.com",
"username": "user123",
"password": "securepassword",
"full_name": "John Doe"
}
User Login
To log in and get an access token:
POST /api/v1/auth/login
This endpoint accepts form data (not JSON) with:
username
: Your username or emailpassword
: Your password
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}
Using the Token
Include the token in the Authorization header for all invoice-related requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Getting Current User
To get the details of the currently authenticated user:
GET /api/v1/auth/me
Headers:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
API Documentation
Once the application is running, you can access:
- Interactive API documentation at
/docs
(Swagger UI) - Alternative API documentation at
/redoc
(ReDoc)
Web Interface
The application comes with a full web interface that allows users to:
- View a list of recent invoices on the home page
- Create new invoices using a dynamic form
- Search for existing invoices by invoice number
- View detailed invoice information
- Update invoice status (PENDING, PAID, CANCELLED)
- Print invoices
Invoice Number Format
Invoices are automatically assigned a unique invoice number with the format:
INV-YYYYMM-XXXXXX
, where:INV
is a fixed prefixYYYYMM
is the year and month (e.g., 202307 for July 2023)XXXXXX
is a random alphanumeric string
Query Parameters
Field Filtering
The API supports field filtering for GET operations. This allows clients to request only the specific fields they need, which can improve performance and reduce bandwidth usage.
How to Use Field Filtering:
- Add a
fields
query parameter to GET requests - Specify a comma-separated list of field names to include in the response
Example:
To get only the ID, invoice number, and total amount of invoices:
GET /api/v1/invoices?fields=id,invoice_number,total_amount
This would return:
[
{
"id": 1,
"invoice_number": "INV-202307-A1B2C3",
"total_amount": 100.0
},
{
"id": 2,
"invoice_number": "INV-202307-D4E5F6",
"total_amount": 200.0
}
]
Status Filtering
The API supports filtering invoices by their status (PENDING, PAID, CANCELLED).
How to Use Status Filtering:
- Add a
status
query parameter to the GET request - Specify one of the allowed status values: "PENDING", "PAID", or "CANCELLED"
Example:
To get only paid invoices:
GET /api/v1/invoices?status=PAID
To combine with other parameters:
GET /api/v1/invoices?status=PENDING&fields=id,invoice_number,total_amount&limit=5
Advanced Filtering
The API supports advanced filtering options for more precise control over your invoice queries.
Date Range Filtering
Filter invoices by creation date or due date:
created_after
: Filter invoices created on or after this date (YYYY-MM-DD)created_before
: Filter invoices created on or before this date (YYYY-MM-DD)due_after
: Filter invoices due on or after this date (YYYY-MM-DD)due_before
: Filter invoices due on or before this date (YYYY-MM-DD)
Examples:
# Get invoices created in January 2023
GET /api/v1/invoices?created_after=2023-01-01&created_before=2023-01-31
# Get overdue invoices (due before today)
GET /api/v1/invoices?due_before=2023-07-01&status=PENDING
Customer Filtering
Search for invoices by customer information:
customer_name
: Filter invoices by customer name (case-insensitive, partial match)customer_email
: Filter invoices by customer email (case-insensitive, partial match)
Examples:
# Find all invoices for customers with "smith" in their name
GET /api/v1/invoices?customer_name=smith
# Find invoices for customers with a specific email domain
GET /api/v1/invoices?customer_email=example.com
Amount Range Filtering
Filter invoices by total amount:
min_amount
: Filter invoices with total amount greater than or equal to this valuemax_amount
: Filter invoices with total amount less than or equal to this value
Examples:
# Get invoices with amounts between $100 and $500
GET /api/v1/invoices?min_amount=100&max_amount=500
# Get high-value invoices
GET /api/v1/invoices?min_amount=1000
Advanced Sorting
The API supports sorting invoices by various fields:
sort_by
: Field to sort by. Available options:date_created
: Sort by creation date (default)due_date
: Sort by due datetotal_amount
: Sort by invoice amountcustomer_name
: Sort alphabetically by customer name
sort_order
: Sort direction:asc
: Ascending order (oldest/smallest/A-Z first)desc
: Descending order (newest/largest/Z-A first, this is the default)
Examples:
# Get highest-value invoices first
GET /api/v1/invoices?sort_by=total_amount&sort_order=desc
# Get invoices sorted alphabetically by customer name
GET /api/v1/invoices?sort_by=customer_name&sort_order=asc
# Get invoices with the earliest due dates first
GET /api/v1/invoices?sort_by=due_date&sort_order=asc
Combining Filters
All filter parameters can be combined for precise results:
# Get pending invoices over $500 created in 2023, sorted by amount (highest first)
GET /api/v1/invoices?status=PENDING&min_amount=500&created_after=2023-01-01&sort_by=total_amount&sort_order=desc
# Get paid invoices for a specific customer
GET /api/v1/invoices?status=PAID&customer_name=acme&sort_by=date_created&sort_order=desc
Available Fields:
Invoices have the following fields that can be filtered:
id
invoice_number
date_created
due_date
total_amount
status
customer_name
customer_email
customer_address
notes
items
(this includes related invoice items)