Date: 2026-02-08 Current coverage: ~25-30% of source files have corresponding tests Coverage enforcement: None (no thresholds, no CI reporting)
The repo has 729 test files across ~2,950 source files. The biggest gaps are:
- API routes: 65 of 85 route files have zero tests (24% coverage)
- API services: 82 of 122 root-level services untested (33% coverage)
- Inngest jobs: 33 of 43 background jobs untested (23% coverage)
- Dashboard components: ~140 of 150+ components untested (<9% coverage)
- CLI: 86 source files, zero tests, no test infrastructure at all
No coverage thresholds are enforced in CI. The API has a V8 coverage config in vitest but it's only wired up for E2E tests and only uploads artifacts — it doesn't gate merges.
Goal: Make coverage visible and start enforcing it on new code.
- Add
@vitest/coverage-v8to dashboard devDependencies - Add coverage config to
dashboard/vitest.config.mts:coverage: { provider: 'v8', reporter: ['text', 'json', 'html', 'lcov'], include: ['src/**/*.{ts,tsx}'], exclude: ['src/**/*.test.{ts,tsx}', 'src/**/*.stories.{ts,tsx}'], }
- Wire API unit tests (
bun test) to produce coverage output (bun supports--coveragenatively; export lcov withbun test --coverage --coverage-reporter=lcov) - Add coverage upload step to all 3 CI test workflows (api-tests, dashboard-tests, api-e2e-tests)
- Set up Codecov or similar service to track coverage over time
- Add a coverage gate on new code: require ≥80% line coverage on changed files in PRs
- Run full coverage locally for API and Dashboard, record baseline numbers
- Create a coverage dashboard (Codecov project badge in README)
- Document current per-directory coverage in a tracking issue
- Add
bun testscript tocli/package.json - Create
cli/src/test/with shared test helpers - Add CLI test job to GitHub Actions
- Verify React 18 isolation doesn't block test runner
Goal: Cover authorization, billing, and access control — the code where bugs cost the most.
| File | Lines | Priority |
|---|---|---|
project-access.service.ts |
2,012 | P0 |
workspace-membership.service.ts |
~400 | P0 |
sso.service.ts |
~300 | P0 |
token-encryption.service.ts |
~200 | P0 |
permissions.service.ts |
~300 | P0 (has test — verify completeness) |
document-access.service.ts |
~250 | P0 |
Test strategy:
- Unit test every public method
- Test all permission boundary conditions (owner vs member vs guest vs unauthenticated)
- Test cross-workspace isolation (user in workspace A cannot access workspace B resources)
- Test token expiry, rotation, and revocation paths
| File | Lines | Priority |
|---|---|---|
stripe.service.ts |
1,315 | P0 |
credits-usage.service.ts |
612 | P0 |
workspace-usage.service.ts |
832 | P0 |
credit-balance.service.ts |
~300 | P0 (has test — verify completeness) |
seat-management.service.ts |
~350 | P0 (has test — verify completeness) |
Test strategy:
- Mock Stripe SDK, test all webhook event handlers
- Test credit calculation edge cases: zero balance, negative balance, concurrent deductions
- Test usage metering accuracy
- Test plan upgrade/downgrade/cancellation flows
- Test proration and billing cycle boundary conditions
| File | Priority |
|---|---|
routes/auth.ts |
P0 |
routes/mobile-auth.ts |
P0 |
routes/sso-providers.ts |
P0 |
routes/stripe-webhooks.ts |
P0 |
Test strategy:
- E2E tests with testcontainers for auth flows
- Test session creation, refresh, expiry
- Test SSO callback handling with various provider responses
- Test Stripe webhook signature verification and idempotency
Goal: Cover the largest untested services — these have the most branching logic and the highest bug surface area.
| File | Lines | What it does |
|---|---|---|
e2b-shell.service.ts |
3,354 | E2B sandbox lifecycle, hydration, command execution |
workspace.service.ts |
2,364 | Workspace CRUD, settings, member management |
Test strategy for e2b-shell.service.ts:
- Mock E2B SDK
- Test sandbox creation, reuse, pause, resume
- Test command execution timeout handling
- Test hydration/rehydration flow
- Test concurrent sandbox access
- Test error recovery (sandbox crash, network failure)
Test strategy for workspace.service.ts:
- Test workspace creation with various plan types
- Test settings update validation
- Test member add/remove/role-change
- Test workspace deletion cascade
- Test domain-based auto-join logic
| File | Lines |
|---|---|
file.service.ts |
1,518 |
folder.service.ts |
1,355 |
automerge-document.service.ts |
1,167 |
objective-tracking.service.ts |
1,075 |
webhook-subscription.service.ts |
1,032 |
| File | Lines |
|---|---|
artifact-query.service.ts |
848 |
thread-folder.service.ts |
754 |
analytics.service.ts |
721 |
published-artifact.service.ts |
689 |
workspace-domain-join.service.ts |
651 |
user.service.ts |
646 |
background-enrichment.service.ts |
583 |
turbopuffer.service.ts |
574 |
inngest-events.service.ts |
549 |
workbooks.service.ts |
544 |
validation-rule.service.ts |
533 |
project-folder.service.ts |
526 |
shortcuts.service.ts |
495 |
artifact-document.service.ts |
472 |
artifact-preview.service.ts |
435 |
image-generation.service.ts |
428 |
inline-text-edit.service.ts |
415 |
custom-mode.service.ts |
381 |
General test strategy for all services:
- Follow existing patterns in
apps/api/src/services/__tests__/ - Use the DI container to inject mocked dependencies (see
apps/api/SERVICE_PATTERNS.md) - Test happy path + each error/validation branch
- Test edge cases documented in any corresponding
.spec.mdfile
Goal: Every route has at least one integration test verifying auth, input validation, and the happy path.
| Route file | Endpoints |
|---|---|
projects.ts |
CRUD, sharing, access |
threads.ts |
CRUD, messaging |
artifacts.ts |
CRUD, versioning |
sheets.ts |
CRUD, cell operations |
workspaces.ts |
CRUD, settings, members |
users.ts |
Profile, preferences |
billing.ts |
Plan management |
tasks.ts |
Task CRUD, scheduling |
messages.ts |
Send, list, search |
files.ts |
Upload, download, delete |
| Route file |
|---|
folders.ts |
notes.ts |
templates.ts |
knowledge.ts |
meetings.route.ts |
recordings.ts |
notifications.ts |
favorites.ts |
shortcuts.ts |
thread-folders.ts |
thread-todos.ts |
calls.ts |
enrichments.ts |
All other route files listed in the audit (agent-v2, analytics, api-keys, auto-join, custom-modes, device-tokens, etc.)
Test strategy for all routes:
- Use vitest + testcontainers (existing E2E pattern)
- Each route file gets a corresponding
.e2e-test.ts - Every endpoint tests:
- Unauthenticated request → 401
- Wrong workspace → 403
- Invalid input → 400 with validation errors
- Happy path → correct status + response shape
- Resource not found → 404
- For mutation endpoints, verify database state after the request
Goal: Cover all async processing — these are the hardest bugs to catch in production because they fail silently.
| Job | What it does |
|---|---|
file-extraction.ts |
Extract content from uploaded files |
connector-import.ts |
Import data from external connectors |
background-enrichment.ts |
Enrich records with external data |
batch-enrichment.ts |
Bulk enrichment operations |
suggestions-analysis.ts |
Analyze data for suggestions |
| Job |
|---|
scheduled-task-checker.ts |
scheduled-task-executor.ts |
sandbox-pause.ts |
sandbox-rehydration-job.ts |
sandbox-rehydration-processor.ts |
credit-auto-reload.ts |
| Job |
|---|
meetings.ts |
call.ts |
slack-agent-response.ts |
| Job |
|---|
cleanup-analytics.ts |
cleanup-notifications.ts |
cleanup-webview-tokens.ts |
objective-cleanup.ts |
sse-connection-cleanup.ts |
| Job |
|---|
backfill-document-indexing.ts |
backfill-meeting-account-calendar.ts |
backfill-slides-indexing.ts |
backfill-thread-indexing.ts |
backfill-workbook-indexing.ts |
calendar-webhook-migration.ts |
Test strategy for all Inngest jobs:
- Mock the Inngest client's
send()andstep.*methods - Test the job function directly with mocked dependencies
- Test idempotency (running the same job twice produces the same result)
- Test failure handling (what happens when an external service is down)
- Test retry behavior and dead-letter scenarios
Goal: Cover the most complex UI components and critical user flows.
| File | Lines | Feature area |
|---|---|---|
field-panel.element.tsx |
1,446 | Column context menu |
slide-grid-editor.tsx |
1,311 | Slide editing |
slide-grid-renderer.tsx |
1,283 | Slide rendering |
project-page.tsx |
1,280 | Main project view |
share-feature.tsx |
1,278 | Sharing UI |
kanban-renderer.tsx |
1,132 | Kanban board |
prompt-input.tsx |
1,122 | Chat input |
mentions-editor.tsx |
1,034 | @mentions |
workspace-billing.element.tsx |
1,021 | Billing page |
toolbar.grid.adapter.tsx |
1,010 | Grid toolbar |
simple-workbook-table-grid.tsx |
1,003 | Workbook table |
editable-artifact.element.tsx |
1,003 | Artifact editor |
| Feature area | # Untested components |
|---|---|
meetings/components/ |
27 |
notes/components/ |
19 |
workspace-settings/ |
12 |
share-feature/components/ |
11 |
file-viewer/ |
10 |
template-settings-sidebar/ |
10 |
comments/ui/ |
7 |
slide-grid-renderer/ |
8 |
47 of ~175 hooks have tests (27%). Priority untested hooks:
- Data fetching hooks (useQuery wrappers)
- Permission/access hooks
- Keyboard shortcut hooks
- Drag-and-drop hooks
Test strategy for dashboard:
- Use vitest + @testing-library/react (existing pattern)
- For complex components, test:
- Renders without crashing
- User interactions produce correct state changes
- Error/empty/loading states render correctly
- Keyboard accessibility
- For hooks, test with
renderHook()from testing-library - Mock API calls with MSW or manual mocks
Goal: Add test infrastructure and cover critical CLI operations.
- Add test script to
cli/package.json - Create test helpers for CLI-specific patterns (command execution, TUI rendering)
- Add to CI pipeline
| File | Lines | What it does |
|---|---|---|
lib/worktree-stack.ts |
~500 | Worktree management (critical infra) |
lib/docker/control.ts |
~300 | Docker compose orchestration |
lib/docker/services.ts |
~200 | Service management |
lib/process.ts |
~200 | Process management |
lib/health.ts |
~150 | Health checking |
lib/prerequisites/checkers.ts |
~200 | Dependency checking |
commands/up.ts |
~400 | Dev server startup |
commands/worktree.ts |
~300 | Worktree commands |
commands/check.ts |
~200 | Lint/type/test orchestration |
Test strategy for CLI:
- Unit test pure functions (port calculation, config generation, path resolution)
- Mock Docker, git, and filesystem operations for command tests
- Test error messages and exit codes
- Test TUI components with ink-testing-library (if applicable)
Goal: Cover export pipelines and third-party integrations.
| File | What it does |
|---|---|
artifact-export.service.ts |
General artifact export |
browserless-pdf-conversion.service.ts |
PDF generation |
bulk-export.service.ts |
Batch export |
docx-conversion.service.ts |
Word doc generation |
grid-slides-pdf.service.ts |
Slide PDF export |
grid-to-pptx.service.ts |
PowerPoint export |
image-embedding.service.ts |
Image processing |
plotly-image.service.ts |
Chart image generation |
presentation-export.service.ts |
Presentation export |
sse-export.service.ts |
SSE-based streaming export |
streaming-csv.service.ts |
CSV export |
streaming-excel.service.ts |
Excel export |
streaming-slides.service.ts |
Slide streaming |
| File | What it does |
|---|---|
google-drive/google-drive.service.ts |
Google Drive integration |
meetings/auto-join.service.ts |
Auto-join meetings |
meetings/calendar-sync.service.ts |
Calendar sync |
meetings/meeting-enrichment.service.ts |
Meeting data enrichment |
github-auth.service.ts |
GitHub OAuth |
- New code gate: PRs must have ≥80% line coverage on changed files
- Ratchet: Overall coverage can never decrease — once a file gets tests, it stays tested
- Required tests for new services/routes: Any new
.service.tsor route file must ship with a corresponding test file (enforce via CI check or pre-commit hook)
| Milestone | API Services | API Routes | Dashboard | Inngest | CLI |
|---|---|---|---|---|---|
| Phase 0 | 33% (baseline) | 24% | ~16% | 23% | 0% |
| Phase 1 | 45% | 30% | ~16% | 23% | 0% |
| Phase 2 | 70% | 30% | ~16% | 23% | 0% |
| Phase 3 | 70% | 80% | ~16% | 23% | 0% |
| Phase 4 | 70% | 80% | ~16% | 75% | 0% |
| Phase 5 | 70% | 80% | 50% | 75% | 0% |
| Phase 6 | 70% | 80% | 50% | 75% | 50% |
| Phase 7 | 85% | 80% | 50% | 75% | 50% |
82 untested root-level services (click to expand)
activity.service.ts
analytics.service.ts
artifact-deletion.service.ts
artifact-document.service.ts
artifact-preview.service.ts
artifact-query.service.ts
artifact-workbook.service.ts
automerge-document.service.ts
background-enrichment.service.ts
call-transcript.service.ts
call.service.ts
credits-usage.service.ts
custom-mode.service.ts
device-token.service.ts
document-access.service.ts
e2b-shell.service.ts
email.service.ts
embedding.service.ts
employee-sandbox-credentials.service.ts
example-di.service.ts
file-extraction.service.ts
file.service.ts
folder.service.ts
github-auth.service.ts
god-mode.service.ts
image-generation.service.ts
inline-text-edit.service.ts
inngest-events.service.ts
markdown-extractor.service.ts
message.service.ts
notification.service.ts
objective-tracking.service.ts
organize.service.ts
preview.service.ts
project-access.service.ts
project-folder.service.ts
project.service.ts
prompt-summarization.service.ts
published-artifact.service.ts
push-notification.service.ts
recording.service.ts
records.service.ts
rule-execution.service.ts
rule-preflight.service.ts
sheet-analysis.service.ts
sheet.service.ts
shortcuts.service.ts
sso.service.ts
starter-prompts-db.service.ts
stripe.service.ts
task.service.ts
task.validation.ts
template-preview.service.ts
thread-folder.service.ts
thread-todo.service.ts
thread.service.ts
token-encryption.service.ts
turbopuffer.service.ts
user-artifact-order.service.ts
user.service.ts
validation-rule.service.ts
verb-summary-generator.service.ts
waitlist.service.ts
webhook-subscription.service.ts
webview-token.service.ts
workspace-domain-join.service.ts
workspace-membership.service.ts
workspace-usage.service.ts
workspace.service.ts
workbooks.service.ts
65 untested route files (click to expand)
agent-v2.ts
analytics-script.ts
analytics.ts
api-keys.route.ts
artifact-tabs.ts
artifacts.ts
auth.ts
auto-join.route.ts
billing-plans.ts
billing-welcome.ts
billing.ts
calls.ts
custom-modes.ts
device-tokens.ts
enrichments.ts
events-stream.ts
favorites.ts
feedback.ts
files.ts
folders.ts
god-mode.ts
hosted-proxy-headers.ts
hosted-proxy-templates.ts
hosted-websocket-relay.ts
hydrate.ts
images.ts
inngest.ts
jobsRouter.ts
knowledge.ts
meetings.route.ts
messages.ts
mobile-auth.ts
notes.ts
notifications.ts
og-image.ts
openai-voice.routes.ts
pinned-artifacts.ts
project-folders.ts
projects.ts
prompt.ts
public-templates.ts
published-artifacts.ts
recordings.ts
seats.ts
sheets.ts
shortcuts.ts
skill-builder.ts
sso-providers.ts
starter-prompts.ts
stripe-webhooks.ts
tabs.ts
tasks.ts
teams.ts
templates.ts
thread-folders.ts
thread-todos.ts
threads.ts
translate.route.ts
ui-guides.ts
user-artifact-order.ts
users.ts
waitlist.ts
workbooks.ts
workspaces.ts
33 untested jobs (click to expand)
auto-join.ts
backfill-document-indexing.ts
backfill-meeting-account-calendar.ts
backfill-slides-indexing.ts
backfill-thread-indexing.ts
backfill-workbook-indexing.ts
background-enrichment.ts
batch-enrichment.ts
calendar-webhook-migration.ts
call.ts
cleanup-analytics.ts
cleanup-notifications.ts
cleanup-webview-tokens.ts
credit-auto-reload.ts
file-extraction.ts
generate-project-name.ts
generate-thread-name.ts
meetings.ts
objective-cleanup.ts
objective-rebirth-checker.ts
organize-project.ts
prompt.ts
research.ts
sandbox-pause.ts
sandbox-rehydration-job.ts
sandbox-rehydration-processor.ts
scheduled-task-checker.ts
scheduled-task-executor.ts
slack-agent-response.ts
sse-connection-cleanup.ts
starter-prompts-generation.ts
suggestions-analysis.ts
template-recreate.ts
template-save.ts
template-update.ts
translate.ts
update-readme.ts
user-onboarding.ts