Skip to content

Module Development Standard

Every business capability on this platform is a module. Modules are licensed via the marketplace catalog and authorized via Spatie permissions. They are not PHP packages or plugins.

Reference implementation: Leads

Guides

AudienceDocument
Engineersmodule-development-developer.md
Production / opsmodule-development-production.md
Documentationdocumentation-governance.md
Architecture freeze../architecture/platform-freeze.md
Module architecturemodule-architecture.md
Module dependenciesmodule-dependencies.md
Module licensingmodule-licensing.md
Notification contractsnotification-architecture-contract.md

Principles

  1. Consistency over abstraction — flat Laravel layout; register through existing catalog, permissions, middleware, nav, and settings.
  2. Licensing ≠ authorizationmodule:{slug} then can:{slug}.{action}.
  3. Mirror Leads — Tasks, Calendar, Communication Templates, Invoices, Inventory, Purchases, HR, Payroll, Accounting, Assets, Projects must follow the same licensing + permission + UI structure (Communication Templates is additionally a cross-cutting consumer pattern).
  4. No shortcuts — every module ships backend, frontend, tests, docs, and CHANGELOG in the same delivery (Documentation Governance).
  5. Migrate-only production — new default modules and permissions ship as data migrations; never production db:seed for catalog/RBAC. When updating an existing module, bump catalog modules.version via DefaultModuleRegistrar::bumpVersion using PATCH / MINOR / MAJOR semver (no breaking changes; platform-wide code + catalog label; entitlement unchanged). See Developer Guide — catalog versioning.
  6. Self-contained modules — each module owns its migrations, models, services, routes, UI, permissions, settings, docs, and tests; communicate through contracts/services only. See Module Architecture.
  7. Declare dependencies — required vs optional; free vs billable. See Module Dependencies.
  8. Independent licensing — design every module so it can be included, free, or billable. See Module Licensing.
  9. One workspace timezone — all current and future modules use Settings → General → Timezone for wall clocks, “today”, due dates, schedules, digests, and office hours. Store absolute datetimes as UTC (UtcDateTime / UtcIso); display/edit via SPA datetime.ts. No per-module timezone. See Workspace timezone convention.

Cross-cutting patterns (Sprint 2+)

  • Dashboard widgets — register via DashboardWidgetService on GET /dashboard; gate by module entitlement, permission, and assignee scope (see Calendar calendar widget as the latest example).
  • Notifications — Follow the frozen Notification Architecture Contract: versioned payload, route descriptors, NotificationBatch aggregation, Reverb/Echo realtime, modular SPA registry. Due/overdue work uses crm:send-due-notifications. Retention: notifications:prune.
  • Realtime rooms — Team Chat adds a private Reverb conversation channel tenant.{tid}.conversation.{id} (membership-gated) beside the existing tenant.{tid}.user.{uid} notification channel. See Module Development Guide — in-app notifications.
  • Assignee scoping — reuse ScopesToAssignee so users without {slug}.assign only see their own records.

Definition of Done

A module is complete only when:

  • [ ] Backend implementation complete (models, migrations, services, controllers, requests, resources, policies, events, notifications)
  • [ ] Frontend complete (list + dedicated create/view/edit pages; hybrid list EntityRecordSheet / ModuleRecordSheet for quick create/peek with renderOverview field summary — billing docs view-peek only; forms, tables, filters, loading/empty/error states; dialogs only for secondary flows)
  • [ ] Module list PageHeader wires tourId with steps under src/tours/{slug}.ts (Module Tours)
  • [ ] Permissions enforced (Spatie + UI gates)
  • [ ] Module licensing enforced (module: middleware + SPA nav)
  • [ ] Tenant isolation verified
  • [ ] Audit logging (PlatformAuditService) implemented
  • [ ] Activity logging (Spatie LogsActivity + domain timeline where applicable)
  • [ ] Notifications implemented where applicable
  • [ ] Date/time behavior follows the Workspace timezone convention (workspace TZ wall clocks; UTC storage for absolute instants; no module-scoped timezone)
  • [ ] Pest tests pass (CRUD, authz, validation, tenant isolation, module gate) — include non-UTC timezone coverage when the module schedules or gates by clock
  • [ ] Playwright suite passes (test:e2e:{slug})
  • [ ] Manual browser QA passes
  • [ ] Developer / User / Production guides updated in the same PR (Documentation Governance) — state that times use Settings → General → Timezone
  • [ ] API + database docs updated
  • [ ] CHANGELOG updated
  • [ ] No console errors; no failed network requests; build passes
  • [ ] No platform refactor required before the next module

Official documentation for the EloSync SaaS Platform.