# ERP Backend — Architecture Reference

## Tech Stack
FastAPI + SQLAlchemy2.0 + SQLite/MySQL + JWT Auth + bcrypt

## API Modules (`app/api/`)
| Module | Route | Auth | Description |
|--------|-------|------|-------------|
| `auth.py` | `/api/auth` | ❌ | Login / token / register |
| `customers.py` | `/api/customers` | ✅ | CRUD customers |
| `products.py` | `/api/products` | ✅ | CRUD products |
| `invoices.py` | `/api/invoices` | ✅ | Invoice lifecycle + PDF |
| `subscriptions.py` | `/api/subscriptions` | ✅ | Subscription management |
| `stats.py` | `/api/stats` | ✅ | Dashboard overview |
| `reminders.py` | `/api/reminders` | ✅ | Email/Telegram reminders |
| `email_templates.py` | `/api/email-templates` | ✅ | Email template CRUD |
| `email_logs.py` | `/api/email-logs` | ✅ | Email sending logs |
| `telegram.py` | `/api/telegram` | ✅ | Telegram send/test/logs |
| `ai.py` | `/api/ai` | ✅ | Chat + AI invoice drafting |
| `config.py` | `/api/config` | Admin | SMTP/Telegram config |

## Core Modules (`app/core/`)
| File | Purpose |
|------|---------|
| `models.py` | SQLAlchemy models: User, Customer, Product, Invoice, InvoiceItem, Subscription, Payment, Reminder, etc. |
| `database.py` | `get_db()` — reads DB_HOST/DB_PORT/DB_USER/DB_PASSWORD/DB_NAME from `.env` |
| `security.py` | `get_current_user()` — JWT Bearer token validation, bcrypt password hashing |
| `config.py` | `get_smtp_config()`, `get_telegram_config()`, `get_ai_config()` — reads runtime config from `system_config` with `.env` fallback |

## Services (`app/services/`)
| File | Purpose |
|------|---------|
| `invoice_service.py` | `generate_invoice_number()`, `calculate_item()`, `recalculate_invoice()`, `issue_invoice()`, `void_invoice()`, `record_payment()`, `write_invoice_event()` |
| `invoice_pdf.py` | `generate_invoice_pdf()` — WeasyPrint HTML→PDF |
| `ai_service.py` | `chat_with_ai()`, `parse_ai_draft()`, `validate_draft_data()` |
| `email_service.py` | SMTP sending |
| `telegram_service.py` | Telegram Bot API calls |
| `reminder_service.py` | APScheduler job: check overdue invoices + subscription expiry |

## Database Config (`.env`)
```
DB_HOST=192.168.50.139
DB_PORT=3306
DB_USER=root
DB_PASSWORD=...
DB_NAME=erp
```

## Required Secrets
- `JWT_SECRET` must be set to a strong value of at least 32 characters.
- `ADMIN_PASSWORD` must be set before running `create_admin.py`.
- `DB_PASSWORD` must be set before running `init_db.py` against MySQL.

## Key Details
- JWT algorithm: `HS256`, expire: `480` minutes
- Default admin username: `admin` (password comes from `ADMIN_PASSWORD`)
- Invoice number format: `INV-YYYYMM-NNNN`
- Tax rate default: `0.15` (15%)
- Currency default: `NZD`
- CORS: `CORS_ORIGINS` env var, comma-separated

## Tables
`users`, `customers`, `products`, `invoices`, `invoice_items`, `subscriptions`, `payments`, `invoice_events`, `reminders`, `email_templates`, `email_logs`, `telegram_logs`, `system_config`

## Running
```bash
cd backend
python3 -m uvicorn app.main:app --host 0.0.0.0 --port 8002 --reload
```

## Init Database
```bash
mysql -u "$DB_USER" -p"$DB_PASSWORD" < init_db.sql
python3 create_admin.py
```
