تخطّ إلى المحتوى
دراسة حالة CRM

المشروع ٠٧ · هندسة نظام CRM

نظام CRM صممته لوكالة سيارات، وكيف أغلقت ثغراته.

ثلاث طبقات، كل واحدة تقول ما هي: كيف كان نظامهم، وما صممته، وكيف أبنيه اليوم.

الكلام البسيط أولاً، ثم مخططات تستكشفها، وأداتان تفاعليتان، والكود خلف إعادة التصميم.

مصادر للعملاء
٧
أقسام
٦
مجموعات تصنيف
٤
ثغرة أُغلقت
١١

بقلم ماجد الأندجاني · آخر تحديث ٢ نوفمبر ٢٠٢٦

في هذه الصفحة

السياق

العملاء يصلون من سبع قنوات، ويتسربون بين ستة أقسام.

في ٢٠٢٤ عملت محللاً للتسويق في وكالة سيارات. كان العملاء يصلون إليها عبر الإعلانات، والموقع، ووسائل التواصل، والرسائل النصية، والبريد، والإعلانات الخارجية، والفعاليات، ومركز الاتصال. وكانت ستة أقسام تحتاج هؤلاء العملاء: المبيعات الهاتفية، وتجربة القيادة، وما بعد البيع، ومركز الاتصال، ومبيعات الأساطيل، والتسويق.

لم يكن بينها رابط. العملاء يُنسخون يدوياً، ويُحوَّلون بالبريد، ويُتابَعون في جدول بيانات، ويُعتبرون مفقودين بعد بضع مكالمات في عصر يوم واحد. ولم يكن أحد يستطيع أن يقول أي حملة باعت سيارة. رسمت كيف كان النظام يعمل، ثم صممت نظام CRM كاملاً. هذه الصفحة تعرض الاثنين، ثم الجزء الذي يهمني أكثر: أين قصّر تصميمي الأول، وكيف أغلق كل ثغرة فيه اليوم.

الطبقة ١ · ما وجدته

لقطتان لحركة العميل قبل إعادة التصميم.

الصناديق المتقطعة كانت تُنجز يدوياً. اختر أي صندوق لتقرأ ما كان يحدث فيه. وأسماء الأدوات معمّمة.

الإعلاناتالموقعوسائل التواصلمركز الاتصالفريق التسويقالوكالة الإعلانيةأداة الاستقبالالبريدنظام الوكالةما بعد البيعالأساطيلالمبيعات الهاتفية
اختر أي مربع لترى ما يفعله وبماذا يرتبط. اسحب جانبياً لترى المخطط كاملاً.

التحويل بالبريد

كل قسم يستلم عملاءه كرسائل بريد. لا شيء يتتبع هل فُتحت الرسالة، أو اتُّصل بالعميل، أو نُسي.

  • التسليم اليدوي: كل عميل يمر بشخص واحد على الأقل ينسخه إلى مكان آخر.

  • لا مصدر: لا يمكن ربط أي حملة ببيع، فكانت الميزانيات تُحدد بالانطباع.

  • لا عميل واحد: الشخص نفسه قد يكون في أداة المهام وجدول البيانات ونظام الوكالة كثلاثة أشخاص مختلفين.

  • خسارة مبكرة: ثلاث مكالمات في عصر يوم واحد كانت تقرر أن العميل ضاع.

  • ما بعد البيع خارج النظام: طلبات الصيانة لم تدخل الأداة المشتركة أبداً.

الطبقة ٢ · التصميم

مدخل واحد، وموزّع واحد، وست قوائم للأقسام، ولا شيء يضيع في النهاية.

كل قناة تحمل رابط UTM، فيعرف كل عميل من أين جاء. وكل عميل يدخل مدخلاً واحداً، ويُفحص هل هو عميل سابق، ثم يُوجَّه إلى قائمة القسم الذي يحتاجه. وكل قسم يعالج قائمته بمحرك الحالات نفسه، وكل نهاية تصب في مستودع بيانات، والمبيعات وما بعد البيع يغذيان بعضهما عبر البيع الإضافي والبيع المتقاطع.

كل نتيجةالفعالياتالرسائلالخارجيةالموقعالبريدالتواصلمركز الاتصالالمدخلنماذج + UTMفحص العميلالموزّعالمبيعاتتجربة القيادةما بعد البيعمركز الاتصالالأساطيلالتسويقبيع إضافي ومتقاطعمستودع البيانات
اختر أي مربع لترى ما يفعله وبماذا يرتبط. اسحب جانبياً لترى المخطط كاملاً.

الموزّع

كل طلب يذهب إلى قائمة القسم الذي يحتاجه، بمتطلبات كل قسم.

الطبقة ٢ · مسارات الأقسام

كيف يتحرك العميل داخل كل قسم.

قائمة المبيعاتجديد، ثم يُسندالتواصلالإجراء التاليساخندافئباردمفقودالبيعتسجيل السببموعد المتابعة
اختر أي مربع لترى ما يفعله وبماذا يرتبط. اسحب جانبياً لترى المخطط كاملاً.

الإجراء التالي

مهتم، أو مهتم جزئياً، أو غير مهتم، أو لم يرد. والمهتم يُصنَّف بحسب موعد شرائه.

هذه المسارات تصميمي كما رسمته، بعد تصحيح أخطاء الرسم: تسمية منسوخة بين قسمين، وحلقة بلا مخرج. ولم يُضف إليها شيء.

مراجعة صريحة

إحدى عشرة ثغرة في تصميمي الأول.

قوة التصميم بقوة أضعف قاعدة فيه. وحين قرأت مخططاتي من جديد، وجدت هذه الثغرات التي كان أي نظام CRM سيصطدم بها في شهره الأول.

  • ١. لا نموذج بيانات. قوائم وحالات، دون سجل واحد للعميل، فالشخص الواحد قد يصبح ثلاثة عملاء.

  • ٢. التوزيع بالكلمات المفتاحية. السكربت يشترط وجود كل الكلمات معاً، ويمسح ملفه مع كل عميل جديد، ويقرأ قاموسه بالعكس، ويُسقط أي عميل لا تطابقه قواعده.

  • ٣. تصنيف يناقض نفسه. نسب احتمال شراء بينها فجوات (٧١ إلى ٧٩٪ لا تنتمي لأي فئة)، وفترات زمنية متداخلة.

  • ٤. لا قاعدة للإسناد. «التوزيع على الفريق» لم يحدد كيف.

  • ٥. لا مهل. لا هدف لأول مكالمة، وثلاث محاولات دون تحديد المسافة بينها.

  • ٦. الشكوى قد تُغلق دون حل. لا تصعيد، ولا تأكيد من العميل.

  • ٧. أخطاء رسم. حلقة بلا مخرج، وتسمية دور منسوخة من قسم آخر، وتذكير يُرسل قبل تأكيد الحجز.

  • ٨. أقسام مفتوحة. التسويق والأساطيل بقيا «قيد الإجراء»، وأسئلة القطع والخدمات بلا مسار.

  • ٩. نظام الوكالة كان صندوقاً. لا تكامل: لم يُحدد ما الذي ينتقل بينه وبين CRM، ولا من يملك ماذا.

  • ١٠. لا موافقات. تذكيرات وإعادة تواصل بالرسائل وواتساب، دون تسجيل موافقة العميل أو إتاحة إلغاء الاشتراك.

  • ١١. فوائد بلا قياس. وُعد بخفض تكلفة الإعلان وزيادة المبيعات، دون خط أساس ولا مؤشر يثبتها.

الطبقة ٣ · إعادة التصميم

عميل واحد، وطلبات كثيرة، وكل تواصل مسجّل.

تبدأ إعادة التصميم من أضعف نقطة في التصميم الأول: البيانات. العميل سجل واحد، مفتاحه رقم جوال واحد بصيغة موحدة. وكل طلب هو عميل محتمل مرتبط بذلك العميل، وكل مكالمة أو زيارة نشاط مسجّل، والموافقات محفوظة في سجل العميل لكل قناة.

واحد لكثيريملكالعميلجوال واحد، سجل واحدالموافقةلكل قناةالطلبالمصدر، UTM، الحالةالموظفالقسم، الفرعالنشاطكل مكالمة وزيارةالحجزتجربة أو صيانةالشكوىتتصاعدنظام الوكالةأحداث بالاتجاهين
اختر أي مربع لترى ما يفعله وبماذا يرتبط. اسحب جانبياً لترى المخطط كاملاً.

العميل

يُعرَّف برقم جوال سعودي واحد بصيغة موحدة، فالشخص نفسه القادم من ثلاث قنوات يبقى عميلاً واحداً.

// One customer, many leads, and every touch recorded as an activity, so
// response times and performance are measured, not guessed.
export type Department = 'telesales' | 'testdrive' | 'aftersales' | 'callcenter' | 'fleet' | 'marketing';
export type Source = 'website' | 'social' | 'sms' | 'email' | 'outdoor' | 'event' | 'callcenter';

export interface Customer {
  id: string;
  phone: string;               // +9665XXXXXXXX: the one key that detects duplicates
  name: string;
  consent: { marketingSms: boolean; marketingWhatsApp: boolean; at: string };
  optedOutAt?: string;
}

export interface Lead {
  id: string;
  customerId: string;
  department: Department;
  inquiryType: string;         // chosen in the form, never guessed when present
  source: Source;
  utm?: { campaign: string; medium: string; content?: string };
  status: 'new' | 'assigned' | 'contacting' | 'qualified' | 'won' | 'lost' | 'nurture';
  temperature?: 'hot' | 'warm' | 'cold' | 'lost';
  ownerId?: string;
  attempts: number;
  lostReason?: string;
  createdAt: string;
  firstContactAt?: string;     // speed to lead is measured from createdAt to here
}

export interface Activity {
  leadId: string;
  agentId: string;
  kind: 'call' | 'whatsapp' | 'sms' | 'visit' | 'test_drive' | 'note';
  outcome: 'answered' | 'no_answer' | 'interested' | 'not_interested' | 'booked';
  at: string;
}

الطبقة ٣ · إعادة التصميم

النموذج يقرر أين يذهب العميل. والكلمات المفتاحية تقترح فقط.

سكربت التوزيع الأول كان يقرأ النص الحر ويبحث عن كلمات مفتاحية، وهو معروض أدناه كما كتبته. كان يشترط وجود كل كلمات القسم في رسالة واحدة، فالعميل الذي كتب «شراء» فقط لا يذهب لأي مكان. وكان يفتح ملفه بوضع الكتابة، فكل عميل جديد يمسح السابق. وكانت حلقته تقرأ القاموس بالعكس. أما إعادة التصميم فتسأل العميل عن طلبه في النموذج نفسه، وتُبقي الكلمات المفتاحية للنص الحر فقط، بالعربية والإنجليزية، مع شخص يراجع كل ما هو غير واضح.

اختر نوع الطلب وتابع مساره

قائمة المبيعات الهاتفية

يُسند إلى موظف المبيعات صاحب أقل عدد من العملاء المفتوحين.

أول مكالمة خلال ١٥ دقيقة في ساعات العمل، ثم حتى ثلاث محاولات في ثلاثة أيام مختلفة.

قبل: يُحوَّل بالبريد، أو يُنسخ من أداة المهام إلى جدول مشترك.

def transfer_text_based_on_keywords(input_file, keywords_to_files):
    # Read the contents of the original file
    with open(input_file, 'r', encoding='utf-8') as file:
        text = file.read()

    # Check each set of keywords and transfer the text to the corresponding file if the keywords are found
    for keywords, output_file in keywords_to_files.items():
        if all(keyword in text for keyword in keywords):
            with open(output_file, 'w', encoding='utf-8') as file:
                file.write(text)
            print(f"The text has been successfully transferred to {output_file}!")

# Define the files and the corresponding keywords
keywords_to_files = {
    'TeleSales.txt': ('buy', 'cost', 'value'),
    'AfterSales.txt': ('part', 'maintenance', 'inspection', 'periodic'),
    'Fleet.txt': ('company', 'institution'),
}

# Use the function to transfer texts
transfer_text_based_on_keywords('path/to/input_file.txt', keywords_to_files)

الطبقة ٣ · إعادة التصميم

قاعدة واحدة، بلا فجوات ولا تداخل.

تصميمي الأول كان فيه تصنيفان لا يتفقان: نسب احتمال شراء بينها فجوات، وفترات شراء متداخلة. لا أحد يستطيع تقدير الاحتمال في مكالمة هاتفية، لكن العميل يستطيع أن يقول متى ينوي الشراء. لذلك تُبقي إعادة التصميم المجموعات الأربع، وتعتمد ثلاثة أسئلة يستطيع الموظف طرحها فعلاً. جرّبها.

صنّف عميلاً

متى ينوي العميل الشراء؟

هل الميزانية أو التمويل مؤكد؟

هل تم الوصول إليه خلال ثلاث محاولات؟

ساخن

معاودة الاتصال خلال يومين وعرض تجربة قيادة. ويبقى العميل مع الموظف نفسه ١٥ يوماً ثم يُعاد تقييمه.

// One rule, with no gaps and no overlaps: the purchase timeframe decides the
// temperature, a confirmed budget or financing separates hot from warm, and a
// lead nobody reached after three attempts is nurtured, not thrown away.
export function classifyLead(timeframe: Timeframe, budgetConfirmed: boolean, answered: boolean): Temperature {
  if (timeframe === 'no') return 'lost';
  if (!answered) return 'cold';
  if (timeframe === 'd30') return budgetConfirmed ? 'hot' : 'warm';
  if (timeframe === 'm3') return 'warm';
  return 'cold';
}

// Days until the next follow-up for each temperature.
export const FOLLOW_UP_DAYS: Record<Temperature, number | null> = {
  hot: 2,     // and the same agent keeps it for 15 days before it is reassessed
  warm: 30,
  cold: 90,
  lost: null, // the reason is recorded; only marketing may re-engage, with consent
};

الطبقة ٣ · إعادة التصميم

العميل في إعادة التصميم، من النموذج إلى نظام الوكالة.

يُستقبل مع مصدره وموافقته

النموذج يسأل العميل عن طلبه، ويسجل مصدر UTM، ويطلب الموافقة على الرسائل التسويقية منفصلة عن رسائل الخدمة.

// A service message, such as a booking reminder, needs no marketing consent.
// Offers and re-engagement do, per channel, and an opt-out wins over everything.
export function canSend(c: Customer, purpose: 'service' | 'marketing', channel: 'sms' | 'whatsapp'): boolean {
  if (purpose === 'service') return true;
  if (c.optedOutAt) return false;
  return channel === 'sms' ? c.consent.marketingSms : c.consent.marketingWhatsApp;
}

١ / ٨

الطبقة ٣ · إعادة التصميم

الوعود تصبح مؤشرات.

تصميمي الأول وعد بخفض تكلفة الإعلان وزيادة المبيعات. وإعادة التصميم تحدد كيف يُتحقق من كل وعد، من سجلات الأنشطة والعملاء، فتُقيَّم الحملة أو الفريق بالأرقام.

  • سرعة الرد: الدقائق من النموذج إلى أول مكالمة.

  • نسبة الوصول: نسبة العملاء الذين تم الوصول إليهم فعلاً.

  • من العميل إلى التجربة، ومن التجربة إلى البيع: أين يفقد المسار الناس.

  • التحويل حسب المصدر والحملة: من UTM في كل عميل، فتتبع الميزانية المبيعات الحقيقية.

  • نسبة عدم الحضور: لتجارب القيادة وزيارات الصيانة.

  • زمن حل الشكاوى والتصعيد: لكل فرع.

  • المتابعات المتأخرة لكل موظف: الطريقة العادلة لتقييم الأداء.

-- What the design is judged by: how fast a lead is answered, how many are
-- reached, and which source really sells, so the budget follows sales.
SELECT source,
       COUNT(*) AS leads,
       AVG(CASE WHEN first_contact_at IS NOT NULL THEN 1.0 ELSE 0 END) AS contact_rate,
       AVG((julianday(first_contact_at) - julianday(created_at)) * 1440) AS minutes_to_first_contact,
       AVG(CASE WHEN status = 'won' THEN 1.0 ELSE 0 END) AS conversion
FROM leads
WHERE created_at >= date('now', '-30 days')
GROUP BY source
ORDER BY conversion DESC;

بوضوح

ما صممته، وما هو إعادة تصميم.

  • صممت نظام CRM هذا بالكامل أثناء عملي محللاً للتسويق. وهذه الصفحة لا تدّعي أن الوكالة تشغّله.

  • نظامهم معروض كما رسمته وقتها، مع تعميم أسماء أدواتهم.

  • تصميمي معروض كما رسمته، بعد تصحيح أخطاء الرسم، دون إضافة شيء.

  • إعادة التصميم هي كيف أبنيه اليوم. وكودها مرجعي كُتب لهذه الصفحة ليُظهر الهندسة، أما سكربت التوزيع الأول فهو الأصلي من تصميمي.

لماذا أعرض الثغرات أيضاً

التصميم الذي يبدو مثالياً في عرض تقديمي ينكسر غالباً في أول يوم مزدحم. وأن أقرأ عملي من جديد، وأجد أين كان سيفشل، وأغلق كل ثغرة، هو الجزء الذي أثق به أكثر في عمل الأنظمة.

وإن كان فريق المبيعات أو الخدمة لديك يفقد العملاء بين الأدوات، يسعدني الحديث معك.