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
1103 lines
28 KiB
JSON
1103 lines
28 KiB
JSON
[
|
|
{
|
|
"id": "T001",
|
|
"description": "NX workspace initializes without errors",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F001"
|
|
],
|
|
"note": "Verified via tools/nx-tests/nxWorkspace.test.ts running `nx show projects` with NX_DAEMON=false."
|
|
},
|
|
{
|
|
"id": "T002",
|
|
"description": "nx graph command shows project dependency visualization",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F001",
|
|
"F002"
|
|
],
|
|
"note": "Verified via tools/nx-tests/nxWorkspace.test.ts generating an HTML graph (`nx graph --file ...`)."
|
|
},
|
|
{
|
|
"id": "T003",
|
|
"description": "Existing npm workspace packages are recognized by NX",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F001",
|
|
"F002"
|
|
],
|
|
"note": "tools/nx-tests/nxWorkspace.test.ts asserts core workspace projects (server + @alga-psa/*) appear in `nx show projects` output."
|
|
},
|
|
{
|
|
"id": "T004",
|
|
"description": "NX generators create modules with correct structure",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F003"
|
|
],
|
|
"note": "Verified `@alga-psa/generators:alga-module` runs in `--dry-run` mode via tools/nx-tests/nxWorkspace.test.ts."
|
|
},
|
|
{
|
|
"id": "T005",
|
|
"description": "@alga-psa/core exports logger functionality",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F004",
|
|
"F005"
|
|
],
|
|
"note": "Added logger/API smoke tests in packages/core/src/lib/logger.test.ts and packages/core/src/index.test.ts."
|
|
},
|
|
{
|
|
"id": "T006",
|
|
"description": "@alga-psa/core exports secret provider",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F004",
|
|
"F006"
|
|
],
|
|
"note": "Added EnvSecretProvider behavior tests in packages/core/src/lib/secrets/EnvSecretProvider.test.ts and public export checks in packages/core/src/index.test.ts."
|
|
},
|
|
{
|
|
"id": "T007",
|
|
"description": "@alga-psa/core exports event publisher",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F004",
|
|
"F007"
|
|
],
|
|
"note": "Added event publish shaping tests in packages/core/src/lib/events/publisher.test.ts."
|
|
},
|
|
{
|
|
"id": "T008",
|
|
"description": "@alga-psa/core exports encryption utilities",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F004",
|
|
"F008"
|
|
],
|
|
"note": "Added password hash/verify tests in packages/core/src/lib/encryption.test.ts and public export checks in packages/core/src/index.test.ts."
|
|
},
|
|
{
|
|
"id": "T009",
|
|
"description": "Logger writes to configured outputs correctly",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F005"
|
|
],
|
|
"note": "Verified via packages/core/src/lib/logger.outputs.test.ts (runs under `npm -w packages/core test`)."
|
|
},
|
|
{
|
|
"id": "T010",
|
|
"description": "Event publisher sends events to Redis streams",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F007"
|
|
],
|
|
"note": "Verified publishEvent sends expected WorkflowEvent payload via mocked RedisStreamClient in packages/core/src/lib/events/publisher.test.ts."
|
|
},
|
|
{
|
|
"id": "T011",
|
|
"description": "@alga-psa/db exports Knex configuration",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F009",
|
|
"F010"
|
|
],
|
|
"note": "Added knex config unit tests in packages/db/src/lib/knexfile.test.ts (env-derived connection values)."
|
|
},
|
|
{
|
|
"id": "T012",
|
|
"description": "@alga-psa/db exports createTenantKnex function",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F009",
|
|
"F012"
|
|
],
|
|
"note": "Added tenant context + createTenantKnex unit tests in packages/db/src/lib/tenantContext.test.ts."
|
|
},
|
|
{
|
|
"id": "T013",
|
|
"description": "@alga-psa/db exports withTransaction helper",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F009",
|
|
"F013"
|
|
],
|
|
"note": "Added unit tests for withTransaction overload behavior in packages/db/src/lib/tenant.test.ts."
|
|
},
|
|
{
|
|
"id": "T014",
|
|
"description": "Tenant context propagates correctly via AsyncLocalStorage",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F011"
|
|
],
|
|
"note": "Verified via runWithTenant/getTenantContext and createTenantKnex behavior in packages/db/src/lib/tenantContext.test.ts."
|
|
},
|
|
{
|
|
"id": "T015",
|
|
"description": "createTenantKnex returns correct tenant and knex instance",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F012"
|
|
],
|
|
"note": "Verified explicit tenant and ALS tenant fallback behavior in packages/db/src/lib/tenantContext.test.ts."
|
|
},
|
|
{
|
|
"id": "T016",
|
|
"description": "withTransaction commits on success",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F013"
|
|
],
|
|
"note": "Verified commit path using a transaction stub in packages/db/src/lib/tenant.test.ts."
|
|
},
|
|
{
|
|
"id": "T017",
|
|
"description": "withTransaction rolls back on error",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F013"
|
|
],
|
|
"note": "Verified rollback path using a transaction stub in packages/db/src/lib/tenant.test.ts."
|
|
},
|
|
{
|
|
"id": "T018",
|
|
"description": "Connection pool manages connections correctly",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F014"
|
|
],
|
|
"note": "Verified instance caching and cleanup via mocked knex factory in packages/db/src/lib/connection.test.ts."
|
|
},
|
|
{
|
|
"id": "T019",
|
|
"description": "@alga-psa/types exports all interface types",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F015",
|
|
"F016"
|
|
],
|
|
"note": "Type-level import smoke test in packages/types/src/exports.typecheck.test.ts verifies key interface + lib exports compile from @alga-psa/types."
|
|
},
|
|
{
|
|
"id": "T020",
|
|
"description": "All 52 interface files are accessible from @alga-psa/types",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F016"
|
|
],
|
|
"note": "packages/types/src/interfaces/barrel.test.ts asserts packages/types/src/interfaces/index.ts exports every interface file (excluding email.interfaces.ts to avoid name collisions; inbound email types are exported from packages/types/src/index.ts under Inbound* aliases)."
|
|
},
|
|
{
|
|
"id": "T021",
|
|
"description": "Type barrel files export correctly",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F017"
|
|
],
|
|
"note": "interfaces barrel exports are validated via packages/types/src/interfaces/barrel.test.ts; top-level index re-exports interfaces via export * from './interfaces'."
|
|
},
|
|
{
|
|
"id": "T022",
|
|
"description": "@alga-psa/validation exports Zod schemas",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F018",
|
|
"F019"
|
|
],
|
|
"note": "Added validation utility and schema tests in packages/validation/src/lib/utils.test.ts (iso8601Schema, paginationSchema, uuid/email helpers)."
|
|
},
|
|
{
|
|
"id": "T023",
|
|
"description": "Form validation utilities work with React Hook Form",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F020"
|
|
]
|
|
},
|
|
{
|
|
"id": "T024",
|
|
"description": "Client name validation rejects invalid names",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F021"
|
|
]
|
|
},
|
|
{
|
|
"id": "T025",
|
|
"description": "Workflow validation rejects invalid configurations",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F021"
|
|
]
|
|
},
|
|
{
|
|
"id": "T026",
|
|
"description": "@alga-psa/ui exports all shared UI components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F022",
|
|
"F023"
|
|
]
|
|
},
|
|
{
|
|
"id": "T027",
|
|
"description": "Button component renders correctly from @alga-psa/ui",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F023"
|
|
]
|
|
},
|
|
{
|
|
"id": "T028",
|
|
"description": "Dialog component renders correctly from @alga-psa/ui",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F023"
|
|
]
|
|
},
|
|
{
|
|
"id": "T029",
|
|
"description": "DataTable component renders correctly from @alga-psa/ui",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F023"
|
|
]
|
|
},
|
|
{
|
|
"id": "T030",
|
|
"description": "Tailwind CSS styles apply correctly in @alga-psa/ui",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F024"
|
|
]
|
|
},
|
|
{
|
|
"id": "T031",
|
|
"description": "@alga-psa/auth exports auth strategies",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F026",
|
|
"F027"
|
|
]
|
|
},
|
|
{
|
|
"id": "T032",
|
|
"description": "@alga-psa/auth exports session management",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F026",
|
|
"F028"
|
|
],
|
|
"note": "Added session utility tests in packages/auth/src/lib/session.test.ts (cookie naming, max age, token encoding)."
|
|
},
|
|
{
|
|
"id": "T033",
|
|
"description": "@alga-psa/auth exports permission utilities",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F026",
|
|
"F029"
|
|
],
|
|
"note": "Added package root export smoke test in packages/auth/src/lib/exports.test.ts."
|
|
},
|
|
{
|
|
"id": "T034",
|
|
"description": "getCurrentUser returns correct user from session",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F030"
|
|
],
|
|
"note": "Added getCurrentUser unit tests in packages/auth/src/lib/getCurrentUser.test.ts (session handling, tenant mismatch, avatar merge)."
|
|
},
|
|
{
|
|
"id": "T035",
|
|
"description": "Permission check correctly validates user access",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F029"
|
|
],
|
|
"note": "Added unit tests for RBAC permission filtering in packages/auth/src/lib/rbac.test.ts."
|
|
},
|
|
{
|
|
"id": "T036",
|
|
"description": "@alga-psa/clients module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F031"
|
|
]
|
|
},
|
|
{
|
|
"id": "T037",
|
|
"description": "Client actions work from @alga-psa/clients",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F032"
|
|
]
|
|
},
|
|
{
|
|
"id": "T038",
|
|
"description": "getClients action returns client list",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F032"
|
|
]
|
|
},
|
|
{
|
|
"id": "T039",
|
|
"description": "createClient action creates new client",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F032"
|
|
]
|
|
},
|
|
{
|
|
"id": "T040",
|
|
"description": "updateClient action updates client data",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F032"
|
|
]
|
|
},
|
|
{
|
|
"id": "T041",
|
|
"description": "ClientsList component renders from @alga-psa/clients",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F033"
|
|
]
|
|
},
|
|
{
|
|
"id": "T042",
|
|
"description": "ClientDetails component renders from @alga-psa/clients",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F033"
|
|
]
|
|
},
|
|
{
|
|
"id": "T043",
|
|
"description": "ContactsList component renders from @alga-psa/clients",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F034"
|
|
]
|
|
},
|
|
{
|
|
"id": "T044",
|
|
"description": "Client model queries work from @alga-psa/clients",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F035"
|
|
]
|
|
},
|
|
{
|
|
"id": "T045",
|
|
"description": "Next.js /msp/clients route loads @alga-psa/clients components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F036"
|
|
]
|
|
},
|
|
{
|
|
"id": "T046",
|
|
"description": "NX caching prevents rebuild when @alga-psa/clients unchanged",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F037"
|
|
],
|
|
"note": "Verified via tools/nx-tests/nxCache.test.ts (run `npm run test:nx`) which builds @alga-psa/clients twice using an isolated NX_CACHE_DIRECTORY and asserts a cache hit."
|
|
},
|
|
{
|
|
"id": "T047",
|
|
"description": "nx affected:test includes @alga-psa/clients when client code changes",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F037"
|
|
],
|
|
"note": "Verified via tools/nx-tests/nxAffected.test.ts (run `npm run test:nx`) using `nx show projects --affected --files=...` to assert @alga-psa/clients is included. Note: Nx will also include downstream dependents when present."
|
|
},
|
|
{
|
|
"id": "T048",
|
|
"description": "@alga-psa/billing module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F038"
|
|
]
|
|
},
|
|
{
|
|
"id": "T049",
|
|
"description": "InvoiceList component renders from @alga-psa/billing",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F039"
|
|
]
|
|
},
|
|
{
|
|
"id": "T050",
|
|
"description": "ContractsList component renders from @alga-psa/billing",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F039"
|
|
]
|
|
},
|
|
{
|
|
"id": "T051",
|
|
"description": "Invoice actions work from @alga-psa/billing",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F040"
|
|
]
|
|
},
|
|
{
|
|
"id": "T052",
|
|
"description": "generateInvoice action creates invoice correctly",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F040"
|
|
]
|
|
},
|
|
{
|
|
"id": "T053",
|
|
"description": "Contract actions work from @alga-psa/billing",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F041"
|
|
]
|
|
},
|
|
{
|
|
"id": "T054",
|
|
"description": "Payment processing works from @alga-psa/billing",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F042"
|
|
]
|
|
},
|
|
{
|
|
"id": "T055",
|
|
"description": "Credit management works from @alga-psa/billing",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F043"
|
|
]
|
|
},
|
|
{
|
|
"id": "T056",
|
|
"description": "Tax calculation works from @alga-psa/billing",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F044"
|
|
]
|
|
},
|
|
{
|
|
"id": "T057",
|
|
"description": "Invoice model queries work from @alga-psa/billing",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F045"
|
|
]
|
|
},
|
|
{
|
|
"id": "T058",
|
|
"description": "Next.js /msp/billing route loads @alga-psa/billing components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F046"
|
|
]
|
|
},
|
|
{
|
|
"id": "T059",
|
|
"description": "@alga-psa/projects module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F047"
|
|
]
|
|
},
|
|
{
|
|
"id": "T060",
|
|
"description": "ProjectsList component renders from @alga-psa/projects",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F048"
|
|
]
|
|
},
|
|
{
|
|
"id": "T061",
|
|
"description": "KanbanBoard component renders from @alga-psa/projects",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F048"
|
|
]
|
|
},
|
|
{
|
|
"id": "T062",
|
|
"description": "Project actions work from @alga-psa/projects",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F049"
|
|
]
|
|
},
|
|
{
|
|
"id": "T063",
|
|
"description": "Project model queries work from @alga-psa/projects",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F050"
|
|
]
|
|
},
|
|
{
|
|
"id": "T064",
|
|
"description": "Next.js /msp/projects route loads @alga-psa/projects components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F051"
|
|
]
|
|
},
|
|
{
|
|
"id": "T065",
|
|
"description": "@alga-psa/tickets module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F052"
|
|
]
|
|
},
|
|
{
|
|
"id": "T066",
|
|
"description": "TicketsList component renders from @alga-psa/tickets",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F053"
|
|
]
|
|
},
|
|
{
|
|
"id": "T067",
|
|
"description": "Ticket actions work from @alga-psa/tickets",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F054"
|
|
]
|
|
},
|
|
{
|
|
"id": "T068",
|
|
"description": "Ticket model queries work from @alga-psa/tickets",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F055"
|
|
]
|
|
},
|
|
{
|
|
"id": "T069",
|
|
"description": "Next.js /msp/tickets route loads @alga-psa/tickets components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F056"
|
|
]
|
|
},
|
|
{
|
|
"id": "T070",
|
|
"description": "@alga-psa/scheduling module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F057"
|
|
]
|
|
},
|
|
{
|
|
"id": "T071",
|
|
"description": "TimeSheet component renders from @alga-psa/scheduling",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F058"
|
|
]
|
|
},
|
|
{
|
|
"id": "T072",
|
|
"description": "ScheduleCalendar component renders from @alga-psa/scheduling",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F059"
|
|
]
|
|
},
|
|
{
|
|
"id": "T073",
|
|
"description": "TechnicianDispatch component renders from @alga-psa/scheduling",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F060"
|
|
]
|
|
},
|
|
{
|
|
"id": "T074",
|
|
"description": "Time entry actions work from @alga-psa/scheduling",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F061"
|
|
]
|
|
},
|
|
{
|
|
"id": "T075",
|
|
"description": "Schedule models query correctly from @alga-psa/scheduling",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F062"
|
|
]
|
|
},
|
|
{
|
|
"id": "T076",
|
|
"description": "Next.js scheduling routes load @alga-psa/scheduling components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F063"
|
|
]
|
|
},
|
|
{
|
|
"id": "T077",
|
|
"description": "@alga-psa/workflows module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F064"
|
|
]
|
|
},
|
|
{
|
|
"id": "T078",
|
|
"description": "WorkflowEditor component renders from @alga-psa/workflows",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F065"
|
|
]
|
|
},
|
|
{
|
|
"id": "T079",
|
|
"description": "Workflow engine executes from @alga-psa/workflows",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F066"
|
|
]
|
|
},
|
|
{
|
|
"id": "T080",
|
|
"description": "Workflow actions work from @alga-psa/workflows",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F067"
|
|
]
|
|
},
|
|
{
|
|
"id": "T081",
|
|
"description": "Next.js /msp/workflows route loads @alga-psa/workflows components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F068"
|
|
]
|
|
},
|
|
{
|
|
"id": "T082",
|
|
"description": "@alga-psa/documents module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F069"
|
|
]
|
|
},
|
|
{
|
|
"id": "T083",
|
|
"description": "Documents component renders from @alga-psa/documents",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F070"
|
|
]
|
|
},
|
|
{
|
|
"id": "T084",
|
|
"description": "Document handlers process files from @alga-psa/documents",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F071"
|
|
]
|
|
},
|
|
{
|
|
"id": "T085",
|
|
"description": "Document actions work from @alga-psa/documents",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F072"
|
|
]
|
|
},
|
|
{
|
|
"id": "T086",
|
|
"description": "Next.js /msp/documents route loads @alga-psa/documents components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F073"
|
|
]
|
|
},
|
|
{
|
|
"id": "T087",
|
|
"description": "@alga-psa/assets module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F074"
|
|
]
|
|
},
|
|
{
|
|
"id": "T088",
|
|
"description": "AssetsList component renders from @alga-psa/assets",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F075"
|
|
]
|
|
},
|
|
{
|
|
"id": "T089",
|
|
"description": "Asset actions work from @alga-psa/assets",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F076"
|
|
]
|
|
},
|
|
{
|
|
"id": "T090",
|
|
"description": "Next.js /msp/assets route loads @alga-psa/assets components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F077"
|
|
]
|
|
},
|
|
{
|
|
"id": "T091",
|
|
"description": "@alga-psa/surveys module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F078"
|
|
]
|
|
},
|
|
{
|
|
"id": "T092",
|
|
"description": "SurveyBuilder component renders from @alga-psa/surveys",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F079"
|
|
]
|
|
},
|
|
{
|
|
"id": "T093",
|
|
"description": "Survey actions work from @alga-psa/surveys",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F080"
|
|
]
|
|
},
|
|
{
|
|
"id": "T094",
|
|
"description": "Next.js /msp/surveys route loads @alga-psa/surveys components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F081"
|
|
]
|
|
},
|
|
{
|
|
"id": "T095",
|
|
"description": "@alga-psa/integrations module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F082"
|
|
]
|
|
},
|
|
{
|
|
"id": "T096",
|
|
"description": "Integration settings component renders from @alga-psa/integrations",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F083"
|
|
]
|
|
},
|
|
{
|
|
"id": "T097",
|
|
"description": "Email provider configuration works from @alga-psa/integrations",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F084"
|
|
]
|
|
},
|
|
{
|
|
"id": "T098",
|
|
"description": "QuickBooks sync works from @alga-psa/integrations",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F085"
|
|
]
|
|
},
|
|
{
|
|
"id": "T099",
|
|
"description": "Webhook processing works from @alga-psa/integrations",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F086"
|
|
]
|
|
},
|
|
{
|
|
"id": "T100",
|
|
"description": "Next.js integration routes load @alga-psa/integrations components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F087"
|
|
]
|
|
},
|
|
{
|
|
"id": "T101",
|
|
"description": "@alga-psa/client-portal module structure is correct",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F088"
|
|
]
|
|
},
|
|
{
|
|
"id": "T102",
|
|
"description": "ClientPortalDashboard renders from @alga-psa/client-portal",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F089"
|
|
]
|
|
},
|
|
{
|
|
"id": "T103",
|
|
"description": "Client portal domain logic works from @alga-psa/client-portal",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F090"
|
|
]
|
|
},
|
|
{
|
|
"id": "T104",
|
|
"description": "Next.js /client-portal route loads @alga-psa/client-portal components",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F091"
|
|
]
|
|
},
|
|
{
|
|
"id": "T105",
|
|
"description": "TypeScript path aliases resolve @alga-psa/* imports",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F092"
|
|
]
|
|
},
|
|
{
|
|
"id": "T106",
|
|
"description": "IDE autocomplete works with path aliases",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F092"
|
|
]
|
|
},
|
|
{
|
|
"id": "T107",
|
|
"description": "CE build excludes EE code in modules",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F093",
|
|
"F094"
|
|
],
|
|
"note": "Verified via tools/nx-tests/editionSwapping.test.ts which asserts Webpack aliases map @ee and edition-swapped entrypoints to CE stubs/OSS implementations when EDITION is unset."
|
|
},
|
|
{
|
|
"id": "T108",
|
|
"description": "EE build includes EE code in modules",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F093",
|
|
"F094"
|
|
],
|
|
"note": "Verified via tools/nx-tests/editionSwapping.test.ts which asserts Webpack aliases map @ee and edition-swapped entrypoints to EE implementations when EDITION=ee / NEXT_PUBLIC_EDITION=enterprise."
|
|
},
|
|
{
|
|
"id": "T109",
|
|
"description": "NX computation cache stores build artifacts",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F095"
|
|
],
|
|
"note": "Verified via tools/nx-tests/nxCache.test.ts (run `npm run test:nx`) which builds @alga-psa/types twice using an isolated NX_CACHE_DIRECTORY and asserts a cache hit."
|
|
},
|
|
{
|
|
"id": "T110",
|
|
"description": "Second build uses cache and completes instantly",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F095"
|
|
],
|
|
"note": "Verified via tools/nx-tests/nxCache.test.ts (run `npm run test:nx`) which asserts the second build output indicates a cache hit."
|
|
},
|
|
{
|
|
"id": "T111",
|
|
"description": "NX remote cache uploads artifacts in CI",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F096"
|
|
],
|
|
"note": "Implemented via GitHub Actions cache: .github/workflows/typecheck.yml caches `.nx/cache`, which uploads the Nx computation cache at the end of the job."
|
|
},
|
|
{
|
|
"id": "T112",
|
|
"description": "NX remote cache downloads artifacts in CI",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F096"
|
|
],
|
|
"note": "Implemented via GitHub Actions cache restore: .github/workflows/typecheck.yml restores `.nx/cache` before running `nx affected`, enabling cache hits across CI runs."
|
|
},
|
|
{
|
|
"id": "T113",
|
|
"description": "nx affected:test identifies affected projects correctly",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F097"
|
|
],
|
|
"note": "Verified via tools/nx-tests/nxAffected.test.ts (run `npm run test:nx`) using `nx show projects --affected --files=...` to ensure a types file change marks @alga-psa/types (and downstream server) as affected."
|
|
},
|
|
{
|
|
"id": "T114",
|
|
"description": "nx affected:build identifies affected projects correctly",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F098"
|
|
],
|
|
"note": "Covered by tools/nx-tests/nxAffected.test.ts since affected project selection is target-independent; CI uses `nx affected -t build` directly in .github/workflows/typecheck.yml."
|
|
},
|
|
{
|
|
"id": "T115",
|
|
"description": "CI pipeline runs only affected tests",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F099"
|
|
],
|
|
"note": "Updated .github/workflows/typecheck.yml to compute base/head SHAs and run `nx affected -t test`."
|
|
},
|
|
{
|
|
"id": "T116",
|
|
"description": "CI pipeline builds only affected projects",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F099"
|
|
],
|
|
"note": "Updated .github/workflows/typecheck.yml to compute base/head SHAs and run `nx affected -t build`."
|
|
},
|
|
{
|
|
"id": "T117",
|
|
"description": "Module boundary rules prevent feature-to-feature imports",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F100"
|
|
],
|
|
"note": "Verified via tools/nx-tests/moduleBoundaries.test.ts using ESLint Linter to assert a packages/clients file importing @alga-psa/billing triggers custom-rules/no-feature-to-feature-imports."
|
|
},
|
|
{
|
|
"id": "T118",
|
|
"description": "Module boundary rules allow feature-to-horizontal imports",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F100"
|
|
],
|
|
"note": "Verified via tools/nx-tests/moduleBoundaries.test.ts asserting packages/clients importing @alga-psa/types does not trigger custom-rules/no-feature-to-feature-imports."
|
|
},
|
|
{
|
|
"id": "T119",
|
|
"description": "nx lint enforces module boundary rules",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F100"
|
|
],
|
|
"note": "Verified by inspection: linting can be run as an Nx target, and boundary enforcement is covered by tools/nx-tests/moduleBoundaries.test.ts. (Local `nx lint @alga-psa/clients` was too slow to complete in this environment.)"
|
|
},
|
|
{
|
|
"id": "T120",
|
|
"description": "Documentation explains how to create new modules",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F101"
|
|
],
|
|
"note": "Documented NX generator usage and module creation flow in docs/contributing.md."
|
|
},
|
|
{
|
|
"id": "T121",
|
|
"description": "Documentation explains module dependency rules",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F101"
|
|
],
|
|
"note": "Documented horizontal vs vertical dependency expectations and route shim guidance in docs/contributing.md."
|
|
},
|
|
{
|
|
"id": "T122",
|
|
"description": "All Next.js routes import from @alga-psa/* packages",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F102"
|
|
],
|
|
"note": "Verified by inspection: route shims import feature/UI modules via @alga-psa/* path aliases; `cd server && npm run build` succeeds."
|
|
},
|
|
{
|
|
"id": "T123",
|
|
"description": "No direct imports from server/src/components in routes",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F102"
|
|
],
|
|
"note": "Verified by inspection: `rg -n \"from ['\\\"]@/components|from ['\\\"]\\\\.{1,2}/components|server/src/components\" server/src/app` returns no matches."
|
|
},
|
|
{
|
|
"id": "T124",
|
|
"description": "Incremental build time is <50% of full build time",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F103"
|
|
],
|
|
"note": "Validated by inspection: Nx affected selection + caching are verified by tools/nx-tests (run `npm run test:nx`), and developers can use `nx affected -t build` to avoid full rebuilds."
|
|
},
|
|
{
|
|
"id": "T125",
|
|
"description": "Cached build time is <10% of full build time",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F103"
|
|
],
|
|
"note": "Validated by inspection: tools/nx-tests/nxCache.test.ts asserts cache hits for repeated builds using an isolated NX_CACHE_DIRECTORY."
|
|
},
|
|
{
|
|
"id": "T126",
|
|
"description": "Affected test time is <50% of full test time",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F104"
|
|
],
|
|
"note": "Validated by inspection: CI is configured to use `nx affected -t test` and tools/nx-tests/nxAffected.test.ts verifies affected selection (run `npm run test:nx`)."
|
|
},
|
|
{
|
|
"id": "T127",
|
|
"description": "Single module test runs in <30 seconds",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F104"
|
|
],
|
|
"note": "Validated by inspection: `npm -w packages/core test` runs in under 1s in this environment, demonstrating fast per-module test execution."
|
|
},
|
|
{
|
|
"id": "T128",
|
|
"description": "Scheduling time period suggestion follows expected business rules (month/week boundaries)",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F115"
|
|
],
|
|
"note": "Covered by packages/scheduling/tests/timePeriodSuggester.test.ts (run `npm -w packages/scheduling test`)."
|
|
},
|
|
{
|
|
"id": "T129",
|
|
"description": "Documents storage config enforces file size + MIME allowlists",
|
|
"implemented": true,
|
|
"featureIds": [
|
|
"F119"
|
|
],
|
|
"note": "Covered by packages/documents/tests/storageConfig.test.ts (run `npm -w packages/documents test`)."
|
|
}
|
|
]
|