ফোন নম্বর সংরক্ষণের অমিল থেকে উদ্ভূত একটি লগইন ব্যর্থতা একটি ত্রুটি প্রকাশ করেছে। একজন ব্যবহারকারীর অ্যাকাউন্ট ব্লক করা হয়েছিল কারণ ডাটাবেসে একই জার্মান মোবাইল নম্বর দুটি ভিন্ন রূপে সংরক্ষিত ছিল—একটি সারিতে 0171 5550134 এবং অন্যটিতে +49 171 5550134—ফলে সিস্টেম সেগুলোকে আলাদা এন্ট্রি হিসেবে গণ্য করেছিল। ফলাফলস্বরূপ: একটি OTP কখনোই আসেনি এবং "send code" বাটনটি একটি জুয়া খেলার মতো হয়ে দাঁড়িয়েছিল।

কেন ফোন নম্বর তারিখের চেয়ে বেশি জটিল

ডেভেলপাররা প্রায়ই ফোন নম্বর ইনপুট নিয়ন্ত্রণের জন্য regex-এর ওপর ভরসা করেন। সেই ভরসা ভেঙে যায় যখন একটি নম্বর সীমান্ত অতিক্রম করে বা কোনো জাতীয় পরিকল্পনা পরিবর্তিত হয়। তারিখ একটি অনুমানযোগ্য ক্যালেন্ডার অনুসরণ করে; ফোন নম্বর ক্যারিয়ার, রেগুলেশন এবং সাংস্কৃতিক প্রথার সাথে পরিবর্তিত হয়।

র (raw) স্ট্রিংয়ের লুকানো খরচ

একটি ফোন নম্বর সাধারণ স্ট্রিং হিসেবে সংরক্ষণ করা অনন্য মনে হতে পারে—যতক্ষণ না দুটি উপস্থাপনা একই লাইনের দিকে নির্দেশ করে। OTP সিস্টেমগুলো যখন ডাটাবেসে "নির্দিষ্ট" নম্বরটি খোঁজে, তখন তারা একটি ডুপ্লিকেট নম্বরে কোড পাঠায় যা ব্যবহারকারীর কাছে কখনোই পৌঁছায় না।

সমস্যাটি আরও প্রকট হয় যখন নম্বরগুলো নিউমেরিক ফিল্ডে থাকে। একটি BIGINT কলাম শুরুর + এবং যেকোনো শুরুর শূন্য (leading zeros) বাদ দিয়ে দেয়, ফলে +49 171 5550134 হয়ে যায় 491715550134। প্লাস চিহ্ন ছাড়া মূল ফরম্যাটটি পুনরায় তৈরি করা একটি অনুমানের বিষয় হয়ে দাঁড়ায়।

E.164 কন্ট্রাক্ট

আন্তর্জাতিক টেলিফোন-নাম্বারিং প্ল্যান, E.164, একটি একক এবং বহনযোগ্য উপস্থাপনা সংজ্ঞায়িত করে:

  • + দিয়ে শুরু হয়
  • এরপর ১ থেকে ৩ ডিজিটের কান্ট্রি কোড
  • তারপর সাবস্ক্রাইবার নম্বর
  • মোট ১৫ ডিজিটের বেশি নয়
  • কোনো স্পেস, ডট বা ড্যাশ থাকবে না

E.164 গ্যারান্টি দেয় না যে নম্বরটি সচল; এটি কেবল নিশ্চিত করে যে স্ট্রিংটি একটি বৈধ কাঠামোগত প্যাটার্ন অনুসরণ করছে। এটিকে একটি ফরম্যাট কন্ট্রাক্ট হিসেবে বিবেচনা করুন, রিয়াচাবিলিটি ওরাকল (reachability oracle) হিসেবে নয়।

সাধারণ ভুল যা regex ঠিক করতে পারে না

  • Numeric storage – BIGINT শুরুর + এবং শূন্যগুলো বাদ দিয়ে দেয়। এর পরিবর্তে একটি টেক্সট কলাম (TEXT বা VARCHAR) ব্যবহার করুন।
  • Hard-coded regexes – জাতীয় পরিকল্পনা পরিবর্তিত হয়। মেক্সিকো ২০১৯ সালে তাদের ট্রাঙ্ক প্রিফিক্স বাদ দিয়েছে; আর্জেন্টিনা এখন মোবাইল লাইনের জন্য কান্ট্রি কোডের পরে একটি 9 প্রয়োজন করে। একটি স্ট্যাটিক প্যাটার্ন দ্রুত অপ্রচলিত হয়ে পড়ে।
  • Blind zero stripping – ইতালীয় ল্যান্ডলাইনগুলোতে শুরুর শূন্য থাকে, জার্মানগুলোতে থাকে না। "সব শুরুর শূন্য মুছে ফেলুন" এমন একটি ঢালাও নিয়ম ইতালীয় ডেটা নষ্ট করে দেয়, অথচ জার্মান নম্বরগুলোকে অপরিবর্তিত রাখে।
  • Assuming format equals deliverability – libphonenumber কাঠামো যাচাই করে কিন্তু হ্যান্ডসেটটি চালু আছে কি না বা নম্বরটি পোর্ট করা হয়েছে কি না তা বলতে পারে না।

একটি নির্ভরযোগ্য পাইপলাইন তৈরি করা

  1. দেশ জিজ্ঞাসা করুন – সাইন-আপ ফর্মে একটি কান্ট্রি সিলেক্টর যোগ করুন এবং সেই অঞ্চলটি পার্সারকে পাঠান।
  2. লাইভ ফরম্যাটিং দেখান – "AsYouType" ফরম্যাটিং ব্যবহার করুন যাতে ব্যবহারকারীরা টাইপ করার সময় সঠিক প্যাটার্ন দেখতে পান।
  3. Blur হওয়ার পর ভ্যালিডেট করুন – প্রতিটি কি-স্ট্রোকের পরিবর্তে ব্যবহারকারী ফিল্ডটি ছেড়ে দেওয়ার পর ভ্যালিডেশন চালান; এটি ঘর্ষণ বা জটিলতা (friction) কমায়।
  4. শুধুমাত্র E.164 স্ট্রিং সংরক্ষণ করুন – ডাটাবেসে নরমালাইজড +-প্রিফিক্সযুক্ত নম্বরটি সংরক্ষণ করুন।
  5. এজ-এ ফরম্যাট করুন – শুধুমাত্র UI বা ইমেল টেমপ্লেটে মানুষের পড়ার উপযোগী লেআউটে রূপান্তর করুন।

লেগাসি ডেটা মাইগ্রেট করার সময়, যে সারিগুলো ভ্যালিডেশনে ব্যর্থ হয় সেগুলো রেখে দিন। প্রতিটি বিদ্যমান এন্ট্রিকে একটি নতুন কলামে পার্স করুন, ব্যর্থতাগুলো ফ্ল্যাগ করুন এবং একটি রিপোর্ট তৈরি করুন। নীরবে ডেটা বাদ দিলে (silent drops) সাপোর্ট টিকিট তৈরি হয় যা পরবর্তীতে ব্যয়বহুল ফিক্সিংয়ে পরিণত হয়।

ডেভেলপারদের জন্য একটি দ্রুত চেকলিস্ট

  • নম্বরগুলো E.164 ফরম্যাটে TEXT/VARCHAR হিসেবে সংরক্ষণ করুন।
  • Google-এর libphonenumber লাইব্রেরি ব্যবহার করুন; এটি গ্লোবাল প্ল্যানগুলোর জটিল বাস্তবতাকে সামলাতে পারে।
  • যারা কান্ট্রি কোড বাদ দেন, তাদের জন্য একটি ডিফল্ট অঞ্চল প্রদান করুন।
  • লাইভ সাইন-আপের জন্য is_valid_number কল করুন; এটি পরীক্ষা করে যে নম্বরটি আঞ্চলিক নিয়ম মেনে চলছে কি না।
  • বাল্ক ডেটা পরিষ্কার করার সময় is_possible_number ব্যবহার করুন; এটি স্পষ্টতই ভুল এন্ট্রিগুলো শনাক্ত করে কিন্তু খুব সামান্য ত্রুটিযুক্ত কেসগুলোকে সরাসরি প্রত্যাখ্যান করে না।

সঠিকভাবে ফোন নম্বর হ্যান্ডলিং করা কেবল একটি বাড়তি সুবিধা নয়; এটি এমন যেকোনো সিস্টেমের জন্য একটি পূর্বশর্ত যা নির্ভরযোগ্য ইউজার কন্টাক্টের ওপর নির্ভর করে। E.164-এ নরমালাইজ করার মাধ্যমে এবং পার্সিংয়ের কাজ একটি পরীক্ষিত লাইব্রেরির ওপর অর্পণ করার মাধ্যমে, ডেভেলপাররা এমন এক শ্রেণির বাগ দূর করতে পারেন যা নীরবে বিশ্বাস এবং রাজস্ব কমিয়ে দেয়। ফোন নম্বরকে ফ্রি-ফর্ম টেক্সট হিসেবে নয়, বরং স্ট্রাকচার্ড ডেটা হিসেবে বিবেচনা করুন এবং স্ট্যান্ডার্ডগুলোকে মূল কাজ করতে দিন।