docs: update root, bot, and pm README files for integrated ERP architecture
This commit is contained in:
@@ -1,359 +1,191 @@
|
||||
# ERP & PM Integrated Platform — Dockerized
|
||||
## سامانه یکپارچه تدارکات، انبارداری، مدیریت پروژه (PM) و ربات هوشمند
|
||||
|
||||
# Procurement Stack v1.3 — Dockerized (PostgreSQL + FastAPI + React + MinIO)
|
||||
مجموعه نرمافزاری یکپارچه و خودکفا (Self-contained) شامل تمامی سرویسها، ماژولها و تنظیمات زیرساختی مورد نیاز برای اجرا در محیط توسعه و عملیات:
|
||||
|
||||
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 (one instance: `procurement` + `casdoor` DBs) | `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 (internal) | via Traefik |
|
||||
| **traefik** | `procurement-traefik` | Traefik v3 — public reverse proxy (edge) | `80` (web), `443` (websecure) |
|
||||
|
||||
|
||||
```
|
||||
|
||||
Browser ──► Traefik :80 (edge)
|
||||
│
|
||||
├── Host(localhost) ──► frontend (nginx SPA :80)
|
||||
│ │
|
||||
│ └── /api/* proxy ──► api :8000 (/api/v1)
|
||||
│
|
||||
├── Host(api.localhost) ──► api :8000
|
||||
├── Host(auth.localhost) ──► casdoor :8000 (OIDC login)
|
||||
└── Host(s3/storage.localhost) ──► minio (API / console)
|
||||
│
|
||||
├── postgres :5432 (procurement + casdoor DBs)
|
||||
└── minio :9000 (invoice/proforma files)
|
||||
|
||||
```
|
||||
| **postgres** | `procurement-postgres` | PostgreSQL 18 (دیتابیس مشترک `procurement` + `casdoor`) | `5455:5432` |
|
||||
| **minio** | `procurement-minio` | MinIO Object Storage (S3-compatible) برای فایلها و پیشفاکتورها | `9000` (API), `9001` (کنسول) |
|
||||
| **casdoor** | `procurement-casdoor` | ارائهدهنده متمرکز هویت سازمانی (OIDC Provider) | `8080:8000` |
|
||||
| **api** | `procurement-api` | بکاند اصلی تدارکات و انبار (FastAPI + Asyncpg) | `8000:8000` |
|
||||
| **frontend** | `procurement-frontend` | فرانتاند وب ERP (React 19 + Vite + Tailwind) | سرو از طریق Traefik روی پورت `80` |
|
||||
| **pm-api** | `pm-api` | بکاند بومی مدیریت پروژه ساخت (FastAPI + Python 3.12) | درونشبکهای (زیرمسیر `/pm/api`) |
|
||||
| **pm-frontend** | `pm-frontend` | فرانتاند پلتفرم PM (React 19 + تقویم شمسی + گانت + QC) | سرو از طریق Traefik روی `/pm` |
|
||||
| **bot** | `procurement-bot` | ربات هوشمند بله با پردازش صوت و متن (DeepSeek LLM + STT) | ارتباط Long-polling با Bale |
|
||||
| **db-backup** | `procurement-db-backup` | پشتیبانگیری خودکار زمانبندیشده از هر دو پایگاه داده | کانتینر دورهای در پسزمینه |
|
||||
| **traefik** | `procurement-traefik` | ریورس پروکسی و مدیریت ترافیک لایه لبه (Traefik v3) | `80` (HTTP), `443` (HTTPS) |
|
||||
|
||||
---
|
||||
|
||||
## 📁 Layout
|
||||
## 🌐 معماری شبکه و هدایت ترافیک (Traefik Edge Routing)
|
||||
|
||||
```text
|
||||
v1.3/
|
||||
├── docker-compose.yml ← all paths are relative to this folder
|
||||
├── docker-compose.prod.yml ← production overlay (real domains + HTTPS via Let's Encrypt)
|
||||
├── start.ps1 ← PowerShell helper (build + start + status)
|
||||
├── mc.cmd ← MinIO Client helper (inspect the bucket)
|
||||
├── README.md
|
||||
┌────────────────────────┐
|
||||
│ Browser / Client │
|
||||
└───────────┬────────────┘
|
||||
│ :80 / :443
|
||||
▼
|
||||
┌────────────────────────┐
|
||||
│ Traefik v3 (Edge) │
|
||||
└───────────┬────────────┘
|
||||
│
|
||||
┌────────────────────────────────────┼───────────────────────────────────┐
|
||||
│ │ │
|
||||
▼ (Host: localhost) ▼ (PathPrefix: /pm) ▼ (Host: api.localhost)
|
||||
┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐
|
||||
│ frontend (React) │ │ pm-frontend / pm-api │ │ api (FastAPI Core) │
|
||||
│ /api/* Proxy ───────┼────────────┼───────────────────────┼──────────►│ /api/v1/* │
|
||||
└───────────────────────┘ └───────────────────────┘ └───────────┬───────────┘
|
||||
│ │
|
||||
├────────────────────────────────────┬──────────────────────────────────────┤
|
||||
▼ ▼ ▼
|
||||
┌───────────────────────┐ ┌───────────────────────┐ ┌───────────────────────┐
|
||||
│ Casdoor OIDC (:8080) │ │ MinIO S3 (:9000) │ │ PostgreSQL 18 (:5455) │
|
||||
│ Host: auth.localhost │ │ Host: s3 / storage │ │ procurement + casdoor │
|
||||
└───────────────────────┘ └───────────────────────┘ └───────────────────────┘
|
||||
▲
|
||||
│ ثبت پیشنویس استعلام
|
||||
┌────────┴──────────────┐
|
||||
│ bot (Bale AI Agent) │
|
||||
└───────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 ساختار پوشهها و اجزای مخزن
|
||||
|
||||
```text
|
||||
ERP/
|
||||
├── docker-compose.yml ← پیکربندی اصلی اجرای کامل تمام سرویسهای استک
|
||||
├── docker-compose.prod.yml ← لایه تنظیمات عملیاتی (Let's Encrypt و دامنههای رسمی)
|
||||
├── docker-compose.coolify.yml ← پیکربندی سازگار با استقرار بر روی Coolify
|
||||
├── start.ps1 ← اسکریپت هلپر پاورشل برای ساخت و اجرا
|
||||
├── mc.cmd ← ابزار خط فرمان MinIO Client برای مدیریت باکتها
|
||||
├── README.md ← همین سند راهنما
|
||||
├── backend/ ← سرویس بکاند اصلی تدارکات و انبار (procurement-api)
|
||||
│ ├── app/
|
||||
│ │ ├── db/ ← اتصال دیتابیس و توابع راهاندازی اسکیمای خودکار (init_db.py)
|
||||
│ │ ├── models/ ← مدلهای پایگاهداده (procurement, inventory, catalog)
|
||||
│ │ ├── routers/ ← اندپوینتهای API v1 (quotes, inventory, users, drafts, ...)
|
||||
│ │ ├── schemas/ ← مدلهای اعتبارسنجی Pydantic
|
||||
│ │ ├── services/ ← منطق بیزینس (انبارداری، استعلامها، ذخیرهسازی، ...)
|
||||
│ │ ├── utils/ ← ابزارهای امنیتی، خطایابی، ریتلیمیت
|
||||
│ │ ├── auth.py ← تایید توکن Casdoor و تفکیک دسترسیها
|
||||
│ │ ├── config.py ← متغیرهای پیکربندی
|
||||
│ │ └── main.py ← اسمبلی برنامه FastAPI و میدلورها
|
||||
│ └── tools/ ← اسکریپتهای سیدینگ (seed_casdoor.py) و تستهای دود (Smoke)
|
||||
├── frontend/ ← وباپلیکیشن اصلی ERP (procurement-frontend)
|
||||
│ ├── src/
|
||||
│ │ ├── components/ ← کامپوننتهای مشترک، لایهبندی و سوییچر پنلها
|
||||
│ │ ├── pages/
|
||||
│ │ │ ├── Admin/ ← پنل مدیریت سامانه و همگامسازی کاربران
|
||||
│ │ │ ├── Auth/ ← صفحه ورود و احراز هویت
|
||||
│ │ │ ├── Dashboard/ ← کارتابل استعلامها و تصمیمگیری خرید
|
||||
│ │ │ ├── Inventory/ ← انبارداری (موجودی، ورود کالا، انتقال کارگاهی، کنترل روزانه)
|
||||
│ │ │ ├── Organization/ ← ماتریس دسترسی پنلها و انتساب پروژهها
|
||||
│ │ │ ├── Projects/ ← مدیریت پروژههای عمرانی
|
||||
│ │ │ ├── Suppliers/ ← دستهبندی موضوعی و فهرست تأمینکنندگان
|
||||
│ │ │ ├── Units/ ← سیستم کاتالوگ متریالها، تامینکنندگان و ضرایب تبدیل
|
||||
│ │ │ └── Wizard/ ← ویزارد مرحلهای ثبت استعلام (با اتصال مستقیم به پیشنویس ربات)
|
||||
│ │ ├── store/ ← مدیریت وضعیت با Zustand
|
||||
│ │ └── App.tsx ← درخت روتها، گیتهای امنیتی پنلها و نقشها
|
||||
├── pm/ ← پلتفرم مدیریت پروژه و کنترل کیفیت (پلتفرم آرامش)
|
||||
│ ├── backend/ ← بکاند مستقل PM (FastAPI, CPM Engine, QC Service)
|
||||
│ ├── frontend/ ← فرانتاند PM (گانت چارت شمسی، WBS، ثبت عیوب و بازرسی)
|
||||
│ ├── sql/ ← اسکیما و اسکریپتهای اختصاصی پایگاه داده PM
|
||||
│ └── API_CONTRACT.md ← قرارداد کامل اندپوینتهای PM
|
||||
├── bot/ ← ایجنت هوشمند بله برای ثبت صوتی/متنی استعلامها
|
||||
│ ├── app/ ← کلاینت Bale، پردازشگر STT صوتی، استخراج NLU با DeepSeek
|
||||
│ ├── docs/SETUP.md ← راهنمای راهاندازی و اتصال توکن بله
|
||||
│ └── requirements.txt
|
||||
├── monitoring/ ← استک مانیتورینگ، متریکها و لاگها (پرومتئوس، گرافانا، لوکی)
|
||||
├── infra/ ← تنظیمات وبهوک دیپلوی خودکار و کانفیگهای داینامیک Traefik
|
||||
├── sql/
|
||||
│ ├── migration.sql ← DB schema v2.6 (auto-runs on first boot)
|
||||
│ └── 02-casdoor-db.sql ← creates the `casdoor` role+DB on the same instance
|
||||
├── infra/
|
||||
│ └── traefik-dynamic.yml ← Traefik shared middlewares (HTTP→HTTPS redirect)
|
||||
├── docs/ ← ERDs + migration plan + auth guide
|
||||
│ ├── erd.txt (v2.4 — old procurement schema)
|
||||
│ ├── new erd.txt (v2.5 — material → supplier → category)
|
||||
│ ├── NewERD.txt (v2.6 — integrated procurement + inventory)
|
||||
│ ├── casdoor-auth.md (v2.6 — Casdoor login, roles, failure scenarios)
|
||||
│ └── 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)
|
||||
|
||||
│ ├── migration.sql ← اسکریپت اولیه پایه دیتابیس
|
||||
│ └── 02-casdoor-db.sql ← اسکریپت راهاندازی دیتابیس هویت Casdoor
|
||||
└── tests/ ← تستهای یکپارچگی NLU و ویزارد استعلام
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Login
|
||||
## 🔐 سیستم احراز هویت، ماتریس پنلها و کنترل دسترسی (RBAC)
|
||||
|
||||
The whole system is behind a login page (`/login`). Login is **in-page**:
|
||||
the form (username / password) is sent to
|
||||
`POST /api/v1/auth/login`; the backend exchanges it with Casdoor
|
||||
(password grant), verifies the returned JWT, and starts the session —
|
||||
no browser redirect to Casdoor.
|
||||
سامانه از سیستم احراز هویت **Casdoor OIDC** بهره میبرد؛ ورود به صورت In-Page بوده و توکن JWT صادر شده توسط بکاند با JWKS اعتبارسنجی میشود.
|
||||
|
||||
* **مدیر پروژه (PM)** → lands in the inventory panel (their project) — can record
|
||||
stock changes, manage the project's warehouses and confirm arrivals («کالاهای در راه»).
|
||||
* **مدیر تدارکات / ادمین** → 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.
|
||||
مدل دسترسی سامانه بر پایه **پنلها (`user_panels`)** بازطراحی شده است:
|
||||
|
||||
**Developer Mode** (top-left button on the login page) is a 3-step flow for
|
||||
the admin (super user): ① superuser auth gate (admin credentials only) →
|
||||
② role switcher (ادمین / مدیر تدارکات / مدیر پروژه + project) → ③ session
|
||||
activation by role (admin → **پنل مدیریت ادمین** at `/admin`, مدیر تدارکات →
|
||||
procurement office, مدیر پروژه → their project's inventory panel). It is
|
||||
controlled by the `VITE_ENABLE_DEV_LOGIN` env var (in Docker: the
|
||||
`DEV_LOGIN_ENABLED` compose build arg, default `true` — set it to `false`
|
||||
for production builds).
|
||||
### ۱. لایههای دسترسی پنلها
|
||||
* **پنل تدارکات (`procurement`):**
|
||||
* `full`: دسترسی کامل به کارتابل استعلامها، تایید یا رد پیشنهادها، تامینکنندگان و قیمتها.
|
||||
* `limited`: فقط امکان ثبت استعلام جدید در ویزارد برای پروژههای منتسب به کاربر (کاربر پس از ورود مستقیماً به `/wizard` یا `/requester` هدایت میشود).
|
||||
* **پنل انبارداری (`inventory`):**
|
||||
* `full`: مشاهده موجودی همه انبارها، رهگیری «کالاهای در راه» و کارتابل تایید رسید.
|
||||
* `limited`: فقط مشاهده و مدیریت انبارهای پروژههای تحت عضویت، همراه با دسترسی به ثبت تغییر موجودی کارگاهی (`/inventory/change`).
|
||||
* **پنل مدیریت پروژه (`pm`):**
|
||||
* دسترسی به مشاهده یا ویرایش تسکها، چارت گانت، ثبت عیوب و فرمهای QC در `/panel/pm`.
|
||||
|
||||
| What | Where | Credentials |
|
||||
| --- | --- | --- |
|
||||
| App | http://localhost (via Traefik) | — |
|
||||
| Casdoor console | http://localhost:8080 | admin credentials are set when you run the seeder (`CASDOOR_ADMIN_PW`) — never commit them |
|
||||
| Seeded app users (org `inventory`) | `razaei` (admin), `mousavi` (مدیر تدارکات), `mohaghegh` (مدیر پروژه), `tester` (مدیر پروژه، پروژه «تست») | password from `CASDOOR_SEED_PASSWORD` (bcrypt-hashed at rest — see `backend/tools/seed_casdoor.py`) |
|
||||
|
||||
Run `backend/tools/seed_casdoor.py` once after the first boot to create the
|
||||
Casdoor organization, application and users (idempotent). Full details —
|
||||
addresses, credentials, role model, failure scenarios and the checklist —
|
||||
are in [`docs/casdoor-auth.md`](https://www.google.com/search?q=docs/casdoor-auth.md).
|
||||
|
||||
> The **currently committed seed** (`backups/علی محقق/`) instead ships a
|
||||
> single admin — `ali.mohaghegh` («علی محقق») — see
|
||||
> [Restoring the committed seed data](https://www.google.com/search?q=%23restoring-the-committed-seed-data).
|
||||
### ۲. قوانین و نقش سرپرست پروژه (`supervisor`)
|
||||
* کاربرانی با نقش `supervisor` تنها در صورتی مجاز به ورود به سامانه هستند که حداقل یک پروژه در جدول `user_project_members` یا `projects.pm_user_id` به آنها منتسب شده باشد. در غیر این صورت، پیام عدم تخصیص پروژه نمایش داده شده و اجازه ورود نخواهند داشت.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Working with the deployed system (server)
|
||||
## 🚀 راهنمای سریع راهاندازی محیط توسعه (Docker)
|
||||
|
||||
The production deployment of this stack runs on the server and is reachable
|
||||
at these public addresses (HTTPS):
|
||||
### پیشنیازها
|
||||
* Docker Desktop (ویندوز) یا Docker Engine + Docker Compose Plugin (لینوکس)
|
||||
* حداقل ۴ گیگابایت فضای خالی دیسک و اتصال اینترنت برای بارگیری ایمیجهای اولیه
|
||||
|
||||
| What | Address |
|
||||
| --- | --- |
|
||||
| **App (ERP)** | https://aramesh.bennu-api-bahrestan.ir/ |
|
||||
| **Casdoor admin panel** | https://casdoor.bennu-api-bahrestan.ir/ |
|
||||
|
||||
Log in to the app with your Casdoor account (org `inventory`); the role is
|
||||
assigned inside the app (`users.role` — see «Login» above and
|
||||
[`docs/casdoor-auth.md`](https://www.google.com/search?q=docs/casdoor-auth.md)).
|
||||
|
||||
### MinIO console on the server (SSH tunnel)
|
||||
|
||||
The MinIO console is deliberately **loopback-only** on the server
|
||||
(`127.0.0.1:9001`) — verified unreachable from the internet — so the way in
|
||||
is an SSH tunnel from your machine:
|
||||
|
||||
1. Open PowerShell and start the tunnel (**keep the window open** while you
|
||||
use the panel):
|
||||
```powershell
|
||||
ssh -L 9001:127.0.0.1:9001 <user>@<server-host>
|
||||
|
||||
```
|
||||
|
||||
|
||||
You will also land in a normal SSH session — that is fine; the tunnel
|
||||
lives as long as the window stays open.
|
||||
2. In your browser, open: **http://localhost:9001**
|
||||
3. Log in with the production MinIO root credentials from the server's
|
||||
`/srv/erp/.env` (`MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD`) — they are
|
||||
**never** written in this repo or its history. See
|
||||
[`docs/SECRET-MANAGEMENT.md`](https://www.google.com/search?q=docs/SECRET-MANAGEMENT.md).
|
||||
|
||||
You will see the **`procurement-files`** bucket — the invoices/proformas the
|
||||
ERP stores, browsable and downloadable from there.
|
||||
|
||||
⚠️ Those credentials are **full admin access to the file storage**. They live
|
||||
only in the server-side `.env`; if one ever leaks, rotate it immediately
|
||||
(checklist in `docs/SECRET-MANAGEMENT.md`).
|
||||
|
||||
Close the PowerShell window (or `Ctrl+C`) when you are done to drop the
|
||||
tunnel.
|
||||
|
||||
Notes from the server setup:
|
||||
|
||||
* The panel is published only on the server's loopback, so the internet
|
||||
cannot reach it at all — the tunnel is what carries it to your browser.
|
||||
* Host port `9000` stays reserved for the deploy-webhook receiver, which is
|
||||
why the console uses `9001`.
|
||||
* If you ever need the raw S3 API from your machine, or a clickable URL for
|
||||
the console (e.g. `storage.aramesh.bennu-api-bahrestan.ir` behind Traefik
|
||||
with a password prompt on top), that can be arranged on request — the
|
||||
tunnel remains the safer default.
|
||||
|
||||
---
|
||||
|
||||
## 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)`).
|
||||
تمام سرویسها باید وضعیت `Up` و دیتابیس وضعیت `(healthy)` را نشان دهند.
|
||||
|
||||
### درگاهها و آدرسهای محلی
|
||||
|
||||
| بخش | آدرس محلی | توضیحات |
|
||||
|---|---|---|
|
||||
| **رابط کاربری ERP** | http://localhost | داشبورد اصلی سامانه |
|
||||
| **پلتفرم PM** | http://localhost/pm | مدیریت پروژه و کنترل کیفیت (قابل دسترس در `/panel/pm`) |
|
||||
| **مستندات API (Swagger)** | http://localhost:8000/docs | مستندات تعاملی اندپوینتهای تدارکات |
|
||||
| **سلامت API** | http://localhost:8000/health/ready | بررسی اتصال دیتابیس، Casdoor و MinIO |
|
||||
| **کنسول MinIO** | http://localhost:9001 | نام کاربری و رمز پیشفرض: `minioadmin` / `minioadmin` |
|
||||
| **کنسول Casdoor** | http://localhost:8080 | نام کاربری و رمز اولیه: `admin` / `123` |
|
||||
| **پایگاه داده PostgreSQL** | `localhost:5455` | نام دیتابیس: `procurement`، کاربر: `postgres` |
|
||||
|
||||
---
|
||||
|
||||
## Verify
|
||||
## 🤖 ربات هوشمند بله (`procurement-bot`)
|
||||
|
||||
| What | Where |
|
||||
| --- | --- |
|
||||
| Frontend UI | http://localhost |
|
||||
| API docs (Swagger) | http://localhost:8000/docs |
|
||||
| API health | http://localhost:8000/health → `{"status":"ok","service":"procurement-api"}` |
|
||||
| API readiness (DB + MinIO + Casdoor) | http://localhost:8000/health/ready |
|
||||
| Metrics | http://localhost:8000/metrics |
|
||||
| MinIO console | http://localhost:9001 (user/pass `minioadmin`/`minioadmin`) |
|
||||
| Database | `localhost:5433`, db `procurement`, user/pass `postgres`/`postgres` (Casdoor uses the same instance, db `casdoor`) |
|
||||
|
||||
Automated end-to-end checks (authenticates via `SMOKE_USER` /
|
||||
`SMOKE_PASSWORD` — the seeder users):
|
||||
|
||||
```powershell
|
||||
backend\tools\smoke_test.py # read paths
|
||||
backend\tools\smoke_test_write.py / smoke_test_misc.py
|
||||
|
||||
```
|
||||
|
||||
> Every API route now requires a Casdoor JWT — a bare
|
||||
> `curl http://localhost/api/v1/quotes` returns **401** by design.
|
||||
> Day-2 operations (deploys, backups, monitoring): [`docs/OPERATIONS.md`](https://www.google.com/search?q=docs/OPERATIONS.md).
|
||||
ربات پیامرسان بله به عنوان یک سرویس اختصاصی درون شبکه فعال است:
|
||||
1. پیام صوتی یا متنی فرستاده شده از طریق هوش مصنوعی (DeepSeek NLU) و تبدیل صوت به متن پردازش میشود.
|
||||
2. قلمها، متریالها، پروژهها و تامینکنندگان به صورت فازی جستجو و شناسایی میشوند.
|
||||
3. پیشنویس در جدول `bot_drafts` ذخیره شده و شناسه پیشنویس تولید میشود.
|
||||
4. کاربر میتواند با زدن دکمه روی بله یا مراجعه به لینک مستقیم:
|
||||
`http://localhost/wizard?draft=<UUID>`
|
||||
اطلاعات استخراجشده را در ویزارد فرانتاند مرور، تکمیل و نهایی کند.
|
||||
5. راهنمای تکمیلی تنظیم توکن در [bot/docs/SETUP.md](file:///c:/Users/Reza/Desktop/v1.6/bot/docs/SETUP.md) قرار دارد.
|
||||
|
||||
---
|
||||
|
||||
## MinIO (object storage for invoice / proforma files)
|
||||
## 🔄 انتقال بینکارگاهی کالاها (`project_transfers`)
|
||||
|
||||
| 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
|
||||
|
||||
```
|
||||
سامانه دارای سیستم ردیابی انتقال متریال بین کارگاههاست:
|
||||
* ثبت انتقال از طریق صفحه «تغییر موجودی» با نوع `انتقال بین کارگاهی`.
|
||||
* وضعیتهای انتقال: `در حال انتقال (in_transit)`، `تحویلشده (received)` و `لغوشده (cancelled)`.
|
||||
* کارگاه مقصد از طریق زبانه «انتقالات ورودی» در صفحه «کالاهای در راه» اقلام ارسالی را دریافت و به انبارهای خود تخصیص میدهد.
|
||||
|
||||
---
|
||||
|
||||
## Database credentials / connection
|
||||
## 🛠️ عملیات نگهداری و دیپلوی در سرور (Operations)
|
||||
|
||||
```text
|
||||
Host: localhost
|
||||
Port: 5433
|
||||
Database: procurement
|
||||
Username: postgres
|
||||
Password: postgres
|
||||
|
||||
```
|
||||
|
||||
```powershell
|
||||
docker exec -it procurement-postgres psql -U postgres -d procurement
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recovery / seeding
|
||||
|
||||
The databases are **not** in git — Docker volumes hold the data, and
|
||||
database dumps must never be committed (they contain user rows and signing
|
||||
material). Two supported ways to bring a fresh stack up:
|
||||
|
||||
1. **Empty boot** — schema v2.6 auto-applies on the first boot of an empty
|
||||
`postgres_data` volume; then run the seeders:
|
||||
```powershell
|
||||
# Casdoor org + app + users (prints/generates credentials — do not commit them)
|
||||
docker compose run --rm -e CASDOOR_BASE=http://casdoor:8000 api python tools/seed_casdoor.py
|
||||
# Demo dataset (optional):
|
||||
docker exec procurement-api sh -c "cd /srv/backend && python -m tools.seed"
|
||||
|
||||
```
|
||||
|
||||
|
||||
2. **Restore your own dump** — create dumps on the server (kept server-side,
|
||||
e.g. `/srv/erp/backups/`), never in git:
|
||||
```powershell
|
||||
docker exec procurement-postgres pg_dump -U postgres -d procurement -Fc > /srv/erp/backups/procurement-$(date +%F).dump
|
||||
docker exec procurement-postgres pg_dump -U postgres -d casdoor -Fc > /srv/erp/backups/casdoor-$(date +%F).dump
|
||||
|
||||
```
|
||||
|
||||
|
||||
Restore with `pg_restore --clean --if-exists` (stop `api` + `casdoor`
|
||||
first — this **replaces all data**). The scheduled backup sidecar
|
||||
(see `docs/OPERATIONS.md`) automates this.
|
||||
|
||||
## 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
|
||||
|
||||
* Authentication is Casdoor-based (JWT verified via JWKS) and **required on
|
||||
every API route** except `/health`, `/health/ready` and `/auth/login`
|
||||
(401 without a token, 403 without a role). The former dev-header fallback
|
||||
(`X-User-Role` / `X-User-Name-B64`) is disabled unless
|
||||
`PROCUREMENT_DEV_LOGIN_ENABLED=true` — never enable it in production.
|
||||
* Roles live in the app's `users` table (Casdoor is identity-only): `pm`,
|
||||
`procurement_manager`, `admin`. Role changes are **admin-only** (RBAC);
|
||||
the procurement manager can only assign projects to project managers.
|
||||
The admin has a dedicated panel at `/admin` (user sync from Casdoor +
|
||||
grant/revoke «مدیر تدارکات»).
|
||||
* **Partial goods receipt** («رسید جزیی») is supported in «کالاهای در راه»:
|
||||
at least one item with a valid quantity is enough to submit; other items
|
||||
stay in transit. The procurement ledger shows «رسیده X از Y» / «در راه Z»
|
||||
badges and a «رسید جزیی» badge on the quote.
|
||||
* **One PostgreSQL instance** serves both the app (`procurement`) and Casdoor
|
||||
(`casdoor`) — the separate casdoor-postgres container is gone (data was
|
||||
dumped/restored; see `docs/casdoor-auth.md`).
|
||||
* **Traefik v3** is the public edge (ports 80/443); the frontend nginx only
|
||||
serves the SPA and proxies `/api` internally. Production (real domains,
|
||||
HTTPS via Let's Encrypt, HTTP→HTTPS redirect):
|
||||
`docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build`
|
||||
(see the prod file header for the required env vars).
|
||||
* 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.
|
||||
* **Material-Supplier Lookup**: Clicking a material in the catalog (e.g., on the `/units` page) dynamically fetches its assigned suppliers (`GET /api/materials/{id}/suppliers`). The backend uses an atomic JOIN to guarantee accurate supplier data (avoiding SQLAlchemy identity-map mismatches), and the UI displays a clean empty state («تامینکنندهای برای این متریال ثبت نشده است») if none exist.
|
||||
* 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`.
|
||||
|
||||
```
|
||||
* **دیپلوی خودکار:** سرور با هر Push به برنچ `production` از طریق وبهوک اختصاصی به صورت خودکار بیلد و بالا میآید. راهنمای کامل: [docs/OPERATIONS.md](file:///c:/Users/Reza/Desktop/v1.6/docs/OPERATIONS.md).
|
||||
* **پشتیبانگیری پایگاه داده:** سرویس `db-backup` به صورت روزانه از هر دو پایگاه داده `procurement` و `casdoor` فایلهای `.dump` تولید و در پوشه `backups/` نگهداری میکند.
|
||||
* **مانیتورینگ و مشاهدهپذیری:** ابزارهای Prometheus، لاگهای Loki و ردیابی خطاهای GlitchTip در پوشه [monitoring/](file:///c:/Users/Reza/Desktop/v1.6/monitoring/README.md) سازماندهی شدهاند.
|
||||
|
||||
Reference in New Issue
Block a user