Manage installed features
Use the existing channel's feature store workflow for catalog inspection, confirmed zero-cost installation and explicit removal. Feature content/operation, visitor ACLs, default entry, channel creation and financial changes are separate tasks.
Read, plan and verify
- Use get to inspect the current plan, catalog, installed IDs, pricing, restrictions and revision. OWNER or a selected-channel DELEGATEE with
MANAGE_P_APP_INSTALL_UNINSTALLis required for the store tools. - For installation, choose one returned code and pricing model whose prerequisites and explicit zero fees are confirmed. For removal, select the exact installed ID/code and explain the irreversible impact. Use human handoff for financial changes.
- Submit a dry run with a stable request ID and the returned revision. Review the plan, then use the same business inputs with
dryRun:falsewithin the user's authorized task. - Interpret task phase, result code and verification together. Refresh current state through get after completion; a replayed result is historical.
Read a selected feature:
{"channelCode":"selected-channel-code","pAppCode":"A00003"}
Plan installation using the returned pricing ID and full-snapshot revision:
{"requestId":"feature-workflow-example-001","channelCode":"selected-channel-code","expectedRevision":"0000000000000000000000000000000000000000000000000000000000000000","pAppCode":"A00003","ppmid":"pricing-model-from-get","dryRun":true}
These values are placeholders, not evidence that a feature is available or free. Install and remove document the full input contracts.
Costs and prerequisites
Direct installation requires all three installation, monthly-base and pay-as-you-go prices to have the channel currency and an amount string matching the runtime regex /^0+(?:\.0+)?$/, such as 0, 00 or 0.00. KRW uses the local fee fields; USD uses the corresponding Global fields. Missing/null amounts, currency mismatch, negative/signed/exponent forms and nonzero values are not confirmed zero. No trimming, numeric coercion or FREE-label inference is used. Pricing must also match the selected code, ppmid and current plan's class prefix.
Catalog visibility and release are separate. Hidden or unreleased features, existing installations and missing prerequisite features block new installation. C00013/X00005 require a separate account allowlist check in the console. FREE_TRIAL blocks F00001 and 3RD_*; 3RD_A00001/3RD_A00002 also need BUSINESS account type, with null treated as unknown. Returned installBlock explains the current reason. Parents are never silently installed.
Removal blocks defaults and protected system/commerce/extension codes, unreleased entries and unresolved catalog policy. Existing extension or multi-instance children must be handled separately. The workflow never cascades a deletion. Current removeBlock and detail readback are authoritative for the observed target; a catalog search result alone is insufficient.
The catalog may contain explicit triple-null placeholders. The adapter omits them from selectable metadata and reports their codes, while still rejecting malformed present metadata and duplicate identifiers. allRowsUsable:false is a disclosure of omissions, not permission to guess eligibility or price. A null installed alias remains null.
Recover the original task
{"taskId":"feature-workflow-example-001","taskType":"papp-lifecycle"}
Use that input with status, then resume when continuing the same authorized operation is appropriate. Status reports saved phase, last result and pending refresh, checking connection identity; it does not read current business state or perform the remaining work.
| Phase or condition | Implemented behavior |
|---|---|
| Fresh dry run | Validate current revision/policy; no new job, install/delete or refresh |
| Existing matching dry run | Return saved phase/task identity; no fresh catalog/eligibility comparison |
prepared |
Recheck original snapshot, policy and removal detail where applicable; may send the original request |
| Definite install/delete rejection | Return the original job to prepared, retaining its original input; later continuation rechecks before another dispatch |
sent with unknown outcome |
Never resend installation/deletion. Resume may still perform a not-yet-sent refresh before verifying the installed list and detail |
| Sent refresh with unchanged credential version | Return CHANNEL_REFRESH_OUTCOME_UNKNOWN; trusted connection recovery is required before continuing |
verified |
Recheck the final installed state and its snapshot checkpoint before completion |
done |
Return the stored completion; get supplies a new observation |
This workflow's definite-rejection rule differs from the display writer's never-resend-after-dispatch policy. Same-ID apply must retain the original expected revision, code, pricing/installed ID and confirmation; changing them yields TASK_CONTEXT_CHANGED. Do not generate another request ID to bypass uncertainty. No automatic rollback, recovery of deleted feature data or atomic server compare-and-swap is provided.
Completion preserves unrelated installed entries and the original plan, currency and account type. Install requires exactly one new matching instance with the selected active current pricing and no scheduled next plan; removal requires exact target absence in list and detail. The final full snapshots must be stable. This is stored-state verification, not visitor use, feature-content validation or financial completion.
Saved record identity
Stored task IDs must match the requested lookup key. An intact task copied under
a different key, or a present JSON null/false/zero/empty-string record, returns
TASK_STATE_UNVERIFIED before context/business calls. Preserve both the original
record and the requested file for inspection; do not replace or delete them to
bypass uncertainty. Only an actually absent file means no task.
An existing matching dry-run returns its saved plan with historical:true,
replayed:true, and verification.currentStateVerified:false. It does not recheck
current install/removal eligibility. Follow nextStep to papps_get for the exact
original channel and feature before planning further changes. The journal is
unchanged and no installation, removal or credential refresh is sent by this plan.
Saved record consistency
Before using an existing task, the workflow checks its original input fingerprint,
before-state revision, allowed progress/refresh/checkpoint combinations and any
stored completion. A completed result must match the original channel, feature,
task, pricing/removed target and preserved installed rows. Inconsistency returns
TASK_STATE_UNVERIFIED before context/business calls and leaves the record intact.
Preserve it for inspection rather than repairing fields or starting replacement
work. This validates consistency, not cryptographic authenticity or current server
state. Historical completion still requires a fresh get for current values.
Detail pricing evidence
An installed-list row may omit pricing or contain null while the detail response confirms valid active pricing. Those list values remain unchanged. New tasks keep a separate internal detail-verification receipt and require it for completed installation recovery. The receipt binds the observed installed ID, feature code, requested active price and absence of a scheduled next price. Legacy histories without that receipt retain their existing verified-method metadata and target/ preservation checks; no receipt or list pricing is invented. Historical replay is not a current detail read. Invalid detail identity/pricing cannot confirm a new installation, and uncertain effects are never resent.
Installed-feature availability
Installation enables the feature; there is no separate activation/deactivation
step. Raw isActive is a legacy observed value and must not be interpreted as an
activation prerequisite. Use design_access_get and design_access_apply for
supported visitor-access restrictions, and retain their paid-access limitations.
Uninstall destroys data and is not a substitute for restricting access. Catalog
publication, product availability, pricing and notification switches remain
separate settings.