docs: add database schema documentation
Define entity relationship diagrams and PostgreSQL DDL structure for the Canina Iran application database.
This commit is contained in:
parent
b4bf57f000
commit
4e2c8d5cfe
318
DATABASE_SCHEMA.md
Normal file
318
DATABASE_SCHEMA.md
Normal file
@ -0,0 +1,318 @@
|
||||
# طرحواره پایگاه داده کانینا ایران (Canina Iran Database Schema) 🗄️
|
||||
|
||||
این سند ساختار دقیق جداول، فیلدها، نوع دادهها (Datatypes)، روابط بین موجودیتها (ERD Relations) و ایندکسهای پیشنهادی را برای راهاندازی پایگاه داده نهایی سیستم کانینا طراحی و ارائه میکند. جهت انعطافپذیری توسعه، پیادهسازی هم بر اساس **پایگاه داده رابطهای (PostgreSQL / MySQL)** و هم **پایگاه داده مستندمحور/سندمراقبتی (NoSQL - MongoDB / Firestore)** مدلسازی شده است.
|
||||
|
||||
---
|
||||
|
||||
## ۱. ساختار سناریو و روابط موجودیتها (Entity Relationship Diagram Summary)
|
||||
|
||||
روابط بین موجودیتهای اصلی به شرح زیر طراحی گردیده است:
|
||||
- هر **کاربر (User)** میتواند چندین **آدرس (Address)**، چندین **حیوان خانگی (Pet)**، چندین **تراکنش کیفپول (WalletTransaction)** و چندین **سفارش خرید (Order)** داشته باشد. (`۱` به `N`)
|
||||
- هر **پت (Pet)** میتواند چندین **برنامه دارویی و یادآور (Reminder)** و چندین **دفترچه روزانه سلامت (HealthLog)** داشته باشد. (`۱` به `N`)
|
||||
- هر **سفارش (Order)** شامل یک سابقه از محصولات خریداری شده تحت قالب **موجودی جزئی فاکتور (OrderItem)** است.
|
||||
- تراکنشهای شارژ کیفپول یا پرداخت هر سفارش مستقیماً به کاربر و فاکتور مرتبط میشوند.
|
||||
|
||||
---
|
||||
|
||||
## ۲. طراحی طرحواره رابطهای (Relational Schema Design - PostgreSQL DDL)
|
||||
|
||||
در ادامه دستورات استاندارد SQL (پشتیبانی کاملاً سازگار با PostgreSQL) برای تولید ساختار پایگاه داده آورده شده است:
|
||||
|
||||
```sql
|
||||
-- فعالسازی افزونه جهت ایجاد UUID خودکار (در صورت تمایل به عدم استفاده از ردیفهای عددی متوالی)
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
-- ۱. جدول کاربران (users)
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
first_name VARCHAR(100) NOT NULL,
|
||||
last_name VARCHAR(100) NOT NULL,
|
||||
email VARCHAR(150) UNIQUE NOT NULL,
|
||||
mobile VARCHAR(15) UNIQUE,
|
||||
role VARCHAR(30) DEFAULT 'User_PetOwner' CHECK (role IN ('User_Guest', 'User_PetOwner', 'User_Partner')),
|
||||
wallet_balance NUMERIC(15, 2) DEFAULT 0.00 CHECK (wallet_balance >= 0),
|
||||
charity_donation_total NUMERIC(15, 2) DEFAULT 0.00,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ۲. جدول آدرسهای کاربران (user_addresses)
|
||||
CREATE TABLE user_addresses (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
title VARCHAR(100) NOT NULL,
|
||||
receptor_name VARCHAR(150) NOT NULL,
|
||||
phone VARCHAR(15) NOT NULL,
|
||||
province VARCHAR(100) NOT NULL,
|
||||
city VARCHAR(100) NOT NULL,
|
||||
detail TEXT NOT NULL,
|
||||
zip_code VARCHAR(10) NOT NULL,
|
||||
is_default BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ۳. جدول تراکنشهای مالی کاربر (wallet_transactions)
|
||||
CREATE TABLE wallet_transactions (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
amount NUMERIC(15, 2) NOT NULL,
|
||||
type VARCHAR(20) NOT NULL CHECK (type IN ('deposit', 'withdrawal')),
|
||||
status VARCHAR(20) NOT NULL CHECK (status IN ('pending', 'completed', 'failed')),
|
||||
transaction_reference VARCHAR(100) UNIQUE,
|
||||
description TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ۴. جدول کاتالوگ محصولات کانینا (products)
|
||||
CREATE TABLE products (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
art_no VARCHAR(20) UNIQUE NOT NULL,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
scientific_tagline VARCHAR(250),
|
||||
description TEXT NOT NULL,
|
||||
short_description TEXT,
|
||||
category VARCHAR(100) NOT NULL,
|
||||
category_slug VARCHAR(100) NOT NULL,
|
||||
price_value NUMERIC(15, 2) NOT NULL,
|
||||
price_display VARCHAR(50) NOT NULL, -- نمایش فارسی مانند "۴,۲۴۰,۰۰۰ تومان"
|
||||
unit VARCHAR(50) NOT NULL,
|
||||
package_size NUMERIC(10, 2) NOT NULL,
|
||||
dosage_logic TEXT,
|
||||
suitable_for VARCHAR(15) NOT NULL CHECK (suitable_for IN ('سگ', 'گربه', 'هر دو')),
|
||||
image_url TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ۵. جدول مواد مشتقه و مزایای محصولات (پیوند چند به چند با جداول فرعی یا ذخیره آرایه)
|
||||
CREATE TABLE product_ingredients (
|
||||
product_id UUID REFERENCES products(id) ON DELETE CASCADE,
|
||||
ingredient VARCHAR(150) NOT NULL,
|
||||
PRIMARY KEY (product_id, ingredient)
|
||||
);
|
||||
|
||||
CREATE TABLE product_symptoms (
|
||||
product_id UUID REFERENCES products(id) ON DELETE CASCADE,
|
||||
symptom VARCHAR(150) NOT NULL,
|
||||
PRIMARY KEY (product_id, symptom)
|
||||
);
|
||||
|
||||
-- ۶. جدول حیوانات خانگی (pets)
|
||||
CREATE TABLE pets (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
type VARCHAR(10) NOT NULL CHECK (type IN ('سگ', 'گربه')),
|
||||
breed VARCHAR(100) NOT NULL,
|
||||
age INT NOT NULL CHECK (age >= 0),
|
||||
weight NUMERIC(5, 2) NOT NULL CHECK (weight > 0),
|
||||
activity_level VARCHAR(15) NOT NULL CHECK (activity_level IN ('کم', 'متوسط', 'زیاد')),
|
||||
image_url TEXT,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE pet_medical_conditions (
|
||||
pet_id UUID REFERENCES pets(id) ON DELETE CASCADE,
|
||||
condition VARCHAR(150) NOT NULL,
|
||||
PRIMARY KEY (pet_id, condition)
|
||||
);
|
||||
|
||||
-- ۷. جدول برنامههای دارویی و یادآورها (reminders)
|
||||
CREATE TABLE reminders (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
pet_id UUID NOT NULL REFERENCES pets(id) ON DELETE CASCADE,
|
||||
product_id UUID REFERENCES products(id) ON DELETE SET NULL, -- اتصال اختیاری به کالای فیزیکی در فروشگاه جهت رصد انبار مصرف خانگی
|
||||
title VARCHAR(150) NOT NULL,
|
||||
time VARCHAR(5) NOT NULL, -- ساعت مانند "08:30"
|
||||
frequency VARCHAR(20) NOT NULL CHECK (frequency IN ('روزانه', 'هفتگی')),
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ۸. جدول روزها و تاریخهای مصرف شده به عنوان یادآور (reminder_completions)
|
||||
CREATE TABLE reminder_completions (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
reminder_id UUID NOT NULL REFERENCES reminders(id) ON DELETE CASCADE,
|
||||
completed_date DATE NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (reminder_id, completed_date)
|
||||
);
|
||||
|
||||
-- ۹. جدول ثبت لاگهای روزانه بیومتریک و گوارش پت (health_logs)
|
||||
CREATE TABLE health_logs (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
pet_id UUID NOT NULL REFERENCES pets(id) ON DELETE CASCADE,
|
||||
appetite VARCHAR(15) NOT NULL CHECK (appetite IN ('عالی', 'متوسط', 'کم')),
|
||||
energy VARCHAR(15) NOT NULL CHECK (energy IN ('زیاد', 'نرمال', 'بیحال')),
|
||||
digestion VARCHAR(15) NOT NULL CHECK (digestion IN ('نرمال', 'حساس', 'مشکلدار')),
|
||||
note TEXT,
|
||||
logged_date DATE DEFAULT CURRENT_DATE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ۱۰. جدول کپنهای تخفیف (coupons)
|
||||
CREATE TABLE coupons (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
code VARCHAR(50) UNIQUE NOT NULL,
|
||||
discount_value NUMERIC(15, 2) NOT NULL, -- مقدار کسر فیزیکی
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ۱۱. جدول فاکتورها و سفارشات نهایی (orders)
|
||||
CREATE TABLE orders (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
coupon_id UUID REFERENCES coupons(id),
|
||||
total_amount NUMERIC(15, 2) NOT NULL,
|
||||
charity_donation NUMERIC(15, 2) DEFAULT 0.00,
|
||||
status VARCHAR(30) DEFAULT 'processing' CHECK (status IN ('processing', 'shipped', 'delivered')),
|
||||
tracking_number VARCHAR(100) UNIQUE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ۱۲. جدول جزئیات اقلام سفارشها (order_items)
|
||||
CREATE TABLE order_items (
|
||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
order_id UUID NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
|
||||
product_id UUID REFERENCES products(id) ON DELETE SET NULL,
|
||||
quantity INT NOT NULL CHECK (quantity > 0),
|
||||
dose_qty NUMERIC(10, 2), -- مقدار حجم دوز محاسبهشده توسط فرانت در ثانیه ثبت سفارش
|
||||
dose_unit VARCHAR(50) -- واحد دوز مانند "Tabs/Day" یا "ml/Day"
|
||||
);
|
||||
```
|
||||
|
||||
### ایندکسهای پیشنهادی جهت بهینهسازی کوئریها (Database Indexes)
|
||||
جهت بالابردن کشش سرور در زمان فیلتر سریع محصولات در صفحه آرشیو یا لود سریع وضعیت پتها:
|
||||
```sql
|
||||
CREATE INDEX idx_products_category ON products(category_slug);
|
||||
CREATE INDEX idx_products_suitable_for ON products(suitable_for);
|
||||
CREATE INDEX idx_user_addresses_default ON user_addresses(user_id) WHERE is_default = TRUE;
|
||||
CREATE INDEX idx_reminders_pet ON reminders(pet_id);
|
||||
CREATE INDEX idx_reminder_completions_ref ON reminder_completions(reminder_id, completed_date);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ۳. طرحواره غیررابطهای مستندمحور (NoSQL Document Architecture - MongoDB Examples)
|
||||
|
||||
در صورتی که سازمان تصمیم به پیادهسازی بکبند با فریمورکهای مقیم بر جاوااسکریپت (نظیر Express.js + Mongoose با موتور MongoDB) داشته باشد، مدل دادهها به شکل کلیدهای کل ساختار به این فرم سند دهی میشوند:
|
||||
|
||||
### ۳.۱. سند کاربران (Users Collection - `users`)
|
||||
```json
|
||||
{
|
||||
"_id": "6472f8d38bfcb8234ecca801",
|
||||
"firstName": "پارسا",
|
||||
"lastName": "آقایی",
|
||||
"email": "parsa.aghaee@gmail.com",
|
||||
"mobile": "09123456789",
|
||||
"role": "User_PetOwner",
|
||||
"walletBalance": 1500000.00,
|
||||
"charityDonationTotal": 15000.00,
|
||||
"addresses": [
|
||||
{
|
||||
"id": "6472f8d38bfcb8234ecca805",
|
||||
"title": "خانه",
|
||||
"receptorName": "پارسا آقایی",
|
||||
"phone": "09123456789",
|
||||
"province": "تهران",
|
||||
"city": "تهران",
|
||||
"detail": "بلوار میرداماد، قبل از میدان مادر، پلاک ۱۲، واحد ۴",
|
||||
"zipCode": "1911122233",
|
||||
"isDefault": true
|
||||
}
|
||||
],
|
||||
"transactions": [
|
||||
{
|
||||
"transactionId": "TXN-998811",
|
||||
"amount": 500000,
|
||||
"type": "deposit",
|
||||
"status": "completed",
|
||||
"createdAt": "2026-05-26T08:15:00Z"
|
||||
}
|
||||
],
|
||||
"createdAt": "2026-05-26T08:00:20Z",
|
||||
"updatedAt": "2026-05-26T08:15:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### ۳.۲. سند حیوانات خانگی (Pets Collection - `pets`)
|
||||
```json
|
||||
{
|
||||
"_id": "6472f8d38bfcb8234ecca952",
|
||||
"userId": "6472f8d38bfcb8234ecca801",
|
||||
"name": "جکی",
|
||||
"type": "سگ",
|
||||
"breed": "ژرمن شپرد",
|
||||
"age": 4,
|
||||
"weight": 28.5,
|
||||
"activityLevel": "زیاد",
|
||||
"medicalConditions": ["درد مفاصل", "لنگیدن"],
|
||||
"image": "https://images.unsplash.com/photo-1589941013453-ec89f33b5e95?auto=format&fit=crop&q=80&w=300",
|
||||
"reminders": [
|
||||
{
|
||||
"id": "REM-001",
|
||||
"productId": "6472f8d38bfcb8234eccb611", // مکمل آرتروفیت کانینا فیزیکی جهت کسر انبار پت
|
||||
"title": "مصرف قرص مفصلساز Canhydrox",
|
||||
"time": "08:30",
|
||||
"frequency": "روزانه",
|
||||
"completedDates": ["2026-05-25", "2026-05-26"]
|
||||
}
|
||||
],
|
||||
"logs": [
|
||||
{
|
||||
"id": "LOG-102",
|
||||
"appetite": "عالی",
|
||||
"energy": "نرمال",
|
||||
"digestion": "نرمال",
|
||||
"note": "امروز جکی به خوبی صبحانهاش را تمام کرد و وضعیت بهتری دارد.",
|
||||
"createdAt": "2026-05-26T08:05:12Z"
|
||||
}
|
||||
],
|
||||
"createdAt": "2026-05-26T08:02:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### ۳.۳. سند محصولات (Products Collection - `products`)
|
||||
```json
|
||||
{
|
||||
"_id": "6472f8d38bfcb8234eccb611",
|
||||
"artNo": "111452",
|
||||
"name": "Petvital Canhydrox (مفصلساز قوی گرید دارویی)",
|
||||
"scientificTagline": "فرمول انحصاری و همگام آلمانی جهت بازسازی سلول استخوانی",
|
||||
"description": "مکمل درمانی فوقحرفهای برای تامین نیاز حیاتی مفاصل سنگین وزن و درمان آسیبهای رباط مفاصل.",
|
||||
"shortDescription": "محرک طبیعی بازسازی غضروفها؛ حاوی کلسیم هیدروکسی آپاتیت ویژه برای رشد استخوانی بی نقص.",
|
||||
"keyBenefits": [
|
||||
{
|
||||
"icon": "Flame",
|
||||
"title": "گرید دارویی",
|
||||
"description": "بالاترین سطح خلوص مواد"
|
||||
}
|
||||
],
|
||||
"category": "مفاصل و استخوان",
|
||||
"categorySlug": "joints",
|
||||
"price": "۴,۲۴۰,۰۰۰ تومان",
|
||||
"priceValue": 4240000,
|
||||
"unit": "60 Tablets / 100g",
|
||||
"packageSize": 60,
|
||||
"mainIngredients": ["کلسیم هیدروکسی آپاتیت", "صدف لب سبز نیوزلندی", "سیلیسیم"],
|
||||
"dosageLogic": "به ازای هر ۵ کیلوگرم وزن، ۲ قرص روزانه تجویز بالا گردد.",
|
||||
"symptoms": ["درد مفاصل", "سختی در بلند شدن", "لنگیدن"],
|
||||
"suitableFor": "هر دو",
|
||||
"image": "https://www.canina.de/media/89/34/9a/1715077271/Petvital-Canhydrox-111421-V1-Canina-100g_600x600.webp"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ۴. چرخه اعتبارسنجی ترافیک (Data Validation Constraints)
|
||||
|
||||
توسعهدهندگان بکبند باید پیش از ترخیص اطلاعات در دیتابیس، کنترلهای زیر را در لایهی اعتبارسنجی کنترلرها (مانند استفاده از کتابخانه `Zod` در Node.js یا ولیدیشن داخلی به همراه `Joi`) اعمال کنند:
|
||||
|
||||
۱. **فرمت شماره تلفن همراه ایران:**
|
||||
- رجکس معتبر: `/^09\d{9}$/` یا `/^\+989\d{9}$/`
|
||||
۲. **کد پستی کشور:**
|
||||
- رجکس اعتبارسنجی ده رقمی: `/^\d{10}$/`
|
||||
۳. **تایپهای سن و وزن:**
|
||||
- سن حیوانات خانگی به عدد صحیح بزگتر یا مساوی صفر (`int >= 0`) محدود شود.
|
||||
- وزن آنها دسیمال مثبت بزرگتر از صفر باشد.
|
||||
|
||||
*با اعمال پیوستگی این دو طرحواره رابطهای و مستندمحور، ارتباطات و تبادل داده میان فرانتاند و هر مدل معماری بکبند بدون اصطکاک انجام خواهد شد.*
|
||||
Loading…
Reference in New Issue
Block a user