𝗕𝘂𝗶𝗹𝗱𝗶𝗻𝗴 𝗮 𝗣𝗿𝗼𝗷𝗲𝗰𝘁 𝗠𝗮𝗻𝗮𝗴𝗲𝗺𝗲𝗻𝘁 𝗧𝗼𝗼𝗹 𝘄𝗶𝘁𝗵 𝗣𝗿𝗶𝘀𝗺𝗮
আমি Trello-এর মতো একটি কোলাবোরেটিভ প্রজেক্ট ম্যানেজমেন্ট টুল তৈরি করছি। আমি React, Express.js, PostgreSQL এবং Socket.io ব্যবহার করছি।
প্রথম ধাপ হলো ডাটাবেস স্কিমা। ইউজার, প্রজেক্ট, বোর্ড, টাস্ক, কমেন্ট এবং নোটিফিকেশন হ্যান্ডেল করার জন্য আমি ছয়টি মডেল ডিজাইন করেছি।
আমার Prisma স্কিমা ডিজাইন থেকে প্রাপ্ত মূল প্রযুক্তিগত সিদ্ধান্ত এবং শিক্ষাগুলো নিচে দেওয়া হলো:
• ID-এর জন্য CUID ব্যবহার করা
আমি সব ID-এর জন্য @default(cuid()) ব্যবহার করি। পাবলিক URL-এর জন্য এগুলো সাধারণ সংখ্যার চেয়ে ভালো। এগুলো মানুষ যাতে আপনার কতগুলো রেকর্ড আছে তা অনুমান করতে না পারে তা নিশ্চিত করে।
• সুস্পষ্ট রিলেশন নাম (Explicit Relation Names)
যখন দুটি ফিল্ড একই মডেলকে নির্দেশ করে, তখন Prisma বিভ্রান্ত হয়ে পড়ে। উদাহরণস্বরূপ, একটি টাস্কের একজন ক্রিয়েটর (creator) এবং একজন অ্যাসাইনি (assignee) থাকে। উভয়ই হলো User। মাইগ্রেশন এরর এড়াতে আমাকে @relation নাম ব্যবহার করে এই রিলেশনগুলোকে স্পষ্টভাবে উল্লেখ করতে হয়।
• Many-to-Many রিলেশনের জন্য জাংশন টেবিল (Junction Tables)
একজন ইউজার অনেকগুলো প্রজেক্টের অন্তর্ভুক্ত হতে পারেন। একটি প্রজেক্টে অনেক ইউজার থাকতে পারেন। তাদের মধ্যে সংযোগ স্থাপনের জন্য আমি একটি ProjectMember মডেল তৈরি করেছি। আমি userId এবং projectId-এর ওপর একটি ইউনিক কনস্ট্রেইন্ট (unique constraint) যোগ করেছি। এটি একই ইউজারকে দুবার একটি প্রজেক্টে যোগ হওয়া থেকে বিরত রাখে।
• হায়ারার্কি এবং লজিক
টাস্কগুলো সরাসরি প্রজেক্টের অন্তর্ভুক্ত নয়; সেগুলো থাকে বোর্ডে। আর বোর্ডগুলো থাকে প্রজেক্টের অন্তর্ভুক্ত। এটি ড্র্যাগ-অ্যান্ড-ড্রপ (drag-and-drop) প্রক্রিয়াকে সহজ করে তোলে। একটি টাস্ক মুভ করতে হলে আপনাকে শুধু এর boardId আপডেট করতে হবে।
• নালিবল রিলেশন (Nullable Relations)
কিছু রিলেশন আবশ্যক (required) এবং কিছু ঐচ্ছিক (optional)। একটি টাস্কের অবশ্যই একজন ক্রিয়েটর থাকতে হবে, তাই আমি কোনো প্রশ্নবোধক চিহ্ন ব্যবহার করিনি। অ্যাসাইনি ঐচ্ছিক, তাই আমি User? এবং String? ব্যবহার করেছি। স্কিমাটি সঠিকভাবে কাজ করার জন্য আপনাকে অবশ্যই উভয়টি অন্তর্ভুক্ত করতে হবে।
আমার পাওয়া কিছু সাধারণ ভুল:
- ডিফল্ট ভ্যালুর জন্য সিঙ্গেল কোট ব্যবহার করা। Prisma-তে ডাবল কোট প্রয়োজন।
- রেফারেন্স সিনট্যাক্সে কোলন (:) দিতে ভুলে যাওয়া।
- ভুলবশত একটি ID ফিল্ডে
@default(now())প্রয়োগ করা।
এরপর, আমি Express ব্যাকএন্ড তৈরি করব এবং রিয়েল-টাইম আপডেটের জন্য Socket.io সেটআপ করব।