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
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
339 lines
12 KiB
JSON
339 lines
12 KiB
JSON
[
|
|
{
|
|
"id": "F001",
|
|
"description": "Register `contacts.create` as a Contact-group workflow action with label, description, category, side-effect metadata, idempotency metadata, input schema, and output schema",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Create contact",
|
|
"UX / UI Notes"
|
|
]
|
|
},
|
|
{
|
|
"id": "F002",
|
|
"description": "Implement `contacts.create` using existing contact validation for full name, primary email, client existence, phone numbers, primary email type, and additional email addresses",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Create contact",
|
|
"Data / API / Integrations"
|
|
]
|
|
},
|
|
{
|
|
"id": "F003",
|
|
"description": "Return a compact normalized created-contact output from `contacts.create` for downstream workflow mappings",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Shared contact output shape",
|
|
"Create contact"
|
|
]
|
|
},
|
|
{
|
|
"id": "F004",
|
|
"description": "Register `contacts.update` as a Contact-group workflow action with a typed patch schema for editable contact fields",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Edit contact",
|
|
"UX / UI Notes"
|
|
]
|
|
},
|
|
{
|
|
"id": "F005",
|
|
"description": "Implement `contacts.update` patch semantics so omitted fields remain unchanged and existing primary-email promotion rules are preserved",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Edit contact"
|
|
]
|
|
},
|
|
{
|
|
"id": "F006",
|
|
"description": "Return before/after contact summaries and updated field names from `contacts.update`",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Edit contact",
|
|
"Shared contact output shape"
|
|
]
|
|
},
|
|
{
|
|
"id": "F007",
|
|
"description": "Register `contacts.delete` as a destructive Contact-group workflow action with guarded hard-delete label, `confirm: true`, `on_not_found`, schema, and output",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Delete contact"
|
|
]
|
|
},
|
|
{
|
|
"id": "F008",
|
|
"description": "Implement `contacts.delete` as tenant-scoped guarded hard delete with dependency blocking and owned-child cleanup consistent with existing contact delete behavior",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Delete contact",
|
|
"Data / API / Integrations"
|
|
]
|
|
},
|
|
{
|
|
"id": "F009",
|
|
"description": "Return deterministic hard-delete status output from `contacts.delete`, including dependency conflict details and return-false behavior for missing contacts when requested",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Delete contact"
|
|
]
|
|
},
|
|
{
|
|
"id": "F010",
|
|
"description": "Register `contacts.duplicate` as a Contact-group workflow action with source contact picker, required new unique email override, optional field overrides, copy-tags option, and action-provided idempotency key",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Duplicate contact",
|
|
"Resolved Decisions"
|
|
]
|
|
},
|
|
{
|
|
"id": "F011",
|
|
"description": "Implement `contacts.duplicate` by loading the source contact, applying overrides, validating uniqueness, excluding historical relationship copies, and creating a new contact in the target or source client",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Duplicate contact"
|
|
]
|
|
},
|
|
{
|
|
"id": "F012",
|
|
"description": "Implement optional tag-copy behavior for `contacts.duplicate` using the canonical contact tag mapping storage",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Duplicate contact",
|
|
"Add tag to contact",
|
|
"Known schema considerations"
|
|
]
|
|
},
|
|
{
|
|
"id": "F013",
|
|
"description": "Register `contacts.add_tag` as a Contact-group workflow action with contact picker, one-or-more tag text inputs, action-provided idempotency key, and added/existing tag output schema",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Add tag to contact"
|
|
]
|
|
},
|
|
{
|
|
"id": "F014",
|
|
"description": "Implement `contacts.add_tag` with idempotent tag definition resolution and tag mapping creation for `tagged_type = contact`, returning existing mappings without duplicate insert error control flow",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Add tag to contact",
|
|
"Known schema considerations"
|
|
]
|
|
},
|
|
{
|
|
"id": "F015",
|
|
"description": "Use the same tag permission policy as `clients.add_tag`: `contacts.add_tag` requires `contact:update` and may create missing contact tag definitions without a separate stricter tag-create gate",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Security / Permissions",
|
|
"Resolved Decisions"
|
|
]
|
|
},
|
|
{
|
|
"id": "F016",
|
|
"description": "Register `contacts.assign_to_ticket` as a Contact-group workflow action with contact and ticket picker-backed inputs",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Assign contact to ticket",
|
|
"UX / UI Notes"
|
|
]
|
|
},
|
|
{
|
|
"id": "F017",
|
|
"description": "Implement `contacts.assign_to_ticket` as a direct ticket contact update that validates tenant-scoped ticket/contact existence, validates contact-client relationship, and returns previous/current contact IDs",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Assign contact to ticket"
|
|
]
|
|
},
|
|
{
|
|
"id": "F018",
|
|
"description": "Implement the resolved no-client-ticket policy for `contacts.assign_to_ticket`: only set `tickets.contact_name_id` unless the existing application action path is found to set `tickets.client_id` too",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Assign contact to ticket",
|
|
"Resolved Decisions"
|
|
]
|
|
},
|
|
{
|
|
"id": "F019",
|
|
"description": "Register `contacts.add_note` as a Contact-group workflow action for document-backed contact note appends with action-provided idempotency key",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Add note to contact"
|
|
]
|
|
},
|
|
{
|
|
"id": "F020",
|
|
"description": "Implement `contacts.add_note` by appending to the contact notes document (`contacts.notes_document_id`), creating and linking the document when missing, and returning document metadata",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Add note to contact",
|
|
"Data / API / Integrations"
|
|
]
|
|
},
|
|
{
|
|
"id": "F021",
|
|
"description": "Register `contacts.add_interaction` as a Contact-group workflow action with contact, optional ticket, interaction type/status, timing, title, notes, and action-provided idempotency fields",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Add interaction to contact",
|
|
"UX / UI Notes"
|
|
]
|
|
},
|
|
{
|
|
"id": "F022",
|
|
"description": "Implement `contacts.add_interaction` using the contact-derived client ID, workflow actor as `user_id`, default interaction status fallback, and relationship validation consistent with `clients.add_interaction`",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Add interaction to contact",
|
|
"Data / API / Integrations"
|
|
]
|
|
},
|
|
{
|
|
"id": "F023",
|
|
"description": "Register `contacts.add_to_client` as a Contact-group workflow action with contact and client picker-backed inputs",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Add contact to client"
|
|
]
|
|
},
|
|
{
|
|
"id": "F024",
|
|
"description": "Implement `contacts.add_to_client` to assign only unassigned contacts, no-op when already assigned to the target client, and conflict when assigned elsewhere",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Add contact to client"
|
|
]
|
|
},
|
|
{
|
|
"id": "F025",
|
|
"description": "Register `contacts.move_to_client` as a Contact-group workflow action with target client picker and optional expected-current-client guard",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Move contact to different client"
|
|
]
|
|
},
|
|
{
|
|
"id": "F026",
|
|
"description": "Implement `contacts.move_to_client` to validate target client, move contact client_id, distinguish no-op/conflict/success, and return previous/current client IDs",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Move contact to different client"
|
|
]
|
|
},
|
|
{
|
|
"id": "F027",
|
|
"description": "Add or reuse workflow JSON schema metadata helpers so contact, client, ticket, and user-facing picker hints survive designer schema serialization; use UUID fields for interaction type/status until picker support exists",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"UX / UI Notes"
|
|
]
|
|
},
|
|
{
|
|
"id": "F028",
|
|
"description": "Create shared contact action schemas/helpers for UUIDs, contact summary output, phone number input, additional email input, and standard action result fields",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Shared contact output shape",
|
|
"Technical design"
|
|
]
|
|
},
|
|
{
|
|
"id": "F029",
|
|
"description": "Create shared contact action helpers for loading tenant-scoped contacts/clients/tickets and throwing standard workflow not-found/validation/conflict errors",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Non-functional Requirements",
|
|
"Data / API / Integrations"
|
|
]
|
|
},
|
|
{
|
|
"id": "F030",
|
|
"description": "Ensure every new side-effectful contact action runs through `withTenantTransaction` and uses tenant filters on all selects, inserts, updates, and deletes",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Non-functional Requirements"
|
|
]
|
|
},
|
|
{
|
|
"id": "F031",
|
|
"description": "Ensure every new side-effectful contact action checks the confirmed actor permissions using `requirePermission` before mutation",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Security / Permissions"
|
|
]
|
|
},
|
|
{
|
|
"id": "F032",
|
|
"description": "Ensure every new side-effectful contact action writes a workflow run audit record with action id, version, affected entity IDs, and meaningful changed data",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Non-functional Requirements"
|
|
]
|
|
},
|
|
{
|
|
"id": "F033",
|
|
"description": "Map model/database errors from new contact actions into standard workflow action error categories and codes",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Non-functional Requirements"
|
|
]
|
|
},
|
|
{
|
|
"id": "F034",
|
|
"description": "Update workflow designer catalog expectations so the Contact group includes all new `contacts.*` actions without disturbing existing built-in group ordering",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Acceptance Criteria",
|
|
"UX / UI Notes"
|
|
]
|
|
},
|
|
{
|
|
"id": "F035",
|
|
"description": "Encode resolved product decisions for required duplicate email override, ticket contact-only assignment behavior, client-parity tag creation policy, and contact domain-event publication parity",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Resolved Decisions"
|
|
]
|
|
},
|
|
{
|
|
"id": "F036",
|
|
"description": "Register `contacts.deactivate` as a separate Contact-group workflow action with safe deactivation label, description, schema, and output",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Deactivate contact",
|
|
"UX / UI Notes"
|
|
]
|
|
},
|
|
{
|
|
"id": "F037",
|
|
"description": "Implement `contacts.deactivate` to set `is_inactive = true`, require `contact:update`, preserve tenant scoping, no-op when already inactive, and use engine-provided idempotency",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Deactivate contact",
|
|
"Security / Permissions"
|
|
]
|
|
},
|
|
{
|
|
"id": "F038",
|
|
"description": "Return previous/current inactive state, `deactivated`, `noop`, and compact contact summary from `contacts.deactivate`",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Deactivate contact",
|
|
"Shared contact output shape"
|
|
]
|
|
},
|
|
{
|
|
"id": "F039",
|
|
"description": "Mirror the new client action runtime conventions for contact actions: action-provided idempotency for create/duplicate/add_tag/add_note/add_interaction, engine-provided idempotency for update/deactivate/delete/assignment, and best-effort lazy domain-event publication for contact create/update/deactivate plus existing note/interaction events",
|
|
"implemented": true,
|
|
"prdRefs": [
|
|
"Non-functional Requirements",
|
|
"Data / API / Integrations",
|
|
"Resolved Decisions"
|
|
]
|
|
}
|
|
]
|