
Multi-Tenant Lead & Parcel Management Platform for Moroccan E-Commerce
Leadify.ma
2024-2025
Lead Full-Stack Developer
18 months
Built a comprehensive multi-tenant SaaS platform that automates the entire lifecycle: leads sync from Google Sheets, agents confirm leads which convert to parcels, deliveries integrate with Coliix and Ameex carriers, commissions auto-calculate, and invoices generate automatically. The platform supports role-based access (Admin, Seller, Agent) with real-time dashboards and analytics.
Leadify demonstrates expertise in building complex multi-tenant platforms with external integrations, real-time data processing, and sophisticated business logic. Let's discuss your project!
Complete SaaS architecture supporting unlimited stores, each with isolated data, custom branding, and independent configurations. Sellers can create multiple stores with separate Google Sheets connections and agent teams.
Automated lead import from Google Sheets with configurable column mapping. Real-time sync preserves formatting, supports custom fields, and handles batch imports with duplicate detection.
Comprehensive agent system with self-assignment, confirmation workflows, commission tracking, performance metrics, and activity logs. Agents can manage leads across multiple stores.
Complete workflow from lead acquisition to delivery: lead import → agent confirmation → parcel creation → delivery tracking → status updates → commission calculation.
Direct integration with Coliix and Ameex delivery services. Automated parcel creation, real-time tracking updates, webhook handling for status changes, and bulk operations support.
The platform uses a comprehensive database schema with over 30 Mongoose models covering all business operations:
Multi-tenant data isolation while maintaining performance with shared database
Implemented tenant-aware middleware that automatically filters all database queries by storeId, combined with compound indexes on (storeId, createdAt) for optimal query performance
// Tenant-aware middleware
export async function withTenant(handler) {
return async (req, res) => {
const session = await getServerSession(authOptions)
const storeId = session.user.storeId
// Inject storeId into all DB queries
req.query.storeId = storeId
req.body.storeId = storeId
return handler(req, res)
}
}
// Schema with tenant isolation
const LeadSchema = new Schema({
storeId: { type: ObjectId, ref: 'Store', required: true },
// ... other fields
})
// Compound indexes for performance
LeadSchema.index({ storeId: 1, createdAt: -1 })
LeadSchema.index({ storeId: 1, status: 1 })Google Sheets sync with thousands of rows causing timeout and memory issues
Comprehensive schema covering all business operations
RESTful APIs for all platform features
Google, Coliix, Ameex, Shopify, WooCommerce, YouCan
Admin, Seller, and Agent with granular permissions
Sophisticated commission calculation for both sellers and agents based on configurable rules. Supports percentage-based, fixed-amount, and tiered commission structures with automatic tracking.
Automated invoice creation with PDF export, QR codes for verification, commission breakdowns, payment tracking, and batch invoice processing with email notifications.
Role-specific dashboards with real-time metrics: lead conversion rates, agent performance, delivery statistics, revenue tracking, commission analytics, and custom date range filtering.
Native integrations with Shopify, WooCommerce, and YouCan platforms. Automated order synchronization, inventory tracking, customer data sync, and webhook-based updates.
AI image generation using OpenAI DALL-E 3, intelligent lead scoring with Google Gemini, automated categorization, sentiment analysis for customer communications, and smart recommendations.
Powerful search across all entities with multi-criteria filtering, saved filters, bulk operations, export functionality, and advanced date range selection with custom periods.
Granular permissions system with three primary roles (Admin, Seller, Agent) and customizable permissions. Route protection, API authorization, and audit logging for compliance.
All models include:
Implemented chunked batch processing with streaming, background jobs for large imports, and incremental sync using row checksums to detect changes
// Chunked batch processing
async function syncGoogleSheet(sheetId: string) {
const CHUNK_SIZE = 100
let offset = 0
while (true) {
const rows = await sheets.spreadsheets.values.get({
spreadsheetId: sheetId,
range: `A${offset + 1}:Z${offset + CHUNK_SIZE}`
})
if (!rows.data.values?.length) break
// Process chunk with upsert
await Lead.bulkWrite(
rows.data.values.map(row => ({
updateOne: {
filter: {
storeId,
sheetRowId: row[0]
},
update: parseRowToLead(row),
upsert: true
}
}))
)
offset += CHUNK_SIZE
}
}Real-time delivery tracking with webhook delays and failures from Coliix/Ameex
Built robust webhook handler with signature verification, idempotency checks, retry queue for failed webhooks, and fallback polling for critical updates
// Webhook handler with retry logic
export async function POST(req: Request) {
const signature = req.headers.get('x-coliix-signature')
const payload = await req.json()
// Verify signature
if (!verifyWebhookSignature(payload, signature)) {
return NextResponse.json({ error: 'Invalid signature' }, { status: 401 })
}
// Idempotency check
const webhookId = payload.webhook_id
const existing = await WebhookLog.findOne({ webhookId })
if (existing) {
return NextResponse.json({ message: 'Already processed' })
}
// Process with retry on failure
try {
await processTrackingUpdate(payload)
await WebhookLog.create({ webhookId, status: 'success' })
} catch (error) {
// Add to retry queue
await RetryQueue.create({
webhookId,
payload,
attempts: 0,
nextRetry: new Date(Date.now() + 60000) // 1 min
})
}
return NextResponse.json({ success: true })
}Complex commission calculations with multiple rule types and edge cases
Created flexible commission engine with rule builder, precedence system, calculation validation, and comprehensive audit trail for all commission changes
// Commission calculation engine
interface CommissionRule {
type: 'percentage' | 'fixed' | 'tiered'
value: number
conditions?: {
minAmount?: number
maxAmount?: number
productCategory?: string
}
priority: number
}
async function calculateCommission(
parcel: IParcel,
agent: IAgent
): Promise<number> {
// Get applicable rules sorted by priority
const rules = await CommissionRule.find({
storeId: parcel.storeId,
active: true
}).sort({ priority: -1 })
// Apply first matching rule
for (const rule of rules) {
if (matchesConditions(parcel, rule.conditions)) {
const commission = applyRule(parcel, rule)
// Audit trail
await CommissionLog.create({
parcelId: parcel._id,
agentId: agent._id,
ruleId: rule._id,
amount: commission,
calculation: {
type: rule.type,
value: rule.value,
baseAmount: parcel.amount
}
})
return commission
}
}
return 0 // No matching rule
}Stable release with continuous updates
From MVP to full production platform