এই ভলিউমে · ভলিউম 01
ভিত্তি
মাল্টি-টেন্যান্সি

অধ্যায় ১.১ — মাল্টি-টেন্যান্সি

১. উদ্দেশ্য

travoBooks একটি multi-tenant প্ল্যাটফর্ম — একই ইনস্টলেশনে একাধিক ট্রাভেল এজেন্সি সম্পূর্ণ ডেটা আইসোলেশনের সাথে চলে। এই অধ্যায়ে কীভাবে আইসোলেশন প্রয়োগ করা হয় তা ব্যাখ্যা করা হয়েছে।

২. কেন এটি গুরুত্বপূর্ণ

এক পার্টনারের ডেটা অন্য পার্টনারের কাছে কখনো ফাঁস হওয়া উচিত নয় — এটি প্ল্যাটফর্মের সবচেয়ে গুরুত্বপূর্ণ নিরাপত্তা নিশ্চয়তা। ভুল করলে গুরুতর কমপ্লায়েন্স লঙ্ঘন (GDPR, DPDPA) এবং বিশ্বাস হ্রাস।

৩. পার্টিশন-ভিত্তিক আইসোলেশন

travoBooks partition-based multi-tenancy ব্যবহার করে — সমস্ত পার্টনার একই ডেটাবেসে কিন্তু প্রতিটি রো-তে partner_id কলাম। বিকল্প পদ্ধতি (পার্টনার-প্রতি আলাদা ডিবি/স্কিমা) বিবেচিত হয়েছিল কিন্তু পার্টিশনের জন্য নির্বাচিত হয়েছে কারণ:

  • অপারেশনাল সরলতা: একটি ডিবি ব্যাকআপ, একটি মাইগ্রেশন
  • খরচ: ছোট পার্টনারের জন্য আলাদা ডিবি অর্থনৈতিকভাবে দুর্বল
  • ক্রস-পার্টনার রিপোর্টিং: প্ল্যাটফর্ম-প্রশাসনিক প্রতিবেদন সহজ

৪. তিনটি এনফোর্সমেন্ট লেয়ার

ডেটা আইসোলেশন একটি একক লেয়ারের উপর নির্ভর করে না — তিনটি লেয়ার ত্রুটি প্রতিরোধে।

লেয়ার ১: অ্যাপ্লিকেশন

সমস্ত ক্যোয়েরিতে partner_id ফিল্টার বাধ্যতামূলক। বেস রিপোজিটরি ক্লাসে স্বয়ংক্রিয়ভাবে যোগ হয়:

$query->where('partner_id', $currentPartnerId);

ডেভেলপার ভুলে গেলেও — ফলব্যাক হিসেবে লেয়ার ২ থাকে।

লেয়ার ২: ডেটাবেস (Row-Level Security)

MySQL ভিউ ব্যবহার করে partner_id ফিল্টারিং প্রয়োগ করা হয়। অ্যাপ্লিকেশন partners.bookings ভিউ ক্যোয়েরি করে, সরাসরি bookings টেবিল নয়। ভিউ স্বয়ংক্রিয়ভাবে সেশন ভেরিয়েবল @current_partner_id দিয়ে ফিল্টার।

লেয়ার ৩: অবজেক্ট স্টোরেজ

S3 অবজেক্টে partner-নির্দিষ্ট prefix: s3://travobooks-prod/partner-{id}/...। IAM পলিসি প্রতি পার্টনারের সেশনকে শুধু তাদের prefix-এ অ্যাক্সেস দেয়।

৫. বাধ্যতামূলক কলাম

প্রতিটি ব্যবসা-অর্থবোধক টেবিলে:

partner_id     BIGINT NOT NULL,
created_at     DATETIME(6) NOT NULL,
created_by     BIGINT NOT NULL,
updated_at     DATETIME(6),
updated_by     BIGINT,
version        INT NOT NULL DEFAULT 1

ফরেন কী constraint: (partner_id, *_id) যৌথভাবে — ক্রস-পার্টনার রেফারেন্স ব্লক।

৬. পার্টনার-স্কোপড সেশন

লগইনের পরে, ব্যবহারকারীর সেশনে partner_id সেট হয়। সমস্ত পরবর্তী অপারেশন এই স্কোপের মধ্যে। প্ল্যাটফর্ম-অ্যাডমিন (Anthropic-of-travoBooks) সুপার-পার্টনার অ্যাক্সেস পায় কিন্তু এটি অডিট-ট্র্যাকড।

৭. সাধারণ ফাঁদ

  • ⚠️ JOIN-এ partner_id চেক না করা — Row-Level Security ধরে ফেলবে কিন্তু performance ক্ষতি।
  • ⚠️ কাস্টম raw SQL যা ফিল্টার বাইপাস করে — কোড রিভিউতে ধরা।
  • ⚠️ পার্টনার ID URL/cookie থেকে নিয়ে — সর্বদা সার্ভার-সাইড সেশন থেকে।