# Scratchpad — Storage Extraction & Phase 2 Cleanup

- Plan slug: `storage-extraction-and-phase2-cleanup`
- Created: `2026-02-19`

## What This Is

Rolling notes for the combined PR that finishes Phase 2 remainders and extracts `@alga-psa/storage` from `@alga-psa/documents`.

## Decisions

- (2026-02-19) Storage extraction scope: move file-storage infrastructure only (StorageService, providers, factory, config, types, FileStoreModel). Keep avatar utils + entity image service in documents -- they have circular deps with documentActions.
- (2026-02-19) The `storage/api/` subfolder (key-value storage service) is a DIFFERENT system from file StorageService. Leave it in documents for now -- it's unrelated to the cross-package violation problem.
- (2026-02-19) blocknoteUtils (formatting) is the cleanest extraction candidate (zero deps) but out of scope for this PR. Save for a separate `@alga-psa/formatting` extraction.
- (2026-02-19) Document-association migration: server version uses `BaseModel.getTenant()`, package version uses `requireTenantId()`. Tests mock DocumentAssociation directly -- need to update mock paths. The DocumentAssociation is not exported from `packages/documents/src/models/index.ts` barrel yet -- need to add export.
- (2026-02-19) Email shim: only 1 actual source caller (`surveyService.ts`). The rest are docs/README references (not real imports). Verify at implementation time.
- (2026-02-19) The `server/src/lib/storage/StorageService.ts` file also imports from `@alga-psa/documents` (StorageProviderFactory + generateStoragePath). This is a SEPARATE server-side StorageService wrapper that will need updating too.

## Discoveries / Constraints

- (2026-02-19) StorageService.ts has `@ts-nocheck` at line 1 -- intentional for sharp dynamic import.
- (2026-02-19) StorageService depends on `@alga-psa/event-bus/publishers` for workflow events -- the new storage package will need this dependency.
- (2026-02-19) StorageService depends on `@alga-psa/auth/getCurrentUser` -- import exists but only used in one internal path. Keep dependency.
- (2026-02-19) StorageProviderFactory uses dynamic import for S3 provider (EE only): `await import('./providers/S3StorageProvider')` -- no S3 provider file exists in CE, that's expected.
- (2026-02-19) `server/scripts/portal-domain-sessions-prune.ts` imports from `'server/src/lib/models/PortalDomainSessionToken'` -- this path doesn't exist anymore. The function is exported from `@alga-psa/auth`.
- (2026-02-19) FileStoreModel lives in `packages/documents/src/models/storage.ts` -- must move with StorageService since it's a direct dependency.
- (2026-02-19) External consumers of StorageService (outside documents): billing (1), client-portal (1), jobs (2), server (1) = 5 files.
- (2026-02-19) External consumers of StorageProviderFactory/generateStoragePath (via main documents index): server (3 files).
- (2026-02-19) External consumer of FileStore type: billing (1 file).

## Commands / Runbooks

```bash
# Verify build after changes
npm run build

# Check for remaining references to old paths
grep -r "from '@alga-psa/documents/storage" packages/ server/ ee/ --include="*.ts" --include="*.tsx"
grep -r "StorageProviderFactory.*from '@alga-psa/documents'" packages/ server/ ee/ --include="*.ts" --include="*.tsx"
grep -r "from '@alga-psa/documents/types/storage" packages/ server/ ee/ --include="*.ts" --include="*.tsx"

# Check no references remain to deleted files
grep -r "document-association" server/src/test/ --include="*.ts" --include="*.tsx"
grep -r "lib/models/PortalDomainSessionToken" server/ --include="*.ts"
grep -r "from '@/lib/email'" server/ --include="*.ts" --include="*.tsx"
grep -r "from '../lib/email'" server/ --include="*.ts" --include="*.tsx"
```

## Links / References

- Analysis source: `.ai/stale-code-and-cross-package-analysis.md`
- Previous cleanup plan: `docs/plans/2026-02-17-stale-code-cleanup-phases-2c-2f/`
- Storage source files: `packages/documents/src/storage/`
- Storage config: `packages/documents/src/config/storage.ts`
- Storage types: `packages/documents/src/types/storage.ts`
- Storage model: `packages/documents/src/models/storage.ts`

## Open Questions

- Should `server/src/lib/storage/StorageService.ts` (server-side wrapper around documents' StorageProviderFactory) also be updated or moved? It's a different file from the package StorageService. For this PR: just update its import from `@alga-psa/documents` to `@alga-psa/storage`.

## 2026-02-20 Updates
- F001: Updated `server/scripts/portal-domain-sessions-prune.ts` to import `pruneExpiredPortalDomainOtts` from `@alga-psa/auth` to fix broken path.
- F002: Exported `DocumentAssociation` from `packages/documents/src/models/index.ts` barrel for package consumers.
- F003: Updated `documentActions.upload.test.ts` to mock/import `DocumentAssociation` from `@alga-psa/documents/models/documentAssociation`.
- F004: Switched `documentPermissionsIntegration.test.ts` to import `DocumentAssociation` from the documents package model path.
- F005: Removed obsolete `server/src/models/document-association.ts` after test imports migrated.
- F006: Updated `server/src/services/surveyService.ts` to import `TenantEmailService` from `@alga-psa/email`.
- F007: Deleted `server/src/lib/email/index.ts` shim after confirming no source imports remain.
- F008: Created `packages/storage/package.json` scaffold with required dependencies and build/typecheck scripts.
- F009: Added `packages/storage/project.json` with `scope:storage` + `type:horizontal` tags.
- F010: Added `packages/storage/tsconfig.json` extending the root config.
- F011: Moved `packages/documents/src/types/storage.ts` to `packages/storage/src/types/storage.ts`.
- F012: Moved `packages/documents/src/config/storage.ts` to `packages/storage/src/config/storage.ts`.
- F013: Moved `StorageProvider` base class to `packages/storage/src/providers/StorageProvider.ts`.
- F014: Moved `LocalStorageProvider` to `packages/storage/src/providers/LocalStorageProvider.ts`.
- F015: Moved FileStoreModel (`models/storage.ts`) into `packages/storage/src/models/storage.ts`.
- F016: Moved `StorageProviderFactory.ts` into `packages/storage/src/StorageProviderFactory.ts`.
- F017: Moved `StorageService.ts` to `packages/storage/src/StorageService.ts`.
- F018: Fixed relative imports inside storage package files (`StorageProviderFactory`, `StorageService`, provider classes) after move.
- F019: Added `packages/storage/src/index.ts` barrel exporting storage services, models, config, and types.
- F020: Added `exports` map to `packages/storage/package.json` for storage subpath entrypoints.
- F021: Updated billing `invoiceJobActions.ts` to import `StorageService` from `@alga-psa/storage`.
- F022: Updated client portal `client-project-details.ts` to import `StorageService` from `@alga-psa/storage`.
- F023: Updated jobs `jobService.ts` to import `StorageService` from `@alga-psa/storage`.
- F024: Updated jobs `jobScheduler.ts` to import `StorageService` from `@alga-psa/storage`.
- F025: Updated `server/src/lib/imports/importActions.ts` to import `StorageService` from `@alga-psa/storage`.
- F026: Updated `server/src/services/pdf-generation.service.ts` to import storage helpers from `@alga-psa/storage`.
- F027: Updated documents view API route to import `StorageProviderFactory` from `@alga-psa/storage`.
- F028: Updated server wrapper `StorageService` to import storage helpers from `@alga-psa/storage`.
- F029: Updated billing `pdfGenerationService.ts` to import `FileStore` from `@alga-psa/storage/types/storage`.
- F030: Updated document handlers to import `StorageService` from `@alga-psa/storage/StorageService`.
- F031: Updated `fileActions.ts` to import `StorageService` from `@alga-psa/storage/StorageService`.
- F032: Updated `documentActions.ts` to import `StorageService` from `@alga-psa/storage/StorageService`.
- F033: Updated `entityImageService.ts` to import `StorageService` from `@alga-psa/storage/StorageService`.
- F034: Re-exported `StorageProviderFactory` and `generateStoragePath` from `@alga-psa/storage` in documents index.
- F035: Added documents package export for `./types/storage` and added thin re-export stubs for `StorageService` and storage types.
- F036: Added `@alga-psa/storage` dependency to `packages/documents/package.json`.
- F037: Added `@alga-psa/storage` dependency to billing, client-portal, and jobs package.json files.
- F038: Verified original storage implementation files removed from documents package; only thin re-export shims remain for compatibility.
- F039: Registered `@alga-psa/storage` path mappings in `tsconfig.base.json` (project.json already added earlier).
- T001: Verified portal-domain-sessions-prune import now points to `@alga-psa/auth`.
- T002: Confirmed `DocumentAssociation` is exported from documents models barrel.
- T003: Verified documentActions upload test imports DocumentAssociation from documents package.
- T004: Verified documentPermissions integration test now imports DocumentAssociation from documents package.
- T005: Confirmed `server/src/models/document-association.ts` has been removed.
- T006: Verified `surveyService.ts` imports `TenantEmailService` from `@alga-psa/email`.
- T007: Confirmed `server/src/lib/email/index.ts` removed.
- T008: `rg` found no remaining `@/lib/email` or `../lib/email` imports in server source files.
- T009: Checked `packages/storage/package.json` for name, required deps, and exports entries.
- T010: Verified storage project tags include `type:horizontal`.
- T011: Confirmed storage tsconfig extends root tsconfig.
- T012: Confirmed `./StorageService` export exists and source file is present in storage package.
- T013: Verified storage barrel exports `StorageProviderFactory` and `generateStoragePath`.
- T014: Confirmed `./types/storage` export and source file exist in storage package.
- T015: Verified storage barrel exports `FileStoreModel`.
- T016: Confirmed storage providers export entry and source file for `StorageError`.
- T017: Ran `npx tsc --noEmit -p packages/storage/tsconfig.json` to confirm storage package imports resolve.
- T018: Verified billing invoiceJobActions imports StorageService from `@alga-psa/storage`.
- T019: Verified client portal project details action imports StorageService from `@alga-psa/storage`.
- T020: Verified jobs jobService imports StorageService from `@alga-psa/storage`.
- T021: Verified jobs jobScheduler imports StorageService from `@alga-psa/storage`.
- T022: Verified server importActions imports StorageService from `@alga-psa/storage`.
- T023: Verified pdf-generation service uses storage package imports.
- T024: Verified documents view route imports `StorageProviderFactory` from storage package.
- T025: Verified server StorageService wrapper imports storage helpers from `@alga-psa/storage`.
- T026: Verified billing pdfGenerationService imports `FileStore` from storage types.
- T027: Verified all document handlers import StorageService from `@alga-psa/storage`.
- T028: Verified fileActions imports StorageService from `@alga-psa/storage`.
- T029: Verified documentActions imports StorageService from `@alga-psa/storage`.
- T030: Verified entityImageService imports StorageService from `@alga-psa/storage`.
- T031: Confirmed documents index re-exports `StorageProviderFactory` from storage package.
- T032: Confirmed documents index re-exports `generateStoragePath` from storage package.
- T033: Verified documents exports include `./storage/StorageService` shim and file exists.
- T034: Verified documents exports include `./types/storage` shim and file exists.
- T035: Confirmed storage dependency present in documents, billing, client-portal, and jobs package.json files.
- T036: Confirmed original storage implementation files are removed from documents package (only compatibility shims remain).
- T037: Verified tsconfig path mappings include `@alga-psa/storage`.
- Added F040/T041: Next.js build failed resolving `@alga-psa/storage/StorageService` because server tsconfig paths lacked storage mapping; adding explicit path mapping to server/tsconfig.json.
- F040: Added @alga-psa/storage path mappings to `server/tsconfig.json` to satisfy Next.js module resolution.
- T041: Verified server tsconfig now maps `@alga-psa/storage` paths.
- Added F041/T042: Next build exposed `VideoDocumentHandler` still importing storage factory from deleted path; update to storage package.
- F041: Updated `VideoDocumentHandler` to import `StorageProviderFactory` from `@alga-psa/storage`.
- T042: Verified VideoDocumentHandler now imports StorageProviderFactory from storage package.
- Build attempt: `npm run build` timed out after 240s during Next.js build (no error before timeout).
- T039: Confirmed no source files reference `server/src/models/document-association`.
- T040: Confirmed no source files reference `lib/models/PortalDomainSessionToken`.
- Build attempt: `npm run build` progressed to Next.js build, then failed with OOM (heap out of memory) after warnings about workflow export conflicts and webpack critical deps.
- Added F042/T043: Next build failed because fileActions still referenced removed documents storage model/type paths; updated to storage package.
- F042: Updated `fileActions.ts` to pull FileStoreModel and FileStore from the storage package.
- T043: Verified fileActions imports storage model and type from `@alga-psa/storage`.
- Build attempt: `NODE_OPTIONS=--max-old-space-size=8192 npm run build` ran through Next build with warnings and static page generation, but command timed out at 6m (no success signal).
- T038: `NODE_OPTIONS=--max-old-space-size=8192 npm run build` completed successfully (warnings only).
