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

316 lines
12 KiB
JSON

[
{
"id": "T001",
"description": "Migration smoke: all seven new tables exist after migrate with composite (tenant, id) PKs, FKs, defaults (is_required true, completed false, source 'manual'), and RLS policies; migrate:down removes them cleanly.",
"implemented": true,
"featureIds": [
"F001",
"F002",
"F003",
"F004",
"F005",
"F006"
]
},
{
"id": "T002",
"description": "Migration: permissions table gains { resource 'ticket', action 'close_override' } per tenant and role_permissions grants it to Admin (verified against a freshly migrated database; the migration itself uses get-or-insert idempotency).",
"implemented": true,
"featureIds": [
"F007"
]
},
{
"id": "T003",
"description": "Migration: notification_subtypes contains the auto-close-warning subtype under the Tickets category and system_email_templates has a matching row whose name equals the string used by the warn phase.",
"implemented": true,
"featureIds": [
"F008",
"F032"
]
},
{
"id": "T004",
"description": "Unit: getBoardCloseRules returns all-gates-off defaults when no row exists; upsertBoardCloseRules persists and round-trips config; required_fields outside the allowed set is rejected.",
"implemented": true,
"featureIds": [
"F009"
]
},
{
"id": "T005",
"description": "Unit: auto-close rule actions reject close_to_status_id that is not is_closed, trigger_status_id that is closed, warning_days_before >= inactivity_days, and a duplicate (board_id, trigger_status_id) pair.",
"implemented": true,
"featureIds": [
"F010"
]
},
{
"id": "T006",
"description": "Unit: validateTicketClosure returns allowed=true when the board has no board_close_rules row and when is_enabled=false, without running any gate queries.",
"implemented": true,
"featureIds": [
"F021"
]
},
{
"id": "T007",
"description": "Unit: resolution-comment gate fails with no qualifying comment; passes with a comments.is_resolution=true row; passes with metadata closes_ticket=true; ignores comments on other tickets/tenants.",
"implemented": true,
"featureIds": [
"F021"
]
},
{
"id": "T008",
"description": "Unit: time-entry gate fails with zero time entries; passes with one time_entries row (work_item_type 'ticket'); ignores time entries with other work_item_types or other tickets.",
"implemented": true,
"featureIds": [
"F021"
]
},
{
"id": "T009",
"description": "Unit: checklist gate fails while any is_required item is incomplete; passes when all required items are complete even if optional items remain unchecked; passes on a ticket with no checklist items.",
"implemented": true,
"featureIds": [
"F021"
]
},
{
"id": "T010",
"description": "Unit: open-children gate fails when a child ticket (master_ticket_id set) has closed_at IS NULL; passes once all children are closed; passes for non-master tickets.",
"implemented": true,
"featureIds": [
"F021"
]
},
{
"id": "T011",
"description": "Unit: required-fields gate fails listing each null configured field (e.g. category_id, assigned_to) in failures meta; passes when all configured fields are set; unconfigured fields are ignored.",
"implemented": true,
"featureIds": [
"F021"
]
},
{
"id": "T012",
"description": "Unit: multiple failing gates produce one failure entry per gate in a single result (not first-failure-only).",
"implemented": true,
"featureIds": [
"F021"
]
},
{
"id": "T013",
"description": "Unit: override with ticket:close_override permission yields allowed=true and a CLOSE_RULES_OVERRIDDEN audit write including the failure list and reason; override without the permission is refused (still blocked).",
"implemented": true,
"featureIds": [
"F022"
]
},
{
"id": "T014",
"description": "Unit: bypass skips gate evaluation and writes CLOSE_RULES_BYPASSED with the source only when the board has enabled gates; no audit noise on ungated boards.",
"implemented": true,
"featureIds": [
"F022"
]
},
{
"id": "T015",
"description": "Integration: updateTicket to a closed status on a gated board throws TicketCloseValidationError with the ticket row untouched, and the same action with overrideCloseRules (permission granted) closes the ticket and writes the override audit with the reason.",
"implemented": true,
"featureIds": [
"F023"
]
},
{
"id": "T016",
"description": "Integration: updateTicket close succeeds once all gates pass — closure fields set, TICKET_CLOSED published, audit row written (regression: identical to pre-feature behavior on ungated boards).",
"implemented": true,
"featureIds": [
"F023"
]
},
{
"id": "T017",
"description": "Integration: updateTicketInTransaction blocks a gated close — transaction aborts, status/is_closed/closed_at/closed_by untouched, no TICKET_CLOSED published — and closes normally once gates pass (covers TicketDetails/board-view/bulk callers).",
"implemented": true,
"featureIds": [
"F024"
]
},
{
"id": "T018",
"description": "Integration: bulkUpdateTicketStatus to a closed status with a mix of passing and failing tickets closes the passing ones and returns per-ticket results with failures for the blocked ones; no batch-wide abort.",
"implemented": true,
"featureIds": [
"F024",
"F028"
]
},
{
"id": "T019",
"description": "Integration: checkTicketClosure (the UI pre-close check the API enforcement shares its evaluator with) returns wouldClose/structured failures/canOverride keyed to the close_override permission; non-closing status changes are always allowed. HTTP-level 422 shape is exercised in the manual smoke pass.",
"implemented": true,
"featureIds": [
"F025"
]
},
{
"id": "T020",
"description": "Integration: exempt sources bypass gates through enforceTicketCloseRules/auditCloseRulesBypassIfGated with a CLOSE_RULES_BYPASSED audit row carrying the source; the workflow tickets.close and CSV import paths call this same helper (wiring verified by type-check and review; end-to-end by smoke).",
"implemented": true,
"featureIds": [
"F026"
]
},
{
"id": "T021",
"description": "Integration: portal updateTicketStatus to a closed status sets is_closed/closed_at/closed_by (portal user id), publishes TICKET_CLOSED, and is never gate-blocked; moving back to open clears the closure fields. Regression: closure emails/SLA recording fire for portal closes.",
"implemented": true,
"featureIds": [
"F029"
]
},
{
"id": "T022",
"description": "Integration: checklist item lifecycle — add, edit, reorder, delete via ticketChecklistActions; ordering persists; tenant isolation enforced (cannot touch another tenant's items).",
"implemented": true,
"featureIds": [
"F013"
]
},
{
"id": "T023",
"description": "Integration: setChecklistItemCompleted(true) stamps completed_by = acting user and completed_at; (false) clears both; each transition writes the matching CHECKLIST_ITEM_* audit row, with the uncheck row preserving the prior signoff in details.",
"implemented": true,
"featureIds": [
"F013",
"F016"
]
},
{
"id": "T024",
"description": "Integration: applyChecklistTemplateToTicket copies items with order, is_required, source and template_id provenance; calling it again for the same template is a no-op (idempotent); two different templates stack their items.",
"implemented": true,
"featureIds": [
"F015"
]
},
{
"id": "T025",
"description": "Integration: template edits after application do not alter items already copied onto tickets.",
"implemented": true,
"featureIds": [
"F015",
"F014"
]
},
{
"id": "T026",
"description": "Integration: auto-apply on ticket creation — a rule matching the new ticket's board/category attaches the template; null matcher fields match any; non-matching rules don't fire; disabled rules don't fire.",
"implemented": true,
"featureIds": [
"F017"
]
},
{
"id": "T027",
"description": "Integration: auto-apply on board/category change — moving a ticket into a matching board/category attaches the template once; moving it back and forth does not duplicate items.",
"implemented": true,
"featureIds": [
"F017"
]
},
{
"id": "T028",
"description": "Integration: workflow-sourced checklist application (applyChecklistTemplateToTicket with source 'workflow', the helper the tickets.apply_checklist action delegates to) applies idempotently and stamps workflow provenance on the items.",
"implemented": true,
"featureIds": [
"F030"
]
},
{
"id": "T029",
"description": "Integration: template/apply-rule/item CRUD actions reject callers without settings-admin permission; checklist item actions reject callers without ticket update permission.",
"implemented": true,
"featureIds": [
"F013",
"F014"
]
},
{
"id": "T030",
"description": "Integration (scan match): a ticket in a rule's trigger status with stale activity gets a ticket_auto_close_state row with scheduled_close_at = last_activity + inactivity_days; new activity (comment) on the next run recomputes/clears the row; status change away from the trigger status clears it; disabling the rule clears it.",
"implemented": true,
"featureIds": [
"F031"
]
},
{
"id": "T031",
"description": "Integration (scan warn): warning sent exactly once when inside the window — notification service called with the ticket-auto-close-warning template, warning_sent_at stamped, AUTO_CLOSE_WARNING_SENT audit row — not resent on subsequent runs, and not sent at all when warning_days_before is null. Tenant/subtype gating lives inside the shared notification service.",
"implemented": true,
"featureIds": [
"F032"
]
},
{
"id": "T032",
"description": "Integration (scan close): a due ticket — on a board with enabled close gates it cannot satisfy — closes to close_to_status_id with is_closed/closed_at set, closed_by null, system-attributed CLOSED audit row, automatic comment (metadata.source=auto_close), CLOSE_RULES_BYPASSED (source 'auto_close') audit entry, and TICKET_CLOSED published with a SYSTEM actor and no closedByUserId.",
"implemented": true,
"featureIds": [
"F033",
"F022"
]
},
{
"id": "T033",
"description": "Integration (scan race): activity recorded between the match snapshot and the close phase prevents the close (in-transaction revalidation); re-running the scan after a completed close is a no-op (idempotent).",
"implemented": true,
"featureIds": [
"F033"
]
},
{
"id": "T035",
"description": "Integration (scan resilience): a ticket that throws during the close phase (e.g. deleted target status) is skipped with the error recorded, and the remaining due tickets in the same run still close.",
"implemented": true,
"featureIds": [
"F031",
"F033"
]
},
{
"id": "T037",
"description": "Integration: tenant isolation across the scan — tenant A's rules never match tenant B's tickets, and state/warning/close writes stay within the rule's tenant.",
"implemented": true,
"featureIds": [
"F031",
"F033"
]
},
{
"id": "T046",
"description": "Regression: closing a ticket on a board with no close rules behaves byte-for-byte as before (no validation queries in the hot path beyond the single board_close_rules lookup, no new audit entries, identical events).",
"implemented": true,
"featureIds": [
"F021",
"F023",
"F024"
]
},
{
"id": "T047",
"description": "Regression: reopening a closed ticket still clears is_closed/closed_at/closed_by and publishes TICKET_REOPENED on every wired path, including the portal after F029.",
"implemented": true,
"featureIds": [
"F023",
"F024",
"F029"
]
}
]