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
14 KiB
14 KiB
Scratchpad — Client Portal Board Visibility Groups
- Plan slug:
client-portal-board-visibility-groups - Created:
2026-03-15
What This Is
Keep a lightweight, continuously-updated log of discoveries and decisions made while implementing this plan.
Prefer short bullets. Append new entries as you learn things, and also update earlier notes when a decision changes or an open question is resolved.
Decisions
- (2026-03-15) Existing portal users keep full board access until restricted.
NULLassignment is the backward-compatible state. - (2026-03-15) Visibility is modeled as per-client reusable groups rather than per-user board checklists.
- (2026-03-15) V1 supports one group per contact/portal user, not multiple groups.
- (2026-03-15) MSP assignment changes are not locked. Client admins can replace them later.
- (2026-03-15) Groups are scoped per client, not shared tenant-wide.
- (2026-03-15) Recommended assignment anchor is the contact record, because portal ticket access already resolves through
users.contact_idand this supports pre-invitation configuration. - (2026-03-15) Deleting an assigned group should fail rather than silently restoring full access.
Discoveries / Constraints
- (2026-03-15) Client portal ticket access is client-wide today.
packages/client-portal/src/actions/client-portal-actions/client-tickets.tsresolves the signed-in user tousers.contact_id, thencontacts.client_id, and filters tickets byt.client_id = contact.client_id. - (2026-03-15) The existing MSP contact portal management surface already exists in
packages/clients/src/components/contacts/ContactPortalTab.tsx. - (2026-03-15) The existing MSP-side contact action for portal admin state lives in
packages/clients/src/actions/contact-actions/contactActions.tsx. - (2026-03-15) Client portal locale files already exist at
server/public/locales/{de,en,es,fr,it,nl,pl,xx,yy}/client-portal.json. - (2026-03-15) Client portal user self-service and contact-linked client-user logic already exists in
packages/client-portal/src/actions/client-portal-actions/clientUserActions.ts. - (2026-03-15) Added MSP portal-side visibility-group capabilities in
ContactPortalTab.tsx:- render assignment selector for selected visibility group / full-access
- render group editor (name/description/boards)
- wire create/edit/delete actions against new contact action handlers
- (2026-03-15) Implemented client-anchored contact action functions in
contactActions.tsx:- list groups, boards, group detail
- create/update/delete group with board validation
- assign/unassign visibility group with client-scoped guard
- delete blocked if currently assigned
- (2026-03-15) Added
visibilityGroupslocale keys inserver/public/locales/de/es/fr/it/nl/pl/xx/yy/client-portal.jsonwith English fallback values for parity. - (2026-03-15) Added server-side guard tests for contact-actions (
visibilityGroupActions.permission.test.ts) covering cross-client assignment guard, delete-blocked-when-assigned, and delete-success-unassigned. - (2026-03-15) Flipped checklists for F019/F020/F022/F023/F024 and T026/T033/T034 to
trueafter implementation. - (2026-03-15) Moved the portal board-visibility resolver into shared tickets lib code at
packages/tickets/src/lib/clientPortalVisibility.tsso both client-portal actions and ticket-form actions use the same enforcement path. - (2026-03-15) Tightened shared resolver scoping to join through
boardsand only return board IDs that still belong to the contact's client, which prevents rogue membership rows from broadening access. - (2026-03-15) Fixed
getDashboardMetricsto apply the visibility filter on a chainable ticket query instead of calling.where(...)on avoidhelper result. - (2026-03-15)
getClientTicketFormDatanow uses the shared resolver; invalid/mismatched assignments fail closed by returning no boards instead of silently restoring unrestricted board choices. - (2026-03-15) Added migration contract coverage in
server/src/test/unit/migrations/clientPortalVisibilityGroupsMigration.test.tsand shared resolver coverage inpackages/tickets/src/lib/clientPortalVisibility.test.ts. - (2026-03-15) Flipped checklists for F001/F002/F003/F004/F005/F006 and T001/T002/T003/T004/T005/T006/T007 to
trueafter code/test verification. - (2026-03-15) Added client portal visibility enforcement tests in
packages/client-portal/src/actions/client-portal-actions/client-tickets.visibility.test.tsfor restricted/unrestricted ticket list behavior, hidden-board detail/document guards, and disallowed-board ticket creation rejection. - (2026-03-15) Added dashboard visibility coverage in
packages/client-portal/src/actions/client-portal-actions/dashboard.visibility.test.tsto prove ticket-backed metrics respect the resolved board set. - (2026-03-15) Flipped checklists for F007/F008/F009/F010/F011/F012/F013 and T008/T009/T010/T011/T012/T015/T016/T017 to
trueafter code/test verification. - (2026-03-15) Updated
ClientAddTicket.tsxto surface a localized no-boards empty state for restricted contacts and keep ticket creation disabled when no boards are available. - (2026-03-15) Added ticket-form visibility tests in
packages/tickets/src/actions/ticketFormActions.clientPortalVisibility.test.tsand dialog UI tests inpackages/client-portal/src/components/tickets/ClientAddTicket.visibility.test.tsx. - (2026-03-15) Added
create.noBoardsAvailableto all supportedserver/public/locales/*/features/tickets.jsonfiles used by the restricted-ticket empty state. - (2026-03-15) Flipped checklists for T013/T014/T037 to
trueafter code/test verification. - (2026-03-15) Added client portal admin action coverage in
packages/client-portal/src/actions/client-portal-actions/visibilityGroupActions.test.tsfor T018/T019/T020/T021/T022/T023/T024/T025/T027/T032. - (2026-03-15) Added locale coverage in
packages/client-portal/src/components/settings/visibilityGroupsLocales.test.tsfor T035/T036 and validated the newclientSettings.visibilityGroups.*keys across all supported client portal locales. - (2026-03-15) Added MSP contact portal tab UI coverage in
packages/clients/src/components/contacts/ContactPortalTab.visibilityGroups.test.tsxfor T029/T030 to verify assignment replacement plus create/edit flows in the PSA surface. - (2026-03-15) Added lifecycle/integration coverage in
packages/tickets/src/lib/clientPortalVisibility.userModelLifecycle.test.tsandpackages/clients/src/actions/contact-actions/visibilityGroupActions.integration.test.tsfor T028/T031/T038. - (2026-03-15) Fixed a second parse error in
packages/clients/src/actions/contact-actions/contactActions.tsxby correcting theassignClientPortalVisibilityGroupToContactwithAuth(...)export terminator from};to});. - (2026-03-15) Flipped checklists for F014/F015/F016/F017/F018/F021 and T018/T019/T020/T021/T022/T023/T024/T025/T027/T028/T029/T030/T031/T032/T035/T036/T038 to
trueafter visibility-focused test verification.
Commands / Runbooks
- (2026-03-15) Search client portal ticket entry points:
rg -n "client.*ticket|portal.*ticket|get.*ticket|list.*ticket" packages/client-portal server/src/app/client-portal packages/portal-shared --glob '!node_modules' - (2026-03-15) Search portal/contact admin surfaces:
rg -n "portal admin|portal invitation|contact.*portal|contact.*user" packages server --glob '!node_modules' - (2026-03-15) Inspect client portal locale coverage:
find server/public/locales -maxdepth 2 -name 'client-portal.json' | sort - (2026-03-15) Run targeted migration/resolver tests from the server Vitest root:
cd server && npx vitest run src/test/unit/migrations/clientPortalVisibilityGroupsMigration.test.ts ../packages/tickets/src/lib/clientPortalVisibility.test.ts - (2026-03-15) Run targeted ticket/dashboard visibility tests from the server Vitest root:
cd server && npx vitest run ../packages/client-portal/src/actions/client-portal-actions/client-tickets.visibility.test.ts ../packages/client-portal/src/actions/client-portal-actions/dashboard.visibility.test.ts - (2026-03-15) Run targeted ticket-form/dialog visibility tests from the server Vitest root:
cd server && npx vitest run ../packages/tickets/src/actions/ticketFormActions.clientPortalVisibility.test.ts ../packages/client-portal/src/components/tickets/ClientAddTicket.visibility.test.tsx - (2026-03-15) Run client portal admin/localization visibility tests from the server Vitest root:
cd server && npx vitest run ../packages/client-portal/src/actions/client-portal-actions/visibilityGroupActions.test.ts ../packages/client-portal/src/components/settings/visibilityGroupsLocales.test.ts - (2026-03-15) Run MSP visibility group tests from the server Vitest root:
cd server && npx vitest run ../packages/clients/src/actions/contact-actions/visibilityGroupActions.permission.test.ts ../packages/clients/src/actions/contact-actions/visibilityGroupActions.integration.test.ts ../packages/clients/src/components/contacts/ContactPortalTab.visibilityGroups.test.tsx - (2026-03-15) Run lifecycle visibility tests from the server Vitest root:
cd server && npx vitest run ../packages/tickets/src/lib/clientPortalVisibility.userModelLifecycle.test.ts - (2026-03-15) Consolidated visibility-focused regression run from the server Vitest root:
cd server && npx vitest run src/test/unit/migrations/clientPortalVisibilityGroupsMigration.test.ts ../packages/tickets/src/lib/clientPortalVisibility.test.ts ../packages/tickets/src/lib/clientPortalVisibility.userModelLifecycle.test.ts ../packages/client-portal/src/actions/client-portal-actions/client-tickets.visibility.test.ts ../packages/client-portal/src/actions/client-portal-actions/dashboard.visibility.test.ts ../packages/tickets/src/actions/ticketFormActions.clientPortalVisibility.test.ts ../packages/client-portal/src/components/tickets/ClientAddTicket.visibility.test.tsx ../packages/client-portal/src/actions/client-portal-actions/visibilityGroupActions.test.ts ../packages/client-portal/src/components/settings/visibilityGroupsLocales.test.ts ../packages/clients/src/actions/contact-actions/visibilityGroupActions.permission.test.ts ../packages/clients/src/actions/contact-actions/visibilityGroupActions.integration.test.ts ../packages/clients/src/components/contacts/ContactPortalTab.visibilityGroups.test.tsx
Links / References
- client-tickets.ts
- ContactPortalTab.tsx
- contactActions.tsx
- clientUserActions.ts
- client-portal.json
- clientPortalVisibility.ts
- clientPortalVisibility.test.ts
- clientPortalVisibilityGroupsMigration.test.ts
- client-tickets.visibility.test.ts
- dashboard.visibility.test.ts
- ticketFormActions.clientPortalVisibility.test.ts
- ClientAddTicket.visibility.test.tsx
- visibilityGroupActions.test.ts
- visibilityGroupsLocales.test.ts
- ContactPortalTab.visibilityGroups.test.tsx
- visibilityGroupActions.integration.test.ts
- clientPortalVisibility.userModelLifecycle.test.ts
Open Questions
- Should the client portal admin UI live under account/settings or under a dedicated administration route?
- Should the PSA-side group CRUD live only in the contact portal tab, or also at the client level?