isaaccladandCursor fab246ac83
Deploy Ladill Frontdesk / deploy (push) Successful in 42s
Add sidebar icons for Recovery, Branches, and Team.
Compliance and administration nav items now match the icon style used
across the rest of the Frontdesk sidebar.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-28 08:38:50 +00:00

Ladill CRM

The Ladill sales CRM at crm.ladill.com — a full SSO web app for managing contacts, leads, deals, activities and productsand the shared Customers/Leads/Products service consumed over HTTP by Ladill Invoice, Merchant, Mini and future apps, so contact + catalog data is owned in one place and reused everywhere.

Every record is scoped to one platform account via owner_ref (the user's public_id / OIDC sub).

App (web UI — Sign in with Ladill)

Authenticates against auth.ladill.com (OIDC Authorization Code + PKCE; see Auth\SsoLoginController). Local session is subordinate to the platform session (platform.session middleware) and joins Single Logout via /sso/logout-frontchannel.

  • Dashboard — KPIs (contacts, open leads, open deals, pipeline value), tasks due, recent activity.
  • Contacts — the contact book, with a per-contact timeline (notes, tasks, logged calls/meetings, sent email + SMS) and cross-product events (invoices, payments, orders) pushed from sibling apps.
  • Leads — list + kanban board (new → contacted → qualified), convert to a contact.
  • Deals — drag-free pipeline kanban across configurable stages (config/crm.pipeline_stages), won/lost tracking.
  • Activities — notes, tasks (with due dates / completion), calls, meetings.
  • Products & services — reusable catalog items.
  • Comms — email contacts (via the app mailer / Ladill Bird SMTP) and SMS (Termii); each send is logged on the timeline.
  • Reports — pipeline by stage, win rate, won value over time, leads by status, activity mix.

Service API (first-party, service-key auth)

Authenticate with a per-consumer service key: Authorization: Bearer <CRM_API_KEY_*> (see config/crm.php, App\Http\Middleware\AuthenticateService, alias auth.service:crm). Every request must pass owner (query or body) to scope data to the end user.

GET    /api/customers?owner=<sub>&search=
POST   /api/customers            {owner,name,email,phone,company,...}
... (show/update/destroy)

GET    /api/leads?owner=<sub>&status=
POST   /api/leads                {owner,name,status,estimated_value_minor,...}
POST   /api/leads/{id}/convert   {owner}        -> creates/links a customer

GET    /api/products?owner=<sub>&type=&active=
POST   /api/products             {owner,name,type,unit_price_minor,currency,tax_rate}

POST   /api/timeline             {owner,event,title,external_id,amount_minor,
                                  currency,url,customer_id|customer_email,...}

POST /api/timeline is how sibling products push "what happened" events onto a contact's timeline (invoice.sent, payment.received, order.paid). The source is derived from the service key (never client-supplied) and the write is idempotent per (owner, source, external_id, event). Reference consumer: ladill-invoice App\Services\Crm\CrmClient::pushTimeline().

No key → 401; missing owner → 422; cross-owner access → 404.

Local dev

composer install
cp .env.example .env && php artisan key:generate
# sqlite for local: set DB_CONNECTION=sqlite and `touch database/database.sqlite`
php artisan migrate
npm install && npm run build   # or `npm run dev`
php artisan serve
php artisan test

See DEPLOY.md for production cutover.

S
Description
No description provided
Readme
2.6 MiB
Languages
PHP 60.7%
Blade 33.2%
JavaScript 3.7%
Shell 1.6%
CSS 0.8%