Customer Portal
Package docs status
Section titled “Package docs status”This page is generated from public package documentation in capell-4/packages and the package manifest checked into the source repository.
| Field | Value |
|---|---|
| Composer package | capell-app/customer-portal |
| Package slug | customer-portal |
| Product group | Capell Content |
| Tier | premium |
| Bundle | content-product |
| Runtime contexts | admin, frontend |
| Capell version | ^4.0 |
| Source repository | capell-app/packages |
| Source path | packages/customer-portal |
| Docs source | packages/customer-portal/docs |
| Manifest | capell.json |
Customer Portal turns a Capell site into an authenticated self-service hub. It gives signed-in customers a private dashboard for profile details, contributed self-service items, preferences, support requests, and recent support history without leaking admin/editor internals into frontend output.
Features
Section titled “Features”- Authenticated frontend routes under
/portalusing the configuredwebandauthmiddleware. - Site-scoped
PortalAccountrecords with encrypted email, display name, profile, and preference storage. - A profile surface powered by
ResolvePortalProfileActionandPortalProfileProviderRegistry. - Dashboard and self-service item registries so packages such as payments, document lifecycle, events, newsletter, and access-gate can contribute cards and feed items without Customer Portal importing their internals.
- Configurable per-provider and global caps for dashboard and self-service item fan-out.
- Preference updates through
UpdatePortalPreferencesAction, with option rendering and validation driven by the package preference schema. - Support request submission and threaded replies through Actions, with encrypted request/reply details and requester email hashing.
- Support request submitted/status-changed events and queued requester mail notifications.
- Admin support-request triage through a Filament resource scoped to the current actor’s assigned sites.
- Real package health diagnostics for required tables and model resolution.
- Package factories for
PortalAccountandPortalSupportRequest.
Frontend Safety
Section titled “Frontend Safety”The dashboard is a private customer surface. Responses send no-store and noindex headers, and tests assert the rendered output does not expose package names, signed editor URLs, Filament internals, account ids, or unsafe profile fields. Public Blade receives hydrated arrays from controllers and Actions; it should not query models directly.
capell.json declares a 200ms frontend render budget and a 20-query frontend budget. Provider adapters should keep expensive lookups out of Blade and return already-hydrated PortalDashboardItemData, PortalSelfServiceItemData, and PortalProfileData objects.
Provider fan-out is bounded by dashboard_items_per_provider_limit, dashboard_items_limit, self_service_items_per_provider_limit, and self_service_items_limit in capell-customer-portal.php.
Authentication Boundary
Section titled “Authentication Boundary”Customer Portal is intentionally a BYO-auth package. It mounts authenticated frontend routes behind the configured middleware stack and resolves the signed-in Laravel user into a site-scoped PortalAccount; it does not install login, registration, password reset, magic-link, or SSO screens. Pair it with the host app’s auth stack, Fortify, Socialite, Access Gate, or another first-party auth package when a site needs a complete customer identity journey.
Extension Points
Section titled “Extension Points”Register provider adapters through the package registries:
PortalProfileProviderRegistryfor customer-facing profile fields.PortalDashboardItemRegistryfor dashboard cards.PortalSelfServiceItemRegistryfor recent payments, documents, gated resources, event registrations, newsletter links, and support items.PortalPreferencesProviderRegistryfor preference-schema work.
Provider output is escaped in Blade. Keep labels, descriptions, URLs, and profile values customer-facing, and do not include internal ids, tokens, admin URLs, selectors, or authoring metadata.
Suite Boundaries
Section titled “Suite Boundaries”Customer Portal aggregates self-service links and dashboard cards; owning packages keep their domain operations. Payments should issue invoice, payment-method, checkout, and subscription URLs through its portal providers. Document Lifecycle and gated-resource packages should issue signed download or entitlement URLs through their own providers. Customer Portal renders those customer-facing items without importing billing, document, or entitlement internals.
Support Workflow
Section titled “Support Workflow”Customers can submit support requests from the dashboard, then continue the thread from their recent-support history. Staff can reply from the admin triage table. The package stores request subject, message, requester email, context, status, priority, and threaded replies in encrypted columns where appropriate; reply attachments are represented as encrypted metadata references so file-owning packages can provide the actual storage/download surface. Submissions emit PortalSupportRequestSubmitted; status transitions emit PortalSupportRequestStatusChanged only when the status changes.
Requester notifications are sent on demand through Laravel’s notification system when a requester email address is available.
Marketplace Screenshots
Section titled “Marketplace Screenshots”docs/screenshots.json defines the Capell runner capture contract for the frontend dashboard, preferences/support workflow, support triage list, and support triage detail screen. The light PNGs are promoted in capell.json; dark variants are committed alongside them for documentation and listing alternates.
Testing
Section titled “Testing”Run the package tests directly from the monorepo root:
vendor/bin/pest packages/customer-portal/tests --configuration=phpunit.xmlvendor/bin/phpstan analyse packages/customer-portal/src packages/customer-portal/tests --configuration=phpstan.neon --memory-limit=1Gvendor/bin/pint --test packages/customer-portal/src packages/customer-portal/testsUse vendor/bin/pest directly in this repository; do not run php artisan here.