Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
7.4 KiB
Scratchpad: Tax Import Service Porting + BackNav Fix + Notification Reconciliation
Decisions
-
Skip adapters and externalTaxImportService — Moving accounting adapters to
@alga-psa/integrationscreates a circular dependency: integrations→billing→integrations (adapters importAccountingMappingResolveretc. from billing; billing importsQboClientService/XeroClientServicefrom integrations). Deferred to future PR with a strategy to extract shared types to@alga-psa/typesfirst. -
Adopt package notification email.ts version — rate limiting is centralized in
TenantEmailService.sendEmail(), inline check in server version is redundant. -
Keep server emailLocaleResolver.ts —
sendEventEmail.tsimports it locally. Don't force server infrastructure to import from package. -
Delete orphan invoiceAdapters.ts — zero callers in server; the billing package has its own independent copy at
packages/billing/src/lib/adapters/invoiceAdapters.ts. -
Use
@alga-psa/corefor parseCSV — csvTaxImportService currently imports fromserver/src/lib/utils/csvParser, but@alga-psa/coreexports the same function (already used by XeroCsvTaxImportService in the integrations package).
Key File Paths
Tax Import Services
- Source:
server/src/lib/services/csvTaxImportValidator.ts(745 LOC) - Source:
server/src/lib/services/csvTaxImportService.ts(595 LOC) - Source:
server/src/lib/utils/csvFieldNormalizer.ts(323 LOC) - Target:
packages/integrations/src/services/andpackages/integrations/src/lib/ - Barrel:
packages/integrations/src/services/index.ts(currently:export * from './email') - Reference pattern:
packages/integrations/src/services/xeroCsvTaxImportService.ts - Caller:
server/src/lib/api/controllers/ApiCSVAccountingController.ts
BackNav Fix
- Fix:
packages/ui/src/components/BackNav.tsxline 7 - Target:
packages/ui/src/context/UnsavedChangesContext.tsx(identical API)
Notification Dual-Copies
- Delete:
server/src/lib/notifications/email.ts(561 LOC) - Delete:
server/src/lib/notifications/emailChannel.ts(7 LOC, identical to package) - Keep:
server/src/lib/notifications/emailLocaleResolver.ts(255 LOC) - Keep:
server/src/lib/notifications/emailService.ts(273 LOC) - Keep:
server/src/lib/notifications/sendEventEmail.ts(509 LOC) - Keep:
server/src/lib/notifications/NotificationAccumulator.ts(459 LOC) - Package barrel:
packages/notifications/src/index.ts— addgetEmailNotificationServiceexport - Package email.ts:
packages/notifications/src/notifications/email.ts(504 LOC) - Package emailChannel:
packages/notifications/src/emailChannel.ts(already in barrel)
Orphan Deletion
- Delete:
server/src/lib/adapters/invoiceAdapters.ts(0 callers)
Discoveries
Circular Dependency: Adapters ↔ Billing
server/src/lib/adapters/accounting/quickBooksOnlineAdapter.tsimports from@alga-psa/billing(AccountingMappingResolver, CompanyAccountingSyncService, etc.)server/src/lib/adapters/accounting/xeroAdapter.tsimports from@alga-psa/billing(same)server/src/lib/adapters/accounting/quickBooksCSVAdapter.tsimports from@alga-psa/billingserver/src/lib/adapters/accounting/xeroCsvAdapter.tsimports from@alga-psa/billingpackages/billing/src/services/companySync/adapters/xeroCompanyAdapter.tsimports from@alga-psa/integrationspackages/billing/src/services/companySync/adapters/quickBooksCompanyAdapter.tsimports from@alga-psa/integrations- Adding
@alga-psa/billingto integrations package.json → circular dependency
Type Availability
TaxSource,IExternalTaxImport,IExternalTaxImportResult— all in@alga-psa/types✓AccountingExportBatch,AccountingExportLine— inpackages/types/src/interfaces/accountingExport.interfaces.tsbut NOT exported from barrel (needed for future adapter migration)parseCSV— available from@alga-psa/core✓
Notification Differences
- Server email.ts (561 LOC) vs package email.ts (504 LOC): server has inline rate limiting (lines 399-412) that package removed
- emailLocaleResolver: functionally identical between server (255 LOC) and package (212 LOC), just different import paths
- emailChannel: byte-for-byte identical (7 LOC each)
- Package barrel already exports
emailChannelbut NOTEmailNotificationService/getEmailNotificationService
Callers Summary
csvTaxImportService:
server/src/lib/api/controllers/ApiCSVAccountingController.ts—getCSVTaxImportService
email.ts (EmailNotificationService):
server/src/lib/jobs/handlers/expiringCreditsNotificationHandler.ts—getEmailNotificationService
emailChannel:
server/src/lib/eventBus/subscribers/ticketEmailSubscriber.ts—getEmailEventChannelserver/src/lib/eventBus/subscribers/projectEmailSubscriber.ts—getEmailEventChannelserver/src/lib/eventBus/publishers/index.ts—getEmailEventChannelserver/src/lib/api/services/TicketService.ts—getEmailEventChannelserver/src/test/integration/ticketEmailDelimiters.test.ts—EMAIL_EVENT_CHANNEL
Implementation Order
- Move csvFieldNormalizer.ts → packages/integrations/src/lib/
- Move csvTaxImportValidator.ts → packages/integrations/src/services/ (update csvFieldNormalizer import)
- Move csvTaxImportService.ts → packages/integrations/src/services/ (update db, types, parseCSV imports)
- Update integrations services barrel
- Update ApiCSVAccountingController.ts caller
- Delete server copies of tax services + csvFieldNormalizer
- Fix BackNav.tsx import
- Add getEmailNotificationService to notifications barrel
- Update 6 notification callers
- Delete server email.ts and emailChannel.ts
- Delete orphan invoiceAdapters.ts
- Verify build (npm run build && npm run build:shared)
Gotchas
parseCSVsignature: verify@alga-psa/core'sparseCSVreturnsstring[][](same as server'scsvParser). XeroCsvTaxImportService uses it withas string[][]cast.csvTaxImportValidator.tsusesanytype for knex parameter — keep as-is, don't try to type-narrow in this PR.- The
packages/integrations/src/services/index.tscurrently only exports./email. Adding CSV tax exports here. Make sure the export doesn't conflict with any existing names. - After deleting server emailChannel.ts, verify that
sendEventEmail.tsdoesn't import from it (it doesn't — only imports fromemailLocaleResolver). - DISCOVERED during implementation:
emailService.ts(kept in server) also imports from./emailChannel— needed to update this caller too (not in original plan's caller list). Updated to@alga-psa/notifications. - DISCOVERED during implementation:
UnsavedChangesContextinpackages/ui/src/context/UnsavedChangesContext.tsxwas declared withconst(notexport const). The server version exports it directly. Had to addexportkeyword to the package version for BackNav.tsx to import it.
Commands
# Verify build after changes
npm run build:shared && npm run build
# Check for remaining boundary violations
grep -r "from 'server/src/lib/services/csvTaxImport" --include="*.ts" --include="*.tsx" | grep -v "docs/"
grep -r "from 'server/src/contexts/UnsavedChangesContext" --include="*.ts" --include="*.tsx" packages/
grep -r "from.*lib/notifications/emailChannel" --include="*.ts" --include="*.tsx" server/src/
grep -r "from.*lib/notifications/email'" --include="*.ts" --include="*.tsx" server/src/