# طرح‌واره پایگاه داده کنینا ایران (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`) محدود شود. - وزن آنها دسی‌مال مثبت بزرگتر از صفر باشد. *با اعمال پیوستگی این دو طرح‌واره رابطه‌ای و مستندمحور، ارتباطات و تبادل داده میان فرانت‌اند و هر مدل معماری بک‌بند بدون اصطکاک انجام خواهد شد.*