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

365 lines
15 KiB
Markdown

# NX Monorepo Modularization - Scratchpad
---
## ⚠️ CRITICAL INSTRUCTION FOR CLAUDE ⚠️
**DO NOT CHEAT.** When implementing features:
0. **Work in large chunks before lint/build.** Prefer moving a whole coherent slice (e.g. an entire folder or feature) and fixing imports broadly. Only run lint/tests/build at the end of a large unit of work (or when truly blocked). Constant lint/build cycles are too expensive and slow the migration dramatically.
1. **Actually move/copy the files** - don't just create re-exports from the old location
2. **Update imports in the moved files** - fix relative imports to work in new location
3. **Update consumers** - change imports in files that use the moved code
4. **If you defer work**, add a NEW feature entry to features.json for that deferred work
5. **Only mark "implemented": true** when the actual migration is complete, not just scaffolding
If you have the choice between an easy path (re-exports) and the right path (actual migration),
**ALWAYS choose the right path**. If you need to defer harder work to later iterations,
add explicit new features to track that work - don't just drop it or pretend it's done.
### Temporary Shim Exception (Migration Only)
If a “shim” is required to keep work moving (e.g. to avoid editing dozens of call sites immediately), it must be:
- treated as temporary and minimal (no long-lived architecture)
- tracked explicitly in `features.json` (with a removal task)
- removed once the owning package/horizontal slice has the real implementation
---
## Analysis Summary (2026-01-15)
### Current Codebase Metrics
- **Total TypeScript/TSX files**: ~2,300+
- **Components**: 777 files across 42 domain directories
- **Lib (actions, models, services, utils)**: 685 files
- **API Routes**: 510 files
- **Interfaces**: 52 files
### Existing Modular Patterns
The codebase already uses npm workspaces with this structure:
```json
"workspaces": [
"server",
"ee/server",
"services/workflow-worker",
"services/email-service",
"shared",
"packages/*",
"sdk/*"
]
```
### Existing Packages (15 total)
Located in `/packages/`:
1. `product-auth-ee` - Enterprise auth
2. `product-billing` - Billing features
3. `product-chat` - Chat functionality
4. `product-client-portal-domain` - Client portal domain logic
5. `product-email-domains` - Email domain management (consolidated into `@alga-psa/integrations/email`)
6. `product-email-providers` - Email provider integrations (consolidated into `@alga-psa/integrations/email`)
7. `product-email-settings` - Email configuration (consolidated into `@alga-psa/integrations/email`)
8. `product-ext-proxy` - Extension proxy
9. `product-extension-actions` - Extension server actions
10. `product-extension-initialization` - Extension init
11. `product-extensions-pages` - Extension pages
12. `product-extensions` - Core extensions
13. `product-settings-extensions` - Settings extensions
14. `product-workflows` - Workflow engine
15. `ui-kit` - UI component library
### Shared Library Structure
`@alga-psa/shared` exports:
- `./types` - Type definitions
- `./core` - Logger, secret provider
- `./db` - Database utilities, admin, connection
- `./events/publisher.js` - Event publishing
- `./utils/encryption.js` - Encryption utilities
- `./workflow` - Workflow core, persistence, streams
- `./models/*` - Shared models (client, contact, tag, ticket, user)
- `./extensions/*` - Extension domain, installs, types
---
## Identified Feature Domains
### Large Domains (>30 component files)
| Domain | Files | Notes |
|--------|-------|-------|
| billing-dashboard | 120 | Invoices, contracts, payments, credits |
| settings | 86 | System configuration |
| ui | 81 | Shared UI components |
| projects | 50 | Project management, kanban, tasks |
| client-portal | 42 | Client-facing portal |
| assets | 37 | Asset management |
| time-management | 32 | Time tracking, timesheets |
| clients | 32 | Client profiles |
### Medium Domains (10-30 files)
- surveys (25), workflows (24), user-activities (21)
- tickets (19), documents (18), contacts (12)
- technician-dispatch (13), auth (12), layout (11)
- integrations (11)
---
## Proposed Module Architecture
### Horizontal Slices (Shared Infrastructure)
1. **@alga-psa/core** - Existing shared package, enhance with:
- Logger, config, secrets
- Event publisher
- Encryption utilities
2. **@alga-psa/db** - Database layer
- Knex configuration
- Tenant context management
- Connection pooling
- Base model patterns
3. **@alga-psa/types** - Type definitions
- All interface files
- Shared types across features
4. **@alga-psa/validation** - Validation logic
- Zod schemas
- Form validation utilities
- Business rule validators
5. **@alga-psa/ui** - UI component library
- Enhance existing ui-kit
- All shared UI components
6. **@alga-psa/auth** - Authentication
- Auth strategies
- Session management
- Permission utilities
### Vertical Slices (Feature Modules)
1. **@alga-psa/billing** - Billing & Contracts
- Invoicing
- Contracts/contract lines
- Payments
- Credits
- Tax management
2. **@alga-psa/clients** - Client Management
- Client profiles
- Contacts
- Companies
- Client relationships
3. **@alga-psa/projects** - Project Management
- Projects
- Tasks/phases
- Kanban boards
- Dependencies
- Resource allocation
4. **@alga-psa/tickets** - Ticket/Issue Tracking
- Support tickets
- Categories
- SLA management
5. **@alga-psa/scheduling** - Scheduling & Time
- Time tracking
- Timesheets
- Calendar
- Technician dispatch
- Schedule entries
6. **@alga-psa/workflows** - Workflow Automation
- Workflow engine
- Triggers
- Actions
- Automation rules
7. **@alga-psa/documents** - Document Management
- Document storage
- Templates
- Sharing
8. **@alga-psa/assets** - Asset Management
- Asset tracking
- Categorization
- Service history
9. **@alga-psa/surveys** - Surveys
- Survey creation
- Responses
- Analytics
10. **@alga-psa/integrations** - Third-party Integrations
- QuickBooks
- Email providers
- Calendar providers
- Webhooks
11. **@alga-psa/client-portal** - Client Portal
- Portal UI
- Portal-specific features
- External access
---
## Key Decisions
### Decision 1: NX vs Enhanced npm Workspaces
**Decision**: Use NX
**Rationale**:
- Existing npm workspaces show modular thinking is established
### Note: Vitest + Workspace Resolution (2026-01-15)
Some dev/test setups may not have newly-added `@alga-psa/*` workspace packages linked into `node_modules`. For Vitest runs from the repo root, add explicit Vite/Vitest aliases (in `server/vitest.config.ts`) pointing `@alga-psa/*` imports to `packages/*/src` to keep unit tests runnable without reinstalling dependencies.
### Note: Root tsconfig.json (2026-01-15)
Several `packages/*/tsconfig.json` files extend `../../tsconfig.json`. Ensure `tsconfig.json` exists at the repo root and extends `tsconfig.base.json` so those package configs work and editors/tools pick up the shared path aliases.
### Note: DB tenant context (2026-01-15)
The `@alga-psa/db` package now owns tenant context via `AsyncLocalStorage` (`runWithTenant`, `getTenantContext`) and exports `createTenantKnex()`. The server-side `server/src/lib/db/index.tsx` continues to handle request/session/header tenant resolution but delegates context storage to `@alga-psa/db`.
### Note: Vitest coverage temp dir (2026-01-15)
Vitest v8 coverage writes a temp directory under `server/coverage/.tmp`. Ensure it exists during test runs (created in `server/src/test/setup.ts`) to avoid occasional `ENOENT` errors when running multiple targeted tests.
### Note: Nx project.json coverage (2026-01-15)
Many `packages/*` were created without `project.json`, which prevented them from being first-class Nx projects. Added `project.json` files for all new `@alga-psa/*` packages (and `packages/ui-kit`) so `nx graph`, caching, and affected commands can reason about them.
- NX adds: computation caching, affected commands, dependency graph visualization
- Better for large codebase with 2300+ files
- Enables parallel builds and test optimization
### Note: UI package split (2026-01-16)
The existing `packages/ui-kit` is used by SDK/extension template consumers and should remain Tailwind-free to avoid breaking external usage. The app/server UI components from `server/src/components/ui` (Tailwind + Radix heavy) were migrated into a new internal package `packages/ui` (`@alga-psa/ui`), and server consumers were updated to import from `@alga-psa/ui`.
### Decision 2: Module Boundaries
**Decision**: Feature-based vertical slices over layer-based
**Rationale**:
- Aligns with existing component organization
- Enables independent deployment/testing
- Clear ownership boundaries
- Reduces cross-team conflicts
### Decision 3: Next.js Routes Location
**Decision**: Keep all routes in single `server/` project
**Rationale**:
- Next.js requirement - App Router needs single entry
- Routes become thin shims calling into feature modules
- API routes can delegate to feature modules
### Decision 4: Migration Strategy
**Decision**: Incremental, bottom-up
**Rationale**:
- Start with horizontal slices (already partially exist in `shared/`)
- Add vertical slices one feature at a time
- Maintain backwards compatibility during migration
- Can deploy incrementally
---
## Technical Constraints
1. **Next.js App Router**: All routes must remain in single project
2. **CitusDB**: Tenant column requirements affect data layer design
3. **Enterprise Edition**: CE/EE code separation must be maintained
4. **Existing Workspaces**: Must migrate, not break existing package structure
---
## Commands & References
### Useful Commands
```bash
# Current workspace structure
npm ls --workspaces
# Check package dependencies
npm -w server ls
# Run tests for specific workspace
npm -w server test
```
### Key File Paths
- Root package.json: `/package.json`
- Server package.json: `/server/package.json`
- Shared exports: `/shared/package.json`
- Coding standards: `/docs/AI_coding_standards.md`
---
## Open Questions
1. **Billing + Contracts**: Should these be one module or separate?
- Current thinking: Combined as `@alga-psa/billing` (they're tightly coupled)
2. **Email modules**: Consolidated into `@alga-psa/integrations/email` (formerly `product-email-domains`, `product-email-providers`, `product-email-settings`).
3. **Extension packages**: 7 extension-related packages - keep as-is or consolidate?
4. **UI components**: Current ui-kit is minimal - expand or keep ui in each feature?
- Recommendation: Expand ui-kit as `@alga-psa/ui` for all shared components
---
## Migration Order (Proposed)
### Phase 1: Foundation
1. Initialize NX workspace
2. Migrate `shared/` to `@alga-psa/core`, `@alga-psa/db`, `@alga-psa/types`
3. Create `@alga-psa/validation` from existing validation utilities
4. Expand `ui-kit` to `@alga-psa/ui`
### Phase 2: Infrastructure Features
5. Create `@alga-psa/auth` from auth actions/lib
6. Create `@alga-psa/integrations` (consolidate email packages + integrations)
### Phase 3: Core Business Features
7. Create `@alga-psa/clients` (clients + contacts)
8. Create `@alga-psa/billing` (invoicing + contracts)
9. Create `@alga-psa/projects`
10. Create `@alga-psa/tickets`
### Phase 4: Supporting Features
11. Create `@alga-psa/scheduling` (time + dispatch + calendar)
12. Create `@alga-psa/workflows`
13. Create `@alga-psa/documents`
14. Create `@alga-psa/assets`
15. Create `@alga-psa/surveys`
16. Create `@alga-psa/client-portal`
### Phase 5: Optimization
17. Configure NX caching
18. Set up affected commands for CI
19. Optimize build pipeline
---
## Implementation Notes (2026-01-16)
- **@alga-psa/types interface migration**: synced `server/src/interfaces` into `packages/types/src/interfaces`, removed duplicate/stub interface files that caused resolution ambiguity, fixed self-imports inside the types package, and added tests to validate the barrel exports. Inbound email types are exported under `Inbound*` aliases to avoid name collisions with outbound email types.
- **NX graph/tests**: `NX_DAEMON=false` avoids the earlier nx command hangs; added an integration test at `tools/nx-tests/nxWorkspace.test.ts` to validate `nx show projects`, `nx graph --file`, and generator dry-run.
- **Module boundaries**: added ESLint rule `custom-rules/no-feature-to-feature-imports` to prevent `packages/<feature>` vertical packages from importing other vertical packages via `@alga-psa/*` (validated in `tools/nx-tests/moduleBoundaries.test.ts`). `nx lint` is currently too memory-hungry (heap OOM) to use as an enforcement test in this environment.
- **npm workspace protocol**: removed `workspace:*` dependency specifiers from `packages/*/package.json` (replaced with `*`) because npm cannot install/update dependencies when `workspace:` protocol is used.
- **NX caching + affected**: added `npm run test:nx` (vitest config for `tools/nx-tests`) including a cache verification test (`nxCache.test.ts`) and an affected-project selection test (`nxAffected.test.ts`); added `npm run affected:test` and `npm run affected:build` scripts; updated `.github/workflows/typecheck.yml` to run `nx affected -t build`/`test`.
- **@alga-psa/clients vertical slice**: migrated client/contacts actions + components into `packages/clients` and updated the `/msp/clients` + `/msp/contacts` routes to import from `@alga-psa/clients` (and actions from `@alga-psa/clients/actions`); `server npm run build` passes after import rewiring.
- **Tax + client type alignment**: resolved an `ITaxRate` export collision by selectively exporting tax interfaces from `@alga-psa/types` (including `ITaxRateDetails` alias). Also aligned client/contacts typing by using `@alga-psa/types` in key action/components and allowing `client.properties` to be nullable where DB can return null.
---
## Implementation Notes (2026-01-18)
### server/src import cleanup (packages)
- Verified no remaining `from 'server/src'` or `import('server/src/...')` usages under `packages/**`.
### Documents storage self-containment
- Added missing documents storage primitives under `packages/documents/src/`:
- `config/storage.ts` (env/secret-driven storage config + validation)
- `types/storage.ts` (provider + file store types)
- `models/storage.ts` (`FileStoreModel` without `BaseModel`; tenant resolved via `requireTenantId`)
- Rewired documents storage imports to stay within `packages/documents/src/**` (avoids importing files outside the package `src/` root).
- Removed `@alga-psa/users/actions` dependency from documents storage to avoid pulling incomplete user avatar utilities into core storage logic.
### Business-logic tests added
- Scheduling: `packages/scheduling/tests/timePeriodSuggester.test.ts` (run `npm -w packages/scheduling test`)
- Documents: `packages/documents/tests/storageConfig.test.ts` (run `npm -w packages/documents test`)
- Auth: adjusted `packages/auth/src/lib/exports.test.ts` to validate RBAC behavior via the subpath export `@alga-psa/auth/rbac` (keeps the test focused and avoids pulling Next.js UI modules).
### Known tooling limitation (out of scope here)
- `tsc --noEmit` in many packages currently fails with `rootDir`/project-reference issues when TypeScript path aliases pull in other package sources (example: importing `@alga-psa/tenancy/actions` from another package). Unit tests via Vitest are still runnable and used for verification.