brand-master/DATABASE.md
dvirlabs 29aa5c2f36
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Add the option to login with username or phone or email and fix the leave messages
2026-05-08 18:54:26 +03:00

261 lines
8.2 KiB
Markdown

# Database Schema
## Overview
The database uses PostgreSQL with SQLAlchemy ORM. All tables are auto-created from models.
## Tables
### users
User accounts and profile information.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY | User identifier |
| email | VARCHAR | UNIQUE, INDEXED | User email |
| username | VARCHAR | UNIQUE, INDEXED | Username (optional, for login) |
| hashed_password | VARCHAR | NOT NULL | Bcrypt hashed password |
| full_name | VARCHAR | NOT NULL | User's full name |
| phone | VARCHAR | UNIQUE, INDEXED | Phone number (optional, for login) |
| address | VARCHAR | NULLABLE | Street address |
| city | VARCHAR | NULLABLE | City |
| postal_code | VARCHAR | NULLABLE | Postal/ZIP code |
| country | VARCHAR | NULLABLE | Country |
| is_active | BOOLEAN | DEFAULT TRUE | Account status |
| is_admin | BOOLEAN | DEFAULT FALSE | Admin privileges |
| must_change_password | BOOLEAN | DEFAULT FALSE | Force password change |
| password_reset_pin | VARCHAR | NULLABLE | Password reset PIN |
| pin_expires_at | DATETIME | NULLABLE | PIN expiration time |
| created_at | DATETIME | DEFAULT NOW() | Account creation date |
**Login Options:** Users can login with email, username, or phone number
### categories
Product categories.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY | Category identifier |
| name | VARCHAR | UNIQUE, INDEXED | Category name |
| slug | VARCHAR | UNIQUE, INDEXED | URL-friendly slug |
| description | VARCHAR | NULLABLE | Category description |
**Predefined Categories:**
- Shoes
- Shirts
- Pants
- Hats
- Accessories
### products
Product inventory and details.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY | Product identifier |
| name | VARCHAR | INDEXED | Product name |
| description | TEXT | NOT NULL | Product description |
| price | FLOAT | NOT NULL | Regular price |
| discount_price | FLOAT | NULLABLE | Sale price if on sale |
| category_id | INTEGER | FOREIGN KEY | Reference to category |
| gender | VARCHAR | NOT NULL | men/women |
| brand | VARCHAR | NOT NULL | Product brand |
| sizes | JSON | NOT NULL | Array of available sizes |
| colors | JSON | NOT NULL | Array of available colors |
| stock | INTEGER | DEFAULT 0 | Quantity available |
| images | JSON | NOT NULL | Array of image URLs |
| is_featured | BOOLEAN | DEFAULT FALSE | Featured product flag |
| is_on_sale | BOOLEAN | DEFAULT FALSE | Sale flag |
| created_at | DATETIME | DEFAULT NOW() | Product added date |
**indexes:**
- category_id (FOREIGN KEY)
### cart
User shopping carts.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY | Cart identifier |
| user_id | INTEGER | FOREIGN KEY UNIQUE | Reference to user |
| created_at | DATETIME | DEFAULT NOW() | Cart creation date |
**Relationships:**
- One cart per user
- Can contain multiple cart_items
### cart_items
Items in shopping carts.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY | Cart item identifier |
| cart_id | INTEGER | FOREIGN KEY | Reference to cart |
| product_id | INTEGER | FOREIGN KEY | Reference to product |
| quantity | INTEGER | DEFAULT 1 | Item quantity |
| size | VARCHAR | NULLABLE | Selected size |
| color | VARCHAR | NULLABLE | Selected color |
**Relationships:**
- Belongs to cart
- References product
### orders
Customer orders.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY | Order identifier |
| user_id | INTEGER | FOREIGN KEY | Reference to user |
| order_number | VARCHAR | UNIQUE, INDEXED | Human-readable order # |
| status | VARCHAR | DEFAULT 'pending' | pending/paid/shipped/delivered |
| total_amount | FLOAT | NOT NULL | Order total |
| shipping_address | VARCHAR | NOT NULL | Shipping street |
| shipping_city | VARCHAR | NOT NULL | Shipping city |
| shipping_postal_code | VARCHAR | NOT NULL | Shipping postal code |
| shipping_country | VARCHAR | NOT NULL | Shipping country |
| created_at | DATETIME | DEFAULT NOW() | Order creation date |
| updated_at | DATETIME | DEFAULT NOW() | Last update date |
**Relationships:**
- Belongs to user
- Can contain multiple order_items
### order_items
Items in orders.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY | Order item identifier |
| order_id | INTEGER | FOREIGN KEY | Reference to order |
| product_id | INTEGER | FOREIGN KEY | Reference to product |
| quantity | INTEGER | NOT NULL | Item quantity |
| price | FLOAT | NOT NULL | Price at purchase time |
| size | VARCHAR | NULLABLE | Selected size |
| color | VARCHAR | NULLABLE | Selected color |
**Note:** Price is stored to preserve historical data
### wishlist
User wishlists.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY | Wishlist item identifier |
| user_id | INTEGER | FOREIGN KEY | Reference to user |
| product_id | INTEGER | FOREIGN KEY | Reference to product |
| created_at | DATETIME | DEFAULT NOW() | Added to wishlist date |
**Constraint:** UNIQUE(user_id, product_id) - one entry per user-product pair
### contact_messages
Contact form submissions.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY | Message identifier |
| full_name | VARCHAR | NOT NULL | Sender full name |
| email | VARCHAR | NOT NULL | Sender email |
| phone | VARCHAR | NULLABLE | Sender phone (optional) |
| subject | VARCHAR | NOT NULL | Message subject |
| message | TEXT | NOT NULL | Message content |
| created_at | DATETIME | DEFAULT NOW() | Submission date |
| is_read | BOOLEAN | DEFAULT FALSE | Admin read status |
| status | VARCHAR | DEFAULT 'new' | Status: new/read/replied |
| admin_notes | TEXT | NULLABLE | Internal admin notes |
**Constraints:** CHECK (status IN ('new', 'read', 'replied'))
**Indexes:** status, is_read, created_at
## Relationships Diagram
```
users
├─ 1:1 ─→ cart
│ ├─ 1:many ─→ cart_items
│ └─ many:1 ─→ products
├─ 1:many ─→ orders
│ ├─ 1:many ─→ order_items
│ └─ many:1 ─→ products
└─ many:many ─→ products (via wishlist)
categories
└─ 1:many ─→ products
contact_messages
(standalone)
```
## Sample Data
The seed script includes:
**Categories:** 5
- Shoes, Shirts, Pants, Hats, Accessories
**Products:** 15+
- emphasis on shoes (Nike, Adidas, Cole Haan, Salomon, etc.)
- Mix of men's and women's items
- Various price points ($19.99 - $189.99)
- Sale and featured items
**Users:** 2
- user@example.com (password: password123)
- jane@example.com (password: password123)
## Indexing Strategy
Indexed columns for performance:
- users.email (UNIQUE)
- users.username (UNIQUE, partial index on non-null)
- users.phone (UNIQUE, partial index on non-null)
- categories.name (UNIQUE)
- categories.slug (UNIQUE)
- products.name
- products.category_id
- orders.order_number (UNIQUE)
- orders.user_id
- contact_messages.status
- contact_messages.is_read
- contact_messages.created_at
## Backup and Restore
### Backup Database
```bash
pg_dump -U postgres ecommerce_db > backup.sql
```
### Restore Database
```bash
psql -U postgres ecommerce_db < backup.sql
```
## Connection Pooling
In production, consider using a connection pool. SQLAlchemy is configured in `database.py`.
## Migration Notes
If modifying models:
1. Update the model in `app/models/`
2. Tables auto-create via `Base.metadata.create_all()`
3. For existing databases, manually ALTER TABLE
## Performance Optimization
- Indexes on frequently queried columns
- JSON columns for flexible attributes
- Pagination implemented in list queries
- EAGER loading relationships where needed
## Data Validation
- Pydantic schemas validate all input
- Email validation via EmailStr
- Price and quantity constraints
- Product stock management
## Time Zone
All timestamps are stored in UTC (datetime.utcnow())