Skip to content

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 ​

bash
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 applications
  • create - Create a new application at the project level
  • get - Get an application's details by slug
  • update - Update an application's name, description, and/or version
  • delete - Delete an application (typed confirmation unless --yes)
  • enable / disable - Enable or disable an application for a tenant
  • list-tenants - List an application's tenant enablements (join rows)
  • config-copy - Copy per-(tenant, application) config between join rows
  • copy - Copy an application to another tenant
  • update-version - Update the version of an application
  • comms-config get / comms-config set - Read or edit the communications (notification) config of one cascade layer
  • promote - Deprecated stub; always refuses (see above)

application list ​

List all applications in a project.

Usage ​

bash
pfy application list --project <project-slug> [flags]

Flags ​

FlagRequiredDescription
--projectYesProject slug to list applications from
--limitNoMaximum number of items to return; if unset, every item is fetched
--offsetNoNumber of items to skip before returning results; defaults to the first item

Example ​

bash
pfy application list --project my-saas

Output:

Applications:
  - Web App (web-app) v1.2.3
  - Admin Portal (admin) v2.0.1
  - API Gateway (api) v1.0.0
3 applications

Verbose 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 ​

bash
pfy application create \
  --project <slug> \
  --slug <slug> \
  --name <name> \
  [--version <version>] \
  [--description <desc>]

Flags ​

FlagRequiredDescription
--projectNo*Project slug (resolved to an ID)
--project-idNo*Project ID (overrides --project)
--slugYesApplication slug (unique within the project)
--nameYesApplication display name
--versionNoInitial version (default: "0.1.0")
--descriptionNoApplication description

* One project selector is needed: --project, --project-id, or a project_id in project.yaml.

Examples ​

Basic creation:

bash
pfy application create \
  --project my-saas \
  --slug web-app \
  --name "Web Application"

With version and description:

bash
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.0

application get ​

Get an application's details, resolved by slug within a project.

Usage ​

bash
pfy application get <slug> --project <project-slug>

Flags ​

FlagRequiredDescription
--projectYesProject slug the application belongs to
--slugNoApplication 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 ​

bash
pfy application get web-app --project my-saas
Application: Web Application (web-app) v1.2.3
ID: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee

application update ​

Update an application's name, description, and/or version.

Usage ​

bash
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 ​

bash
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 ​

bash
pfy application delete <slug|id> [--project <slug>] [--yes]
FlagAliasesDescription
--projectProject slug (needed to resolve an application slug to its ID)
--yes-ySkip 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 ​

bash
pfy application enable --app <slug> --tenant <slug> --project <project-slug>
pfy application disable --app <id> --tenant-id <id>

Flags ​

FlagAliasesDescription
--app--app-idApplication slug (resolved via --project), or an application ID
--tenantTenant slug (requires --project to resolve)
--tenant-idTenant ID (alternative to --tenant + --project)
--projectProject slug (resolves --tenant and an --app slug to IDs)

Example ​

bash
pfy application enable --app web-app --tenant acme --project my-saas
Enabled 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 ​

bash
pfy application list-tenants --app <slug> --project <project-slug>
FlagAliasesDescription
--app--app-idApplication slug (resolved via --project), or an application ID
--projectProject slug (resolves an --app slug to its ID)

Example ​

bash
pfy application list-tenants --app web-app --project my-saas
Tenant enablements:
  - acme: join 99999999-aaaa-bbbb-cccc-dddddddddddd enabled=true forward_role=false
1 enablement

application config-copy ​

Copy the per-(tenant, application) configuration from one join row to another. This is how per-tenant config moves between tenants.

Usage ​

bash
pfy application config-copy --from <t2a-id> --to <t2a-id>
FlagDescription
--fromSource Tenant2Application join ID (discover with list-tenants)
--toTarget Tenant2Application join ID (discover with list-tenants)

Example ​

bash
pfy application config-copy \
  --from 99999999-aaaa-bbbb-cccc-dddddddddddd \
  --to   88888888-aaaa-bbbb-cccc-dddddddddddd

application 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 ​

bash
pfy application copy \
  --source-application-id <slug|id> \
  --target-tenant-id <slug|id> \
  --slug <slug> \
  [--project <slug>] \
  [--name <name>] \
  [--version <version>] \
  [--update-version]

Flags ​

FlagAliasesRequiredDescription
--source-application-id--from-appYesSource application: a slug (resolved within --project) or an application ID
--target-tenant-id--to-tenantYesTarget tenant: a slug (resolved within --project) or a tenant ID (cross-project needs the ID)
--slugYesApplication slug in target tenant
--projectNoProject slug used to resolve slugs (or --project-id)
--nameNoApplication name (defaults to source name)
--versionNoVersion (defaults to project.yaml version, then source version)
--update-versionNoUpdate project.yaml with the copied version (default: false)

Examples ​

Basic copy (IDs):

bash
pfy application copy \
  --from-app aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee \
  --to-tenant 44444444-5555-6666-7777-888888888888 \
  --slug web-app-copy

Copy by slugs within a project:

bash
pfy application copy \
  --project my-saas \
  --from-app web-app \
  --to-tenant customer-a \
  --slug customer-portal \
  --name "Customer Portal" \
  --version 1.0.0

application update-version ​

Update the version number of an existing application.

Usage ​

bash
pfy application update-version --app <slug|id> --version <version> [--project <slug>]

Flags ​

FlagAliasesRequiredDescription
--app--app-id, --application-idYesApplication slug (resolved via --project), or an application ID
--versionYesNew version number
--projectNoProject slug for slug resolution (or --project-id)

Example ​

bash
pfy application update-version --app web-app --project my-saas --version 1.3.0

application 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 ​

bash
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 flagTypeDescription
--enabledboolEnable comms on this layer. --enabled=false records an explicit off; omitting it leaves the layer with no opinion
--email-enabledboolEnable the out-of-app email channel on this layer
--email-fromstringSender address for out-of-app email
--email-subject-prefixstringSubject prefix for out-of-app email
--email-layout-templatestringLayout template name for out-of-app email
--digest-grace-minutesintMinutes the outbox worker waits before falling back to email

set with none of these flags fails with nothing to set.

Examples ​

bash
# 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.example

get 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 tenant
  • pfy 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 ​

bash
# 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.0

GraphQL Operations ​

GetApplications ​

graphql
query GetApplications(
  $projectSlug: String!
  $filters: [FilterInput!]
  $order: [OrderInput!]
  $pagination: PaginationInput
) {
  applications(
    projectSlug: $projectSlug
    filters: $filters
    order: $order
    pagination: $pagination
  ) {
    id
    slug
    name
    version
  }
}

CreateApplication ​

graphql
mutation CreateApplication($projectId: ID!, $input: CreateApplicationInput!) {
  createApplication(projectId: $projectId, input: $input) {
    id
    slug
    name
    version
  }
}

Input Type:

graphql
input CreateApplicationInput {
  slug: String!
  name: String!
  description: String
  version: String
}

CopyApplication ​

graphql
mutation CopyApplication($input: CopyApplicationInput!) {
  copyApplication(input: $input) {
    id
    slug
    name
    version
  }
}

Input Type:

graphql
input CopyApplicationInput {
  sourceApplicationId: ID!
  targetTenantId: ID!
  slug: String!
  name: String
  version: String
}

UpdateApplicationVersion ​

Uses the existing UpdateApplication mutation:

graphql
mutation UpdateApplication($id: ID!, $input: UpdateApplicationInput!) {
  updateApplication(id: $id, input: $input) {
    id
    slug
    name
    version
  }
}

See Also ​

  • project - Manage projects
  • tenant - Manage tenants
  • service - Manage an application's services
  • data - Manage an application's data stores
  • version - Manage project version
  • ci - CI/CD template generation