Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

288 lines
11 KiB
JSON

[
{
"id": "F001",
"description": "Availability resolver registry in shared/workflow/runtime/registries (sibling of integrationModuleRegistry.ts): resolver type (knex, tenantId) => Promise<boolean>, registerWorkflowModuleAvailabilityResolver(key, resolver), lookup by availabilityKey; duplicate-key registration guarded.",
"implemented": true,
"prdRefs": [
"5.1"
]
},
{
"id": "F002",
"description": "loadAvailableFirstPartyIntegrationAppKeys (ee/packages/workflows/src/actions/workflow-runtime-v2-actions.ts) delegates to the resolver registry; hardcoded 'rmm:ninjaone' branch removed; missing resolver => unavailable (fail closed); resolver exceptions caught and treated as unavailable so catalog listing never throws.",
"implemented": true,
"prdRefs": [
"5.1",
"5.3"
]
},
{
"id": "F003",
"description": "rmmIntegrationAvailability(provider) resolver factory: rmm_integrations row for (tenant, provider) with is_active = true and connected_at IS NOT NULL.",
"implemented": true,
"prdRefs": [
"5.2"
]
},
{
"id": "F004",
"description": "registerIntegrationWorkflowModule({ module, availability, registerActions }) helper in ee/packages/workflows: registers actions, module tile, and availability resolver in one idempotent call (re-invocation does not duplicate module or actions).",
"implemented": true,
"prdRefs": [
"5.3"
]
},
{
"id": "F005",
"description": "NinjaOne migrated onto registerIntegrationWorkflowModule + rmmIntegrationAvailability('ninjaone'); module registration removed from core.ts inline block; palette/catalog output identical before and after for connected and disconnected tenants.",
"implemented": true,
"prdRefs": [
"5.3"
]
},
{
"id": "F006",
"description": "FetchNinjaOneWorkflowClient gains runScript (POST /v2/device/{id}/script/run with type SCRIPT|ACTION, script id/uid, parameters, runAs) and scripting-options discovery (verify exact path, expected GET /v2/device/{id}/scripting/options).",
"implemented": true,
"prdRefs": [
"6.1"
]
},
{
"id": "F007",
"description": "Action ninjaone.devices.run_script (sideEffectful) and ninjaone.devices.scripting_options (read); both added to app:ninjaone allowedActionIds.",
"implemented": true,
"prdRefs": [
"6.1"
]
},
{
"id": "F008",
"description": "Tactical client wrappers (getAgent, listScripts, runScript, runCommand, reboot) implemented in a self-contained FetchTacticalWorkflowClient inside ee/packages/workflows (api_key + Knox auth with 401 refresh + token persistence, beta pagination). DEVIATION from plan: workflows dist marks @alga-psa/* external and packages/integrations' runtime subpath maps to TS source, so the shared TacticalRmmClient is not importable at runtime \u2014 NinjaOne-style thin client instead.",
"implemented": true,
"prdRefs": [
"6.2"
]
},
{
"id": "F009",
"description": "Tactical runtime support resolves rmm_integrations row (instance_url, settings.auth_mode) via ctx.knex and tenant secrets (tacticalrmm_api_key or tacticalrmm_username/password/knox_token) matching the sync path's auth modes. No workspace dependency added (see F008 deviation).",
"implemented": true,
"prdRefs": [
"6.2"
]
},
{
"id": "F010",
"description": "Actions tacticalrmm.agents.find and tacticalrmm.agents.get (reads over /api/beta/v1/agent/ and agent detail).",
"implemented": true,
"prdRefs": [
"6.2"
]
},
{
"id": "F011",
"description": "Action tacticalrmm.scripts.list (read; script id + name + shell so run_script inputs are discoverable).",
"implemented": true,
"prdRefs": [
"6.2"
]
},
{
"id": "F012",
"description": "Actions tacticalrmm.agents.run_script (returns script output), tacticalrmm.agents.run_command, tacticalrmm.agents.reboot (all sideEffectful).",
"implemented": true,
"prdRefs": [
"6.2"
]
},
{
"id": "F013",
"description": "Module registration app:tacticalrmm via registerIntegrationWorkflowModule (label, icon token, default action tacticalrmm.agents.find, availability rmmIntegrationAvailability('tacticalrmm')).",
"implemented": true,
"prdRefs": [
"6.2",
"5.3"
]
},
{
"id": "F014",
"description": "Thin Level fetch client in ee/packages/workflows (tenant secret levelio_api_key, instance/base URL convention, cursor pagination) \u2014 ee/server client not importable across package boundary.",
"implemented": true,
"prdRefs": [
"6.3"
]
},
{
"id": "F015",
"description": "Actions levelio.devices.find (group filters), levelio.devices.get, levelio.alerts.list_active, levelio.updates.list (reads).",
"implemented": true,
"prdRefs": [
"6.3"
]
},
{
"id": "F016",
"description": "Action levelio.alerts.resolve (sideEffectful; POST /v2/alerts/{id}/resolve).",
"implemented": true,
"prdRefs": [
"6.3"
]
},
{
"id": "F017",
"description": "Actions levelio.automations.list (automations + webhook tokens for discovery) and levelio.automations.run_status (read).",
"implemented": true,
"prdRefs": [
"6.3"
]
},
{
"id": "F018",
"description": "Action levelio.automations.trigger (sideEffectful; POST /v2/automations/webhooks/{token} with optional device_ids[]; actionable error when the automation has no webhook trigger configured in Level).",
"implemented": true,
"prdRefs": [
"6.3"
]
},
{
"id": "F019",
"description": "Module registration app:levelio via registerIntegrationWorkflowModule (availability rmmIntegrationAvailability('levelio')).",
"implemented": true,
"prdRefs": [
"6.3",
"5.3"
]
},
{
"id": "F020",
"description": "Thin Huntress fetch client in ee/packages/workflows: Basic auth from tenant secrets huntress_api_key/huntress_api_secret, 60 req/min throttle with min-interval spacing and 429 backoff replicated from ee/server client.",
"implemented": true,
"prdRefs": [
"6.4"
]
},
{
"id": "F021",
"description": "Actions huntress.incidents.find (status/severity/org filters), huntress.incidents.get, huntress.organizations.list, huntress.agents.get, huntress.account.get (reads).",
"implemented": true,
"prdRefs": [
"6.4"
]
},
{
"id": "F022",
"description": "Action huntress.incidents.resolve (sideEffectful; Huntress write API for resolving incident reports \u2014 verify exact endpoint/payload against api.huntress.io docs).",
"implemented": true,
"prdRefs": [
"6.4"
]
},
{
"id": "F023",
"description": "Module registration app:huntress via registerIntegrationWorkflowModule (availability rmmIntegrationAvailability('huntress')).",
"implemented": true,
"prdRefs": [
"6.4",
"5.3"
]
},
{
"id": "F024",
"description": "Teams availability resolver: teams_integrations.install_status = 'active' AND Teams add-on active for tenant (mirrors delivery-path checks).",
"implemented": true,
"prdRefs": [
"6.5",
"5.1"
]
},
{
"id": "F025",
"description": "teams.notify_user implemented with self-contained Graph support in ee/packages/workflows (the ee-microsoft-teams package depends on @alga-psa/workflows \u2014 circular \u2014 and is source-mapped): Graph app token per selected microsoft_profile, sendActivityNotification with category->activityType mapping (manifest-declared types), generic entity deep link; actionable error when the user lacks a linked Microsoft account (user_auth_accounts provider=microsoft).",
"implemented": true,
"prdRefs": [
"6.5"
]
},
{
"id": "F026",
"description": "Action teams.send_dm: proactive Bot Framework message (text + optional card) using stored teams_conversation_references; actionable error if the user has never opened the bot.",
"implemented": true,
"prdRefs": [
"6.5"
]
},
{
"id": "F027",
"description": "createConversation support implemented in ee/packages/workflows teamsWorkflowRuntimeSupport (not ee/packages/microsoft-teams \u2014 circular dependency): proactive channel conversation via Bot Framework POST /v3/conversations with trusted-serviceUrl guard and cached bot token from TEAMS_BOT_APP_* env.",
"implemented": true,
"prdRefs": [
"6.5"
]
},
{
"id": "F028",
"description": "Action teams.post_to_channel built on createConversation; actionable error when the app is not installed in the target team.",
"implemented": true,
"prdRefs": [
"6.5"
]
},
{
"id": "F029",
"description": "Module registration app:teams via registerIntegrationWorkflowModule with the Teams availability resolver.",
"implemented": true,
"prdRefs": [
"6.5",
"5.3"
]
},
{
"id": "F030",
"description": "Shared core action scheduling.create_entry (CE+EE, scheduling.* family): assigned user(s), title, start/end, optional ticket/project link, optional status/notes; creates dispatch-board entry via the same model layer the UI uses; entry rides existing outbound calendar sync; explicit validation errors (unknown user, end before start).",
"implemented": true,
"prdRefs": [
"7"
]
},
{
"id": "F031",
"description": "Designer icon tokens for tacticalrmm, levelio, huntress, teams (reusing settings-UI integration logos); palette grouping verified for the new app:* groups, extending category ordering only if required.",
"implemented": true,
"prdRefs": [
"8"
]
},
{
"id": "F032",
"description": "Error-handling conventions applied across all new actions: vendor HTTP errors surface status + vendor message without credentials; integration-not-connected and the named Teams/Level failure modes produce explicit actionable messages.",
"implemented": true,
"prdRefs": [
"9"
]
},
{
"id": "F033",
"description": "WorkflowDesignerCatalogRecord gains optional available flag; listWorkflowDesignerActionCatalogAction keeps first-party integration records when disconnected and annotates available=true/false instead of filtering them out (extension-app filtering unchanged).",
"implemented": true,
"prdRefs": [
"11"
]
},
{
"id": "F034",
"description": "Designer palette excludes catalog records with available === false client-side, preserving the hide-when-not-enabled palette decision.",
"implemented": true,
"prdRefs": [
"11"
]
},
{
"id": "F035",
"description": "Editor disconnected state for existing steps: GroupedActionConfigSection renders an amber '{group} is not connected' banner when record.available === false (action select stays usable), and the step card shows a Disconnected badge with explanatory tooltip; config panel now renders for steps of disconnected integrations instead of silently dropping the group section.",
"implemented": true,
"prdRefs": [
"11"
]
}
]