Skip to main content

Overview

The Customer Management system maintains a database of all customers with categorization, contact information, and integration with WhatsApp bulk messaging. It provides tools for customer segmentation, data import/export, and targeted communications.

Key Benefits

  • Centralized Database: Store all customer contact information and history
  • Customer Categories: Segment customers (VIP, Regular, New) with custom categories
  • Bulk WhatsApp Messaging: Send promotions to specific customer segments
  • CSV Import/Export: Easily import existing customer lists or export for analysis
  • Automatic Creation: New customers auto-created from orders and reservations
  • Duplicate Prevention: System prevents duplicate phone/email entries

Customer Data Structure

Customer Interface

From types.ts:183-191:
export interface Customer {
  id: string;           // Format: CUST-{timestamp}-{random}
  name: string;
  phone?: string;       // Validated format
  email?: string;       // Validated format
  address?: string;
  categoryId: string;   // Reference to CustomerCategory.id
  createdAt: string;   // ISO timestamp
}

Customer Category Interface

From types.ts:193-197:
export interface CustomerCategory {
  id: string;      // Format: CUSTCAT-{timestamp}-{random}
  name: string;    // Display name (e.g., "VIP", "Regular")
  color: string;   // Hex color for visual grouping
}

Default Categories

From services/customerCategoryService.ts:15-19:
const initialCategories = [
  { name: 'Nuevo', color: '#4CAF50' },      // Green - new customers
  { name: 'Regular', color: '#2196F3' },    // Blue - repeat customers
  { name: 'VIP', color: '#FFC107' },        // Gold - VIP customers
];
“Nuevo” Category is Protected:The “Nuevo” category cannot be deleted as it’s the default for new customers. You can rename it or change its color, but deletion is blocked by the system.

Core Service Functions

Managing Customers

From services/customerService.ts:

Creating Customers

addCustomer(
  customerData: Omit<Customer, 'id' | 'createdAt'>
): Promise<Customer>
Example:
import { addCustomer } from './services/customerService';
import { getCustomerCategoriesFromCache } from './services/customerCategoryService';

const vipCategory = getCustomerCategoriesFromCache().find(c => c.name === 'VIP');

const newCustomer = await addCustomer({
  name: 'Ana Martínez',
  phone: '1145678901',
  email: '[email protected]',
  address: 'Av. Corrientes 1234',
  categoryId: vipCategory!.id
});

console.log(newCustomer.id);  // "CUST-1710087654321-abc5d"
Validation Rules:
Duplicate Prevention:
  • System checks for existing customers with same phone OR email
  • Throws error if duplicate found
  • Comparison is case-insensitive for emails
  • Phone comparison is exact match
Auto-Category Assignment (from customerService.ts:71-78):
// If no categoryId provided, use default "Nuevo" category
const defaultCategory = getDefaultNewCustomerCategory();
const categoryId = customerData.categoryId || defaultCategory!.id;

Updating Customers

updateCustomer(updatedCustomer: Customer): Promise<Customer>
Example:
import { updateCustomer, getCustomersFromCache } from './services/customerService';

const customers = getCustomersFromCache();
const ana = customers.find(c => c.name === 'Ana Martínez');

if (ana) {
  // Promote to VIP
  const vipCategory = getCustomerCategoriesFromCache().find(c => c.name === 'VIP');
  
  await updateCustomer({
    ...ana,
    categoryId: vipCategory!.id,
    address: 'Nueva dirección 456'  // Update address too
  });
}
Update Validation:
  • Checks for duplicate phone/email (excluding current customer)
  • Throws error if trying to use another customer’s phone/email

Deleting Customers

deleteCustomer(customerId: string): Promise<void>

Managing Customer Categories

From services/customerCategoryService.ts:
// Add category
addCustomerCategory(
  categoryData: Omit<CustomerCategory, 'id'>
): Promise<CustomerCategory>

// Update category
updateCustomerCategory(
  updatedCategory: CustomerCategory
): Promise<CustomerCategory>

// Delete category (reassigns customers to "Nuevo")
deleteCustomerCategory(categoryId: string): Promise<void>

// Get all categories
getCustomerCategoriesFromCache(): CustomerCategory[]

// Get default category for new customers
getDefaultNewCustomerCategory(): CustomerCategory | undefined
Example:
import { addCustomerCategory } from './services/customerCategoryService';

const corporateCategory = await addCustomerCategory({
  name: 'Corporativo',
  color: '#9C27B0'  // Purple
});
Category Deletion (from customerCategoryService.ts:115-129): When deleting a category:
  1. System reassigns all customers in that category to “Nuevo”
  2. Updates Firebase in batch
  3. Updates local cache
  4. Prevents deletion of “Nuevo” category

Bulk Import/Export

CSV Import

From services/customerService.ts:156-202:
importCustomers(
  customersToImport: any[]
): Promise<{ added: number; updated: number; errors: number }>
CSV Structure:
name,phone,email,address,categoryName
Juan Pérez,1123456789,[email protected],Calle 123,VIP
María González,1198765432,[email protected],Av. 456,Regular
Import Logic:
1

Validate Fields

Each row must have:
  • name (required)
  • phone (required, must be 10+ digits)
  • email (required, valid format)
  • categoryName (must exist or defaults to “Nuevo”)
2

Match Existing Customers

Checks if customer with same phone or email exists.
3

Update or Add

  • If exists: updates existing customer data
  • If new: creates new customer
4

Batch Write

All changes written to Firebase in single batch for performance.
5

Return Statistics

Returns count of:
  • added: New customers created
  • updated: Existing customers updated
  • errors: Rows with validation failures
Example:
import { importCustomers } from './services/customerService';

const csvData = [
  {
    name: 'Juan Pérez',
    phone: '1123456789',
    email: '[email protected]',
    address: 'Calle 123',
    categoryName: 'VIP'
  },
  // ... more rows
];

const result = await importCustomers(csvData);

console.log(`Added: ${result.added}`);
console.log(`Updated: ${result.updated}`);
console.log(`Errors: ${result.errors}`);
Validation Rules:
// Phone validation
if (!/^\d{10,}$/.test(phone.replace(/\D/g, ''))) {
  errors++;
  continue;
}

// Email validation
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
  errors++;
  continue;
}

WhatsApp Bulk Messaging

From services/whatsappBotService.ts and components/admin/CustomersPanel.tsx:

Sending Messages to Customers

sendWhatsAppMessage(
  number: string,
  content: string,
  mediaUrl?: string
): Promise<{ success: boolean; error?: string }>
Example - Single Customer:
import { sendWhatsAppMessage } from './services/whatsappBotService';

const result = await sendWhatsAppMessage(
  '1145678901',
  '¡Hola Ana! Tenemos una promoción especial para clientes VIP: 20% de descuento en pizzas este fin de semana.',
  'https://example.com/promo.jpg'  // Optional image
);

if (result.success) {
  console.log('Message sent!');
} else {
  console.error(`Failed: ${result.error}`);
}

Bulk Send

From components/admin/CustomersPanel.tsx: The admin panel provides bulk messaging UI: User Workflow:
1

Navigate to Customers Panel

Click “Clientes” in admin sidebar.
2

Filter by Category (Optional)

Select category (e.g., “VIP”) to send targeted messages.
3

Click 'Envío Masivo'

Opens bulk messaging modal.
4

Compose Message

  • Enter message text
  • Optionally add image URL
  • Preview shows recipient count
5

Send to All or Selected

Choose:
  • All customers in current filter
  • Manually selected customers (checkbox)
6

Monitor Progress

System shows:
  • Total to send
  • Sent count (updates in real-time)
  • Failed count
  • Progress percentage
Bulk Send Job Tracking (from types.ts:258-265):
export interface BulkSendJob {
  status: 'running' | 'completed' | 'cancelled' | 'error' | 'idle';
  total: number;       // Total messages to send
  sent: number;        // Successfully sent
  failed: number;      // Failed attempts
  startTime: number;   // Timestamp
  isCancelled: boolean;
}
WhatsApp Bot Must Be Active:Bulk messaging requires WhatsApp bot to be connected (status: ‘active’). The UI disables messaging features when bot is disconnected.

User Workflows

Adding a Customer Manually

1

Navigate to Customers Panel

Click “Clientes” in the admin sidebar.
2

Click 'Nuevo Cliente'

Opens customer creation form.
3

Fill Customer Details

  • Name (required)
  • Phone (optional but required for WhatsApp)
  • Email (optional)
  • Address (optional, useful for delivery history)
  • Category (defaults to “Nuevo”)
4

Submit

System:
  • Validates phone and email format
  • Checks for duplicates
  • Creates customer with auto-generated ID
  • Syncs to Firebase

Importing Customer List

1

Prepare CSV File

Create CSV with columns: name, phone, email, address, categoryNameEnsure:
  • Phone numbers have 10+ digits
  • Emails are valid format
  • Category names match existing categories (or blank for “Nuevo”)
2

Open Import Tool

In CustomersPanel, click “Importar CSV” button.
3

Upload File

Select CSV file from computer.
4

Review Results

System displays:
  • Customers added (new)
  • Customers updated (duplicates)
  • Errors (validation failures)
5

Verify in Customer List

Check that customers appear with correct categories and contact info.

Sending Promotional Message to VIP Customers

1

Ensure WhatsApp Bot is Active

Check bot status in “Bots” panel. If disconnected, connect first.
2

Filter VIP Customers

In CustomersPanel, select “VIP” category filter.
3

Open Bulk Messaging

Click “Envío Masivo WhatsApp” button.
4

Compose Message

¡Hola! Como cliente VIP, te ofrecemos 25% de descuento
en todas nuestras pizzas este viernes y sábado.

Usa el código: VIP25

¡Te esperamos!
Optionally add promotional image URL.
5

Send to All VIP

Click “Enviar a Todos” (or select specific customers).
6

Monitor Progress

Watch real-time progress:
  • Total: 150 customers
  • Sent: 145
  • Failed: 5 (invalid numbers)

Automatic Customer Creation

Customers are auto-created from orders and reservations when they don’t exist: From Orders (when using AI assistants):
// AI creates order with customer data
const order = await saveOrder({
  customer: {
    name: 'Nuevo Cliente',
    phone: '1199887766',
    address: 'Calle Nueva 789'
  },
  // ... order details
});

// System can later extract this to create customer record:
await addCustomer({
  name: order.customer.name,
  phone: order.customer.phone,
  address: order.customer.address,
  categoryId: getDefaultNewCustomerCategory()!.id
});
From Reservations:
// Reservation created with customer info
const reservation = await addReservation({
  customerName: 'Carlos Ruiz',
  customerPhone: '1166554433',
  // ...
});

// Later, add to customer database:
await addCustomer({
  name: reservation.customerName,
  phone: reservation.customerPhone,
  categoryId: getDefaultNewCustomerCategory()!.id
});

Real-Time Synchronization

From components/AdminDashboard.tsx:112-113:
const unsubCustomers = onSnapshot(
  collection(db, 'Customers'),
  (querySnapshot) => {
    const customers = querySnapshot.docs.map(doc => doc.data() as Customer);
    updateCustomersCache(customers);
    setDataTimestamp(Date.now());
  }
);

const unsubCustomerCategories = onSnapshot(
  collection(db, 'CustomerCategories'),
  (querySnapshot) => {
    const categories = querySnapshot.docs.map(doc => doc.data() as CustomerCategory);
    updateCustomerCategoriesCache(categories);
  }
);

Best Practices

Categorize Strategically

Use categories to segment customers by:
  • Purchase frequency (New, Regular, VIP)
  • Order value (Economy, Standard, Premium)
  • Location (Local, Tourist)

Keep Contact Info Updated

Encourage customers to provide both phone and email for multi-channel communication.

Import Periodically

If you have customer data in other systems (POS, CRM), import regularly to keep database current.

Target Messages by Category

Send VIP offers to VIP customers, re-engagement messages to lapsed customers, etc.

Monitor Bulk Send Results

Check failed messages - they may indicate outdated phone numbers. Clean up database accordingly.

Protect Customer Data

Customer data is stored in Firebase. Ensure proper security rules and access controls.
  • Orders - Orders reference customer data
  • Reservations - Reservations include customer contact info
  • AI Assistants - AI assistants can collect customer data during interactions

Build docs developers (and LLMs) love