# Capell Marketplace

## Package docs status

This page is generated from public package documentation in `capell-4 core packages` and the package manifest checked into the source repository.

| Field | Value |
| --- | --- |
| Composer package | `capell-app/marketplace` |
| Package slug | `marketplace` |
| Product group | Capell Foundation |
| Tier | free |
| Bundle | `foundation` |
| Runtime contexts | `admin`, `console` |
| Capell version | `^4.0` |
| Source repository | `capell-app/capell` |
| Source path | `packages/marketplace` |
| Docs source | `packages/marketplace/docs` |
| Manifest | [`capell.json`](https://github.com/capell-app/capell/edit/4.x/packages/marketplace/capell.json) |

`capell-app/marketplace` connects a Capell installation to the Capell extension marketplace. It owns catalogue browsing, Capell account linking, public domain verification, diagnostics, heartbeat/update advisory state, licence decisions, and signed install/upgrade authorization records.

Use this package when an admin needs to discover, authorize, or maintain extensions from the Capell marketplace. Local enable, disable, uninstall, and bulk extension management remain part of the installed Extensions surface.

## Package Boundary

Marketplace owns:

- the Marketplace page, extension browser, extension detail flow, account connection action, diagnostics action, heartbeat action, domain verification action, and install intent records
- public `.well-known/capell/marketplace/*` attestation and challenge endpoints
- signed Marketplace client requests, account connection callbacks, catalogue caching, heartbeat snapshots, update notices, advisory dismissals, registration sessions, install intents, and connection domain diagnostics
- Marketplace permissions for viewing extension and Marketplace surfaces

Marketplace does not own:

- Core package registry internals or generic package cache behavior
- Admin's installed Extensions table and local extension management actions
- Composer changes after an authorization has been granted unless a deployment package is installed and explicitly handles them
- public frontend rendering or theme output

## Install

```bash
composer require capell-app/marketplace
```

The package is enabled by default. Main config values:

| Env var                                   | Purpose                                                              |
| ----------------------------------------- | -------------------------------------------------------------------- |
| `CAPELL_MARKETPLACE_ENABLED`              | Enable Marketplace integration.                                      |
| `CAPELL_INSTANCE_ID`                      | Existing Marketplace instance ID fallback.                           |
| `CAPELL_MARKETPLACE_URL`                  | Marketplace API base URL. Defaults to `https://capell.app/api/v1`.   |
| `CAPELL_MARKETPLACE_WEB_URL`              | Public web URL for purchase and account flows.                       |
| `CAPELL_MARKETPLACE_CATALOGUE_PAGE_LIMIT` | Maximum catalogue pages fetched for the browser listing.             |
| `CAPELL_MARKETPLACE_WEBHOOK_URL`          | Public callback URL used by Capell App when `APP_URL` is not enough. |
| `CAPELL_MARKETPLACE_WEBHOOK_SECRET`       | Fallback signing secret for configured instances.                    |
| `CAPELL_MARKETPLACE_TROUBLESHOOTING_URL`  | Help URL shown from Marketplace diagnostics.                         |

Only override `CAPELL_MARKETPLACE_URL` for staging or self-hosted Marketplace APIs. The active public API path is versioned with `/api/v1`.

## Runtime Surfaces

- Provider: `Capell\Marketplace\Providers\MarketplaceServiceProvider`
- Config: `packages/marketplace/config/capell-marketplace.php`
- Routes: `packages/marketplace/routes/marketplace.php`
- Marketplace client: `Capell\Marketplace\Services\MarketplaceClient`
- Main Filament surfaces: `MarketplacePage`, `MarketplaceExtensionDetailPage`, `MarketplaceExtensionsBrowser`, marketplace header actions, connection status actions, and the extension health widget
- Admin extenders: `MarketplaceExtensionsPageExtender` tagged as `ExtensionsPageExtender::TAG`; `ThemeMarketplaceHeaderActionExtender` tagged as `ResourceHeaderActionExtender::TAG`
- Header action registry keys: `capell-marketplace.open-marketplace`, `capell-marketplace.connect-account`, `capell-marketplace.validate-domain`
- Livewire aliases: `capell-marketplace.marketplace-extensions-browser` and `capell-marketplace::marketplace-extensions-browser`
- Activation binding: `capell.marketplace.activation-verifier`
- Main actions: `StartMarketplaceAccountConnectionAction`, `CompleteMarketplaceAccountConnectionAction`, `StartMarketplaceRegistrationAction`, `VerifyMarketplaceRegistrationAction`, `RefreshMarketplaceConnectionDiagnosticsAction`, `PhoneHomeAction`, `CheckForUpdatesAction`, `CreateExtensionAcquisitionAction`, `RecordThemeInstallIntentAction`, `ResolvePendingThemeInstallsAction`, `VerifyMarketplaceSignedActivationAction`

The account connection callback is authenticated under the configured admin path. Attestation and challenge routes are public because Capell App must fetch them during verification.

## How The Main Flows Work

| Flow                       | Classes                                                                                                                                   | Notes                                                                                                                                                                                                   |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Account connection         | `StartMarketplaceAccountConnectionAction`, `CompleteMarketplaceAccountConnectionAction`, `MarketplaceAccountConnectionCallbackController` | Creates a short-lived account connection session, redirects the admin to Capell App, validates the returned state/code, requires a verified account email, and stores a `marketplace_instances` row.    |
| Public domain verification | `StartMarketplaceRegistrationAction`, `VerifyMarketplaceRegistrationAction`, `MarketplaceChallengeController`                             | Writes a challenge file under `public/.well-known/capell/marketplace/*`, records the pending session, asks Capell App to fetch the exact host, stores verified domains, and deletes the challenge file. |
| Catalogue browsing         | `MarketplaceClient`, `MarketplaceExtensionsBrowser`, `MarketplaceCatalogueTable`                                                          | Fetches JSON catalogue pages from `/extensions`, scopes cache keys by query and connection context, and serves stale cache only when the browser explicitly allows it.                                  |
| Install authorization      | `CreateExtensionAcquisitionAction`, `MarketplaceInstallActionPresenter`                                                                   | Requests Marketplace authorization, records an install intent when an instance is known, then either hands off to Deployments or shows the Composer command.                                            |
| Theme install resolution   | `RecordThemeInstallIntentAction`, `ResolvePendingThemeInstallsAction`                                                                     | Records pending theme install choices and resolves them when the Composer package is present.                                                                                                           |
| Heartbeat/update checks    | `PhoneHomeAction`, `CheckForUpdatesAction`, `RecordUpdateAdvisorySnapshotAction`                                                          | Sends installed package snapshots and stores update/advisory results locally.                                                                                                                           |

## Account And Domain Trust Flow

Account linking is the default trust path. An admin connects a Capell account, approves the site in Capell App, and returns to the CMS with Marketplace instance credentials.

Public domain verification is a stronger production signal. It writes a short-lived challenge file under `public/.well-known/capell/marketplace/{challengeId}`, records the pending registration, asks Capell App to fetch the exact domain, and removes the challenge file after successful verification.

Local hosts such as `localhost`, `127.*`, `.test`, `.localhost`, and IP addresses can be account-linked but cannot be publicly verified by Capell App.

## Data And Security

Marketplace is schema-owning. It creates registration session, instance, update advisory, install intent, account connection, and connection domain tables.

The package stores Marketplace instance IDs and encrypted signing secrets. Authorization requests are signed before they are sent to Capell App. Do not expose instance credentials, signing secrets, licence keys, or challenge tokens in public output or unauthenticated admin copy.

Signed authorization proves Marketplace entitlement and request integrity. It does not make a package's runtime code, screenshots, docs, or public/admin output inherently safe. Treat marketplace metadata as remote product data and treat installed extension code as normal executable application code.

Catalogue responses are cached for a short period. The cache is scoped by query and Marketplace context so account/domain state can affect visible actions without leaking one installation's state to another.

## Verification

Run Marketplace package tests after changing connection, registration, catalogue, heartbeat, permission, or install authorization behavior:

```bash
vendor/bin/pest packages/marketplace/tests --configuration=phpunit.xml
```

Run focused action or HTTP tests first when changing a specific flow, for example:

```bash
vendor/bin/pest packages/marketplace/tests/Feature/Actions/MarketplaceAccountConnectionActionTest.php --configuration=phpunit.xml
vendor/bin/pest packages/marketplace/tests/Feature/Http/MarketplaceAccountConnectionCallbackControllerTest.php --configuration=phpunit.xml
```

## Troubleshooting

| Symptom                                                  | Check                                                                                                                         | Fix                                                                                                                     |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `The route api/registration-sessions could not be found` | `php artisan config:show capell-marketplace.marketplace.base_url`                                                             | Use `https://capell.app/api/v1` and run `php artisan config:clear`.                                                     |
| Connect account fails immediately                        | `php artisan config:show app.url` and the latest `marketplace_account_connection_sessions.last_error`                         | Set `APP_URL` to a URL with a host, clear config cache, and retry before the 10-minute session expires.                 |
| Account callback says the session or state is invalid    | Latest row in `marketplace_account_connection_sessions`                                                                       | Retry from the same browser tab. Do not reuse old approval URLs after starting a newer connection.                      |
| Domain verification fails                                | Latest `marketplace_registration_sessions` row and public `curl -i https://host/.well-known/capell/marketplace/{challengeId}` | Use the exact host, remove auth/redirect/CDN blocks, and start a fresh verification if the challenge expired.           |
| Verification route is behind auth or page cache          | `php artisan route:list --name=capell-marketplace` and web server rules                                                       | Let the public `.well-known/capell/marketplace/*` routes reach Laravel/public files without admin auth.                 |
| Catalogue loads but install is blocked                   | Marketplace detail response and connection diagnostics                                                                        | Connect a Capell account first, resolve licence/domain requirements, then request authorization again.                  |
| Heartbeat/update check fails                             | `PhoneHomeAction::lastFailureMessage()` or admin notification copy                                                            | Set `APP_URL` or `CAPELL_MARKETPLACE_WEBHOOK_URL`, confirm an instance exists, and check network access to the API URL. |
| Catalogue looks stale                                    | Cache keys beginning `capell-marketplace.marketplace.*`                                                                       | Run `php artisan cache:clear` locally, or use the browser refresh action when available.                                |
| Marketplace surfaces disappear                           | `CAPELL_MARKETPLACE_ENABLED` and `php artisan optimize:clear`                                                                 | Re-enable the package config and clear cached config/routes.                                                            |
| Local-only domains will not publicly verify              | Domain is `localhost`, `127.*`, `.test`, `.localhost`, or an IP address                                                       | Use account linking for local development or verify a real public hostname for production.                              |

## Further Reading

| Page                                                        | Covers                                                                       |
| ----------------------------------------------------------- | ---------------------------------------------------------------------------- |
| [Marketplace overview](overview.md)                    | Marketplace responsibilities, admin flow, account linking, and verification. |
| [Operations docs](../../docs/operations/index.md)           | Marketplace connection and production troubleshooting entry points.          |
| [Approved packages catalog](../../docs/packages/catalog.md) | Host packages and first-party add-on catalogue.                              |
| [Package authoring docs](../../docs/packages/README.md)     | Package shape, manifests, extension points, migrations, and tests.           |