রিজেনারেশন-ফার্স্ট ডেভেলপমেন্ট: নিরাপদে পরিবর্তনশীল অ্যাপ তৈরির উপায়
রিজেনারেশন-ফার্স্ট ডেভেলপমেন্ট শিখুন: ডেটা, লজিক ও UI পরিবর্তন করে সাফ কোড রিজেনারেট করে অ্যাপগুলোকে নমনীয় ও নিরাপদ রাখুন—প্যাচ করার বদলে।

কেন প্যাচ-স্টাইলে পরিবর্তন প্রযুক্তিগত ঋণে পরিণত হয়
প্যাচ করা হয় যখন নতুন কোনো চাহিদা আসে এবং আপনি সেটা অ্যাপে সবচেয়ে ছোট সম্পাদনার মাধ্যমে ঢুকিয়ে দেন। এটি তাড়াতাড়ি মনে হয়—কারণ তা সত্যিই দ্রুত। সমস্যা হলো প্রত্যেকটি প্যাচ একটি স্থানীয় সমাধান; এবং স্থানীয় সমাধানগুলো সাধারণত অ্যাপের সঠিক গঠনকে প্রতিফলিত করে না।
ধীরে ধীরে, প্যাচগুলো জমা হয়। অ্যাপটা এখনও চলে, কিন্তু কোড এবং কনফিগারেশন একে অপরের সাথে অমিল করতে থাকে: ডাটাবেস একরকম ইঙ্গিত দেয়, UI আরেকরকম দেখায়, আর বাস্তব নিয়ম তিনটি আলাদা জায়গায় লুকিয়ে থাকে। সেই অমিলটাই প্রযুক্তিগত ঋণ। এটা শুধু “খারাপ কোড” নয়—এটা পরবর্তী পরিবর্তন করার বাড়তে থাকা খরচ।
সাধারণত এভাবে ধরা যায়:
- লজিক জটিল হয়ে যায়, তাই এক ছোট নিয়ম বদল অনেক স্ক্রিন বা এন্ডপয়েন্টকে ছুঁয়ে দেয়।
- ফিল্ড ডুপ্লিকেট হয়ে যায় ("status", "ticket_status", "status_v2") কারণ রিনেম করা ঝুঁকিপূর্ণ মনে হয়।
- UI ভঙ্গুর হয়ে পড়ে, নির্দিষ্ট ডেটা শেপ বা এজ কেসের ওপর লুকানো নির্ভরশীলতা থাকে।
- ওয়ার্কঅ্যারাউন্ডগুলো "অস্থায়ী" পতাকা হয়ে যায় যা কখনো মুছে না যায়।
- ফিক্সের পরে ফলো-আপ ফিক্স লাগে কারণ কেউ নিশ্চিত নয় আর কোথায় কী ভেঙে পড়তে পারে।
দুর্বিষহ অংশ হলো ঝুঁকি কতো দ্রুত বেড়ে যায়। এমন একটি পরিবর্তন যা ছোট হওয়া উচিত (একটি অনুমোদন ধাপ যোগ করা, মূল্য নীতির সামঞ্জস্য করা, একটি ব্যবহারকারী ভূমিকা দুটিতে ভাগ করা) তা ঝুঁকিপূর্ণ রিলিজে পরিণত হয় কারণ আপনি ব্লাস্ট রেডিয়াস পূর্বানুমেয় করতে পারেন না। টেস্টিং হয় আন্দাজে; রোলব্যাক কঠিন কারণ প্যাচ অনাসক্ত অংশও স্পর্শ করেছে।
রিজেনারেশন-ফার্স্ট ডেভেলপমেন্ট ঠিক এরই জবাব। লক্ষ্য হলো অ্যাপকে এমনভাবে গঠন করা যাতে পরিবর্তনগুলো পূর্বানুমেয় ও উল্টো করা যায়, এবং প্ল্যাটফর্ম পরিষ্কার কোড পুনরায় তৈরি করতে পারে এমনভাবে যাতে গতকালের হ্যাকগুলো বয়ে নিয়ে না চলে।
একটি ব্যবহারযোগ্য লক্ষ্য:
- ডেটার জন্য একটি স্পষ্ট সোর্স অফ ট্রুথ (প্রায় একরকম ফিল্ড দ্বৈত নয়)।
- নিয়মগুলো এক জায়গায় থাকে, UI ও এন্ডপয়েন্ট জুড়ে ছড়িয়ে নেই।
- UI শুধু প্রদর্শন ও ইনপুটে মনোযোগ দেয়, ব্যবসায়িক সিদ্ধান্তে নয়।
- পরিবর্তন মডেল ও লজিকে করা হয়, তারপর আপনি রিজেনারেট করেন—হাতে করে আউটপুট এডিট করার বদলে।
AppMaster-এর মতো প্ল্যাটফর্ম এটি সমর্থন করে কারণ অ্যাপগুলো মডেল ও ভিজ্যুয়াল লজিকে সংজ্ঞায়িত, এবং প্ল্যাটফর্ম পুরো সোর্স কোড রিজেনারেট করে। কিন্তু রিজেনারেশন কেবল তখনই পরিষ্কার থাকে যখন আপনি শুরু থেকেই প্যাচ-নির্ভর গঠনের পথ এড়ান।
রিজেনারেশন-ফার্স্ট ডেভেলপমেন্ট মানে কী
রিজেনারেশন-ফার্স্ট ডেভেলপমেন্ট আপনার অ্যাপকে স্পষ্ট মডেলের সেট হিসেবে বিবেচনা করে, হাত দিয়ে লিখিত কোডের গুচ্ছ হিসেবে নয়। আপনি মডেলগুলো বদলান, রিজেনারেট করেন, এবং একটি নতুন, সামঞ্জস্যপূর্ণ ভার্শন পান। উদ্দেশ্য হলো পরিবর্তন পাঠানো যাতে অতিরিক্ত হ্যাকপাথ রেখে না যায় যা পরবর্তী পরিবর্তনকে কঠিন করে।
প্যাচ-প্রথম ওয়ার্কফ্লোতে, একটি ছোট অনুরোধ (একটি নতুন স্ট্যাটাস ফিল্ড, একটি নতুন অনুমোদন ধাপ) যেখানে দ্রুত যায় সেখানে ঢুকে পড়ে। কেউ একটি API হ্যান্ডলার টুইক করে, একটি স্ক্রিন আপডেট করে, অন্যত্র একটি বিশেষ কেস যোগ করে, এবং এগিয়ে চলে। অ্যাপ আজ কাজ করে, কিন্তু লজিক ছড়িয়ে পড়ে। কয়েকটি চক্রের পরে, কেউ আর নিশ্চিত নয় যে বাস্তব নিয়ম কোথায় রয়েছে।
রিজেনারেশন-ফার্স্ট ডেভেলপমেন্টে সোর্স অফ ট্রুথ মডেলগুলোতে থাকে:
- ডেটা মডেল: এন্টিটি, ফিল্ড, সম্পর্ক, কনস্ট্রেইন্ট
- বিজনেস লজিক মডেল: নিয়ম ও ফ্লো যা নির্ধারণ করে কী হয়
- UI মডেল: স্ক্রীন, কম্পোনেন্ট, এবং কীভাবে সেগুলো ডেটার সাথে বাইন্ড করে
এই মডেলগুলো থেকে জেনারেট করা সবকিছু (API এন্ডপয়েন্ট, ডাটাবেস অ্যাক্সেস, ওয়েব ও মোবাইল কোড) হল আউটপুট—তাত্ক্ষণিক ফিক্স করার জায়গা নয়।
AppMaster-এ আউটপুট হিসেবে ব্যাকএন্ডের জন্য Go, ওয়েবের জন্য Vue3, এবং মোবাইলের জন্য Kotlin বা SwiftUI অন্তর্ভুক্ত হতে পারে। যখন চাহিদা বদলে যায়, আপনি মডেল একবার আপডেট করেন এবং রিজেনারেট করেন, বদলে ডিফাইনিশন খুঁজে খুঁজে একাধিক ফাইলে তাড়া করবেন না।
এতে অ্যাপ লেয়ার জুড়ে সামঞ্জস্য থাকে কারণ একই সংজ্ঞাগুলো প্রতিটি অংশ চালায়। যদি "Ticket Status" বাধ্যতামূলক হয়ে যায়, তাহলে ডাটাবেস স্কিমা, ভ্যালিডেশন, API, এবং UI বাইন্ডিংগুলো একসাথে আপডেট হওয়া উচিত। যদি একটি অনুমোদন নিয়ম বদলে যায়, আপনি প্রসেসটি আপডেট করবেন যাতে প্রতিটি এন্ডপয়েন্ট ও স্ক্রীন একই লজিক প্রদর্শন করে।
মনোভাবের স্লোগান সোজা: যা আপনি বলতে চান সেটাই এডিট করুন (মডেল), যা দরকার তা জেনারেট করুন (কোড)।
এমন এক ডেটা মডেল তৈরির করুন যা বিকশিত হতে পারে
রিজেনারেশন-ফার্স্ট কাজ করার জন্য, এমন অংশ দিয়ে শুরু করুন যেটা সবচেয়ে কম বদল হওয়া উচিত: ডেটা মডেল। পরিবর্তন-উপযোগী অ্যাপগুলো টিকে থাকে কারণ কোর এন্টিটি স্থিতিশীল ও ভালভাবে নামকরণ করা আছে—স্ক্রিনগুলোর নিখুঁত হওয়ার কারণে নয়।
যে নামগুলো আপনার ব্যবসা এক বছর পরও ব্যবহার করবে সেই নাউনগুলো দিয়ে শুরু করুন। অনেক অ্যাপের জন্য এরা হল: User, Account, Team, Ticket, Order, Invoice, Product, Message। এগুলো স্পষ্ট হলে বাকি (ওয়ার্কফ্লো, পারমিশন, UI) ভালো ভিত্তির ওপর দাঁড়ায়।
নামকরণ একটি ছোট বিষয় নয়। এটা পরে পরিবর্তনগুলোকে বিভ্রান্তিকারক মাইগ্রেশন ও ভাঙা লজিকে পরিণত হওয়া থেকে রক্ষা করে। সত্তা নামগুলোর জন্য একবচন ব্যবহার করুন, ধারাবাহিক ফিল্ড নাম (created_at বনাম createdAt) এবং বাস্তবতার সাথে মিলানো টাইপ বেছে নিন (টাকা decimal, টাইমস্ট্যাম্পে টাইমজোন নীতিমালা)। ছোট অসামঞ্জস্যগুলো নিয়ম, ফিল্টার, রিপোর্টে ছড়িয়ে পড়ে।
বড় ডিজাইন করার বদলে বৃদ্ধি পরিকল্পনা করুন। প্রত্যেক ভবিষ্যৎ ফিল্ড ভবিষ্যদ্বাণী করতে হবে না, কিন্তু সাধারণ পরিবর্তন টাইপগুলোকে নিরাপদ করা যায়:
- প্রতিটি ধাপের জন্য আলাদা টেবিল বানানোর বদলে স্ট্যাটাস ফিল্ড রাখতে পছন্দ করুন যা নতুন মান নিতে পারে।
- সবসময় উপস্থিত নয় এমন ডেটার জন্য অপশনাল ফিল্ড ব্যবহার করুন (phone_number, external_id)।
- শুরুতেই অডিট ফিল্ড যোগ করুন (created_at, updated_at, created_by) যাতে পরে রেট্রোফিট করতে না হয়।
- পরীক্ষামূলক ডেটা মূল মডেল দূষিত না করেই রাখার জন্য "notes" ও "metadata" আলাদা রাখুন।
ভিজ্যুয়াল ডেটা ডিজাইনার সাহায্য করে কারণ আপনি কোড হওয়ার আগে সম্পর্ক ও কনস্ট্রেইন্ট দেখতে পারেন। AppMaster-এ Data Designer আপনার স্কিমাকে PostgreSQL-এ ম্যাপ করে, তাই আপনি একটি জায়গায় টেবিল, ফিল্ড, লিঙ্ক মডেল করে প্রয়োজন বদলালে পরিষ্কার সোর্স কোড রিজেনারেট করতে পারেন।
উদাহরণ: একটি সাপোর্ট পোর্টাল Tickets কে Accounts ও Users-এ লিঙ্ক করে শুরু করে। পরে ব্যবসা চাইলে priority, category, এবং একটি নতুন স্ট্যাটাস "Waiting on Customer" যোগ করতে পারে। যদি Tickets-এ আগেই একটি স্ট্যাটাস ফিল্ড ও বিশদ জন্য অপশনাল ফিল্ড থাকে, আপনি নতুন মান ও ফিল্ড যোগ করে ডাটাবেস পুনরায় ডিজাইন না করেই কাজটি করতে পারবেন। রিজেনারেটেড অ্যাপ কোয়েরি ও API-গুলোকে ধারাবাহিক রাখে, এবং একধরনের প্যাচের গুচ্ছ এড়ানো যায়।
লক্ষ্য হলো আজ পড়তে সহজ থাকা এবং কাল ক্ষমাশীল থাকা।
ব্যবসায়িক লজিককে মডুলার ও পড়তে সুবিধাজনক করুন
পরিবর্তন সাধারণত ব্যবসায়িক লজিকে ভাঙে। এক দ্রুত ফিক্স যা আজ "কাছে কাজ করে" পরবর্তীতে বিশেষ কেসের জালে পরিণত হতে পারে। রিজেনারেশন-ফার্স্ট ডেভেলপমেন্টে, আপনি লজিক এমনভাবে ডিজাইন করেন যাতে তা পরিষ্কারভাবে রিজেনারেট করা যায়, মাথার মধ্যে থাকা প্যাচগুলোর ওপর নির্ভর করে না।
একটি ব্যবহারিক পদ্ধতি হল প্রতিটি ওয়ার্কফ্লোকে ছোট ব্লকের সেট হিসেবে বিবেচনা করা। প্রতিটি ব্লক একটি কাজ করে: ইনপুট ভ্যালিডেট করা, একটি মূল্য হিসাব করা, রুট ঠিক করা, মেসেজ পাঠানো, একটি রেকর্ড আপডেট করা। AppMaster-এ এটা Business Process Editor-র সাথে স্বাভাবিকভাবে মেলে। ছোট প্রসেস পড়তে, টেস্ট করতে, পুনঃব্যবহার করতে ও বদলাতে সহজ।
ইনপুট ও আউটপুট হিসেবে চিন্তা করুন
কোন ব্লক তৈরির আগে দুইটি জিনিস লিখে ফেলুন: এটি কী চায়, এবং কী রিটার্ন করে। যদি এক বাক্যে বলতে না পারেন, ব্লকটি সম্ভবত অনেক কাজ করছে।
ভালো ব্লকগুলির স্পষ্ট সীমা থাকে। তারা স্পষ্ট ইনপুট নেয় (user role, ticket status, order total) এবং স্পষ্ট আউটপুট দেয় (approved or denied, final price, next step)। ঐ স্পষ্টতা বদলগুলোকে নিরাপদ করে কারণ আপনি একটি ব্লক পরিবর্তন করলেও অনুমান করতে হবে না বাকিগুলো কী প্রভাবিত হবে।
একটি দ্রুত চেকলিস্ট:
- প্রতি ব্লকের একটাই উদ্দেশ্য (ভ্যালিডেশন, ক্যালকুলেশন বা রাউটিং)
- ইনপুট পাস করা হয়, "কোথাও খুঁজে পাওয়া" নয়
- আউটপুট রিটার্ন করা হয়, সাইড-এফেক্টে লুকানো নয়
- নামগুলো আউটকাম বর্ণনা করে (مثلاً
ValidateRefundRequest) - ত্রুটিগুলো ধারাবাহিকভাবে হ্যান্ডেল করা হয়
লুকানো ডিপেন্ডেন্সি এড়ান
লুকানো ডিপেন্ডেন্সি লজিককে ভঙ্গুর করে তোলে। যদি একটি ওয়ার্কফ্লো গ্লোবাল ফ্ল্যাগ, চুপচাপ স্টেট পরিবর্তন, বা "এই ভেরিয়েবলটা আগে কোথাও সেট করা হয়েছিল" এর ওপর নির্ভর করে, ছোট সম্পাদনাও আচরণ বদলে দিতে পারে যেটা আপনি আশা করেননি।
স্টেটকে উদ্দেশ্যমত প্রসেসের মাধ্যমে পাঠান। যদি কিছু সংরক্ষণ করতে হয়, তা একটি স্পষ্ট জায়গায় (যেমন ডাটাবেস ফিল্ড) সংরক্ষণ করুন এবং স্পষ্টভাবে পড়ুন। "ম্যাজিক" আচরণ—এক ধাপে রেকর্ড পরিবর্তন করে ধরে নেওয়া যে অন্য ধাপটি সেটি দেখবে—এড়িয়ে চলুন।
নির্ণয় পয়েন্টগুলো দৃশ্যমান রাখুন। উদাহরণস্বরূপ, একটি সাপোর্ট পোর্টাল "Is this ticket VIP?" এবং "Is it after business hours?" এর ওপর শাখা করতেই পারে। যদি সেই শাখাগুলো স্পষ্ট ও লেবেল করা থাকে, ভবিষ্যতে যেমন "VIP নিয়ম ছুটির দিনে বদলেছে"—এটি একটা দ্রুত এডিট হয়ে যাবে, ঝুঁকিপূর্ণ পুনর্লিখন নয়।
UI উদ্বেগগুলোকে নিয়ম ও ডেটা থেকে আলাদা করুন
পরিবর্তন-উপযোগী অ্যাপ তখনই সহজে রিজেনারেট করা যায় যখন UI "ডাম্ব" থাকে। স্ক্রীনগুলো ইনপুট সংগ্রহ, স্টেট দেখানো এবং ব্যবহারকারীকে গাইড করা উচিত। যখন ব্যবসায়িক সিদ্ধান্ত বাটন, ভ্যালিডেশন বা এক-অফ স্ক্রিন লজিকে লুকানো থাকে, প্রতিটি নতুন চাহিদা প্যাচে পরিণত হয়।
UI-কে শেয়ারড নিয়ম ও ডেটার একটি পাতলা লেয়ার হিসেবে বিবেচনা করুন। তখন প্ল্যাটফর্ম উপস্থাপন পুনরায় নির্মাণ করতে পারবে, প্রতিটি জায়গায় নিয়মগুলো পুনর্বিবেচনা না করে।
UI কোথায় শেষ হয় এবং ব্যবসায়িক নিয়ম কোথায় শুরু করে
একটি ব্যবহারিক বিভাজন হল: UI স্পষ্টতা সামলায়; ব্যবসায়িক লজিক 'সত্য' নির্ধারণ করে। UI ফরম্যাট, লেবেল, ও ব্যবহারকারী সহায়তা করতে পারে। ব্যবসায়িক লজিক নির্ধারণ করে কী অনুমোদিত এবং পরবর্তী কী হবে।
UI-এর সাধারণ কাজগুলো অন্তর্ভুক্ত:
- ডেটা প্রদর্শন ও ব্যবহারকারীর ইনপুট সংগ্রহ করা
- ফরম্যাটিং (তারিখ, মুদ্রা, ফোন মাস্ক)
- বেসিক রিকোয়ার্ড-ফিল্ড চেক (খালি কি না)
- লজিক দ্বারা ফেরত করা ত্রুটিগুলো সাধারণ ভাষায় দেখানো
- ন্যাভিগেশন ও লেআউট
বিজনেস রুলগুলো স্ক্রিনের বাইরে রাখা উচিত—উদাহরণস্বরূপ ওয়ার্কফ্লো বা প্রসেস এডিটরে: "refund requires manager approval", "VIP customers skip the queue", "ticket cannot be closed without a resolution code"। ঐ নিয়মগুলো ডেটা মডেলের সঙ্গে বাঁধা রাখুন, নির্দিষ্ট পেজের সঙ্গে নয়।
একবার ডিজাইন করুন, ওয়েব ও মোবাইলে পুনঃব্যবহার করুন
যদি আপনি একাধিক ক্লায়েন্ট (ওয়েব ও নেটিভ মোবাইল) সাপোর্ট করেন, ডুপ্লিকেশন ড্রিফট সৃষ্টি করে। সাধারণ প্যাটার্নগুলোর জন্য শেয়ারড কম্পোনেন্ট reused করুন (টিকেট স্ট্যাটাস ব্যাজ, প্রায়োরিটি সিলেক্টর, কাস্টমার কার্ড), কিন্তু তাদের আচরণ নিশ্চিতভাবে একই রাখুন—একই ডেটা ও একই নিয়ম ফলাফল খাওয়ান।
উদাহরণস্বরূপ, আপনি ডেটা ডিজাইনারে টিকেট স্টেটগুলো মডেল করতে পারেন, স্টেট পরিবর্তনগুলো একক বিজনেস প্রসেস দিয়ে চালাতে পারেন, এবং ওয়েব ও মোবাইল উভয়ই সেই প্রসেস কল করে রিটার্ন করা স্টেট রেন্ডার করবে। যখন "Escalated" হয়ে যায় "Urgent review," আপনি একবার আপডেট করে রিজেনারেট করবেন, প্রতিটি স্ক্রিনে লুকানো কন্ডিশন খুঁজে বের করে পরিবর্তন করবেন না।
একটি ভাল টেস্ট: যদি আপনি একটি স্ক্রিন tomorrow সরিয়ে আবার বানান, অ্যাপ কি একই নিয়মগুলো বজায় রাখবে? যদি করে, আলাদা থাকা কাজ করে।
ধাপে ধাপে: পরিষ্কার রিজেনারেশনের জন্য অ্যাপ স্ট্রাকচার করুন
রিজেনারেশন-ফার্স্ট ডেভেলপমেন্ট সবচেয়ে ভাল কাজ করে যখন আপনার অ্যাপ স্পষ্ট অংশে ভাগ করা থাকে যা স্বাধীনভাবে বদলানো যায়। মডিউলগুলো প্রথমে ভাবুন, স্ক্রিন নয়।
কোর মডিউলগুলোর নাম রাখুন এবং সেগুলোকে আপনার মাথায় ও কাজের মধ্যে আলাদা রাখুন: ডেটা (টেবল ও রিলেশন), প্রসেস (লজিক), API (এন্ডপয়েন্ট), ওয়েব UI, মোবাইল UI। যখন একটি চাহিদা বদলে যায়, আপনি সহজেই বলতে পারেন কোনটা বদলাবে এবং কোনটা অছুঁয়াই থাকবে।
পরিবর্তন-উপযোগী থাকা একটি বিল্ড অর্ডার
একটি ছোট লুপ ব্যবহার করুন এবং প্রতিটি ধাপকে সংযত রাখুন:
- প্রথমে ডেটা মডেল: বাস্তবতার সঙ্গে মিলানো এন্টিটি, ফিল্ড, সম্পর্ক।
- পুনঃব্যবহারযোগ্য ফ্লো হিসেবে বিজনেস প্রসেস যোগ করুন। প্রতিটি প্রসেস একটি কাজ করুক (Create Ticket, Assign Agent, Close Ticket)।
- যখন লজিক পড়তে সুবিধা করে, প্রসেসগুলোকে API এন্ডপয়েন্টের সঙ্গে কানেক্ট করুন। এন্ডপয়েন্টগুলোকে আপনার ফ্লোদের ওয়্র্যাপ হিসেবে ট্রীট করুন—নিয়ম লুকানোর জায়গা নয়।
- ব্যবহারকারী কাজের চারপাশে UI স্ক্রীন গঠন করুন, ডাটাবেস টেবিলের চারপাশে নয়।
- প্রতিটি ছোট পরিবর্তনের পরে রিজেনারেট ও টেস্ট করুন।
ছোট উদাহরণ: গরম প্যাচ ছাড়া পরিবর্তন করা
ধরা যাক আপনি AppMaster-এ একটি সাপোর্ট পোর্টাল বানাচ্ছেন। প্রথম ভার্শনে Tickets ও Comments আছে। পরে সপ্তাহ পরে ব্যবসা Priority এবং একটি নতুন নিয়ম চায়: VIP গ্রাহররা সর্বদা High দিয়ে শুরু হবে।
মডুলার স্ট্রাকচারের সাথে, আপনি ডেটা মডেল বদলান (Priority যোগ করুন), এক বিজনেস প্রসেস আপডেট করেন (Create Ticket গ্রাহকের টাইপ দেখে Priority সেট করে), রিজেনারেট করেন, এবং একই UI টাস্ক কাজ করে তা যাচাই করেন। ছড়িয়ে থাকা একাধিক স্ক্রিনে একসাথে ফিক্স করা লাগবে না।
একটি সরল অভ্যাস সহায়ক: প্রতিটি রিজেনারেশনের পরে মূল ফ্লোগুলো (create, update, permission check) দ্রুত এন্ড-টু-এন্ড চালান তারপর নতুন ফিচার যোগ করুন।
উদাহরণ: ক্রমাগত বদল হতে থাকা একটি কাস্টমার সাপোর্ট পোর্টাল
একটি ছোট সাপোর্ট পোর্টাল কল্পনা করুন। কাস্টমাররা লগইন করে, তাদের টিকেট দেখে, টিকেট খুলে বিবরণ দেখেন, এবং রিপ্লাই যোগ করেন। সাপোর্ট এজেন্টরা একই টিকেটগুলো এবং ইন্টার্নাল নোট দেখেন।
রিজেনারেশন-ফার্স্ট দৃষ্টিভঙ্গি তিনটি জিনিস আলাদা করে: টিকেট ডেটা মডেল, বিজনেস প্রসেস (কিভাবে টিকেট চলে), এবং UI স্ক্রীন। যখন এগুলো স্পষ্ট থাকে, একটিকে বদলালে অন্যগুলোতে প্যাচ করার দরকার পড়ে না।
সোজা শুরু করুন, কিন্তু পরিবর্তনের জন্য গঠন রাখুন
প্রথম ভার্শন হতে পারে ন্যূনতম:
- ডেটা: Users, Tickets, Messages
- প্রসেস: Create ticket, Reply, Assign to agent
- UI: Ticket list, Ticket details, New ticket form
AppMaster-এ এটি PostgreSQL-ভিত্তিক ডেটা মডেল (Data Designer), ভিজ্যুয়াল ওয়ার্কফ্লো (Business Process Editor), এবং আলাদা ওয়েব ও মোবাইল UI বিল্ডারের সঙ্গে পরিষ্কারভাবে মানায়।
পরিবর্তন 1: প্রায়োরিটি ও SLA তারিখ যোগ করা
প্রোডাক্ট প্রায়োরিটি (Low, Normal, High) ও একটি SLA_due_date চায়। রিজেনারেশন-ফার্স্ট গঠনের সাথে, আপনি Ticket মডেলে ফিল্ড যোগ করেন, তারপর মাত্র সেই জায়গাগুলো আপডেট করেন যেগুলি পড়ে বা লেখে: create-ticket প্রসেস ডিফল্ট প্রায়োরিটি সেট করবে, এজেন্ট স্ক্রিন SLA_due_date দেখাবে, এবং লিস্ট স্ক্রিনে ফিল্টার যোগ হবে।
প্ল্যাটফর্ম ব্যাকএন্ড ও API রিজেনারেট করে নতুন ফিল্ডগুলো কোডের প্রথম-শ্রেণির অংশ হয়ে যায়।
পরিবর্তন 2: ক্লোজ করার আগে অনুমোদন ধাপ যোগ করা
এখন নির্দিষ্ট গ্রাহকদের জন্য টিকেট ক্লোজ করার আগে ম্যানেজার অনুমোদন লাগবে। ক্লোজ নিয়মগুলো ছড়িয়ে না ছড়িয়ে একটিমাত্র প্রসেসে রাখুন: মডেলে স্পষ্ট স্টেট যোগ করুন (Open, Pending approval, Closed) এবং ক্লোজ প্রসেসটি হালনাগাদ করুন:
- এজেন্ট ক্লোজ অনুরোধ করে
- সিস্টেম চেক করে যে অনুমোদন প্রয়োজন কি না
- ম্যানেজার অনুমোদন বা প্রত্যাখ্যান করে
- অনুমোদনের পরেই টিকেট ক্লোজ হয়
নিয়মটি একটিই প্রসেসে থাকায় UI বর্তমান স্ট্যাটাস ও পরবর্তী অনুমোদিত অ্যাকশন দেখায়।
পরিবর্তন 3: মোবাইল পুশ নোটিফিকেশন
ব্যবহারকারীরা চাইলে এজেন্ট রিপ্লাই করলে পুশ নোটিফিকেশন পেতে। নোটিফিকেশন লজিক UI কোডে না গুটিয়ে "New message" প্রসেসে রাখুন: যখন একটি রিপ্লাই সেভ হয়, নোটিফিকেশন মডিউল ট্রিগার করুন। রিজেনারেশন তারপর আপডেটেড নেটিভ অ্যাপ তৈরি করে—হাতে করে প্যাচ জুড়তে হবে না।
সাধারণ ভুল যা রিজেনারেশন-ফার্স্ট ওয়ার্কফ্লো ভেঙে দেয়
রিজেনারেশন-ফার্স্ট ডেভেলপমেন্ট তখনই কাজ করে যখন আপনার অ্যাপ রিজেনারেটেবল থাকে। টিমগুলো সাধারণত ছোট তাত্ক্ষণিক ফিক্স দিয়ে এটিকে ভেঙে দেয়—যা আজ ক্ষুদ্র মনে হয় কিন্তু কাল বড় ওয়ার্কঅ্যারাউন্ড তৈরি করে।
১) জেনারেটেড কোড এডিট করা মডেলের বদলে
জেনারেটেড অংশে ম্যানুয়াল এডিট করা এবং সেগুলোকে ওভাররাইট করা প্ল্যাটফর্মের দ্বারা খুব দ্রুত পরিষ্কার রিজেনারেশন হারিয়ে দেয়। যদি প্ল্যাটফর্ম সত্যিই সোর্স কোড জেনারেট করে (AppMaster-এ যেমন ব্যাকএন্ড, ওয়েব, মোবাইলের জন্য), ভিজ্যুয়াল প্রজেক্টকেই সোর্স অফ ট্রুথ হিসেবে আচরণ করুন। যখন চাহিদা বদলে, ডেটা মডেল, বিজনেস প্রসেস, বা UI বিল্ডার বদলান—not the generated files.
একটি সহজ নিয়ম: যদি আপনি ভিজ্যুয়াল প্রজেক্ট থেকে রিজেনারেট করে আপনার পরিবর্তন পুনরুত্পাদন করতে না পারেন, সেটা নিরাপদ পরিবর্তন নয়।
২) UI-কে নিয়ম নির্ধারণ করতে দেওয়া
যখন স্ক্রিনগুলো ব্যবসায়িক নিয়ম এনকোড করে ("এই বাটন শুধুমাত্র VIP ইউজারের জন্য দেখায়", "এই ফর্ম UI-তে মোট হিসাব করে"), প্রতিটি নতুন স্ক্রিনই একটি স্পেশাল কেস হয়ে ওঠে। ভ্যালিডেশন, পারমিশন, ক্যালকুলেশনগুলো বিজনেস লজিকে রাখুন (উদাহরণস্বরূপ Business Process), তারপর UI-কে ফলাফল দেখাতে দিন।
৩) অনেক আগে থেকেই ফ্যান্টাসি ডেটা মডেল ডিজাইন করা
ওভার-মডেলিং দেখতে পারে যে আপনি ব্যবহারিক ব্যবহার না বোঝেই ডজনো ফিল্ড, স্ট্যাটাস, ও এজ-কেস টেবিল যোগ করছেন। এটি পরিবর্তনকে কষ্টকর করে তোলে কারণ প্রতিটি আপডেটে অনেক অংশ স্পর্শ হয়।
ছোট করে শুরু করুন এবং ধাপে ধাপে বাড়ান:
- শুধুমাত্র সেই ফিল্ড যোগ করুন যেগুলো আপনি সাধারণ ভাষায় ব্যাখ্যা করতে পারেন।
- স্ট্যাটাস মানগুলো সংক্ষিপ্ত ও বাস্তব রাখুন (3–6, 20 নয়)।
- একটা বড় টেবিলে সব মান চাপানোর বদলে পরে নতুন টেবিল যোগ করার পক্ষে থাকুন।
৪) নামকরণের কনসিস্টেন্সি স্কিপ করা
অসামঞ্জস্যপূর্ণ নামকরণ মডেল ও এন্ডপয়েন্টগুলোকে বিভ্রান্ত করে: "Cust", "Customer", এবং "Client" একই অ্যাপেই থাকলে সমস্যা বাড়ে। শুরুর দিকে একটি সহজ প্যাটার্ন (একবচন টেবিল নাম, ক্রিয়ার জন্য ধারাবাহিক ভার্ব) বেছে নিন এবং তা মানুন।
৫) এক বিশাল ওয়ার্কফ্লো তৈরি করা
প্রথমে এক বিশাল ওয়ার্কফ্লো টাইট মনে হতে পারে, পরে সেটি বদলাতে ঝুঁকিপূর্ণ হয়ে ওঠে। লজিককে ছোট প্রসেসে ভাগ করুন—প্রতি প্রসেসের স্পষ্ট ইনপুট ও আউটপুট থাকুক। উদাহরণস্বরূপ, সাপোর্ট পোর্টালে "Create ticket", "Assign agent", এবং "Send notification" আলাদা রাখুন যাতে এক ধাপ বদলালে বাকিগুলো ঝুঁকির মুখে না পড়ে।
রিজেনারেট ও শিপ করার আগে দ্রুত চেকলিস্ট
রিজেনারেশন-ফার্স্ট শুধুই তখনই নিরাপদ লাগে যখন আপনার একটি রুটিন থাকে যা সাধারণ “নীরব ভাঙন” সমস্যাগুলো ধরে। রিজেনারেশনের আগে একটি সংক্ষিপ্ত পাস করুন যা আপনার অ্যাপের গঠন মেনে চলে: ডেটা, লজিক, UI, এবং API।
একটি দ্রুত চেকলিস্ট:
- ডেটা: এন্টিটি ও ফিল্ডগুলো বর্তমান চাহিদার সাথে মেলে, নামকরণ ধারাবাহিক, এবং দুটি আলাদা ফিল্ড একেই বোঝায় না।
- লজিক: প্রতিটি ওয়ার্কফ্লো স্পষ্ট ইনপুট, স্পষ্ট আউটপুট, এবং পূর্বানুমেয় এরর পথ আছে।
- UI: স্ক্রিনগুলো শেয়ারড কম্পোনেন্ট ব্যবহার করে এবং নিয়ম হার্ড-কোড করে না।
- API: এন্ডপয়েন্টগুলো স্পষ্টভাবে ওয়ার্কফ্লোদের ম্যাপ করে। আপনি সহজে বলতে পারেন "এই এন্ডপয়েন্টটি কোন ওয়ার্কফ্লো চালায়?"—বিনা খোঁজে।
- রিলিজ: আপনার কাছে ছোট, পুনরাবৃত্তিযোগ্য টেস্ট স্ক্রিপ্ট আছে—"ক্লিক করে ঠিক আছে মনে হওয়া" নয়।
নিয়মগুলো জন্য একটি সোর্স অফ ট্রুথ রাখুন। যদি টিকেট প্রায়োরিটি কাস্টমার টিয়ারের ওপর নির্ভর করে, একটিমাত্র ওয়ার্কফ্লোতে সেটি সংজ্ঞায়িত করুন এবং UI ও API উভয়ই তা প্রতিফলিত করুক।
একটি 10-মিনিটের টেস্ট স্ক্রিপ্ট সাধারণত যথেষ্ট:
- কেবল প্রয়োজনীয় ফিল্ড নিয়ে একটি নতুন রেকর্ড তৈরি করুন।
- প্রধান ওয়ার্কফ্লো ট্রিগার করুন এবং প্রত্যাশিত স্ট্যাটাস পরিবর্তন নিশ্চিত করুন।
- একটি জানা এরর কেস চেষ্টা করুন (অনুপ্রবেশ অনুমতি বা প্রয়োজনীয় ডেটা অনুপস্থিত)।
- ওয়েব ও মোবাইলে মূল স্ক্রিনগুলো খুলে একই নিয়ম একইভাবে দেখাচ্ছে কি না নিশ্চিত করুন।
- একটি বা দুটি কোর এন্ডপয়েন্ট কল করে নিশ্চিত করুন রেসপন্স UI-র সঙ্গে মেলে।
যদি কিছু ব্যর্থ হয়, প্রথমে স্ট্রাকচার ঠিক করুন (ডেটা, ওয়ার্কফ্লো, শেয়ারড UI) এবং পুনরায় রিজেনারেট করুন।
পরবর্তী ধাপ: আপনার পরবর্তী পরিবর্তনে এই পদ্ধতি প্রয়োগ করুন
প্রথমে একটি জায়গা নির্বাচন করে ছোট রাখুন। যদি সাম্প্রতিক পরিবর্তনগুলো কষ্টদায়ক হয়ে থাকে, সেই অংশ থেকে শুরু করুন: ডেটা মডেল, জটিল লজিকের টুকরা, অথবা সে স্ক্রিন যেটা বারবার "আরেকটি ছোট পরিবর্তন" পাচ্ছে।
আপনার পরবর্তী পরিবর্তনটাকে একটি ড্রিল হিসেবে ট্রিট করুন: সামঞ্জস্য করুন, রিজেনারেট করুন, যাচাই করুন, শিপ করুন। লক্ষ্য হলো যাতে আপডেটগুলো রুটিনের মত লাগে—ঝুঁকিপূর্ণ নয়।
কোনো ছোট লুপ বারবার করুন:
- এক ছোট পরিবর্তন করুন (একটি ফিল্ড, এক নিয়ম, বা এক UI আচরণ)।
- রিজেনারেট করুন যাতে কোড সামঞ্জস্য থাকে।
- একটি দ্রুত স্মোক টেস্ট চালান (হ্যাপি পাথ + একটি এজ কেস)।
- প্রথমে একটি নিরাপদ এনভায়রনমেন্টে ডিপ্লয় করুন (staging বা টেস্ট ওয়ার্কস্পেস)।
- শিপ করুন এবং শেখা বিষয়গুলো নোট করুন।
সংক্ষিপ্ত চেঞ্জলগ রাখুন যা কেবল এডিট নয়, সিদ্ধান্তও ব্যাখ্যা করে। উদাহরণ: "আমরা টিকেট প্রায়োরিটিকে enum হিসেবে সংরক্ষণ করি, ফ্রি-টেক্সট নয়, যাতে লেবেল বদলে রিপোর্ট ভাঙ্গে না।" এরকম দুই লাইন পরে ঘণ্টায় সঞ্চয় করতে পারে।
যদি আপনি জেনারেটেড আউটপুট হাতে-এডিট না করেই অনুশীলন করতে চান, AppMaster-এ একটি ছোট, সীমাবদ্ধ মডিউল তৈরি করে অনুশীলন করুন (উদাহরণ: একটি টিকেট ফর্ম, একটি অ্যাডমিন লিস্ট, বা একটি সিম্পল অনুমোদন ধাপ), প্রতিটি পরিবর্তনের পরে রিজেনারেট করুন, এবং লক্ষ্য করুন মডেল সোর্স অফ ট্রুথ থাকলে অ্যাপ কত সহজে উন্নয়ন করে। যদি আপনি টুলগুলো মূল্যায়ন করছেন, appmaster.io হলো সেই ওয়ার্কফ্লো অনুশীলন করার একটি সরল জায়গা।
আপনার পরবর্তী পরিবর্তনই শুরু করার ভালো সময়। অ্যাপের একটি কোর্নার বেছে নিন এবং আজই সেটি পরিবর্তন-উপযোগী করুন।
প্রশ্নোত্তর
Patching হল যখন নতুন কোনো চাহিদা দ্রুততমভাবে অ্যাপে ঢুকানো হয়—সবচেয়ে ছোট সম্পাদনীর মাধ্যমে। এটা তৎক্ষণাৎ কাজ করে, কিন্তু প্রায়ই ডাটাবেস, API, লজিক এবং UI একে অপরের সাথে মিল রাখে না। ফলে পরবর্তী পরিবর্তন ধীর ও ঝুঁকিপূর্ণ হয়ে যায়।
এখানে প্রযুক্তিগত ঋণ মানে ভবিষ্যতের পরিবর্তনের উপর অতিরিক্ত খরচ—কারণ আজকের গঠন অগোছানো বা অসামঞ্জস্যপূর্ণ। এটা দেখা দেয় দীর্ঘ বাস্তবায়ন সময়, রিগ্রেশন ঝুঁকি বেশি, এবং সাধারণত সাদামাটা পরিবর্তনেও বেশি টেস্টিং ও সমন্বয় দরকার হয়।
সাধারণ লক্ষণগুলির মধ্যে আছে: প্রায় একই অর্থ বহন করা ডুপ্লিকেট ফিল্ড, UI ও এন্ডপয়েন্ট জুড়ে ছড়িয়ে থাকা ব্যবসায়িক নিয়ম, এবং “অস্থায়ী” ফ্ল্যাগ যা কখনো মুছে যায় না। ছোট নিয়ম পরিবর্তন অনেক ভিন্ন জায়গায় স্পর্শ করলে সেটাও একটি চিহ্ন।
Regeneration-first development মানে আপনি অ্যাপের মডেল (ডেটা, লজিক, UI) পরিবর্তন করেন এবং তারপর সেই সংজ্ঞা থেকে আউটপুট (ব্যাকএন্ড, API, ক্লায়েন্ট) পুনরায় জেনারেট করেন। ফলে সোর্স অফ ট্রুথ কেন্দ্রীভূত থাকে এবং পরিবর্তনগুলো পূর্বানুমেয় হয়।
ভিজ্যুয়াল প্রজেক্টকে সোর্স অফ ট্রুথ হিসেবে ধরে রাখুন এবং জেনারেট করা কোডকে আউটপুট বলে বিবেচনা করুন। যদি আপনি জেনারেটেড অংশে ম্যানুয়াল সম্পাদনা করেন, তা পুনরায় জেনারেশনের সময় হারিয়ে যেতে পারে কিংবা আপনি জেনারেট না করাই বেছে নেবেন—দুটোই খারাপ।
স্থায়ী নাউন দিয়ে শুরু করুন—যেগুলো আপনার ব্যবসা বছর খানেক পরেও ব্যবহার করবে। স্পষ্ট ও ধারাবাহিক নামকরণ ব্যবহার করুন (উদাহরণ: singular entity names, created_at বনাম createdAt মতো একরকম নিয়ম), এবং টাইপগুলো বাস্তবতার সাথে মেলে এমনভাবে বেছে নিন (টাকা decimal, টাইমস্ট্যাম্পে টাইমজোন নীতিমালা)। অপ্রয়োজনীয় ডুপ্লিকেশন ও নামবদল পরবর্তীতে সমস্যা বাড়ায়।
লজিককে ছোট, পুনঃব্যবহারযোগ্য ব্লকে ভাগ করুন—প্রতি ব্লকের একটি স্পষ্ট ইনপুট ও আউটপুট থাকে। স্টেট উদ্দেশ্যমত প্রসেসে পাঠান; গোপন ডিপেন্ডেন্সি এড়িয়ে চলুন। এর ফলে আপনি একটি ব্লক সহজেই বদলে দিতে পারবেন, অন্য অংশে অনিশ্চিত প্রভাব না পড়ে।
UI বরং প্রদর্শন ও ইনপুট সংগ্রহে মনোযোগ রাখুক, সিদ্ধান্ত গ্রহণ নয়। ব্যবসায়িক নিয়মগুলো শেয়ারড লজিকে (উদাহরণ: ওয়ার্কফ্লো বা প্রসেস) রাখুন। UI কেবল দেখাবে কি অনুমোদিত, কিন্তু সত্য সিদ্ধান্ত ব্যাকএন্ড লজিক নেবে—এতে নিয়মগুলো স্ক্রিন ও ক্লায়েন্ট জুড়ে বিচ্ছিন্ন হয় না।
সহজ ক্রমটি অনুসরণ করুন: প্রথমে ডেটা মডেল, তারপর পড়তে ও বুঝতে সহজ প্রসেস, এরপর এন্ডপয়েন্টগুলোকে প্রসেসে র্যাপ করুন, এবং শেষে ইউআই বানান। প্রতিটি ছোট পরিবর্তনের পরে জেনারেট করে হালকা একটি এন্ড-টু-এন্ড স্মোক টেস্ট চালান—এতে নীরব ভাঙন ধরা পড়ে।
যেখানে নিয়মিত পরিবর্তন আসে এবং একাধিক ক্লায়েন্ট (ওয়েব ও নেটিভ) আছে, সেখানে এটি সবচেয়ে কার্যকর। যদি আপনি কোড-অ্যাকচুয়াল উদ্যোগ ছাড়াই অনুশীলন করতে চান, AppMaster আপনাকে ডেটা মডেল, ভিজ্যুয়াল লজিক এবং পূর্ণ সোর্স কোড জেনারেট করার সুযোগ দেয়—এভাবে পরিবর্তনগুলো এক-অফ প্যাচ নয়।


