SMP
مدير النظامEnterprise

مخطط قاعدة البيانات (ERD)

مخطط بصري لجداول النظام وعلاقاتها، مع توضيح عزل بيانات كل عميل عبر client_id

عزل بيانات Multi-Tenant عبر client_id

كل جدول (باستثناء clients) يحتوي على عمود client_id يشير إلى الجدول الجذر. تُفعَّل سياسة Row Level Security على كل جدول لتضمن أن كل استعلام يُرجع فقط الصفوف التي تنتمي إلى العميل الحالي، حتى لو حاول مستخدم قراءة بيانات مباشرة عبر API.

-- Example RLS policy applied to every tenant table
ALTER TABLE public.tweets ENABLE ROW LEVEL SECURITY;

CREATE POLICY "tenant_isolation_select" ON public.tweets
  FOR SELECT TO authenticated
  USING (client_id = public.current_client_id());

CREATE POLICY "tenant_isolation_write" ON public.tweets
  FOR ALL TO authenticated
  USING (client_id = public.current_client_id())
  WITH CHECK (client_id = public.current_client_id());
مفتاح رئيسي (PK)
مفتاح خارجي (FK)
NNغير فارغ
UQفريد
client_idعمود العزل
مرّر المؤشر فوق جدول لإبراز الجداول المرتبطة
clients
العملاء (Tenants)
iduuidNN
nametextNN
logo_urltext
primary_colortext
plantextNN
expires_attimestamptz
statustextNN
created_attimestamptzNN
users
المستخدمون
iduuidNN
client_iduuidNN
emailtextNNUQ
full_nametext
roleapp_roleNN
last_logintimestamptz
statustextNN
RLS: client_id = auth.client_id()
settings
الإعدادات
iduuid
client_iduuidNNUQ
languagetext
currencytext
timezonetext
brand_nametext
RLS: client_id = auth.client_id()
tweets
التغريدات والمنشورات
iduuid
client_iduuidNN
author_iduuid
contenttextNN
scheduled_attimestamptz
statustextNN
RLS: client_id = auth.client_id()
attack_log
سجل الهجمات
iduuid
client_iduuidNN
attacker_handletextNN
typetextNN
severitytextNN
statustextNN
reported_byuuid
RLS: client_id = auth.client_id()
responses
بنك الردود
iduuid
client_iduuidNN
bodytextNN
categorytext
tonetext
usage_countint
RLS: client_id = auth.client_id()
reports
التقارير
iduuid
client_iduuidNN
period_startdateNN
period_enddateNN
kindtextNN
file_urltext
generated_byuuid
RLS: client_id = auth.client_id()
invoices
الفواتير
iduuid
client_iduuidNN
numbertextNNUQ
amountnumericNN
currencytextNN
statustextNN
due_atdate
RLS: client_id = auth.client_id()
activity_log
سجل النشاط
iduuid
client_iduuidNN
user_iduuid
actiontextNN
entitytextNN
entity_iduuid
created_attimestamptzNN
RLS: client_id = auth.client_id()

خريطة العلاقات

الجدول الفرعيالعموديشير إلىنوع العلاقةعند الحذف
usersclient_idclients.idTenant IsolationCASCADE
settingsclient_idclients.idTenant IsolationCASCADE
tweetsclient_idclients.idTenant IsolationCASCADE
tweetsauthor_idusers.idN : 1SET NULL
attack_logclient_idclients.idTenant IsolationCASCADE
attack_logreported_byusers.idN : 1SET NULL
responsesclient_idclients.idTenant IsolationCASCADE
reportsclient_idclients.idTenant IsolationCASCADE
reportsgenerated_byusers.idN : 1SET NULL
invoicesclient_idclients.idTenant IsolationCASCADE
activity_logclient_idclients.idTenant IsolationCASCADE
activity_loguser_idusers.idN : 1SET NULL

ضمانات العزل

  • كل جدول يفعّل RLS ولا يمكن قراءته بدون client_id صحيح.
  • دالة current_client_id() تُستخرج من JWT للمستخدم الحالي.
  • عند حذف عميل من clients تُحذف كل بياناته تلقائياً (ON DELETE CASCADE).
  • الأدوار محفوظة في جدول user_roles منفصل لتفادي هجمات رفع الصلاحيات.

التدقيق والمراقبة

  • كل عملية إنشاء/تعديل/حذف تُسجَّل في activity_log.
  • يحتوي السجل على user_id و client_id والزمن والإجراء.
  • لا يمكن للمستخدمين حذف سجلات التدقيق حتى لو كانوا مديرين.
  • Super Admin فقط يمكنه رؤية سجلات جميع العملاء عبر عرض مخصص.