Files
ladill-frontdesk/config/frontdesk.php
T
isaacclad b3842adaff
Deploy Ladill Frontdesk / deploy (push) Successful in 1m7s
chore(pricing): align free host SMS allowance with suite messaging
Free plan includes 50 host SMS per month to match platform free suite caps.
2026-07-16 11:24:22 +00:00

366 lines
14 KiB
PHP

<?php
return [
/*
|--------------------------------------------------------------------------
| Inbound service API keys (sibling Ladill apps calling Frontdesk)
|--------------------------------------------------------------------------
*/
'service_api_keys' => array_filter([
'pos' => env('FRONTDESK_API_KEY_POS'),
'crm' => env('FRONTDESK_API_KEY_CRM'),
'care' => env('FRONTDESK_API_KEY_CARE'),
'lab' => env('FRONTDESK_API_KEY_LAB'),
]),
'visitor_types' => [
'visitor' => 'Visitor',
'contractor' => 'Contractor',
'vendor' => 'Vendor',
'interview_candidate' => 'Interview Candidate',
'delivery' => 'Delivery Personnel',
],
'visit_purposes' => [
'meeting' => 'Business meeting',
'interview' => 'Job interview',
'delivery' => 'Delivery or pickup',
'maintenance' => 'Maintenance or repairs',
'sales' => 'Sales or vendor visit',
'training' => 'Training or workshop',
'personal' => 'Personal visit',
'other' => 'Other',
],
'visit_statuses' => [
'scheduled' => 'Scheduled',
'expected' => 'Expected',
'waiting' => 'Waiting',
'checked_in' => 'Checked In',
'checked_out' => 'Checked Out',
'cancelled' => 'Cancelled',
'overdue' => 'Overdue',
],
'watchlist_statuses' => [
'allowed' => 'Allowed',
'requires_approval' => 'Requires Approval',
'blacklisted' => 'Blacklisted',
],
'audit_actions' => [
'visit.checked_in' => 'Visit checked in',
'visit.checked_out' => 'Visit checked out',
'visit.awaiting_approval' => 'Visit awaiting approval',
'visit.scheduled' => 'Visit scheduled',
'visit.waiting' => 'Visitor waiting',
'visit.cancelled' => 'Visit cancelled',
'visit.deleted' => 'Visit archived',
'visit.restored' => 'Visit restored',
'visitor.deleted' => 'Visitor archived',
'visitor.restored' => 'Visitor restored',
'watchlist.blocked_attempt' => 'Blocked check-in attempt',
'watchlist.flagged_checkin' => 'Flagged visitor check-in',
'watchlist.entry_created' => 'Watchlist entry added',
'watchlist.entry_removed' => 'Watchlist entry removed',
'badge.expired' => 'Badge expired',
'employee.signed_in' => 'Employee signed in',
'employee.signed_out' => 'Employee signed out',
'employee.stepped_out' => 'Employee stepped out',
'employee.stepped_in' => 'Employee returned',
],
'roles' => [
'super_admin' => 'Super Administrator',
'org_admin' => 'Organization Administrator',
'branch_admin' => 'Branch Administrator',
'receptionist' => 'Receptionist',
'security_officer' => 'Security Officer',
'host' => 'Host',
'auditor' => 'Auditor',
],
'device_types' => [
'reception_computer' => 'Reception Computer',
'kiosk' => 'Visitor Kiosk',
'tablet' => 'Tablet',
'badge_printer' => 'Badge Printer',
'qr_scanner' => 'QR Scanner',
'camera' => 'Camera',
'signature_pad' => 'Signature Pad',
],
/*
| Device types that receive a server-generated token for unattended API/kiosk access.
*/
'device_token_types' => ['kiosk', 'badge_printer', 'qr_scanner'],
/*
| Contextual copy for the register / edit device forms (keyed by device type).
*/
'device_registration_hints' => [
'reception_computer' => 'Tracked for your team only. Staff sign in on this machine — no device token or automatic connection is created.',
'kiosk' => 'A device token is created after registration. Open the kiosk URL on your tablet to run self-service check-in without staff login.',
'tablet' => 'Tracked for inventory. Use Visitor Kiosk if this tablet should run unattended check-in.',
'badge_printer' => 'A device token is created for unattended printing. The printer connects when your print agent sends requests with that token.',
'qr_scanner' => 'A device token is created for unattended scanning. The scanner connects when it calls Frontdesk with that token.',
'camera' => 'Tracked for inventory at this reception desk or branch — no device token is issued.',
'signature_pad' => 'Tracked for inventory at this reception desk or branch — no device token is issued.',
],
'notification_channels' => [
'email' => 'Email (platform SMTP)',
'sms' => 'SMS',
],
'billing' => [
'email_cost_ghs' => (float) env('FRONTDESK_EMAIL_COST_GHS', 0.0135),
'sms_cost_per_segment_ghs' => (float) env('FRONTDESK_SMS_COST_PER_SEGMENT_GHS', 0.05),
'sms_segment_length' => (int) env('FRONTDESK_SMS_SEGMENT_LENGTH', 160),
],
'pro' => [
'grace_days' => (int) env('FRONTDESK_PRO_GRACE_DAYS', 3),
'period_days' => (int) env('FRONTDESK_PRO_PERIOD_DAYS', 30),
],
'plans' => [
'free' => [
'label' => 'Free',
'price_minor' => 0,
'max_branches' => 1,
'max_kiosk_devices' => 1,
'free_emails_per_month' => (int) env('FRONTDESK_FREE_EMAILS_PER_MONTH', 100),
// Align with platform suite free allowance (messaging.plans.free).
'free_sms_per_month' => (int) env('FRONTDESK_FREE_SMS_PER_MONTH', 50),
'features' => [
'check_in',
'hosts',
'badges',
'watchlist',
],
],
'pro' => [
'label' => 'Pro',
// GHS 1,990/branch/mo (legacy FRONTDESK_PRO_PRICE_MINOR still honored).
'price_minor_per_branch' => (int) env(
'FRONTDESK_PRO_PRICE_PER_BRANCH_MINOR',
env('FRONTDESK_PRO_PRICE_MINOR', 199000),
),
'price_minor' => (int) env(
'FRONTDESK_PRO_PRICE_PER_BRANCH_MINOR',
env('FRONTDESK_PRO_PRICE_MINOR', 199000),
),
'max_branches' => null,
'max_kiosk_devices' => null,
// 5,000 email + 5,000 SMS host alerts / month (10,000 combined).
'free_emails_per_month' => (int) env('FRONTDESK_PRO_FREE_EMAILS_PER_MONTH', 5000),
'free_sms_per_month' => (int) env('FRONTDESK_PRO_FREE_SMS_PER_MONTH', 5000),
'features' => [
'check_in',
'hosts',
'badges',
'watchlist',
'branches',
'team',
'integrations',
'webhooks',
'scheduled_reports',
],
],
'enterprise' => [
'label' => 'Enterprise',
// GHS 2,990/branch/mo.
'price_minor_per_branch' => (int) env('FRONTDESK_ENTERPRISE_PRICE_PER_BRANCH_MINOR', 299000),
'max_branches' => null,
'max_kiosk_devices' => null,
// null = unlimited host email / SMS alerts.
'free_emails_per_month' => null,
'free_sms_per_month' => null,
'features' => [
'check_in',
'hosts',
'badges',
'watchlist',
'branches',
'team',
'integrations',
'webhooks',
'scheduled_reports',
'custom_badge_templates',
],
],
],
'enterprise' => [
'min_branches' => (int) env('FRONTDESK_ENTERPRISE_MIN_BRANCHES', 1),
],
'prepaid_months' => [6, 12, 24],
'notification_events' => [
'visitor_arrived' => 'Visitor arrived (checked in)',
'visitor_checked_out' => 'Visitor checked out',
'visitor_expected' => 'Visitor expected today',
'visitor_waiting' => 'Visitor waiting in reception',
'visit_cancelled' => 'Visit cancelled',
'approval_needed' => 'Approval required',
'watchlist_alert' => 'Watchlist / security alerts',
'badge_expired' => 'Expired badge while checked in',
'employee_overdue_return' => 'Employee overdue to return from step-out',
],
'default_notification_events' => [
'visitor_arrived' => true,
'visitor_checked_out' => true,
'visitor_expected' => true,
'visitor_waiting' => true,
'visit_cancelled' => true,
'approval_needed' => true,
'watchlist_alert' => true,
'badge_expired' => true,
'employee_overdue_return' => true,
],
'kiosk' => [
'inactivity_reset_seconds' => (int) env('FRONTDESK_KIOSK_RESET_SECONDS', 120),
'default_visit_duration_minutes' => 60,
],
'employee_presence_statuses' => [
'off_site' => 'Off site',
'on_site' => 'On site',
'stepped_out' => 'Stepped out',
],
'employee_step_out_reasons' => [
'lunch' => 'Lunch',
'client_visit' => 'Client / external meeting',
'errand' => 'Bank / errands',
'personal' => 'Personal',
'other' => 'Other',
],
'employee_presence_events' => [
'sign_in' => 'Sign in',
'sign_out' => 'Sign out',
'step_out' => 'Step out',
'step_in' => 'Return',
],
'badge' => [
'default_expiry_hours' => 8,
'qr_url_path' => '/q',
'employee_qr_url_path' => '/eq',
],
'default_badge_template' => [
'show_photo' => true,
'show_qr' => true,
'show_host' => true,
'show_company' => true,
'show_type' => true,
'primary_color' => '#0d9488',
'footer_text' => '',
],
'webhook_events' => [
'visit.checked_in',
'visit.checked_out',
'visit.awaiting_approval',
'employee.signed_in',
'employee.signed_out',
'employee.stepped_out',
'employee.stepped_in',
],
'integrations' => [
'care' => 'Ladill Care',
'lab' => 'Ladill Lab',
'pos' => 'Ladill POS',
'crm' => 'Ladill CRM',
'queue' => 'Ladill Queue',
],
'queue' => [
'api_url' => env('QUEUE_API_URL', 'https://queue.ladill.com/api/v1'),
'api_key' => env('QUEUE_API_KEY_FRONTDESK'),
],
'printers' => [
'default_driver' => env('FRONTDESK_PRINTER_DRIVER', 'pdf'),
'drivers' => ['pdf', 'zebra', 'brother', 'dymo'],
],
/*
|--------------------------------------------------------------------------
| Visitor type workflows (Phase 4)
|--------------------------------------------------------------------------
| Config-driven fields, badge expiry overrides, and approval requirements.
*/
'visitor_type_config' => [
'visitor' => [
'requires_approval' => false,
'badge_expiry_hours' => null,
'details_key' => null,
'fields' => [],
],
'contractor' => [
'requires_approval' => false,
'badge_expiry_hours' => 12,
'details_key' => 'contractor_details',
'fields' => [
['name' => 'contract_company', 'label' => 'Contract company', 'type' => 'text', 'required' => true],
['name' => 'supervisor', 'label' => 'Site supervisor', 'type' => 'text', 'required' => true],
['name' => 'contract_start', 'label' => 'Contract start', 'type' => 'date', 'required' => false],
['name' => 'contract_end', 'label' => 'Contract end', 'type' => 'date', 'required' => false],
['name' => 'safety_induction_completed', 'label' => 'Safety induction completed', 'type' => 'checkbox', 'required' => true],
['name' => 'insurance_reference', 'label' => 'Insurance reference', 'type' => 'text', 'required' => false],
['name' => 'permit_number', 'label' => 'Permit number', 'type' => 'text', 'required' => false],
['name' => 'equipment_carried', 'label' => 'Equipment carried', 'type' => 'textarea', 'required' => false],
],
],
'delivery' => [
'requires_approval' => false,
'badge_expiry_hours' => 2,
'details_key' => 'delivery_details',
'fields' => [
['name' => 'courier_company', 'label' => 'Courier company', 'type' => 'text', 'required' => true],
['name' => 'recipient', 'label' => 'Recipient', 'type' => 'text', 'required' => true],
['name' => 'tracking_number', 'label' => 'Tracking number', 'type' => 'text', 'required' => false],
['name' => 'package_description', 'label' => 'Package description', 'type' => 'text', 'required' => false],
['name' => 'delivery_photo', 'label' => 'Delivery photo', 'type' => 'photo', 'required' => false],
['name' => 'delivery_signature', 'label' => 'Signature', 'type' => 'signature', 'required' => false],
],
],
'vendor' => [
'requires_approval' => true,
'badge_expiry_hours' => null,
'details_key' => 'contractor_details',
'fields' => [
['name' => 'vendor_company', 'label' => 'Vendor company', 'type' => 'text', 'required' => true],
['name' => 'service_type', 'label' => 'Service / product', 'type' => 'text', 'required' => true],
['name' => 'purchase_order', 'label' => 'PO number', 'type' => 'text', 'required' => false],
],
],
'interview_candidate' => [
'requires_approval' => true,
'badge_expiry_hours' => null,
'details_key' => 'contractor_details',
'fields' => [
['name' => 'position_applied', 'label' => 'Position applied for', 'type' => 'text', 'required' => true],
['name' => 'interviewer', 'label' => 'Interviewer', 'type' => 'text', 'required' => false],
['name' => 'scheduled_interview_at', 'label' => 'Interview time', 'type' => 'datetime-local', 'required' => false],
],
],
],
'upgrade_banner' => [
'title' => 'Unlock Frontdesk Pro or Enterprise',
'description' => 'Ladill-provided visitor kiosks, multi-branch, team, webhooks & reports — from GHS 1,990/branch/mo.',
'route' => 'frontdesk.pro.index',
],
];