Files
ERP/README.md
T

192 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Procurement Stack v1.3 — Dockerized (PostgreSQL + FastAPI + React + MinIO)
Self-contained ship package: everything needed to run the stack is in this
folder — no external files or sibling folders required.
| Service | Container | Tech | Exposed port |
|---|---|---|---|
| **postgres** | `procurement-postgres` | PostgreSQL 18 | `5433` |
| **minio** | `procurement-minio` | MinIO object storage (S3-compatible) | `9000` (API), `9001` (console) |
| **casdoor** | `procurement-casdoor` | Casdoor (OIDC identity provider) | `8080` |
| **api** | `procurement-api` | FastAPI + SQLAlchemy (asyncpg) | `8000` |
| **frontend** | `procurement-frontend` | React 19 + Vite, served by nginx | `3000` |
```
Browser ──► frontend :3000 (nginx SPA)
│
└── /api/* proxy ──► api :8000 (FastAPI, /api/v1)
│
├── postgres :5432 (procurement DB)
├── minio :9000 (invoice/proforma files, bucket `procurement-files`)
└── casdoor :8000 (OIDC — login for the inventory panel)
```
---
## 📁 Layout
```text
v1.3/
├── docker-compose.yml ← all paths are relative to this folder
├── start.ps1 ← PowerShell helper (build + start + status)
├── mc.cmd ← MinIO Client helper (inspect the bucket)
├── README.md
├── sql/
│ └── migration.sql ← DB schema v2.6 (auto-runs on first boot)
├── docs/ ← ERDs + migration plan
│ ├── erd.txt (v2.4 — old procurement schema)
│ ├── new erd.txt (v2.5 — material → supplier → category)
│ ├── NewERD.txt (v2.6 — integrated procurement + inventory)
│ └── material-supplier-category-migration-plan.md
├── backend/ ← build context of the `api` service
│ ├── Dockerfile
│ ├── requirements.txt
│ ├── .dockerignore
│ ├── app/ (source code — procurement + inventory + auth)
│ └── tools/ (smoke-test + seed scripts, copied into the image)
└── frontend/ ← build context of the `frontend` service
├── Dockerfile
├── nginx.conf
├── .dockerignore
├── .env.example (copy to .env if you need a custom API base URL)
├── index.html
├── package.json
├── package-lock.json
├── tsconfig*.json
├── vite.config.ts
├── public/
└── src/
└── pages/
├── Dashboard/ (procurement office)
├── Wizard/ (add new offer)
├── Suppliers/ (suppliers & topics)
├── Projects/ (projects)
├── Units/ (unit conversions)
└── Inventory/ (warehouse management panel — React port)
```
---
## 🔐 Login
The whole system is behind a login page (`/login`):
- **مدیر پروژه (PM)** → lands in the inventory panel (their project) — can record
stock changes, manage the project's warehouses and confirm arrivals («کالاهای در راه»).
- **مدیر تدارکات / ادمین** (the same person) → lands in the procurement office — can manage
quotes, suppliers, projects, and in the inventory panel: dashboard, daily control,
«کالاهای در راه» (receiving included) and «سازمان‌دهی» (users, PMs, warehouses).
The «انبارها» and «تغییر موجودی» sections are PM-only.
Until Casdoor is fully seeded, use «ورود آزمایشی (توسعه)» on the login page
(role + project). Casdoor (org `inventory`, app `inventory-app`) is the planned
production identity source.
---
## Prerequisites (target machine)
- **Docker Desktop** (Windows) or Docker Engine + Compose plugin (Linux/macOS)
- ~3–4 GB free disk for images (`postgres:18`, `python:3.13-slim`, `node:22-alpine`, `nginx:alpine`, `minio/minio`, `minio/mc`)
- Internet access on first build (image + `npm ci` downloads)
---
## Start the whole stack
```powershell
cd <this-folder>
docker compose up -d --build
```
First run downloads base images and builds the frontend (takes a few minutes).
Subsequent runs: `docker compose up -d`.
Wait until all services are up:
```powershell
docker compose ps
```
All should show `Up` (postgres also `(healthy)`).
---
## Verify
| What | Where |
|---|---|
| Frontend UI | http://localhost:3000 |
| API docs (Swagger) | http://localhost:8000/docs |
| API health | http://localhost:8000/health → `{"status":"ok","service":"procurement-api"}` |
| MinIO console | http://localhost:9001 (user/pass `minioadmin`/`minioadmin`) |
| Database | `localhost:5433`, db `procurement`, user/pass `postgres`/`postgres` |
Quick end-to-end check (frontend proxy → API → DB):
```powershell
curl http://localhost:3000/api/v1/quotes?expand=supplier,project,line_items,termsheets,events,decision,receipt
```
---
## MinIO (object storage for invoice / proforma files)
| Item | Value |
|---|---|
| S3 API endpoint | `localhost:9000` (from the API container: `minio:9000`) |
| Web console | http://localhost:9001 |
| Root user / password | `minioadmin` / `minioadmin` (dev — change for production) |
| Bucket | `procurement-files` (created automatically by the `minio-init` container) |
| Object key layout | `{quote_id}/{kind}/{attachment_id}` where kind = `invoice` \| `proforma` |
File **bytes** live in MinIO; the `quote_attachments` table holds the metadata.
Ad-hoc bucket inspection from the host (see `mc.cmd`):
```powershell
.\mc.cmd ls --recursive
```
---
## Database credentials / connection
```text
Host: localhost
Port: 5433
Database: procurement
Username: postgres
Password: postgres
```
```powershell
docker exec -it procurement-postgres psql -U postgres -d procurement
```
---
## Common operations
```powershell
docker compose logs -f api # see logs
docker compose down # stop (keep data)
docker compose up -d --build # rebuild after code changes
docker compose down -v # ⚠️ full reset — wipes DB + MinIO volumes
```
---
## Known behavior
- The backend has **no authentication** (dev placeholder) — do not expose to the public internet.
- Schema runs automatically ONLY on the first boot of an empty `postgres_data` volume
(see `docker-entrypoint-initdb.d`); the API also runs `CREATE TABLE IF NOT EXISTS`
for the units-dashboard tables and `quote_attachments` at startup.
- Invoice upload requires an `accepted`/`arrived` quote; proforma has no restriction.
- The supplier detail page (`/suppliers/:id`) shows the purchase history with
invoice/proforma download links from MinIO.
- If builds fail with disk-full errors: `docker system prune -a`, then rebuild.
- If the frontend shows «اتصال به سرور برقرار نشد» → the api container is not
reachable; check `docker compose ps` and `docker compose logs api`.