319 lines
15 KiB
Markdown
319 lines
15 KiB
Markdown
# طرحواره پایگاه داده کنینا ایران (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-Canino-100g_600x600.webp"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## ۴. چرخه اعتبارسنجی ترافیک (Data Validation Constraints)
|
||
|
||
توسعهدهندگان بکبند باید پیش از ترخیص اطلاعات در دیتابیس، کنترلهای زیر را در لایهی اعتبارسنجی کنترلرها (مانند استفاده از کتابخانه `Zod` در Node.js یا ولیدیشن داخلی به همراه `Joi`) اعمال کنند:
|
||
|
||
۱. **فرمت شماره تلفن همراه ایران:**
|
||
- رجکس معتبر: `/^09\d{9}$/` یا `/^\+989\d{9}$/`
|
||
۲. **کد پستی کشور:**
|
||
- رجکس اعتبارسنجی ده رقمی: `/^\d{10}$/`
|
||
۳. **تایپهای سن و وزن:**
|
||
- سن حیوانات خانگی به عدد صحیح بزگتر یا مساوی صفر (`int >= 0`) محدود شود.
|
||
- وزن آنها دسیمال مثبت بزرگتر از صفر باشد.
|
||
|
||
*با اعمال پیوستگی این دو طرحواره رابطهای و مستندمحور، ارتباطات و تبادل داده میان فرانتاند و هر مدل معماری بکبند بدون اصطکاک انجام خواهد شد.*
|