Skip to content

Customer Portal Overview

Status: Available, schema-owning · Kind: package · Tier: premium · Bundle: content-product · Contexts: admin, frontend · Product group: Capell Content

Customer Portal turns a Capell site into an authenticated customer self-service hub. Customers get a private dashboard for profile details, preferences, support requests, and links contributed by other packages.

Use Customer Portal when a site needs a logged-in area without every package inventing its own customer dashboard. The package owns the account boundary, dashboard shell, preference form, support request workflow, and staff triage screen.

Other packages can add customer-facing cards or links:

  • Payments can expose invoices, payment methods, subscriptions, or checkout links.
  • Document Lifecycle can expose controlled downloads.
  • Events can expose registrations.
  • Access Gate can expose gated resources.
  • Newsletter can expose preference or subscription links.

Customer Portal is intentionally BYO-auth. It relies on the host app’s authenticated middleware and does not ship login, registration, password reset, magic-link, or SSO screens.

  • Authenticated frontend routes under the configured portal path.
  • PortalAccount, PortalSupportRequest, and PortalSupportRequestReply models.
  • Provider registries for profile fields, dashboard items, self-service items, and preferences.
  • Support request submission, replies, status transitions, and requester notifications.
  • A Filament support-request triage resource for staff.
  • Public-output safeguards: private portal responses are no-store/noindex and should not expose package names, editor URLs, admin selectors, account IDs, or unsafe profile fields.

Use these extension points instead of importing another package’s internals into Customer Portal:

NeedEntry point
Customer profile fieldsPortalProfileProviderRegistry with PortalProfileProvider
Dashboard cardsPortalDashboardItemRegistry with PortalDashboardItemProvider
Self-service feed entriesPortalSelfServiceItemRegistry with PortalSelfServiceItemProvider
Preference optionsPortalPreferencesProviderRegistry with PortalPreferencesProvider
Resolve portal accountResolveAuthenticatedPortalAccountAction
Submit support requestSubmitSupportRequestAction
Update preferencesUpdatePortalPreferencesAction

Provider output must be customer-facing. Do not include internal model IDs, signed admin URLs, tokens, selectors, package internals, or authoring metadata.

use Capell\CustomerPortal\Contracts\PortalDashboardItemProvider;
use Capell\CustomerPortal\Data\PortalDashboardItemData;
use Capell\CustomerPortal\Enums\PortalDashboardItemPriority;
use Capell\CustomerPortal\Models\PortalAccount;
final class BillingDashboardItemProvider implements PortalDashboardItemProvider
{
public function dashboardItemsFor(PortalAccount $portalAccount): iterable
{
yield new PortalDashboardItemData(
key: 'billing.open-invoices',
label: __('capell-payments::portal.open_invoices'),
description: __('capell-payments::portal.open_invoices_description'),
url: route('billing.invoices.index'),
priority: PortalDashboardItemPriority::High,
);
}
}
  • Customer Portal owns account/profile/preference/dashboard aggregation and support request workflows.
  • Billing, documents, gated resources, events, and newsletter operations stay with the owning package.
  • Public Blade receives hydrated arrays and data objects. Do not query models directly from portal views.
  • The package does not own customer authentication screens.

docs/screenshots.json covers the authenticated dashboard, preferences/support workflow, support triage list, and support triage detail screen.

Terminal window
vendor/bin/pest packages/customer-portal/tests --configuration=phpunit.xml
vendor/bin/phpstan analyse packages/customer-portal/src packages/customer-portal/tests --configuration=phpstan.neon --memory-limit=1G
vendor/bin/pint --test packages/customer-portal/src packages/customer-portal/tests