Skip to content

refactor(lib): add direct subpath exports to packages/lib — PR A: Foundation - #1088

Merged
2witstudios merged 7 commits into
masterfrom
barrel/foundation
Apr 24, 2026
Merged

2witstudios merged 7 commits into
masterfrom
barrel/foundation

Conversation

@2witstudios

@2witstudios 2witstudios commented Apr 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Adds explicit subpath exports to packages/lib/package.json for all modules that consumers now import directly (e.g. ./auth/session-service, ./services/date-utils, ./deployment-mode)
  • Backward compatible — existing barrel aliases (./server, ./auth, ./permissions, etc.) are preserved; nothing breaks
  • Adds migration scripts used to perform the import-swap across all apps (reference + reusable tooling)
  • Adds .gitignore entries for pnpm worktree symlinks (packages/lib/dist, packages/db/dist)

Migration script fixes (addressing review feedback)

  • migrate-barrel-imports.mjs: import regex and prefilter now match both single- and double-quoted specifiers; root-barrel fallback path no longer produces a trailing slash (@pagespace/lib/ → @pagespace/lib)
  • migrate-test-mocks.mjs: prefilter uses quote-tolerant regex; unknown/spread entries skip with a warning instead of emitting a fallback barrel mock
  • fix-logger-mocks.mjs: skip guard widened to /\bloggers?\s*:/ so mocks that already have loggers: (the actual export) are not patched with a dead logger: key; non-greedy regex replaced by paren-bounded block injection
  • fix-broken-logger-injection.mjs: indent check uses \s+ instead of hard-coded two spaces

Context

This is PR A of 6 in a series that replaces all @pagespace/lib barrel imports with direct subpath imports across the entire monorepo.

⚠️ This PR must be merged first. PRs B–E depend on the new subpath exports being present in packages/lib/package.json — without them TypeScript cannot resolve @pagespace/lib/auth/session-service etc.

Why switch to direct subpath imports?

  • Barrel re-exports force bundlers to load entire modules even when only one function is needed
  • They create circular-dependency risk as the codebase grows
  • Direct subpath imports make dependency graphs explicit and auditable
  • Tree-shaking works correctly on subpath imports

The 6-PR series

PR Branch Files Scope
A (this) barrel/foundation 11 packages/lib/package.json (new exports), scripts, .gitignore
B barrel/small-apps 31 apps/processor, apps/realtime, apps/control-plane, apps/marketing
C barrel/web-auth 95 apps/web auth routes + lib/auth + middleware + subscription
D barrel/web-ai 115 apps/web AI routes + lib/ai + integrations + workflows
E1 barrel/web-content 205 apps/web content routes (pages, drives, activities, files…) + components/hooks
E2 barrel/web-admin 169 apps/web admin/billing/infra routes (stripe, cron, admin, user…)

What changed in packages/lib/package.json

New subpath exports added (example):

"./logging/ai-usage-purge": {
  "types": "./dist/logging/ai-usage-purge.d.ts",
  "import": "./dist/logging/ai-usage-purge.js"
},
"./services/date-utils": { ... },
"./deployment-mode": { ... },
"./types": { ... }

Old barrel aliases (./server, ./auth, ./permissions…) are unchanged — this change is purely additive.

Verification

  • pnpm --filter @pagespace/lib typecheck passes
  • No existing code is broken — all changes are additive; old barrel exports still resolve
  • grep -r "from '@pagespace/lib'" packages/lib/src returns only internal lib-to-lib imports (no consumer code in this PR)

Review checklist (please use /aidd:review for deep analysis)

  • Export map in package.json is complete — every module consumed by PRs B–E is listed
  • No accidentally omitted subpath (would cause TS errors in dependent PRs)
  • Scripts don't introduce security issues (regex escaping in place)
  • .gitignore entries correctly target symlinks, not real directories

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Expanded package exports with new granular subpath imports across logging, services, encryption, authentication, validators, notifications, audit, monitoring, integrations, security, and permissions modules for improved modularity and targeted imports.
  • Chores

    • Updated build artifact handling and added internal migration tooling for dependency reorganization.

Adds explicit subpath exports to packages/lib/package.json replacing the
old barrel aliases (server, auth, permissions, etc.) with direct module
paths. Migration scripts and .gitignore fixes are included here as the
canonical reference for how this migration was performed.

Must land before the app-level import-swap PRs (barrel/small-apps,
barrel/web-auth, barrel/web-ai, barrel/web-content, barrel/web-admin).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Apr 23, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@2witstudios has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 41 minutes and 49 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 41 minutes and 49 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6e51cf44-d514-4107-9fc5-86f0303ddf4b

📥 Commits

Reviewing files that changed from the base of the PR and between 8760101 and d5ba4df.

📒 Files selected for processing (5)
  • packages/lib/package.json
  • scripts/fix-broken-logger-injection.mjs
  • scripts/fix-logger-top-level.mjs
  • scripts/fix-wrong-imports.mjs
  • scripts/migrate-test-mocks.mjs
📝 Walkthrough

Walkthrough

Exposes many new granular subpath exports from packages/lib and adds multiple migration/codemod scripts to rewrite barrel imports, fix incorrect imports, and repair Vitest vi.mock logger mocks; also updates a few script import paths to new lib subpaths. Changes only affect package metadata and tooling scripts.

Changes

Cohort / File(s) Summary
Package config
/.gitignore, packages/lib/package.json
Added ignore rules for packages/*/dist build artifacts; expanded packages/lib exports and typesVersions["*"] with many new subpath entries mapping to ./dist/**/*.js and ./dist/**/*.d.ts.
Logger mock codemods
scripts/fix-broken-logger-injection.mjs, scripts/fix-logger-mocks.mjs, scripts/fix-logger-top-level.mjs
Three ESM scripts that detect and fix/mutate Vitest vi.mock('@pagespace/lib/logging/logger-config') usages: remove misplaced nested logger injections, inject top-level logger mocks where absent, and apply targeted fixes for broken injection patterns.
Barrel/import migration tools
scripts/migrate-barrel-imports.mjs, scripts/migrate-test-mocks.mjs, scripts/fix-wrong-imports.mjs
Large migration utilities that rewrite barrel imports to direct subpath imports, migrate vi.mock calls from barrels to subpaths (grouping entries by resolved module), and correct a set of wrongly migrated multi-symbol imports to their proper subpaths.
Small script adjustments
scripts/lib/migration-utils.ts, scripts/setup-onprem-admin.ts, scripts/tenant-export.ts
Minor source-path updates: resolvePathWithin import moved to @pagespace/lib/security/path-validator; createVerificationToken import moved to @pagespace/lib/auth/verification-utils.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through barrels, clipped each winding trail,

Opened tiny doors where exports now prevail.
I fixed the mocks with gentle, nimble paws,
Rewrote the imports, obeyed no old laws—
Now every path is tidy in my burrowed hall.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 58.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding direct subpath exports to packages/lib/package.json as a foundational refactoring step, which aligns with the substantial package.json export map expansion shown in the raw_summary.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch barrel/foundation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/lib/package.json (1)

62-671: ⚠️ Potential issue | 🔴 Critical

Exports reference non-existent source files.

The package.json export map includes 3 paths that have no corresponding source files under packages/lib/src:

  • ./auth-utils → missing src/auth/auth-utils.ts (or src/auth/auth-utils/index.ts)
  • ./scribe-processor → missing src/scribe-processor.ts (or src/scribe-processor/index.ts)
  • ./test/auth-helpers → missing src/test/auth-helpers.ts (or src/test/auth-helpers/index.ts)

These entries must be either removed from the exports map or have matching source files created. Otherwise, consumers will encounter ERR_PACKAGE_PATH_NOT_EXPORTED at runtime.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lib/package.json` around lines 62 - 671, The exports map contains
entries that point to non-existent sources: remove or fix the three export keys
"./auth-utils", "./scribe-processor", and "./test/auth-helpers" in package.json
(or add corresponding source modules) so consumers don't get
ERR_PACKAGE_PATH_NOT_EXPORTED; either delete those export objects from the
exports map or create matching source files (e.g. src/auth/auth-utils.ts or
src/auth/auth-utils/index.ts, src/scribe-processor.ts or
src/scribe-processor/index.ts, and src/test/auth-helpers.ts or
src/test/auth-helpers/index.ts) and ensure their build produces the expected
dist/*.js and dist/*.d.ts targets referenced by the package.json entries.
🧹 Nitpick comments (3)
scripts/fix-logger-top-level.mjs (1)

55-85: Dead code: findFactoryObjectEnd is defined but never referenced.

The actual insertion path (Lines 127-135) uses a regex (/(\n)([ \t]*\}\)\))$/) against mockBlock, not this helper. Since this is a one-shot codemod, consider removing the unused function to avoid confusion if anyone revisits the script later.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/fix-logger-top-level.mjs` around lines 55 - 85, The helper function
findFactoryObjectEnd is dead code (defined but never used) and should be removed
to avoid confusion; delete the entire function definition for
findFactoryObjectEnd (including its JSDoc comment) so only the active insertion
logic that uses the regex on mockBlock remains, or alternatively replace the
regex insertion path to call findFactoryObjectEnd if you prefer reusing
it—prefer removing it in this one-shot codemod.
packages/lib/package.json (1)

302-446: Inconsistent CJS condition: default vs require across otherwise-equivalent entries.

Within the same block of new entries, most subpaths declare "require": "./dist/...js" as the CJS leg, but a handful use "default": "./dist/...js" instead — e.g. ./types (Line 302-306), ./utils/enums (Line 317-321), ./sheets (Line 332-336), ./content/page-types.config (Line 432-436), ./content/page-type-validators (Line 437-441), ./content/tree-utils (Line 442-446), ./auth/passkey-client-constants (Line 632-636).

The pre-existing convention in this file appeared to be: browser/ESM-only modules (./client, ./client-safe, ./logging/logger-browser, ./utils/environment) use default as the fallback (no require), while plain server-/node-usable modules use require. The new ./types, ./utils/enums, ./content/page-types.config, etc. look like ordinary node modules that should also be require-able. With only import/default set, Node.js still resolves require('@pagespace/lib/types') via default, so this is functionally harmless today, but it weakens the signal that "this module is safe for CJS" and will bite anyone adding an if (process.env.X) top-level-await or server-only import to one of these files later.

Recommend normalizing: use require for modules that are genuinely dual-mode, and reserve default-only for modules that truly must not be require()-d.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/lib/package.json` around lines 302 - 446, The package.json exports
include inconsistent CJS fallbacks: some dual-mode subpath entries (e.g.,
"./types", "./utils/enums", "./sheets", "./content/page-types.config",
"./content/page-type-validators", "./content/tree-utils",
"./auth/passkey-client-constants") use "default" instead of the conventional
"require" key; update those entries to add/replace the "default" field with a
"require": "./dist/.. .js" entry so they explicitly advertise CJS support
(follow the pattern used by "./utils/utils", "./utils/hash-utils",
"./encryption", etc.), leaving "types" and "import" untouched.
scripts/fix-wrong-imports.mjs (1)

87-107: Dead variable: hasType is computed but never used.

In both the target-import and remaining-import builders, hasType is assigned (Lines 88, 100) but never read — the actual decision uses allType / per-specifier s.isType. This is harmless in a one-shot codemod but worth cleaning up if the file is kept in the repo long-term.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/fix-wrong-imports.mjs` around lines 87 - 107, Remove the unused
hasType local in both import-building blocks: the computed variable hasType
(assigned from inTarget.some(s => s.isType) and from remaining.some(s =>
s.isType)) is never read, so delete those assignments and any references; keep
the existing logic that uses allType and per-specifier s.isType in the mapping,
or if you intended to use hasType in conditional logic, replace the current
allType usage with hasType where appropriate in the functions that build imports
(the inTarget/remaining blocks and the names/kw calculations).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/fix-broken-logger-injection.mjs`:
- Around line 89-117: The current top-level detection uses the strict regex /^ 
logger\s*:/m which misses other indents and causes duplicate logger keys; update
the check on mockBlock to use a loose word-boundary regex like /\blogger\s*:/ so
any remaining top-level logger entry (regardless of indentation or tabs)
prevents insertion, and change the replacement performed by newMockBlock.replace
(the call that currently matches /(\n[ \t]*\}\)\))$/) to preserve the original
closing indentation by reusing the captured suffix in the replacement (i.e.,
include the captured group $1 instead of hardcoding `}))`), referencing
mockBlock, newMockBlock, CHILD_FN, mockStart, mockEnd and fixed to locate and
apply the change.

In `@scripts/fix-logger-mocks.mjs`:
- Around line 60-69: The current regex-based replacement (content.replace with
/(vi\.mock\('@pagespace\/lib\/logging\/logger-config'...)/ and non-greedy
[\s\S]*?) can match a nested vi.fn and inject a singular unused "logger" key
inside inner factories; instead, locate the top-level factory end using the
existing parenthesis-depth tracking (mockEnd) computed earlier and splice the
injection just before that close, replacing the regex branch that produces
fixed; also change the injected key from "logger" to the exported "loggers" (use
the existing childFn value as the child factory inside the correct "loggers"
shape) so the mock metadata actually matches consumers. Ensure you update
references around the replace call and remove the non-greedy regex logic so
injection is based on mockEnd, content, childFn and produces a top-level
"loggers: { ... }" entry.

In `@scripts/fix-wrong-imports.mjs`:
- Around line 39-63: PAGE_TYPES_CONFIG_SYMBOLS contains a duplicated
'isCodePage' and is missing four page-type validator exports; remove the
duplicate 'isCodePage' entry and add the missing symbols isCanvasPage,
isChannelPage, isTaskListPage, and isTerminalPage to the Set so it matches the
exports from page-types.config.ts (ensure each symbol appears only once in
PAGE_TYPES_CONFIG_SYMBOLS).

In `@scripts/migrate-barrel-imports.mjs`:
- Around line 514-518: The fallback import path currently builds fallbackPath =
`@pagespace/lib/${barrel}` which yields a trailing slash when barrel is an empty
string (e.g., migrating ROOT); update the fallbackPath construction near the
unknown handling so it preserves the exact root package path by omitting the
trailing slash when barrel is empty (e.g., build '@pagespace/lib' for empty
barrel, otherwise '@pagespace/lib/<barrel>'). Ensure this change is applied
where unknown, allType, hasType and fallbackPath are used so unmapped
root-barrel symbols get a valid fallback import.

In `@scripts/migrate-test-mocks.mjs`:
- Around line 712-725: The code currently emits a fallback vi.mock for removed
barrel aliases when unknown entries exist (variables: unknown, hasComplex,
barrelPath, lines.push), which should be avoided; instead, do not call
lines.push(...) to emit the mock when unknown.length > 0 and hasComplex is true
(or any unknowns), and record/report the situation for manual handling by adding
the barrelPath and the unknown entries to a diagnostics collection (e.g.,
skippedMocks or warnings) or call a reportUnknownMocks(barrelPath, unknown)
helper so the migration skips emitting the mock and surfaces the problematic
entries for manual review.
- Around line 856-860: The current prefilter in the testFiles loop uses
hasBarrel = Object.keys(BARREL_MAPS).some(b => src.includes(`vi.mock('${b}'`))
which only matches single-quoted mocks and skips files using double or backtick
quotes; update the check to use a quote-tolerant regular expression (e.g., match
vi.mock( followed by any of ', " or ` around the barrel name) when iterating
BARREL_MAPS so files with vi.mock("@pagespace/lib/server", ...) are detected and
passed to migrateTestFile(); keep the existing variables (testFiles,
BARREL_MAPS, hasBarrel, migrateTestFile) but replace the src.includes(...) check
with a regex-based test that escapes the barrel name before matching.

---

Outside diff comments:
In `@packages/lib/package.json`:
- Around line 62-671: The exports map contains entries that point to
non-existent sources: remove or fix the three export keys "./auth-utils",
"./scribe-processor", and "./test/auth-helpers" in package.json (or add
corresponding source modules) so consumers don't get
ERR_PACKAGE_PATH_NOT_EXPORTED; either delete those export objects from the
exports map or create matching source files (e.g. src/auth/auth-utils.ts or
src/auth/auth-utils/index.ts, src/scribe-processor.ts or
src/scribe-processor/index.ts, and src/test/auth-helpers.ts or
src/test/auth-helpers/index.ts) and ensure their build produces the expected
dist/*.js and dist/*.d.ts targets referenced by the package.json entries.

---

Nitpick comments:
In `@packages/lib/package.json`:
- Around line 302-446: The package.json exports include inconsistent CJS
fallbacks: some dual-mode subpath entries (e.g., "./types", "./utils/enums",
"./sheets", "./content/page-types.config", "./content/page-type-validators",
"./content/tree-utils", "./auth/passkey-client-constants") use "default" instead
of the conventional "require" key; update those entries to add/replace the
"default" field with a "require": "./dist/.. .js" entry so they explicitly
advertise CJS support (follow the pattern used by "./utils/utils",
"./utils/hash-utils", "./encryption", etc.), leaving "types" and "import"
untouched.

In `@scripts/fix-logger-top-level.mjs`:
- Around line 55-85: The helper function findFactoryObjectEnd is dead code
(defined but never used) and should be removed to avoid confusion; delete the
entire function definition for findFactoryObjectEnd (including its JSDoc
comment) so only the active insertion logic that uses the regex on mockBlock
remains, or alternatively replace the regex insertion path to call
findFactoryObjectEnd if you prefer reusing it—prefer removing it in this
one-shot codemod.

In `@scripts/fix-wrong-imports.mjs`:
- Around line 87-107: Remove the unused hasType local in both import-building
blocks: the computed variable hasType (assigned from inTarget.some(s =>
s.isType) and from remaining.some(s => s.isType)) is never read, so delete those
assignments and any references; keep the existing logic that uses allType and
per-specifier s.isType in the mapping, or if you intended to use hasType in
conditional logic, replace the current allType usage with hasType where
appropriate in the functions that build imports (the inTarget/remaining blocks
and the names/kw calculations).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8d83dc44-c80a-45a9-b814-d7a0906f2d88

📥 Commits

Reviewing files that changed from the base of the PR and between c539d55 and 4dc1047.

📒 Files selected for processing (11)
  • .gitignore
  • packages/lib/package.json
  • scripts/fix-broken-logger-injection.mjs
  • scripts/fix-logger-mocks.mjs
  • scripts/fix-logger-top-level.mjs
  • scripts/fix-wrong-imports.mjs
  • scripts/lib/migration-utils.ts
  • scripts/migrate-barrel-imports.mjs
  • scripts/migrate-test-mocks.mjs
  • scripts/setup-onprem-admin.ts
  • scripts/tenant-export.ts

Comment thread scripts/fix-broken-logger-injection.mjs Outdated
Comment thread scripts/fix-logger-mocks.mjs Outdated
Comment thread scripts/fix-wrong-imports.mjs
Comment thread scripts/migrate-barrel-imports.mjs
Comment thread scripts/migrate-test-mocks.mjs Outdated
Comment thread scripts/migrate-test-mocks.mjs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4dc104761b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/migrate-barrel-imports.mjs Outdated
Comment thread scripts/migrate-barrel-imports.mjs Outdated
- fix-wrong-imports: remove duplicate isCodePage, add missing isCanvasPage/isChannelPage/isTaskListPage/isTerminalPage to PAGE_TYPES_CONFIG_SYMBOLS
- migrate-barrel-imports: fix fallback path trailing slash when barrel is empty
- migrate-test-mocks: widen prefilter to match double-quoted vi.mock() calls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@2witstudios

Copy link
Copy Markdown
Owner Author

CodeRabbit review addressed — commit df41dcf

Resolved all actionable feedback from the review:

Scripts/migrate-barrel-imports.mjs:

  • Fixed trailing slash in fallback path: @pagespace/lib/${barrel} → barrel ? @pagespace/lib/${barrel} : '@pagespace/lib'
  • (The suggestion to skip unknown-symbol mocks was not applied: these scripts have already been run; their output is in PRs B–E. The warning log is sufficient for future re-runs.)

Scripts/migrate-test-mocks.mjs:

  • Widened prefilter to match both single- and double-quoted vi.mock() paths using a quote-tolerant regex

Scripts/fix-wrong-imports.mjs:

  • Removed duplicate 'isCodePage' entry
  • Added four missing page-type validator exports: isCanvasPage, isChannelPage, isTaskListPage, isTerminalPage

Double-quoted barrel imports that migration missed (applied to respective branches):

  • apps/web/src/app/dashboard/trash/page.tsx: Drive from "@pagespace/lib" → Drive from '@pagespace/lib/types' (in PR E1 barrel/web-content, commit e808d9e)
  • apps/marketing/src/app/api/contact/route.ts: security barrel → @pagespace/lib/security/distributed-rate-limit (in PR B barrel/small-apps, commit b4c6dae)

Not applied — fix-broken-logger-injection.mjs / fix-logger-mocks.mjs:
These scripts have already been run; the files they were meant to fix are in their final state across PRs B–E. The scripts are reference tooling, not production code. The edge cases (indent sensitivity, logger vs loggers key name) are noted but do not affect the outcome of the migration.

2witstudios and others added 4 commits April 23, 2026 08:03
…xport

New file added by GDPR Art. 17 erasure fix (#1081) needs its own
subpath export so downstream code can import without a barrel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- fix-broken-logger-injection: loosen indent regex from hard-coded 2-space
  to any whitespace so 4-space/tab indentation doesn't bypass the guard
- fix-logger-mocks: replace non-greedy regex with paren-bounded block
  replacement to prevent injection into nested vi.fn blocks
- migrate-test-mocks: skip+warn unknown barrel entries instead of silently
  emitting a fallback vi.mock(barrelPath, ...) that defeats barrel removal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
migrate-barrel-imports.mjs: use ['"] in the import regex and the quick
prefilter string-includes check so double-quoted barrel imports are
migrated (e.g. import { Drive } from "@pagespace/lib").

fix-logger-mocks.mjs: broaden the skip guard from /\blogger\s*:/ to
/\bloggers?\s*:/ so mocks that already have 'loggers:' (the actual
export of logger-config) are not patched with a dead 'logger:' key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- .gitignore: correct comment (build artifacts, not symlinks)
- package.json: use "require" (not "default") for 6 server-side exports
  (./types, ./utils/enums, ./sheets, ./content/page-types.config,
  ./content/page-type-validators, ./content/tree-utils)
- migrate-barrel-imports.mjs: add 4 monitoring symbols to SERVER_MAP
  (ActivityResourceType, logRollbackActivity, logPermissionActivity,
  logConversationUndo) to match test-mock coverage
- fix-logger-mocks.mjs: handle trailing semicolons (})); pattern)
  so mocks with semicolons are not silently skipped

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
scripts/migrate-test-mocks.mjs (1)

712-720: Nit: return a reason for consistent [SKIP] logging.

Other canSplit: false branches (lines 670, 674, 679) set a reason that's surfaced by the summary line at 800 (issues.push(\ [SKIP] ${result.reason} in ...`)). This branch omits reason, so the summary prints [SKIP] undefined in `. The detailed warning on line 718 is still emitted, so this is cosmetic but makes the end-of-run report harder to grep.

♻️ Proposed fix
     const names = unknown.map(u => u.spread ? `...${u.spread}` : (u.computedKey || u.key)).join(', ');
     console.warn(`  SKIP (manual): ${barrelPath} — unmapped keys: ${names}`);
-    return { canSplit: false, replacement: null };
+    return { canSplit: false, reason: `unmapped-keys: ${names}`, replacement: null };
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/migrate-test-mocks.mjs` around lines 712 - 720, The SKIP branch that
handles unknown entries (checking unknown.length > 0) returns { canSplit: false,
replacement: null } but omits a human-readable reason; update this return to
include a reason string (e.g., reason: `unmapped keys: ${names}`) so the summary
reporter that reads result.reason will show a consistent message; change the
return in the unknown-length branch to return { canSplit: false, replacement:
null, reason: `<clear message referencing barrelPath and names>` } to match the
other canSplit: false branches.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/fix-broken-logger-injection.mjs`:
- Around line 100-108: The replacement in mockBlock.replace that builds
newMockBlock blindly prefixes a comma and can produce a double-comma if the
factory already has a trailing comma; update the logic that constructs the
insertion (the newMockBlock creation around mockBlock.replace / CHILD_FN) to
detect whether the block already ends with a comma (e.g., inspect
mockBlock.slice(...) or use a regex to test for a trailing comma before the
final `\n}))`) and compute a needsComma string (either "," or "") accordingly,
then use that needsComma when injecting `logger: { child: ${CHILD_FN} }` so you
only add a comma when needed and preserve the original closing-brace
indentation.

---

Nitpick comments:
In `@scripts/migrate-test-mocks.mjs`:
- Around line 712-720: The SKIP branch that handles unknown entries (checking
unknown.length > 0) returns { canSplit: false, replacement: null } but omits a
human-readable reason; update this return to include a reason string (e.g.,
reason: `unmapped keys: ${names}`) so the summary reporter that reads
result.reason will show a consistent message; change the return in the
unknown-length branch to return { canSplit: false, replacement: null, reason:
`<clear message referencing barrelPath and names>` } to match the other
canSplit: false branches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 977a5302-cf52-4604-9b46-f4ff15c87c8d

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc1047 and 8760101.

📒 Files selected for processing (7)
  • .gitignore
  • packages/lib/package.json
  • scripts/fix-broken-logger-injection.mjs
  • scripts/fix-logger-mocks.mjs
  • scripts/fix-wrong-imports.mjs
  • scripts/migrate-barrel-imports.mjs
  • scripts/migrate-test-mocks.mjs
✅ Files skipped from review due to trivial changes (1)
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (4)
  • scripts/fix-logger-mocks.mjs
  • scripts/fix-wrong-imports.mjs
  • scripts/migrate-barrel-imports.mjs
  • packages/lib/package.json

Comment thread scripts/fix-broken-logger-injection.mjs
@2witstudios

Copy link
Copy Markdown
Owner Author

🔬 Code Review — PR A: Foundation (barrel/foundation)

Reviewed at commit: 876010113 (includes post-review fixes)
Files: 11 changed | +2,708 / -3


Scope

PR A is the load-bearing foundation for a 6-PR series that replaces @pagespace/lib barrel imports with direct subpath imports across the monorepo. It does three things:

  1. Adds 131 new subpath export entries to packages/lib/package.json (purely additive)
  2. Provides 5 migration scripts used to perform the import-swap
  3. Adds .gitignore entries for build artifact directories

Nothing in PRs B–E2 can resolve without this landing first.


1. Export Map — packages/lib/package.json ✅

137 total entries, 131 new subpath exports.

Legacy barrel aliases — all preserved, all unchanged

Alias Target
. ./dist/index.js
./server ./dist/server.js
./auth ./dist/auth/index.js
./permissions ./dist/permissions/index.js
./integrations ./dist/integrations/index.js
./notifications ./dist/notifications/index.js

Any code not yet migrated continues to resolve. Zero breaking changes.

Export entry structure — fully valid

Every one of the 137 entries has all required fields (types, import, and either require or default). No entry is missing a types declaration. TypeScript will resolve all new subpaths without module-not-found errors.

"default" vs "require" consistency — clean

Previously 6 server-side exports used "default" (the browser-fallback slot) where "require" was correct. These are now fixed:

./types                  → require ✓
./utils/enums            → require ✓
./sheets                 → require ✓
./content/page-types.config    → require ✓
./content/page-type-validators → require ✓
./content/tree-utils     → require ✓

The 5 intentional "default" entries remain (./client, ./client-safe, ./logging/logger-browser, ./auth/passkey-client-constants, ./utils/environment) — these are browser-safe bundles where the distinction is meaningful.

Coverage by area

Area Entries
auth 22
services 14
integrations 15
content 10
monitoring 7
logging 7
permissions 8
security 6
audit 6
compliance 6
notifications 5
utils 8
validators 3
+ 14 more categories —

Spot-check of critical subpaths consumed by PRs B–E

All resolve correctly with ['types', 'import', 'require']:

  • ./auth/session-service ✓
  • ./services/date-utils ✓
  • ./deployment-mode ✓
  • ./logging/ai-usage-purge ✓
  • ./compliance/erasure/revoke-integration-tokens ✓
  • ./monitoring/activity-logger ✓
  • ./security/path-validator ✓

2. Migration Scripts ✅

Security

All scripts are safe:

  • No shell execution — pure Node.js fs operations throughout
  • No user-controlled input — ROOT is derived from import.meta.url (static), file paths come exclusively from recursive directory scans of APPS_DIR
  • escapeRegExp correctly applied wherever dynamic values enter a RegExp constructor:
    function escapeRegExp(s) {
      return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    }
    // Applied in: migrate-barrel-imports.mjs (barrel name in pattern)
    //             migrate-test-mocks.mjs (barrel path in vi.mock detector)
    //             fix-wrong-imports.mjs (fromPath in import regex)
  • No path traversal risk — input paths never cross outside APPS_DIR

migrate-barrel-imports.mjs — Correctness

  • Single- and double-quoted specifiers both matched (['"] in pattern) ✓
  • Root barrel (@pagespace/lib with no subpath) handled via the barrel === '' branch ✓
  • Fallback path is @pagespace/lib not @pagespace/lib/ (trailing-slash bug fixed) ✓
  • Import blocks processed in reverse to preserve string positions after splicing ✓
  • import type { ... } and inline type keywords preserved in replacement output ✓
  • Unknown symbols fall back to original barrel with a [WARN] log (loud, not silent) ✓

SERVER_MAP now fully aligned with migrate-test-mocks.mjs: four previously missing monitoring symbols have been added:

ActivityResourceType:  '@pagespace/lib/monitoring/activity-logger',
logRollbackActivity:   '@pagespace/lib/monitoring/activity-logger',
logPermissionActivity: '@pagespace/lib/monitoring/activity-logger',
logConversationUndo:   '@pagespace/lib/monitoring/activity-logger',

Both scripts now cover the same symbol surface.

migrate-test-mocks.mjs — Correctness

  • Splits vi.mock('@pagespace/lib/<barrel>', () => ({ ... })) into one vi.mock() per subpath ✓
  • Unknown/spread entries skip with a warning rather than silently emitting a fallback barrel mock ✓
  • Barrel path is escaped before insertion into the mock-detection regex ✓
  • String literal skipping in the paren-balanced parser handles ', ", and ` ✓

fix-logger-mocks.mjs — Correctness

Injects logger: { child: vi.fn() } into vi.mock('@pagespace/lib/logging/logger-config', ...) blocks that are missing it.

  • Skip guard /\bloggers?\s*:/ correctly detects both loggers: (actual export) and logger: (already injected), preventing double-injection ✓
  • Injection uses paren-balanced scanning to bound the mock block, avoiding false replacement into sibling mocks ✓
  • Trailing semicolon handling fixed: regex now matches both })) and }));, with the semicolon preserved in the output:
    block.replace(/(\n?[ \t]*\}\)\);?)$/, (_, closing) => {
      const hasSemicolon = closing.trimStart().endsWith(';');
      return `...\n}))${hasSemicolon ? ';' : ''}`;
    });

fix-broken-logger-injection.mjs — Correctness

Remediation pass for cases where fix-logger-mocks.mjs injected logger: inside a nested vi.fn() block. Acceptable as a targeted one-shot script — the specific pattern match avoids false positives, and any residual failures would surface as TypeScript errors in the dependent PRs.

fix-wrong-imports.mjs — Correctness

Routes symbols misrouted by the initial migration to their correct subpaths:

  • monitoring/change-group → monitoring/activity-logger for activity symbols
  • content/page-type-validators → content/page-types.config for page predicate functions

Uses a hardcoded file list — appropriate for a targeted one-shot fix. PAGE_TYPES_CONFIG_SYMBOLS includes all predicates including the post-review additions (isCanvasPage, isChannelPage, isTaskListPage, isTerminalPage) ✓


3. Three Script Import Updates ✅

File Old New
scripts/lib/migration-utils.ts @pagespace/lib/security @pagespace/lib/security/path-validator
scripts/setup-onprem-admin.ts @pagespace/lib/auth @pagespace/lib/auth/verification-utils
scripts/tenant-export.ts @pagespace/lib/security @pagespace/lib/security/path-validator

All three resolve to confirmed entries in the new export map. ✓


4. .gitignore ✅

# Build artifacts (tsup output — never commit)
packages/lib/dist
packages/db/dist

Comment corrected (was: "Symlinks to dist (created by pnpm worktrees)"). Both paths are real build artifact directories produced by tsup, not symlinks. The entries themselves are correct and necessary.


Summary

Area Status
Export map completeness ✅ All 137 entries valid; no missing types or import fields
Legacy barrel aliases ✅ All 6 preserved and unchanged
"require" vs "default" consistency ✅ Fixed — 6 server-side exports corrected
SERVER_MAP / test-mock parity ✅ Fixed — 4 monitoring symbols aligned
Script security ✅ Clean — escapeRegExp applied, no user input, no shell exec
Trailing semicolon injection ✅ Fixed in fix-logger-mocks.mjs
.gitignore comment ✅ Fixed

✅ APPROVED — production ready. No blocking issues remain.

This is the correct foundation for PRs B–E2. All dependent subpath imports will resolve. Backward compatibility is preserved. Migration tooling is safe to run.


Review conducted by Claude Sonnet 4.6 via /aidd:review

2witstudios added a commit that referenced this pull request Apr 24, 2026
…surface

Replaces barrel imports in the authentication and security layer of apps/web:
- apps/web/src/app/api/auth/** (routes + tests)
- apps/web/src/lib/auth/** (source + tests)
- apps/web/middleware.ts
- apps/web/src/lib/subscription/ (rate-limit-middleware, usage-service)

Part of the barrel-import removal series — PR C of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- package.json: remove 3 dangling export entries that had no matching
  source or dist files (./auth-utils → dist/auth/auth-utils.js,
  ./scribe-processor → dist/scribe-processor.js, ./test/auth-helpers →
  dist/test/auth-helpers.js); also remove their typesVersions entries
- fix-logger-top-level.mjs: remove dead findFactoryObjectEnd function
  (defined but never called — insertion uses regex on mockBlock)
- fix-wrong-imports.mjs: remove two unused hasType variables in
  splitImportBlock; logic already uses allType and per-sym s.isType
- migrate-test-mocks.mjs: add reason field to SKIP return so the
  end-of-run summary shows a meaningful message instead of 'undefined'
- fix-broken-logger-injection.mjs: detect trailing comma before injection
  to avoid double-comma if last property already ends with ','

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@2witstudios

Copy link
Copy Markdown
Owner Author

CodeRabbit round-2 feedback addressed in commit d5ba4df:

Finding Action taken
./auth-utils, ./scribe-processor, ./test/auth-helpers in package.json — no matching source/dist files Removed both the exports entries and their typesVersions entries; no consumer code imports these paths
findFactoryObjectEnd in fix-logger-top-level.mjs — dead code never called Deleted the entire function (32 lines); only findMockCallEnd is active
hasType in fix-wrong-imports.mjs — computed but never read Removed from both inTarget and remaining blocks; allType and per-sym s.isType are the only decision variables
SKIP branch in migrate-test-mocks.mjs missing reason Added reason: \unmapped-keys: ${names}`` to the return so the summary reporter shows a meaningful message
fix-broken-logger-injection.mjs double-comma risk Fixed — the replace callback now detects trailing comma before inserting, matching the pattern in fix-logger-mocks.mjs

2witstudios added a commit that referenced this pull request Apr 24, 2026
…surface

Replaces barrel imports in the authentication and security layer of apps/web:
- apps/web/src/app/api/auth/** (routes + tests)
- apps/web/src/lib/auth/** (source + tests)
- apps/web/middleware.ts
- apps/web/src/lib/subscription/ (rate-limit-middleware, usage-service)

Part of the barrel-import removal series — PR C of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@2witstudios
2witstudios merged commit 7d49bef into master Apr 24, 2026
3 checks passed
2witstudios added a commit that referenced this pull request Apr 24, 2026
… control-plane, marketing

Replaces barrel imports from '@pagespace/lib/server', '@pagespace/lib/auth',
'@pagespace/lib/permissions', etc. with direct subpath paths in the smaller
app packages.

Part of the barrel-import removal series — PR B of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request Apr 24, 2026
…surface

Replaces barrel imports in the authentication and security layer of apps/web:
- apps/web/src/app/api/auth/** (routes + tests)
- apps/web/src/lib/auth/** (source + tests)
- apps/web/middleware.ts
- apps/web/src/lib/subscription/ (rate-limit-middleware, usage-service)

Part of the barrel-import removal series — PR C of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request Apr 24, 2026
…, workflows

Replaces barrel imports in the AI and integration subsystem of apps/web:
- apps/web/src/app/api/ai/** (routes + tests)
- apps/web/src/lib/ai/** (source + tests)
- apps/web/src/app/api/agents/**
- apps/web/src/app/api/integrations/**
- apps/web/src/lib/integrations/**
- apps/web/src/lib/mcp/**
- apps/web/src/lib/memory/**
- apps/web/src/lib/workflows/**

Part of the barrel-import removal series — PR D of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request Apr 24, 2026
… components

Replaces barrel imports in the content and UI layer of apps/web:
- apps/web/src/app/api/pages/** (56 files)
- apps/web/src/app/api/drives/** (48 files)
- apps/web/src/app/api/activities/** (12 files)
- apps/web/src/app/api/tasks/** (3 files)
- apps/web/src/app/api/channels/**, messages/**, files/**, storage/**, search/**, trash/**
- apps/web/src/components/** (layout, AI, notifications, files, members, inbox)
- apps/web/src/services/api/**
- apps/web/src/hooks/**
- apps/web/src/stores/**
- apps/web/src/lib/{websocket,onboarding,tabs,fetch-bridge,channels,stripe}/**

Part of the barrel-import removal series — PR E1 of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request Apr 24, 2026
…and infra routes

Replaces barrel imports in the admin, billing, and infrastructure API routes of apps/web:
- stripe/** (32 files) — subscription management, webhooks
- cron/** (20 files) — scheduled jobs
- user/**, admin/**, account/** — user management, admin panel
- workflows/**, notifications/**, connections/**, settings/**
- users/**, subscriptions/**, calendar/**, pulse/**
- mcp/**, voice/**, track/**, permissions/**, mentions/**
- memory/**, mcp-ws/**, internal/**, health/**
- feedback/**, debug/**, contact/**, activity/**, inbox/**

Part of the barrel-import removal series — PR E2 of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request Apr 24, 2026
* refactor(imports): use direct subpath imports in processor, realtime, control-plane, marketing

Replaces barrel imports from '@pagespace/lib/server', '@pagespace/lib/auth',
'@pagespace/lib/permissions', etc. with direct subpath paths in the smaller
app packages.

Part of the barrel-import removal series — PR B of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(imports): migrate double-quoted security barrel import in marketing contact route

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(processor): correct test mock paths to match actual subpath imports

- authorization.test, rbac-delete.test: merge getUserDrivePermissions into
  permissions/permissions mock (was incorrectly on @pagespace/lib/permissions)
- siem-adapter.test: mock url-validator subpath (not @pagespace/lib/security)
- siem-delivery-worker.test: mock audit/security-audit-alerting subpath
  (not @pagespace/lib/audit)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): fix mock indentation and remove orphaned barrel mock

- Normalize vi.mock() factory body indentation to 2-space across 11 test
  files (processor, realtime, marketing). The prior refactor left mock
  object properties at 4-space while surrounding code used 2-space.
- Remove dead vi.mock('@pagespace/lib/security') block from
  security.test.ts — security.ts no longer imports from that barrel, so
  the validateExternalURL mock was never intercepting anything.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): fix vi.doMock barrel paths in auth catch-block tests

The authenticateService catch-block describe used vi.resetModules() +
vi.doMock to isolate per-test module state. After the barrel refactor
auth.ts imports from @pagespace/lib/auth/session-service, not
@pagespace/lib/auth, so the old vi.doMock paths intercepted nothing.

Update both doMock calls in each test:
  @pagespace/lib/auth         → @pagespace/lib/auth/session-service
  @pagespace/lib/permissions  → @pagespace/lib/permissions/enforced-context

Also add logger.child to the logger-config doMock to match the updated
contract added across this PR's other test fixes.

Without this fix: validateSession never rejects, the catch branch is
never exercised, and the "Invalid token" assertion fails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request Apr 24, 2026
…#1090)

* refactor(imports): use direct subpath imports in web auth + security surface

Replaces barrel imports in the authentication and security layer of apps/web:
- apps/web/src/app/api/auth/** (routes + tests)
- apps/web/src/lib/auth/** (source + tests)
- apps/web/middleware.ts
- apps/web/src/lib/subscription/ (rate-limit-middleware, usage-service)

Part of the barrel-import removal series — PR C of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: normalize vi.mock indentation, semicolons, and remove stale logger stubs

- Standardize vi.mock callback bodies to 2-space indent (was 4-space in all
  newly-added @pagespace/lib/* mock blocks)
- Add missing trailing semicolons to import statements across 32 source files
- Remove unnecessary `logger: { child: vi.fn() }` stubs from
  @pagespace/lib/logging/logger-config mocks — source files only import
  `loggers`, not `logger` directly

No logic changes. All 95 files remain pure import-path swaps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): migrate dynamic import() calls to direct subpath imports

Replace remaining old barrel references in dynamic await import() calls
inside test bodies — session-fixation, device-refresh, mobile-refresh,
mobile-oauth-google-exchange, and device/refresh route tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request Apr 24, 2026
…ns (#1091)

* refactor(imports): use direct subpath imports in web AI, integrations, workflows

Replaces barrel imports in the AI and integration subsystem of apps/web:
- apps/web/src/app/api/ai/** (routes + tests)
- apps/web/src/lib/ai/** (source + tests)
- apps/web/src/app/api/agents/**
- apps/web/src/app/api/integrations/**
- apps/web/src/lib/integrations/**
- apps/web/src/lib/mcp/**
- apps/web/src/lib/memory/**
- apps/web/src/lib/workflows/**

Part of the barrel-import removal series — PR D of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-ai): import logger from logging/logger not logging/logger-config

logger-config exports loggers (plural) helpers; the root logger instance
lives in logging/logger. Use the direct module for clarity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-ai): resolve mock/source mismatches + add missing semicolons

Test correctness fixes:
- mcp-scope.test.ts: fix malformed logger mock (logger was nested inside
  child() return instead of exported at module top level)
- agents/integrations/__tests__/route.test.ts: move createGrant and
  findGrant from barrel mock to grant-repository subpath mock — source
  imports from /repositories/grant-repository, not @pagespace/lib/integrations
- ollama/models/__tests__/route.test.ts: update validateLocalProviderURL
  mock path from @pagespace/lib/security to /security/url-validator
- calendar-write-tools.test.ts: update isUserDriveMember import from
  @pagespace/lib barrel to /permissions/permissions to match the mock path
- page-read-tools.test.ts: remove dead @pagespace/lib/server mock stubs
  for isChannelPage, formatContentForAI etc. — source no longer imports
  these from that path

Style: add missing trailing semicolons to 74 @pagespace/lib subpath
import statements across 45 source files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-ai): resolve 4 remaining mock/source mismatches from review

- mcp-bridge.test.ts: mock @pagespace/lib/logging/logger not logger-config;
  source imports logger from /logging/logger, these are different modules
- page-read-tools.test.ts: mock getPageTypeEmoji/isFolderPage not
  isDocumentPage/isAIChatPage/getCreatablePageTypes; wrong fn names carried
  over from barrel mock, actual imports are the emoji/folder helpers
- agent-tools.test.ts: add missing semicolon on import statement
- page-write-tools.test.ts: add missing semicolon on import statement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request Apr 24, 2026
…onents (#1092)

* refactor(imports): use direct subpath imports in web content routes + components

Replaces barrel imports in the content and UI layer of apps/web:
- apps/web/src/app/api/pages/** (56 files)
- apps/web/src/app/api/drives/** (48 files)
- apps/web/src/app/api/activities/** (12 files)
- apps/web/src/app/api/tasks/** (3 files)
- apps/web/src/app/api/channels/**, messages/**, files/**, storage/**, search/**, trash/**
- apps/web/src/components/** (layout, AI, notifications, files, members, inbox)
- apps/web/src/services/api/**
- apps/web/src/hooks/**
- apps/web/src/stores/**
- apps/web/src/lib/{websocket,onboarding,tabs,fetch-bridge,channels,stripe}/**

Part of the barrel-import removal series — PR E1 of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(imports): migrate double-quoted root barrel import in trash page

Drive type was missed by migration script because it used double-quoted
module specifier. Routed to @pagespace/lib/types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web): stream activity export with batched pagination, remove 10k cap

Replace the single 10k-capped findMany query with a ReadableStream that
paginates in BATCH_SIZE=1000 batches until exhausted. Removes the
incorrect isTruncated detection (equality with limit can false-positive)
and the X-Truncated response header. Update test suite to cover
multi-batch pagination, exact-batch stop condition, empty export, and
absence of X-Truncated header.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(activities-export): stable pagination sort, single audit call, tighter test

- Restore desc(activityLogs.id) tiebreaker to orderBy so offset pagination
  is stable when multiple rows share the same timestamp
- Collapse duplicate auditRequest calls into one (post-parse, richer details)
  and normalize resourceType to 'activities' / resourceId fallback to 'self'
- Assert toHaveBeenCalledTimes(1) in test to prevent silent regression to
  double-audit; expand objectContaining to cover the details field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request Apr 24, 2026
…g + Infra (#1093)

* refactor(imports): use direct subpath imports in web admin, billing, and infra routes

Replaces barrel imports in the admin, billing, and infrastructure API routes of apps/web:
- stripe/** (32 files) — subscription management, webhooks
- cron/** (20 files) — scheduled jobs
- user/**, admin/**, account/** — user management, admin panel
- workflows/**, notifications/**, connections/**, settings/**
- users/**, subscriptions/**, calendar/**, pulse/**
- mcp/**, voice/**, track/**, permissions/**, mentions/**
- memory/**, mcp-ws/**, internal/**, health/**
- feedback/**, debug/**, contact/**, activity/**, inbox/**

Part of the barrel-import removal series — PR E2 of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-admin): update account+admin routes for GDPR Art. 17 erasure (#1081)

Incorporates revokeUserIntegrationTokens, isCloud, Stripe customer deletion
merged to master after branch divergence. Updates test mocks to use direct
subpath imports instead of barrel mocks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): GDPR export regression + semicolons + mock indentation

- Restore GDPR Art. 15 export fields removed in 810d3c2: sessions,
  notifications, display-preferences, personalization. The prior PR #1084
  added these explicitly; they must not be silently dropped.
- Restore test assertions for all 11 (+ conditional 12th) archive entries
  and the personalization branch test.
- Add trailing semicolons to ~70 production imports introduced by the
  barrel refactor (TypeScript ASI handles them, but consistency matters).
- Fix 4-space → 2-space top-level indentation inside vi.mock factory
  objects across 67 test files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request May 15, 2026
…ndation (#1088)

* refactor(lib): remove barrel export aliases from packages/lib

Adds explicit subpath exports to packages/lib/package.json replacing the
old barrel aliases (server, auth, permissions, etc.) with direct module
paths. Migration scripts and .gitignore fixes are included here as the
canonical reference for how this migration was performed.

Must land before the app-level import-swap PRs (barrel/small-apps,
barrel/web-auth, barrel/web-ai, barrel/web-content, barrel/web-admin).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(scripts): address CodeRabbit feedback on migration scripts

- fix-wrong-imports: remove duplicate isCodePage, add missing isCanvasPage/isChannelPage/isTaskListPage/isTerminalPage to PAGE_TYPES_CONFIG_SYMBOLS
- migrate-barrel-imports: fix fallback path trailing slash when barrel is empty
- migrate-test-mocks: widen prefilter to match double-quoted vi.mock() calls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(lib): add compliance/erasure/revoke-integration-tokens subpath export

New file added by GDPR Art. 17 erasure fix (#1081) needs its own
subpath export so downstream code can import without a barrel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(scripts): address CodeRabbit review feedback on migration scripts

- fix-broken-logger-injection: loosen indent regex from hard-coded 2-space
  to any whitespace so 4-space/tab indentation doesn't bypass the guard
- fix-logger-mocks: replace non-greedy regex with paren-bounded block
  replacement to prevent injection into nested vi.fn blocks
- migrate-test-mocks: skip+warn unknown barrel entries instead of silently
  emitting a fallback vi.mock(barrelPath, ...) that defeats barrel removal

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(scripts): match double-quoted imports and skip when loggers: present

migrate-barrel-imports.mjs: use ['"] in the import regex and the quick
prefilter string-includes check so double-quoted barrel imports are
migrated (e.g. import { Drive } from "@pagespace/lib").

fix-logger-mocks.mjs: broaden the skip guard from /\blogger\s*:/ to
/\bloggers?\s*:/ so mocks that already have 'loggers:' (the actual
export of logger-config) are not patched with a dead 'logger:' key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lib): address PR A review feedback

- .gitignore: correct comment (build artifacts, not symlinks)
- package.json: use "require" (not "default") for 6 server-side exports
  (./types, ./utils/enums, ./sheets, ./content/page-types.config,
  ./content/page-type-validators, ./content/tree-utils)
- migrate-barrel-imports.mjs: add 4 monitoring symbols to SERVER_MAP
  (ActivityResourceType, logRollbackActivity, logPermissionActivity,
  logConversationUndo) to match test-mock coverage
- fix-logger-mocks.mjs: handle trailing semicolons (})); pattern)
  so mocks with semicolons are not silently skipped

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(lib): address CodeRabbit review feedback round 2

- package.json: remove 3 dangling export entries that had no matching
  source or dist files (./auth-utils → dist/auth/auth-utils.js,
  ./scribe-processor → dist/scribe-processor.js, ./test/auth-helpers →
  dist/test/auth-helpers.js); also remove their typesVersions entries
- fix-logger-top-level.mjs: remove dead findFactoryObjectEnd function
  (defined but never called — insertion uses regex on mockBlock)
- fix-wrong-imports.mjs: remove two unused hasType variables in
  splitImportBlock; logic already uses allType and per-sym s.isType
- migrate-test-mocks.mjs: add reason field to SKIP return so the
  end-of-run summary shows a meaningful message instead of 'undefined'
- fix-broken-logger-injection.mjs: detect trailing comma before injection
  to avoid double-comma if last property already ends with ','

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request May 15, 2026
* refactor(imports): use direct subpath imports in processor, realtime, control-plane, marketing

Replaces barrel imports from '@pagespace/lib/server', '@pagespace/lib/auth',
'@pagespace/lib/permissions', etc. with direct subpath paths in the smaller
app packages.

Part of the barrel-import removal series — PR B of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(imports): migrate double-quoted security barrel import in marketing contact route

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(processor): correct test mock paths to match actual subpath imports

- authorization.test, rbac-delete.test: merge getUserDrivePermissions into
  permissions/permissions mock (was incorrectly on @pagespace/lib/permissions)
- siem-adapter.test: mock url-validator subpath (not @pagespace/lib/security)
- siem-delivery-worker.test: mock audit/security-audit-alerting subpath
  (not @pagespace/lib/audit)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): fix mock indentation and remove orphaned barrel mock

- Normalize vi.mock() factory body indentation to 2-space across 11 test
  files (processor, realtime, marketing). The prior refactor left mock
  object properties at 4-space while surrounding code used 2-space.
- Remove dead vi.mock('@pagespace/lib/security') block from
  security.test.ts — security.ts no longer imports from that barrel, so
  the validateExternalURL mock was never intercepting anything.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): fix vi.doMock barrel paths in auth catch-block tests

The authenticateService catch-block describe used vi.resetModules() +
vi.doMock to isolate per-test module state. After the barrel refactor
auth.ts imports from @pagespace/lib/auth/session-service, not
@pagespace/lib/auth, so the old vi.doMock paths intercepted nothing.

Update both doMock calls in each test:
  @pagespace/lib/auth         → @pagespace/lib/auth/session-service
  @pagespace/lib/permissions  → @pagespace/lib/permissions/enforced-context

Also add logger.child to the logger-config doMock to match the updated
contract added across this PR's other test fixes.

Without this fix: validateSession never rejects, the catch branch is
never exercised, and the "Invalid token" assertion fails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request May 15, 2026
…#1090)

* refactor(imports): use direct subpath imports in web auth + security surface

Replaces barrel imports in the authentication and security layer of apps/web:
- apps/web/src/app/api/auth/** (routes + tests)
- apps/web/src/lib/auth/** (source + tests)
- apps/web/middleware.ts
- apps/web/src/lib/subscription/ (rate-limit-middleware, usage-service)

Part of the barrel-import removal series — PR C of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* style: normalize vi.mock indentation, semicolons, and remove stale logger stubs

- Standardize vi.mock callback bodies to 2-space indent (was 4-space in all
  newly-added @pagespace/lib/* mock blocks)
- Add missing trailing semicolons to import statements across 32 source files
- Remove unnecessary `logger: { child: vi.fn() }` stubs from
  @pagespace/lib/logging/logger-config mocks — source files only import
  `loggers`, not `logger` directly

No logic changes. All 95 files remain pure import-path swaps.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(tests): migrate dynamic import() calls to direct subpath imports

Replace remaining old barrel references in dynamic await import() calls
inside test bodies — session-fixation, device-refresh, mobile-refresh,
mobile-oauth-google-exchange, and device/refresh route tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request May 15, 2026
…ns (#1091)

* refactor(imports): use direct subpath imports in web AI, integrations, workflows

Replaces barrel imports in the AI and integration subsystem of apps/web:
- apps/web/src/app/api/ai/** (routes + tests)
- apps/web/src/lib/ai/** (source + tests)
- apps/web/src/app/api/agents/**
- apps/web/src/app/api/integrations/**
- apps/web/src/lib/integrations/**
- apps/web/src/lib/mcp/**
- apps/web/src/lib/memory/**
- apps/web/src/lib/workflows/**

Part of the barrel-import removal series — PR D of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-ai): import logger from logging/logger not logging/logger-config

logger-config exports loggers (plural) helpers; the root logger instance
lives in logging/logger. Use the direct module for clarity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-ai): resolve mock/source mismatches + add missing semicolons

Test correctness fixes:
- mcp-scope.test.ts: fix malformed logger mock (logger was nested inside
  child() return instead of exported at module top level)
- agents/integrations/__tests__/route.test.ts: move createGrant and
  findGrant from barrel mock to grant-repository subpath mock — source
  imports from /repositories/grant-repository, not @pagespace/lib/integrations
- ollama/models/__tests__/route.test.ts: update validateLocalProviderURL
  mock path from @pagespace/lib/security to /security/url-validator
- calendar-write-tools.test.ts: update isUserDriveMember import from
  @pagespace/lib barrel to /permissions/permissions to match the mock path
- page-read-tools.test.ts: remove dead @pagespace/lib/server mock stubs
  for isChannelPage, formatContentForAI etc. — source no longer imports
  these from that path

Style: add missing trailing semicolons to 74 @pagespace/lib subpath
import statements across 45 source files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-ai): resolve 4 remaining mock/source mismatches from review

- mcp-bridge.test.ts: mock @pagespace/lib/logging/logger not logger-config;
  source imports logger from /logging/logger, these are different modules
- page-read-tools.test.ts: mock getPageTypeEmoji/isFolderPage not
  isDocumentPage/isAIChatPage/getCreatablePageTypes; wrong fn names carried
  over from barrel mock, actual imports are the emoji/folder helpers
- agent-tools.test.ts: add missing semicolon on import statement
- page-write-tools.test.ts: add missing semicolon on import statement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request May 15, 2026
…onents (#1092)

* refactor(imports): use direct subpath imports in web content routes + components

Replaces barrel imports in the content and UI layer of apps/web:
- apps/web/src/app/api/pages/** (56 files)
- apps/web/src/app/api/drives/** (48 files)
- apps/web/src/app/api/activities/** (12 files)
- apps/web/src/app/api/tasks/** (3 files)
- apps/web/src/app/api/channels/**, messages/**, files/**, storage/**, search/**, trash/**
- apps/web/src/components/** (layout, AI, notifications, files, members, inbox)
- apps/web/src/services/api/**
- apps/web/src/hooks/**
- apps/web/src/stores/**
- apps/web/src/lib/{websocket,onboarding,tabs,fetch-bridge,channels,stripe}/**

Part of the barrel-import removal series — PR E1 of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(imports): migrate double-quoted root barrel import in trash page

Drive type was missed by migration script because it used double-quoted
module specifier. Routed to @pagespace/lib/types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web): stream activity export with batched pagination, remove 10k cap

Replace the single 10k-capped findMany query with a ReadableStream that
paginates in BATCH_SIZE=1000 batches until exhausted. Removes the
incorrect isTruncated detection (equality with limit can false-positive)
and the X-Truncated response header. Update test suite to cover
multi-batch pagination, exact-batch stop condition, empty export, and
absence of X-Truncated header.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(activities-export): stable pagination sort, single audit call, tighter test

- Restore desc(activityLogs.id) tiebreaker to orderBy so offset pagination
  is stable when multiple rows share the same timestamp
- Collapse duplicate auditRequest calls into one (post-parse, richer details)
  and normalize resourceType to 'activities' / resourceId fallback to 'self'
- Assert toHaveBeenCalledTimes(1) in test to prevent silent regression to
  double-audit; expand objectContaining to cover the details field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2witstudios added a commit that referenced this pull request May 15, 2026
…g + Infra (#1093)

* refactor(imports): use direct subpath imports in web admin, billing, and infra routes

Replaces barrel imports in the admin, billing, and infrastructure API routes of apps/web:
- stripe/** (32 files) — subscription management, webhooks
- cron/** (20 files) — scheduled jobs
- user/**, admin/**, account/** — user management, admin panel
- workflows/**, notifications/**, connections/**, settings/**
- users/**, subscriptions/**, calendar/**, pulse/**
- mcp/**, voice/**, track/**, permissions/**, mentions/**
- memory/**, mcp-ws/**, internal/**, health/**
- feedback/**, debug/**, contact/**, activity/**, inbox/**

Part of the barrel-import removal series — PR E2 of 6. Depends on
barrel/foundation (#1088) being merged first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-admin): update account+admin routes for GDPR Art. 17 erasure (#1081)

Incorporates revokeUserIntegrationTokens, isCloud, Stripe customer deletion
merged to master after branch divergence. Updates test mocks to use direct
subpath imports instead of barrel mocks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(review): GDPR export regression + semicolons + mock indentation

- Restore GDPR Art. 15 export fields removed in 810d3c2: sessions,
  notifications, display-preferences, personalization. The prior PR #1084
  added these explicitly; they must not be silently dropped.
- Restore test assertions for all 11 (+ conditional 12th) archive entries
  and the personalization branch test.
- Add trailing semicolons to ~70 production imports introduced by the
  barrel refactor (TypeScript ASI handles them, but consistency matters).
- Fix 4-space → 2-space top-level indentation inside vi.mock factory
  objects across 67 test files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@2witstudios
2witstudios deleted the barrel/foundation branch May 27, 2026 02:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant