.github/9
ISSUE_TEMPLATE/3bug_report.md config.yml feature_request.md
workflows/3ci.yml clean-clone.yml release.yml
CODEOWNERS dependabot.yml pull_request_template.md
apps/630
api/250
src/243
common/30
__tests__/3authorize.test.ts bigint-serialization.interceptor.test.ts files-limits.test.ts
filters/1all-exceptions.filter.ts
guards/3auth.guard.ts internal-service.guard.ts rate-limit.guard.ts
interceptors/2actor-context.interceptor.ts bigint-serialization.interceptor.ts
middleware/2idempotency.test.ts idempotency.ts
pipes/1zod-validation.pipe.ts
actor-context.ts audit.service.ts cache.test.ts cache.ts cookies.ts core.module.ts deprecation.ts email.service.ts errors.ts event-bus.ts log-scrubber.test.ts log-scrubber.ts logger.ts permission-cache-bridge.ts prisma.service.ts redis.service.ts trace-metadata.ts types.ts
config/1env.ts
lib/11
__tests__/5crypto.test.ts filter-builder.test.ts jwt.test.ts pagination.test.ts positions.test.ts
authorize.ts crypto.ts filter-builder.ts jwt.ts pagination.ts positions.ts
modules/197
ai/28
__tests__/4ai-writing.test.ts database-ai.test.ts generate-executor.test.ts prompts.test.ts
generator/4executor.ts generate.controller.ts generate.dto.ts generate.service.ts
ai-chat.service.ts ai-rate-limit.ts ai-writing.controller.ts ai-writing.dto.ts ai-writing.service.ts ai.controller.ts ai.module.ts ai.service.ts budget-guard.service.ts database-ai.controller.ts database-ai.dto.ts database-ai.service.ts db-prompts.ts dto.ts gateway-provider.ts ledger.service.ts prompts.ts rag.controller.ts rag.dto.ts rag.service.ts
api-keys/3api-keys.controller.ts api-keys.module.ts api-keys.service.ts
audit/2audit-log.controller.ts audit.module.ts
auth/4auth.controller.ts auth.module.ts auth.service.ts dto.ts
automations/5automations.controller.ts automations.module.ts automations.service.ts dto.ts webhook-incoming.controller.ts
blocks/5
__tests__/1batch-version-cas.test.ts
block.service.ts blocks.controller.ts blocks.module.ts dto.ts
comments/4comments.controller.ts comments.module.ts comments.service.ts dto.ts
databases/9
__tests__/3normalize-select-options.test.ts option-id-canonicalization.test.ts record-open-query-shape.test.ts
database.service.ts databases.controller.ts databases.module.ts dto.ts property-cache-schema.ts query.service.ts
docs/2docs.controller.ts docs.module.ts
files/10
__tests__/1quota.test.ts
dto.ts files.controller.ts files.module.ts files.service.ts quota.ts record.ts s3.ts uploads.controller.ts uploads.service.ts
forms/18debug.controller.ts form.dto.ts forms.controller.ts forms.module.ts forms.service.ts markdown.test.ts markdown.ts optional-auth.guard.ts public-forms.controller.ts public-forms.service.ts question.dto.ts questions.service.ts rate-limit.ts recaptcha.ts slug.ts submissions.controller.ts submissions.service.ts submit-schema.ts
health/3health.controller.ts health.module.ts health.service.ts
integrations/3integrations.controller.ts integrations.module.ts integrations.service.ts
internal/12
__tests__/2flush-query-shape.test.ts internal.endpoints.test.ts
ai-test-seam.controller.ts ai-test-seam.dto.ts ai-test-seam.service.ts internal.controller.ts internal.dto.ts internal.module.ts internal.service.ts test-seam.controller.ts test-seam.dto.ts test-seam.service.ts
notifications/3notifications.controller.ts notifications.module.ts notifications.service.ts
oauth/6
__tests__/1oauth.scopes.test.ts
oauth.controller.ts oauth.module.ts oauth.service.ts scopes.ts token-keys.ts
org/15audit.service.ts embed-preview.controller.ts guards.ts members.service.ts org-admin.controller.ts org-policy.service.ts org.module.ts overview.service.ts policy-effective.controller.ts policy.schema.ts policy.test.ts retention.service.ts totp.test.ts totp.ts two-factor.service.ts
orgs/5dto.ts orgs.controller.ts orgs.module.ts orgs.service.ts util.ts
pages/4dto.ts page.service.ts pages.controller.ts pages.module.ts
scim/15
__tests__/3email-mapping.test.ts etag.test.ts filters.test.ts
etag.ts filters.ts groups.service.ts schemas.ts scim-admin.controller.ts scim-admin.service.ts scim-auth.guard.ts scim-auth.service.ts scim-errors.ts scim.controller.ts scim.module.ts users.service.ts
search/4
__tests__/1search.service.test.ts
search.controller.ts search.module.ts search.service.ts
sessions/3sessions.controller.ts sessions.module.ts sessions.service.ts
share/3share.controller.ts share.module.ts share.service.ts
sso/16
__tests__/4enforcement.test.ts oidc.verify.test.ts provisioning.test.ts saml.validate.test.ts
enforcement.ts oidc.controller.ts oidc.service.ts oidc.ts provisioning.service.ts saml.controller.ts saml.ts schemas.ts sso-admin.controller.ts sso-admin.service.ts sso-secrets.ts sso.module.ts
teams/4dto.ts teams.controller.ts teams.module.ts teams.service.ts
users/4dto.ts users.controller.ts users.module.ts users.service.ts
webhooks/3webhooks.controller.ts webhooks.module.ts webhooks.service.ts
workspaces/4dto.ts workspaces.controller.ts workspaces.module.ts workspaces.service.ts
types/1xmldom.d.ts
app.module.ts constants.ts main.ts
_probe_rawbody.cjs .env.example Dockerfile package.json README.md tsconfig.json vitest.config.ts
realtime/33
src/17auth.ts comments.ts config.ts event-source.ts http-store.ts index.ts metrics.ts notifications.ts page-updated-source.ts presence.ts prisma-store.ts protocol.ts rate-limit.ts room-key.ts rooms.ts server.ts update-log.ts
test/11auth.test.ts config.test.ts event-source.test.ts http-store.test.ts metrics-merge.test.ts page-updated-source.test.ts presence.test.ts protocol.test.ts rate-limit.test.ts rooms.test.ts task-0094-builders.test.ts
.env.example Dockerfile package.json README.md tsconfig.json
web/255
src/244
app/45
__tests__/1theme-tokens.test.ts
(app)/26
w/25
[workspace]/25
ask/1page.tsx
databases/1
[id]/1page.tsx
favorites/1page.tsx
files/1page.tsx
notifications/1page.tsx
page/4
[id]/4
[block]/1page.tsx
share/1page.tsx
layout.tsx page.tsx
search/1page.tsx
settings/10
appearance/1page.tsx
automations/3
[id]/1page.tsx
new/1page.tsx
page.tsx
billing/1page.tsx
developers/1page.tsx
members/1page.tsx
permissions/1page.tsx
teams/1page.tsx
page.tsx
shared/1page.tsx
templates/1page.tsx
trash/1page.tsx
layout.tsx page.tsx
layout.tsx
(auth)/4
login/1page.tsx
register/1page.tsx
reset-password/1page.tsx
layout.tsx
api/2
metrics/1route.ts
v1/1
health/1route.ts
f/1
[slug]/1page.tsx
health/1
ready/1route.ts
org/2
[orgId]/2
admin/2
integrations/1page.tsx
page.tsx
share/1
[id]/1page.tsx
error.tsx global-error.tsx globals.css layout.tsx not-found.tsx page.tsx providers.tsx
components/118
admin/10
org-admin/8ApiKeysTab.tsx AuditTab.tsx MembersTab.tsx OverviewTab.tsx PoliciesTab.tsx RetentionTab.tsx WebhooksTab.tsx WorkspacePicker.tsx
ScimCard.tsx SsoTabs.tsx
ai/6ai-panel.tsx ask-ai-submenu.tsx db-ai-dialog.tsx generate-page-dialog.tsx writing-actions-menu.tsx writing-diff.tsx
automations/5action-editor.tsx condition-editor.tsx lib.ts run-history.tsx trigger-editor.tsx
collaboration/6CursorLayer.tsx OfflineBanner.tsx PresenceBar.tsx README.md ReviewFailedDialog.tsx StatusChip.tsx
comments/3comment-panel.tsx comment-thread.tsx mention-input.tsx
database/27
__tests__/2cell-editor.test.tsx cell-renderer.test.tsx
AiExtractDialog.tsx AiFormulaDialog.tsx AiGenerateDialog.tsx board-view.tsx buttons-panel.tsx calendar-view.tsx cell-editor.tsx cell-renderer.tsx chart-view.tsx database-page-view.tsx database-toolbar.tsx database-view-renderer.tsx db-embedded.tsx filter-builder.tsx form-builder-view.tsx formula-editor.tsx gallery-view.tsx group-builder.tsx list-view.tsx property-editor.tsx record-header.tsx record-panel.tsx sort-builder.tsx table-view.tsx timeline-view.tsx
dialogs/7
__tests__/1move-to-dialog.test.tsx
create-dialog.tsx dialog.tsx file-permissions-dialog.tsx invite-dialog.tsx move-to-dialog.tsx share-dialog.tsx
editor/19
__tests__/3code-block-text.test.ts code-block.test.tsx expandable.test.tsx
block-card.tsx block-renderer.tsx block-save-queue.ts block-toolbar.tsx context-menu.tsx expandable.tsx history-popover.tsx inline-editor.tsx insert-dialog.tsx page-canvas.tsx page-spinner.tsx page-view.tsx selection-toolbar.tsx slash-menu.tsx template-dialog.tsx type-menu.tsx
files/4FileBlock.tsx FileBrowser.tsx FilePicker.tsx PreviewModal.tsx
form/4form-field.tsx form-renderer.tsx form-responses-view.tsx form-view.tsx
layout/8
__tests__/1page-tree-icon.test.tsx
command-palette.tsx factory-logo.tsx page-tree-node.tsx sidebar.tsx theme-provider.tsx topbar.tsx workspace-shell.tsx
mentions/3
__tests__/1mention-model.test.ts
mention-model.ts MentionPopup.tsx
search/3ask-ai-search.tsx results-list.tsx search-dialog.tsx
settings/10
api-keys/4ApiKeyCreateDialog.tsx ApiKeyRevealDialog.tsx ApiKeyTable.tsx ScopesBadge.tsx
webhooks/5CurlExamples.tsx DeliveryInspector.tsx EventExplorer.tsx OverviewTab.tsx WebhooksTab.tsx
settings-shell.tsx
ui/3confirm-dialog.tsx form.tsx toaster.tsx
hooks/21
__tests__/4realtime-frame-handler.test.ts use-blocks.test.ts use-database-options.test.ts use-workspace.test.tsx
realtime-frame-handler.ts use-ai-stream.ts use-auth.ts use-blocks.ts use-database.ts use-db-ai-stream.ts use-forms.ts use-members.ts use-mention-sources.ts use-notifications.ts use-offline-status.ts use-pages.ts use-presence-announcer.ts use-presence-toasts.ts use-presence.ts use-realtime.ts use-workspace.ts
lib/50
__tests__/21ai-database.test.ts ai-generate.test.ts ai-sse.test.ts ai-writing.test.ts api-keys.test.ts api-members.test.ts auth-refresh.test.ts auth-store.test.ts batch-queue-drop.test.ts block-content.test.ts clipboard-import.test.ts code-highlight.test.ts offline-status.test.ts presence-announcer.test.ts presence-color.test.ts presence-cursor.test.ts presence-emitter.test.ts realtime-url.test.ts search.test.ts utils.test.ts writing-diff.test.ts
files/7
__tests__/2picker.test.ts upload.test.ts
api.ts picker.ts upload-store.ts upload.ts use-file-uploads.ts
ai-database.ts ai.ts api-keys.ts api.ts auth-store.ts batch-queue.ts block-content.ts clipboard-import.ts code-highlight.ts constants.ts offline-status.ts org-admin.ts presence-announcer.ts presence-color.ts presence-cursor.ts presence-editor-views.ts presence-emitter.ts query-client.ts realtime.ts search.ts types.ts utils.ts
stores/8
__tests__/1block-patch-store.test.ts
block-patch-store.ts comment-pill-store.ts database-store.ts editor-store.ts offlineQueue.ts presence-store.ts ui-store.ts
instrumentation.ts middleware.ts
.env.example Dockerfile next-env.d.ts next.config.mjs package.json postcss.config.mjs README.md tailwind.config.ts tsconfig.json tsconfig.tsbuildinfo vitest.config.ts
worker/92
src/87
__tests__/13ai-embedding.test.ts ai-request.test.ts ai-usage-budget.test.ts audit-export.test.ts email-decision.test.ts encrypt.test.ts health-search-index-lag.test.ts mime.test.ts retention.test.ts s3-sign.test.ts search-index.test.ts smtp.test.ts webhook-sign.test.ts
health/1server.ts
lib/12
__tests__/1clamav.test.ts
clamav.ts encrypt.ts job-otel.ts mime.ts notify.ts prisma.ts redis-stream.ts redis.ts s3.ts sharp.ts smtp.ts
processors/56
automations/28
__tests__/3condition-evaluator.spec.ts executors.spec.ts run-pipeline.spec.ts
executors/17assign-user.ts call-integration.ts change-status.ts classify.ts create-notification.ts create-page.ts email-cap.ts helpers.ts integration-registry.ts permission.ts record-write.ts registry.ts run-ai-action.ts send-email.ts send-webhook.ts types.ts update-record.ts
condition-evaluator.ts dead-letter.ts log.ts matcher.ts pipeline.ts run-state.ts schedule.ts watchdog.ts
files/15
__tests__/4errors.test.ts scan-gate.test.ts status.test.ts temp.test.ts
steps/4finalize.ts metadata.ts scan.ts thumbnails.ts
cleanup.ts errors.ts generateThumbs.ts processor.ts status.ts temp.ts types.ts
search-index/4builders.ts grants.ts index.ts processor.ts
ai-embedding.ts ai.processor.ts audit-export.ts automations.processor.ts email-decision.processor.ts email.processor.ts maintenance.processor.ts retention.ts webhooks.processor.ts
config.ts events.ts index.ts logger.ts queues.ts
.env.example Dockerfile package.json README.md tsconfig.json
docs/73
api/17ai.md authentication.md automations.md blocks.md comments.md databases.md files.md forms.md openapi.yaml org-admin.md pages.md scim.md search.md sso.md versioning.md webhooks.md workspaces.md
architecture/10ai-architecture.md automation.md backend-architecture.md database-architecture.md frontend-architecture.md realtime-architecture.md search-architecture.md security-architecture.md storage.md system-architecture.md
database/2database-architecture.md redis-keys.md
development/8admin-guide.md coding-standards.md deployment.md development-guide.md files-pipeline.md perf-report.md performance.md testing.md
product/4functional-requirements.md non-functional-requirements.md product-requirements.md ux-requirements.md
requirements/1requirements-matrix.md
security/5audit-report.md files.md forms.md license-allowlist.md security-architecture.md
tasks/16phase-00-foundation.md phase-01-authentication.md phase-02-workspace.md phase-03-pages.md phase-04-editor.md phase-05-databases.md phase-06-relations.md phase-07-collaboration.md phase-08-search.md phase-09-files.md phase-10-forms.md phase-11-automation.md phase-12-ai.md phase-13-api.md phase-14-enterprise.md phase-15-production.md
ui/9ai.md automations.md design-system.md developers.md files.md forms.md org-admin.md scim.md sso.md
support-matrix.md
infrastructure/71
caddy/1Caddyfile
docker/6
init/101-extensions.sql
opensearch/1init-indices.json
.env.docker docker-compose.yml opensearch-init.sh README.md
kubernetes/40
observability/20
alertmanager/1alertmanager.yaml
grafana/8
dashboards/6ai.json api-overview.json infra.json realtime.json search.json workers-queues.json
provisioning/2
dashboards/1dashboards.yaml
datasources/1datasource.yaml
prometheus/3alerts.yaml recording-rules.yaml scrape.yaml
scripts/1sync-sources.mjs
alertmanager.yaml grafana.yaml kustomization.yaml namespace.yaml node-exporter.yaml otel-collector.yaml prometheus.yaml
postgres/7configmap.yaml cronjob-backup.yaml cronjob-opensearch-snapshot.yaml pgbouncer.yaml replica.yaml statefulset.yaml walg-iam-policy.yaml
api.yaml configmap.yaml ingress.yaml kustomization.yaml namespace.yaml networkpolicy.yaml pdb.yaml README.md realtime.yaml redis.yaml secret.example.yaml web.yaml worker.yaml
nginx/2nginx.conf README.md
observability/14
alertmanager/1alertmanager.yaml
grafana/8
dashboards/6ai.json api-overview.json infra.json realtime.json search.json workers-queues.json
provisioning/2
dashboards/1dashboards.yaml
datasources/1datasource.yaml
prometheus/3alerts.yaml recording-rules.yaml scrape.yaml
scripts/1dashboard-completeness.mjs
README.md
terraform/8compute.tf data.tf main.tf network.tf outputs.tf README.md security.tf variables.tf
packages/289
ai/24
src/20
providers/7anthropic.ts google.ts http.ts index.ts openai-compatible.ts rag.test.ts writing.test.ts
schemas/2database.ts generate.ts
adapters.test.ts config.test.ts config.ts gateway.test.ts gateway.ts index.ts tools.test.ts tools.ts types.ts usage.test.ts usage.ts
package.json README.md tsconfig.json vitest.config.ts
auth/11
src/7index.ts passwords.test.ts passwords.ts sessions.test.ts sessions.ts tokens.test.ts tokens.ts
package.json README.md tsconfig.json vitest.config.ts
collaboration/17
src/13awareness.ts codec.test.ts codec.ts index.ts lww.test.ts lww.ts mapping.ts offline.ts outbox.test.ts outbox.ts provider.test.ts provider.ts types.ts
package.json README.md tsconfig.json vitest.config.ts
config/7
src/4eslint.base.js index.ts prettier.base.json tsconfig.base.json
package.json README.md tsconfig.json
database-client/5
src/2index.test.ts index.ts
package.json README.md tsconfig.json
database-engine/33
src/29
filter/2filter.test.ts index.ts
formula/8evaluator.ts formula.test.ts functions.ts index.ts lexer.ts parser.ts types.ts validate.ts
query/6group.ts index.ts paginate.ts pivot.ts query.test.ts sort.ts
relations/2index.ts relations.test.ts
rollups/2index.ts rollups.test.ts
values/5dates.ts index.ts registry.ts types.ts values.test.ts
views/3buttons.ts index.ts views.test.ts
index.ts
package.json README.md tsconfig.json vitest.config.ts
editor/25
src/21
marks/1highlight.ts
nodes/2equation.ts mention.ts
autosave.test.ts autosave.ts clipboard.test.ts clipboard.ts codec.test.ts codec.ts context-menu.test.ts context-menu.ts diff.test.ts diff.ts factory.ts history.test.ts history.ts index.ts positions.ts slash.test.ts slash.ts types.ts
package.json README.md tsconfig.json vitest.config.ts
observability/20
src/16
__tests__/8db-redis-metrics.test.ts metrics.test.ts otel.test.ts pino-otel.test.ts prometheus.test.ts resource.test.ts scrubber.test.ts traceparent.test.ts
index.ts metrics.ts otel.ts pino-otel.ts prometheus.ts resource.ts scrubber.ts traceparent.ts
package.json README.md tsconfig.json vitest.config.ts
permissions/11
src/7index.ts levels.test.ts levels.ts resolve.test.ts resolve.ts rules.test.ts rules.ts
package.json README.md tsconfig.json vitest.config.ts
search/22
src/18chunking.test.ts chunking.ts client.test.ts client.ts embeddings.test.ts embeddings.ts hybrid.test.ts hybrid.ts index.ts indexer.test.ts indexer.ts mapping.test.ts mapping.ts queries.test.ts queries.ts rrf.test.ts rrf.ts types.ts
package.json README.md tsconfig.json vitest.config.ts
shared/61
src/57
dto/17ai.dto.ts auth.dto.test.ts auth.dto.ts block.dto.ts browser-safety.test.ts comment.dto.ts database.dto.test.ts database.dto.ts file.dto.ts formula-ast.ts index.ts notification.dto.ts page.dto.ts search.dto.ts share.dto.ts webhook.dto.ts workspace.dto.ts
events/8audit-catalog.test.ts audit-catalog.ts audit-csv.test.ts audit-csv.ts audit-scope.test.ts audit-scope.ts catalog.test.ts catalog.ts
realtime/6comment-events.ts frames.test.ts frames.ts notification-policy.ts notification-prefs.ts task-0094.test.ts
automation.test.ts automation.ts constants.ts crypto.test.ts crypto.ts env.ts errors.ts events.test.ts events.ts forms.test.ts forms.ts index.ts markdown.test.ts markdown.ts mentions.test.ts mentions.ts net.test.ts net.ts positions.test.ts positions.ts presence.test.ts presence.ts security-headers.ts webhook-delivery.test.ts webhook-delivery.ts webhook-events.ts
package.json README.md tsconfig.json vitest.config.ts
storage/16
src/12client.test.ts client.ts index.ts keys.test.ts keys.ts mime.test.ts mime.ts presign.test.ts presign.ts thumbnails.test.ts thumbnails.ts types.ts
package.json README.md tsconfig.json vitest.config.ts
ui/37
src/33
components/19avatar.tsx badge.tsx button.tsx checkbox.tsx command.tsx context-menu.tsx dialog.tsx dropdown-menu.tsx empty-state.tsx index.ts popover.tsx separator.tsx skeleton.tsx slider.tsx spinner.tsx switch.tsx tabs.tsx toast.tsx tooltip.tsx
color.ts command-filter.test.ts command-filter.ts focus.test.ts focus.ts formatters.test.ts formatters.ts index.ts theme.test.ts theme.ts toast-store.test.ts toast-store.ts tokens.test.ts tokens.ts
package.json README.md tsconfig.json vitest.config.ts
prisma/16
migrations/13
20260927000000_init/1migration.sql
20260928000000_search_documents_content_hash/1migration.sql
20260929000000_workspace_usage_storage_bytes/1migration.sql
20260930000000_form_submitted_notification_type/1migration.sql
20261001000000_ai_phase12/1migration.sql
20261002000000_webhooks_secret_encrypted_dlq/1migration.sql
20261002111436_webhook_delivery_latency/1migration.sql
20261002120000_org_admin_2fa_retention_unique/1migration.sql
20261002215124_audit_export/1migration.sql
20261003210000_perf_indexes_hot_paths/1migration.sql
20261004004500_perf_indexes_hot_paths_2/1migration.sql
migration_lock.toml README.md
schema.prisma seed.ts verify.ts
scripts/7backup-health.ts docs-completeness.mjs generate-openapi.mjs minio-init.ts opensearch-reindex.ts storage-orphans.ts verify-clean-clone.sh
tests/169
e2e/63
.auth/1user.json
fixtures/7
files/6clip.mp4 clip.wav clip.webm hero-1400.png note.docx note.txt
realtime.ts
mocks/2oidc-issuer.ts saml-idp.ts
playwright-report/3
data/2a6557bae9c2714a658968d4eb8534195c08ebda8.png e3092d07d00a16063e46385c02a559a9054fa847.webm
index.html
reports/1files-security.json
specs/34ai-database.spec.ts ai-generate.spec.ts ai-rag.spec.ts ai-security.spec.ts ai-writing.spec.ts ai.spec.ts api-keys.spec.ts appearance-theme.spec.ts auth.spec.ts automation.spec.ts collab-two-tab.spec.ts comments.spec.ts databases.spec.ts default-workspace-alias.spec.ts developers.spec.ts editor.spec.ts files.spec.ts final-flow.spec.ts forms.spec.ts oauth.spec.ts org-admin.spec.ts pages.spec.ts performance.spec.ts presence-cursors.spec.ts qa-paste-toggle.spec.ts realtime.spec.ts scim.spec.ts search-index-lag.spec.ts search.spec.ts sharing.spec.ts sso.spec.ts task-0094-comments-notifications.spec.ts webhooks.spec.ts workspace.spec.ts
test-results-final-flow/3
final-flow-Release-v1-0-fi-6c06b-w-state-carries-sequential--chromium-desktop/2test-failed-1.png trace.zip
.last-run.json
utils/4api.ts dnd.ts search-lag.ts wait.ts
.gitignore fixtures.ts global-setup.ts package.json playwright.config.ts playwright.final-flow.config.ts README.md tsconfig.json
fixtures/1
files/1make-sparse.ts
integration/60
ai-capability/2ai-app.capability.test.ts gateway.capability.test.ts
drill/2seed-drill.mjs verify-restore.mjs
fixtures/5
files/5clip.mp4 clip.wav doc.pdf hero-1400.png note.txt
helpers/3api.ts containers.ts seed.ts
realtime/11control-channel.test.ts convergence.test.ts flush-rebase-http.test.ts handshake.test.ts heartbeat-limits.test.ts lifecycle.test.ts presence.test.ts rebase.test.ts resume.test.ts rt-helpers.ts task-0094-fanout.test.ts
ai-chat.integration.test.ts ai-database.integration.test.ts ai-generate.integration.test.ts ai-rag.integration.test.ts ai-writing.integration.test.ts api-keys.integration.test.ts audit-completeness.integration.test.ts audit-export-s3.integration.test.ts auth.integration.test.ts automation-pipeline.integration.test.ts automations.integration.test.ts blocks.integration.test.ts cache-invalidation.integration.test.ts comments.integration.test.ts databases.integration.test.ts files-lifecycle.integration.test.ts files-pipeline.integration.test.ts files-security.integration.test.ts files.integration.test.ts forms-responses.integration.test.ts forms.integration.test.ts oauth.integration.test.ts openapi.contract.test.ts org-admin.integration.test.ts package.json pages.integration.test.ts permissions.integration.test.ts README.md replica-routing.integration.test.ts retention-engine.integration.test.ts scim.integration.test.ts search.integration.test.ts sso.integration.test.ts tsconfig.json vitest.config.ts webhooks.integration.test.ts workspace.integration.test.ts
performance/28
fixtures/1search-100k.ts
helpers/2seed-100k.mjs seed-1k-load.mjs
reports/7api-load-smoke.json database-load-smoke.json editor-local.json realtime-load.json search-full.json search-last.json search-reduced.json
api-load.js api.js archive.tar database-load.js database.js editor-local.mjs extract-100k-env.mjs package.json README.md realtime-1k.js realtime-load.js realtime.js run-realtime-load.sh search-search.k6.js search-summary.json seed-100k.mjs threshold-breach-demo.js verify-zero-op-loss.mjs
security/16
helpers/1app.ts
audit-report.test.ts auth-paths.test.ts deps.test.ts formula-fuzz.test.ts gitleaks-config.test.ts headers.test.ts images.test.ts oracle.ts package.json permission-fuzz.test.ts rate-limits.test.ts README.md tsconfig.json upload-abuse.test.ts vitest.config.ts
README.md
.dockerignore .env .env.bak-task0125 .env.example .eslintrc.json .gitignore .npmrc .prettierignore .prettierrc.json AGENTS.md ARCHITECTURE.md CHANGELOG.md CONTRIBUTING.md gitleaks.toml LICENSE package.json pnpm-lock.yaml pnpm-workspace.yaml PRODUCT-SPEC.md README.md ROADMAP.md SECURITY.md tsconfig.json turbo.json
phase-15-production.mddocs/tasks/phase-15-production.md← tasks63,621 B← Back to the app

Phase 15 — Production Hardening

Purpose: Task specs for Phase 15 — the final phase before v1.0: the OWASP ASVS L2 security audit + hardening, and performance/observability/backup-DR + the v1.0 release with the final full-flow E2E.

Phase exit criteria (ROADMAP.md, Phase 15):

  • All perf targets met in the tests/performance suite.
  • Restore drill documented + executed.
  • Dashboards + alerts live in staging.

Task range: TASK-0134 … TASK-0135 (2 tasks — this agent owns exactly TASK-0134..TASK-0135; TASK-0096..0120 are owned by other agents).

Section references: performance targets are PRODUCT-SPEC §26 and docs/product/non-functional-requirements.md; the metric list cited by the brief as "§62" does not exist in the 28-section PRODUCT-SPEC.md — the metric set is defined by docs/product/non-functional-requirements.md and this file's TASK-0135 metrics requirement (recorded conflict per AGENTS rule 29).

Task Table

ID Title Estimate
TASK-0134 Security audit + hardening (OWASP ASVS L2) L
TASK-0135 Performance, observability, backup/DR + release v1.0 L

Staging Environment (TASK-0135 precondition)

The staging cluster is where the hard perf gates, dashboards, backup drill, and final E2E run. Specification (provisioned in infrastructure/kubernetes/ by this task's infra work; the cluster itself is an environment, not code):

Component Staging spec
Nodes 3× (4 vCPU / 16 GB) worker + 1× control (managed); k8s 1.29+
factory-api 3 replicas, 1000m/512Mi requests (2000m/1Gi limits), HPA 3–10 on CPU 70%
factory-web 2 replicas, 500m/512Mi, behind the same ingress
factory-worker 2 replicas per queue group (ai/webhooks/maintenance/email pools), 1000m/1Gi
factory-realtime 2 replicas, 1000m/1Gi, max 5k ws conns per pod (the 10k load test spans both)
PostgreSQL 16 primary (8 vCPU/32 GB, 500 GB gp3) + 1 read replica (4 vCPU/16 GB, 250 GB); PgBouncer 2 replicas in front (transaction mode)
OpenSearch 2.x 3-node cluster, 10 GB heap, 200 GB; indices per workspace-tenant pattern
Redis 7 single node with AOF (dev-grade acceptable for staging DR — documented), 16 GB
MinIO 4-node erasure set, 500 GB, S3 versioning on files + backups
Observability stack OTel collectors (daemonset + deployment), Prometheus (2 h local + S3 remote-write optional), Grafana, Alertmanager, Loki optional (pino → stdout is primary; Loki scrape of pod logs is the staging convenience path)
S3 (AWS) factory-staging-backups (versioned, private, KMS), factory-staging-files, factory-staging-exports
CI self-hosted runner (4 vCPU) for the local editor perf test; staging deploy token; ghcr org robot for image pushes

Environment config lives in infrastructure/kubernetes/values.staging.yaml (the single values file per environment, the convention for the release). The staging AI provider is AI_PROVIDER=mock (TASK-0126's scripted mock — the final-flow AI step is deterministic and cost-free in staging).

Phase Completion Checklist


TASK-0134

Title

Security audit + hardening (OWASP ASVS L2)

Objective

Run a structured OWASP ASVS Level 2 audit across the platform — dependencies, secrets, auth paths, permissions (property-based fuzzing vs a brute-force oracle), transport/headers (CORS/CSRF/CSP), file-upload abuse, formula-engine fuzzing, and rate-limit verification — and harden every finding with a fix + regression test, closing with a signed ASVS L2 checklist in docs/security/audit-report.md.

Background

Phases 0–14 shipped the full product surface: auth with rotating refresh tokens (Phase 1), RBAC + resource permissions via packages/permissions (Phase 2/3), files with presigned uploads + virus scan (Phase 9), the safe formula AST evaluator in packages/database-engine (Phase 6), public API keys/OAuth/webhooks (Phase 13), SSO/SCIM (Phase 14). docs/security/security-architecture.md is the threat-model home; .env.example documents MASTER_ENCRYPTION_KEY and the auth secrets. CI already runs lint → typecheck → unit → integration → build → security scan → E2E (Phase 0) — this task makes the security scan real (npm audit, gitleaks, license) and adds the audit suites. The permission engine's brute-force oracle: the spec is small enough (roles Owner/Admin/Member/Guest × resource visibility × grants) that an exhaustive reference implementation in the test can enumerate every (subject, resource) pair and compute the expected decision by direct rule evaluation — the engine under test must match on all 10k random cases.

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0135

Title

Performance + observability + backup/DR + release v1.0

Objective

Take the platform to production shape: profile and fix the top-5 hot paths (Redis caching, indexes, Prisma query shape, pooling/replica), make the tests/performance k6 suites pass the PRODUCT-SPEC §26 criteria in CI, ship OpenTelemetry + Prometheus + Grafana + alerting as code, build PITR-capable backup/DR with an executed restore drill, and cut the v1.0 release with the final full-flow E2E green in staging.

Background

The system is feature-complete (Phases 0–14): apps/web (Next.js 14), apps/api (NestJS modular monolith), apps/worker (BullMQ: automations, AI, webhooks, email, maintenance queues), apps/realtime (ws + Yjs), Prisma/PostgreSQL (models incl. Block, DatabaseRecord, AuditLog, SearchDocument), OpenSearch, MinIO, Redis. Performance targets: PRODUCT-SPEC §26 (initial load < 2 s, editor interaction < 50 ms, local block move < 16 ms, search < 500 ms p95, API p95 < 300 ms, realtime update < 200 ms p95, 100k-record databases) + the brief's load-test matrix (1k rps API, 10k WS conns, 100k-record table, editor E2E latency) — all to be enforced in CI via k6 (report-only in dev, hard in staging). infrastructure/kubernetes/ has per-app manifests (Phase 0); infrastructure/docker/ the dev compose (postgres, redis, minio, opensearch). docs/product/non-functional-requirements.md is the verification owner for these targets. The brief's "§62 metric list" does not exist (PRODUCT-SPEC has 28 sections) — the metric set is defined by that NFR doc + the metrics requirement below (conflict recorded in the file header).

Requirements

Release pipeline specification

One CI pipeline (infra/pipeline/release.yml, the Phase 0 pipeline extended), stages in strict order — a stage cannot start on a red predecessor, and the tag step runs only at the end:

# Stage What it does Gate
1 install+lint+typecheck pnpm frozen install, ESLint, tsc strict hard
2 unit Vitest (packages) + Jest (api/worker) hard
3 integration tests/integration (Postgres/Redis/OpenSearch/MinIO via compose services) hard
4 security TASK-0134's 10 suites (deps, gitleaks, auth paths, permission fuzz, headers, upload abuse, formula fuzz, rate limits, image scans, report cross-check) hard
5 build all apps + packages built; Docker images built (not yet pushed) hard
6 deploy-staging values.staging.yaml → k8s apply (api, web, worker, realtime, observability, pgbouncer, replica) hard (apply + readiness)
7 smoke Phase 0 smoke suite against staging (login + page create + search), < 2 min hard
8 performance the 4 k6/local suites, hard thresholds (the dev run of the same suites in PRs is report-only) hard
9 backup-health last base backup < 26 h, last WAL ship < 10 min, OpenSearch snapshot < 26 h hard
10 final-e2e tests/e2e/final-flow.spec.ts (13 steps) in staging hard
11 docs-completeness scripts/docs-completeness.mjs (READMEs, OpenAPI+docs coverage, ROADMAP boxes) hard
12 push+tag push ghcr images (v1.0.0 + latest), create annotated tag v1.0.0 on main, publish release notes (digests, drill results, E2E run link, runbook links) hard (tag is the last act)

Rules: stages 8/10 read staging after stage 6's rollout is Ready (a rollout wait step, 10 min budget); a failure at any stage pages the on-call channel (the Alertmanager webhook from the observability work — self-dogfood); the pipeline is re-runnable per stage (--from-stage), and the tag step is idempotent (re-run pushes the same images/digests, never moves the tag). The dev/PR pipeline runs stages 1–5 + a report-only performance stage + E2E against compose (not staging) — the staging cluster is release-pipeline-only, so release load never corrupts PR feedback timing.

k6 scenario matrices (the four suites, exact shape)

Suite Scenarios (vusers) Profile Thresholds (staging-hard)
api-load.js tree-load 400 (GET page tree, 200 distinct pages), record-list 300 (GET database pages, 5 distinct 100k-adjacent DBs), search 200 (POST /search, 100 distinct queries), record-create 100 (POST records, 5% of traffic) 5 min ramp 0→1k rps (constant-arrival-rate), hold 3 min, ramp down 1 min overall p95 < 300 ms; per-scenario p95 < 300 ms; http_req_failed < 0.1%; p99 < 800 ms (soft, reported)
realtime-load.js connect 10k over 5 min (100 rooms × 100 conns, jittered join), edit all 10k sending block-edit ops, 200 msg/s aggregate (rate-limited per-conn), presence 1k (join/leave churn 10/min) 15 min steady state update p95 (client-observed op-ack) < 200 ms; connect p95 < 1 s; zero lost Yjs ops (final doc state hash equals the sequential-replay hash); disconnects < 0.5% (excl. scripted)
database-load.js table-first 50 (table view first page on the seeded 100k DB, fresh cache), table-scroll 100 (pages 2..50), record-open 50 (record → page → blocks), record-create 100 (sustained 100 rps creates) 2 min table-*, 2 min record-create, 1 min record-open table view p95 < 500 ms; record-open p95 < 500 ms; creates p95 < 500 ms + create rate ≥ 100 rps sustained (no > 5 s stalls); error rate < 0.1%
editor-local.mjs headless Chromium on the local runner: type 500 key-insertions across 10 blocks, create-block 100 (Enter/slash), move-block 200 drag-simulations (the editor's programmatic move API — the real DnD path), render frame-time sampling during the above single browser instance, 10 min interaction p95 < 50 ms (input→commit); move < 16 ms (the local §26 target, p95 and p99 both asserted); no frame > 100 ms during move-block

The seed fixture seed-100k.mjs builds, per staging run: one 100k-record database (5 properties incl. 1 date, 1 select), one 10k-block page (for tree-load), 200 pages (for search/tree), committed to the DB directly (Prisma createMany in 1k batches, ~3 min wall clock) — it is a test-data job, run by the pipeline stage 8 precondition, and is idempotent (re-runs are no-ops by marker table test_seeds).

Alert rules (the six, exact expressions)

Alert Expr (Prometheus) For Severity Route
ApiErrorRateHigh sum(rate(http_request_count{status=~"5.."}[5m])) / sum(rate(http_request_count[5m])) > 0.01 5m page webhook (automation) + email
ApiP95Slow histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[10m])) by (le, route_group)) > 0.5 10m page webhook + email
QueueDepthHigh queue_depth > 10000 (any queue) 5m page webhook + email
WsConnectionsDrop ws_active_connections < 0.7 * avg_over_time(ws_active_connections[1h]) 15m page webhook + email
DiskUsageHigh node_filesystem_usage{mountpoint="/var/lib"} > 0.8 10m warn email (webhook on page-only)
CertExpiringSoon probe_ssl_earliest_cert_expiry - time() < 14 * 86400 (blackbox probes on the ingress) 1h page webhook + email

Plus two operational (warn, email-only): BackupStale (stage-9 conditions as a continuous alert) and SearchIndexLagHigh (indexer lag > 30 s, the Phase 8 SLO). Alertmanager config: repeat_interval: 4h, the webhook receiver posts to the platform's own incoming-webhook automation ("Alert: <name> firing, <value>, <link>") — the dogfood — and the email receiver uses the nodemailer queue (Phase 7/11 processor).

Final E2E flow (the 13 steps, exact)

tests/e2e/final-flow.spec.ts, one project, sequential (state carries), against the staging URL, ~6 min budget:

# Step Assertion
1 Register (unique email per run, final-e2e-<runId>@test) 201 + verification email in staging mailcatcher (API poll)
2 Verify email (click link in the mailcatcher HTML) session established, profile page
3 Create workspace "Release Co" workspace shell + sidebar (Home/Inbox/Search/…)
4 Create page "Release Plan" under Home page route renders, title in the doc
5 Editor: type 5 blocks, drag the 3rd below the 1st order persists across reload; the move used the DnD path
6 Create database "Tasks" (3 props: title, status select, due date) + 3 records via UI table renders 3 rows
7 Add relation Tasks→"People" db + a formula column (isOverdue) rollup/relation links render; formula value correct on 1 row (asserted via API read)
8 Global search: query "Release Plan" finds the page; query a unique record title finds the record result links resolve (click → correct page/record)
9 Upload a 10 MB file into the page (file block) preview renders; file metadata via API (size, mime)
10 Create a public form (1 question) + submit it anonymously (context-isolated page) record created in the mapped db; form.submitted fired (audit)
11 Create automation: trigger record.created(Tasks) → action notify (in-app) → trigger by creating a 4th record via API automation run row SUCCEEDED; notification appears in Inbox
12 AI: open Ask AI on the page (staging AI_PROVIDER=mock), ask about the page streamed answer (≥ 3 incremental DOM updates) + a citation chip linking to the page
13 API + webhook: create API key (UI reveal), fetch POST /api/v1/pages with the key, then the test receiver gets page.created ≤ 10 s with a valid X-Factory-Signature (recomputed in-test); then log out 201; signed delivery + HMAC verified; session gone (refresh 401)

Step 13's webhook receiver is the same in-process HTTP server pattern as TASK-0130's E2E; the run's artifacts (mailcatcher dump, receiver log, k6-less timing trace) are attached to the CI job for the release notes.

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


Deviations & Conflicts (AGENTS rule 29 — recorded, not guessed)

Implementation/verification drift recorded while completing TASK-0135 locally (dev box; staging-only items documented, never faked). App-side bugs found by the final 13-step E2E (tests/e2e/specs/final-flow.spec.ts) and fixed server- or client-side; spec-side edits were limited to test-logic defects with the assertions left unchanged.

  1. Relation read-path gap (fixed, API). Relation values are written to the RelationLink junction (via the links field) but were never materialized in the record DTO — toDto read the relation value from DatabaseRecordProperty, where a RELATION property row is never stored, so properties[relPropId] was always null. Fixed in apps/api/src/modules/databases/query.service.ts: a buildRelationLinkRecords batch helper (one relationLink.findMany + one relation.findMany, replica- routed for reads, primary for updateRecord read-your-own-write) and a RELATION branch in toDto that synthesizes { recordIds }. Wired into list / query / getRecord / updateRecord.

  2. Record search-doc titles were "(untitled record)" (fixed, worker). apps/worker/.../search-index/builders.ts buildRecordDoc read the title from the isTitle DatabaseRecordProperty row, which the API never writes (title lives on Page.title). Now the record and its linked records are fetched with a page.title join and the doc title is Page.title (the isTitle property is a legacy fallback only and is excluded from the body when the page title is used).

  3. Webhook envelope field is type, not event (spec fixed). The delivery envelope (buildDeliveryEnvelope, packages/shared/src/webhook-delivery.ts) and docs/api/webhooks.md §4 both carry the event name in type; there is no event field. The final-flow spec's step-13 assertion was corrected from parsed.event to parsed.type (assertion value unchanged).

  4. Step-8 getByLabel('Search') strict-mode violation (spec fixed). Non-exact matched both the toolbar button (aria-label="Search (Command K)") and the input (aria-label="Search"). Spec now uses getByLabel("Search", { exact: true }) (the input, which is the one .fill()ed).

  5. useRelations returned PromiseFulfilledResult wrappers (fixed, web). apps/web/src/hooks/use-database.ts mapped a Promise.allSettled result without unwrapping, so consumers read .recordId/.record off the wrapper (always undefined) and rendered the "Record" fallback; this also produced the pre-existing web tsc baseline errors at cell-editor.tsx L765. Now .filter(fulfilled).map(r => r.value).

  6. Record-open query-shape test mock (test updated, bounds unchanged). record-open-query-shape.test.ts counting mock gained the read()/write() delegates (returning the same counting client) and a no-op relation delegate required by the new RELATION helper (the fixture has no RELATION property, so the helper short-circuits). The ≤4 / ≤5 / 6 query-count assertions are unchanged.

  7. Step-13 refresh-after-logout 200 (spec fixed). The final assert used context.request.post("/api/v1/auth/refresh") — a relative URL. BrowserContext.request is bound to the context's baseURL (WEB_BASE, :3000, the Next app), which has no such route and 307-redirects to /login (→200), masking the real revocation. The API correctly returns 401 (verified by a pure-API diag and an in-browser diag). The spec now posts to ${API_BASE}/api/v1/auth/refresh (absolute); the context.request still shares the browser context's (cleared) cookies, so the assertion is unchanged.

  8. Mobile (<640 px) layout: the fixed 256 px sidebar squeezed the editor (fixed, web). The app shell rendered the sidebar as an in-flow column at EVERY breakpoint, so at 375 px the editor column was ~119 px wide and the block drag-handle gutter (left of the row) landed under the sidebar, which intercepted the pointer — dnd-kit reorder was unreachable on mobile (the final-flow mobile project failed at step 5). docs/product/ux-requirements.md (mobile row + the z-index tokens) specifies the intended behavior: single- column everything, the sidebar as a z-90 DRAWER (closed by default), and the editor's ⋮⋮ handle always visible in the RIGHT gutter. Implemented: ui-store mobileNavOpen (default false) + setMobileNav; the sidebar renders the drawer only when open below md: and the in-flow column only at md: and up (the topbar hamburger is breakpoint-aware); the block toolbar gutter in page-view.tsx is right-anchored + always visible below md: (one toolbar, one data-testid="drag-handle"). Desktop behavior is unchanged (left gutter on row hover; the final-flow desktop run is green). The final-flow mobile spec gains the real user's opener (topbar hamburger → drawer visible) before clicking user-menu-logout, since the button now lives inside the closed-by-default drawer (the desktop path is unchanged).

Still-open pre-existing notes (not fixed here, recorded for follow-up): shared block.dto op set; inline-editor dead guards (L163/L168); use-pages.ts L74; base-36 vs base-62 id handling; next lint/ESLint-9 pre-existing breakage; /page-tree 404 route; web tsc baseline (was 123 → now lower after the useRelations fix); list() replica-routed read (dev has no replica → primary).

ROADMAP Phase 15 says "Database optimization (indexes, partitioning for blocks/audit, query plans)"; the TASK-0135 spec's database-optimization AC is EXPLAIN-proven indexes + query-shape fixes (no partitioning AC), so partitioning was NOT implemented — no EXPLAIN case demonstrates the need at the dev scale, and a speculative partition migration would violate the "no speculative indexes" rule. Recorded per rule 29 (spec over roadmap wording); if the audit table outgrows a single partition it is a follow-up task.