application
pfy application manages applications and which tenants can use them. An application is defined once per project; a tenant gets access when you enable the application for it. The group also copies per-tenant configuration between tenants, edits an application's communications settings, and updates its version.
Synopsis
pfy application <subcommand> [flags]Aliases: app
Description
Applications are deployable products defined once at the project level. Each has its own configuration, modules, themes, and version management, and is made available to a customer organization by enabling it for that tenant (the Tenant2Application join).
promote is a deprecated stub: it always refuses and points to enable/disable (per-tenant access) and config-copy (per-tenant configuration).
Several subcommands take a project selector: --project <slug> (resolved to an ID) or --project-id <id> (overrides --project); when neither is given, the project_id from project.yaml is used where noted.
Subcommands
list- List a project's applicationscreate- Create a new application at the project levelget- Get an application's details by slugupdate- Update an application's name, description, and/or versiondelete- Delete an application (typed confirmation unless--yes)enable/disable- Enable or disable an application for a tenantlist-tenants- List an application's tenant enablements (join rows)config-copy- Copy per-(tenant, application) config between join rowscopy- Copy an application to another tenantupdate-version- Update the version of an applicationcomms-config get/comms-config set- Read or edit the communications (notification) config of one cascade layerpromote- Deprecated stub; always refuses (see above)
application list
List all applications in a project.
Usage
pfy application list --project <project-slug> [flags]Flags
| Flag | Required | Description |
|---|---|---|
--project | Yes | Project slug to list applications from |
--limit | No | Maximum number of items to return; if unset, every item is fetched |
--offset | No | Number of items to skip before returning results; defaults to the first item |
Example
pfy application list --project my-saasOutput:
Applications:
- Web App (web-app) v1.2.3
- Admin Portal (admin) v2.0.1
- API Gateway (api) v1.0.0
3 applicationsVerbose output (pfy --verbose application list --project my-saas) additionally prints each application's ID: line. pfy -o json application list --project my-saas emits the same list as JSON; see Output formats. --limit and --offset page through the list.
application create
Create a new application at the project level.
Usage
pfy application create \
--project <slug> \
--slug <slug> \
--name <name> \
[--version <version>] \
[--description <desc>]Flags
| Flag | Required | Description |
|---|---|---|
--project | No* | Project slug (resolved to an ID) |
--project-id | No* | Project ID (overrides --project) |
--slug | Yes | Application slug (unique within the project) |
--name | Yes | Application display name |
--version | No | Initial version (default: "0.1.0") |
--description | No | Application description |
* One project selector is needed: --project, --project-id, or a project_id in project.yaml.
Examples
Basic creation:
pfy application create \
--project my-saas \
--slug web-app \
--name "Web Application"With version and description:
pfy application create \
--project my-saas \
--slug admin-portal \
--name "Admin Portal" \
--version "1.0.0" \
--description "Internal administration interface for managing tenant data"Output:
Application created successfully: Admin Portal (admin-portal) v1.0.0application get
Get an application's details, resolved by slug within a project.
Usage
pfy application get <slug> --project <project-slug>Flags
| Flag | Required | Description |
|---|---|---|
--project | Yes | Project slug the application belongs to |
--slug | No | Application slug (alternative to the positional) |
Passing a UUID (or --id) is refused: application get resolves by slug only; use pfy application list to find an application by ID.
Example
pfy application get web-app --project my-saasApplication: Web Application (web-app) v1.2.3
ID: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeeapplication update
Update an application's name, description, and/or version.
Usage
pfy application update <slug|id> [--project <slug>] [--name <name>] [--description <desc>] [--version <version>]A slug needs --project to resolve; a UUID is used directly. At least one of --name, --description, --version must be passed.
Example
pfy application update web-app --project my-saas --name "Customer Web App"application delete
Delete an application. On a TTY you must type the application's slug/ID back to confirm; under --ci or without a TTY, --yes is required.
Usage
pfy application delete <slug|id> [--project <slug>] [--yes]| Flag | Aliases | Description |
|---|---|---|
--project | Project slug (needed to resolve an application slug to its ID) | |
--yes | -y | Skip the confirmation prompt (required under --ci or non-TTY) |
application enable / disable
Enable or disable an application for a tenant (writes the Tenant2Application join).
Usage
pfy application enable --app <slug> --tenant <slug> --project <project-slug>
pfy application disable --app <id> --tenant-id <id>Flags
| Flag | Aliases | Description |
|---|---|---|
--app | --app-id | Application slug (resolved via --project), or an application ID |
--tenant | Tenant slug (requires --project to resolve) | |
--tenant-id | Tenant ID (alternative to --tenant + --project) | |
--project | Project slug (resolves --tenant and an --app slug to IDs) |
Example
pfy application enable --app web-app --tenant acme --project my-saasEnabled application <app-id> for tenant <tenant-id> (join <t2a-id>, enabled=true)application list-tenants
List the tenant enablements (Tenant2Application join rows) for an application. The join IDs printed here are what config-copy --from/--to take.
Usage
pfy application list-tenants --app <slug> --project <project-slug>| Flag | Aliases | Description |
|---|---|---|
--app | --app-id | Application slug (resolved via --project), or an application ID |
--project | Project slug (resolves an --app slug to its ID) |
Example
pfy application list-tenants --app web-app --project my-saasTenant enablements:
- acme: join 99999999-aaaa-bbbb-cccc-dddddddddddd enabled=true forward_role=false
1 enablementapplication config-copy
Copy the per-(tenant, application) configuration from one join row to another. This is how per-tenant config moves between tenants.
Usage
pfy application config-copy --from <t2a-id> --to <t2a-id>| Flag | Description |
|---|---|
--from | Source Tenant2Application join ID (discover with list-tenants) |
--to | Target Tenant2Application join ID (discover with list-tenants) |
Example
pfy application config-copy \
--from 99999999-aaaa-bbbb-cccc-dddddddddddd \
--to 88888888-aaaa-bbbb-cccc-ddddddddddddapplication copy
Copy an application to another tenant with a new slug and optional customizations. The source application and target tenant accept a slug or a raw ID: a slug is resolved within --project; a UUID passes straight through (which is also the cross-project escape hatch, since a slug is unique only within one project).
Usage
pfy application copy \
--source-application-id <slug|id> \
--target-tenant-id <slug|id> \
--slug <slug> \
[--project <slug>] \
[--name <name>] \
[--version <version>] \
[--update-version]Flags
| Flag | Aliases | Required | Description |
|---|---|---|---|
--source-application-id | --from-app | Yes | Source application: a slug (resolved within --project) or an application ID |
--target-tenant-id | --to-tenant | Yes | Target tenant: a slug (resolved within --project) or a tenant ID (cross-project needs the ID) |
--slug | Yes | Application slug in target tenant | |
--project | No | Project slug used to resolve slugs (or --project-id) | |
--name | No | Application name (defaults to source name) | |
--version | No | Version (defaults to project.yaml version, then source version) | |
--update-version | No | Update project.yaml with the copied version (default: false) |
Examples
Basic copy (IDs):
pfy application copy \
--from-app aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee \
--to-tenant 44444444-5555-6666-7777-888888888888 \
--slug web-app-copyCopy by slugs within a project:
pfy application copy \
--project my-saas \
--from-app web-app \
--to-tenant customer-a \
--slug customer-portal \
--name "Customer Portal" \
--version 1.0.0application update-version
Update the version number of an existing application.
Usage
pfy application update-version --app <slug|id> --version <version> [--project <slug>]Flags
| Flag | Aliases | Required | Description |
|---|---|---|---|
--app | --app-id, --application-id | Yes | Application slug (resolved via --project), or an application ID |
--version | Yes | New version number | |
--project | No | Project slug for slug resolution (or --project-id) |
Example
pfy application update-version --app web-app --project my-saas --version 1.3.0application comms-config
Read or edit the communications config, the settings that decide whether notifications may leave the app as email, on one layer of the cascade. The layers are project, tenant, and app (the (tenant, application) join). A layer either holds an opinion for a field or leaves it unset, in which case the value falls through to the layer above. See Communications & notifications for the model.
Usage
pfy application comms-config get --app <slug> --tenant <slug> --project <project-slug> [--layer project|tenant|app]
pfy application comms-config set --app <slug> --tenant <slug> --project <project-slug> [--layer <layer>] <field flags>Target flags are the same as for enable/disable: --app (--app-id), --tenant, --tenant-id, --project. --layer defaults to app.
set writes only the flags you pass; every other field keeps whatever opinion (including none) the layer already had.
set flag | Type | Description |
|---|---|---|
--enabled | bool | Enable comms on this layer. --enabled=false records an explicit off; omitting it leaves the layer with no opinion |
--email-enabled | bool | Enable the out-of-app email channel on this layer |
--email-from | string | Sender address for out-of-app email |
--email-subject-prefix | string | Subject prefix for out-of-app email |
--email-layout-template | string | Layout template name for out-of-app email |
--digest-grace-minutes | int | Minutes the outbox worker waits before falling back to email |
set with none of these flags fails with nothing to set.
Examples
# What does the tenant layer say?
pfy application comms-config get --app web-app --tenant acme --project my-saas --layer tenant
# Turn email on for one tenant's enablement, with a sender address
pfy application comms-config set --app web-app --tenant acme --project my-saas \
--enabled --email-enabled --email-from noreply@acme.exampleget prints the stored values, naming the layer by its IDs:
Communications config for application <app-id> x tenant <tenant-id> (join <t2a-id>):
enabled: true
email.enabled: true
email.from: noreply@acme.example
email.subject_prefix: (unset)
email.layout_template: (unset)
digest: (unset)A layer with no stored config prints (unset — this layer has no opinion; the cascade falls through).
application promote (deprecated)
pfy application promote is a flagless stub that always refuses with an error directing you to the replacements. Under the project-level application model there is nothing to promote between tenants:
pfy application enable --app <id> --tenant-id <id>: enable an app for a tenantpfy application config-copy --from <t2a-id> --to <t2a-id>: copy per-tenant config
A script that calls promote (with or without flags) fails; point it at the commands above.
Workflow Example
Roll an application out to tenants
# 1. Create the application once, at the project level
pfy application create --project my-saas --slug web-app --name "Web Application" --version 1.0.0
# 2. Enable it for the tenants that should see it
pfy application enable --app web-app --tenant customer-a --project my-saas
pfy application enable --app web-app --tenant customer-b --project my-saas
# 3. Copy tuned per-tenant config from a reference tenant to a new one
pfy application list-tenants --app web-app --project my-saas
pfy application config-copy --from <t2a-of-customer-a> --to <t2a-of-customer-b>
# 4. Bump the application version after a release
pfy application update-version --app web-app --project my-saas --version 1.1.0GraphQL Operations
GetApplications
query GetApplications(
$projectSlug: String!
$filters: [FilterInput!]
$order: [OrderInput!]
$pagination: PaginationInput
) {
applications(
projectSlug: $projectSlug
filters: $filters
order: $order
pagination: $pagination
) {
id
slug
name
version
}
}CreateApplication
mutation CreateApplication($projectId: ID!, $input: CreateApplicationInput!) {
createApplication(projectId: $projectId, input: $input) {
id
slug
name
version
}
}Input Type:
input CreateApplicationInput {
slug: String!
name: String!
description: String
version: String
}CopyApplication
mutation CopyApplication($input: CopyApplicationInput!) {
copyApplication(input: $input) {
id
slug
name
version
}
}Input Type:
input CopyApplicationInput {
sourceApplicationId: ID!
targetTenantId: ID!
slug: String!
name: String
version: String
}UpdateApplicationVersion
Uses the existing UpdateApplication mutation:
mutation UpdateApplication($id: ID!, $input: UpdateApplicationInput!) {
updateApplication(id: $id, input: $input) {
id
slug
name
version
}
}