.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-06-relations.mddocs/tasks/phase-06-relations.md← tasks141,496 B← Back to the app

Phase 6 — Relations — Task Specifications (TASK-0081 … TASK-0090)

Purpose. Task spec sheet for Phase 6 of ROADMAP.md: relations (1:1 / 1:N / M:N, bidirectional), rollups (COUNT/SUM/AVERAGE/MIN/MAX/PERCENT/UNIQUE), the safe formula engine (parser → AST → evaluator, zero eval), formula/rollup properties with event-driven recompute, database buttons, and sub-items — per PRODUCT-SPEC §9.4–9.7, docs/product/functional-requirements.md §5.5, and the Phase-5 handoff contract recorded in docs/tasks/phase-05-databases.md (TASK-0080 R4: query endpoint, codec registry, cell renderers, record event shapes, dbmeta cache, view-settings contract).

Phase exit criteria (verbatim from ROADMAP.md, Phase 6):

Task table

ID Title Estimate
TASK-0081 Relations API + model (cardinality, bidirectional, link maintenance, cascade) L
TASK-0082 Relation property editor (multi-select dialog, bidirectional side) M
TASK-0083 Rollups (7 aggregates, on-read compute + Redis cache, event invalidation) L
TASK-0084 Formula engine (tokenizer → Pratt parser → AST → safe evaluator, fuzz) L
TASK-0085 Formula property (config, AST storage, editor UI with autocomplete + preview) M
TASK-0086 Formula/rollup evaluation pipeline (worker recompute, depth limit, cycle guard) L
TASK-0087 Database buttons (7 action types, execution endpoint, button UI) L
TASK-0088 Sub-items (isSubItem, child list in parent page, rollup dependency across sub-items) M
TASK-0089 E2E relations suite (tests/e2e/relations.spec.ts) L
TASK-0090 Formula engine coverage + phase-exit verification (zero-eval CI gate) M

Phase Completion Checklist (evidence recorded by TASK-0090)

Recorded notes (conflicts/adjustments, per AGENTS.md):

  1. The phase brief's button action list names send_webhook (stub Phase 13) and trigger_automation (stub Phase 11); functional-requirements §5.5 has both as real actions "enqueued asynchronously." Resolution: Phase 6 implements the execution plumbing (the action type is accepted, validated, and executed as an enqueue against the Phase-11/13 queue names — automation BullMQ queue and webhook-deliveries flow) with the worker-side executors stubbed to NOT_IMPLEMENTED-marked jobs that log and no-op until their phases land; the button result report shows "queued" (not "executed") for those two types until then. This keeps the execution endpoint's contract stable for Phase 11/13.
  2. rollups.recompute: the brief says "computed on read with Redis cache (TTL 60 s) + invalidation via domain events"; database-architecture §1.4 says computed values are "computed at query time for small sets, event-driven precomputed into a materialized cache for large ones." Resolution (both, by dataset size): on-read compute is the default path; when a database exceeds ROLLUP_MATERIALIZE_THRESHOLD (5,000 records with ≥ 1 rollup, env-tunable), the TASK-0086 worker precomputes into record_properties rows (the schema already supports it — record_properties.value for a ROLLUP property) and queries read the materialized rows; invalidation events flush both the Redis cache and the materialized rows. Recorded so the two docs agree.
  3. Formula now() is documented nondeterministic (re-evaluated on each read) per functional-requirements §5.5; the materialized cache therefore excludes formulas containing now() (they always compute on read) — the dependency scanner flags the AST, not just the dependencies list.
  4. Relation values are NOT stored in record_properties — links live in relation_links (database-architecture §1.4, uniform M:N join table; 1:1/1:N are service-layer count assertions). Phase 5's "computed values 422" contract for the RELATION property is lifted in this phase: PATCH with a relation value is now accepted (it maps to link operations) — the 422 applies only to ROLLUP/FORMULA.

TASK-0081

Title

Relations API + model (cardinality, bidirectional reverse property, link maintenance, cascade)

Objective

Implement relation creation and link management end-to-end: POST /v1/databases/:id/relations creates the Relation row (+ the RELATION property on both databases when bidirectional), cardinality enforcement (1:1 replacement semantics, 1:N single-side assertion), the relation_links join table maintenance (add/remove/replace in one transaction), reverse-link maintenance (setting links from either side keeps both sides consistent by construction — one row, two reads), and cascade rules (record delete → links removed; relation delete → links removed + properties soft-deleted).

Background

PR-075/076 P0. Schema (already present): relations (databaseId → targetDatabaseId, cardinality ONE_TO_ONE/ONE_TO_MANY/MANY_TO_MANY, bidirectional, propertyId? this side, reversePropertyId? counterpart, name/targetName per-side display names); relation_links (uniform M:N join: databaseId × recordId × targetDatabaseId × targetRecordId unique, plus the reverse-lookup index). database-architecture §1.4: "Cardinality as policy, not constraint… 1:1 ('exactly one target') and 1:N ('many on one side') are validated in RelationService.setLinks (transactional delete-then-insert with count asserts)." functional-requirements §5.5: "ONE_TO_ONE: linking a second target on the 'one' side unlinks the previous — API returns the replaced link"; "Deleting a record removes its links (cascade); deleting a relation property removes all its links." Events: relation.linked / relation.unlinked (backend-architecture §7.2 — consumed by TASK-0086 recompute and Phase-13 webhooks). Phase-5 handoff (TASK-0080 R4): the RELATION property type exists in the schema with config: {} placeholder; this task fills config with {relationId, multiple} and wires the cell (TASK-0082).

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0082

Title

Relation property editor (multi-select dialog with search, bidirectional side, relation cell)

Objective

Implement the RELATION property's user surface: the relation cell (chips of linked record titles, count, + to link), the multi-select dialog (search records in the target database, select/deselect with a live count, pre-populated from the current links), and the bidirectional experience (editing from either side updates the same link set; the reverse property's cell shows the same links with its own column name).

Background

PR-076 P0: "Relation cells show linked record titles (multi-select popover, search); reverse side updates automatically." functional-requirements §5.1 row 20: value ["recordId"], editor "Multi-select popover of linked records (search)". The Phase-5 cell placeholder (apps/web/database/cells/RelationCell.tsx — "Phase 6" chip) is replaced here. The data path: cell click → dialog → GET …/links (current)

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0083

Title

Rollups (7 aggregates, on-read compute + Redis cache, event invalidation)

Objective

Implement ROLLUP properties: POST /v1/databases/:id/rollups (relation + target property + aggregate + optional filter), on-read computation with a 60 s Redis cache, event-driven invalidation (record.updated/relation.linked|unlinked on the linked database → cache flush), correct results for all 7 aggregates (COUNT, SUM, AVERAGE, MIN, MAX, PERCENT, UNIQUE), and the read-only ROLLUP cell.

Background

PR-077/078 P1. Schema: rollups (relationId, targetPropertyId, aggregate, filter Json?, propertyId? = the ROLLUP property it feeds). functional-requirements §5.5: "value computed lazily on read and eagerly refreshed via events (record.updated, relation.changed) for the affected records; PERCENT = fraction of matching (filtered) related records (0–1, displayed %); UNIQUE = deduped value list (or count when display is 'count'); result type inferred (SUM/AVG → number; MIN/MAX → type of target; COUNT/PERCENT → number; UNIQUE → array)." Header note 2: on-read is the default; the materialized path (worker precompute into record_properties for large dbs) is TASK-0086's job — this task builds the pure aggregate engine + the cache + the invalidation, and the query integration reads either path through one interface (ComputedValueProvider — on-read here, materialized swap-in in TASK-0086).

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0084

Title

Formula engine (tokenizer → Pratt parser → AST → safe evaluator, fuzz)

Objective

Implement the formula engine in packages/database-engine/src/formula: a tokenizer, a Pratt parser producing a JSON AST, and a safe AST evaluator with the fixed function set (if, and, or, not, sum, average, min, max, dateAdd, dateBetween, now, concat, replace, contains, length + prop(name)), type inference, a structured FormulaError {PARSE|TYPE|RUNTIME|UNKNOWN_FUNCTION}, per-evaluation step limits, and zero eval/new Function — the engine is pure TypeScript over the AST only, with 100 % function coverage via golden tests and 100-expression fuzzing.

Background

PR-079/080/081 P1; the Phase-6 exit criterion: "formula engine 100 % function coverage, zero eval." database-architecture §1.4: "The source is parsed at save time by the safe parser in packages/database-engine (lexer → Pratt parser → AST with the fixed function set … + prop()); an invalid formula is rejected with VALIDATION_ERROR (never stored). Evaluation runs the AST only, with per-evaluation step limits (10k steps, 1 MB output) so a hostile formula cannot DoS the query path. dependencies is extracted from the AST — the recompute worker uses it, not string matching." functional-requirements §5.5: tokens (identifiers, strings, numbers, booleans, dates, prop("Name"), function calls, arithmetic, comparison, logical, ternary); "No recursion depth > 16, no string eval, no access to host objects, evaluation budget 10 000 steps"; errors surface in the cell as a red badge; now() re-evaluates on each read (documented nondeterminism); dateAdd(date, amount, unit), dateBetween(a, b) → days, contains(hay, needle), replace(s, from, to), concat(a, b, …), length(x), if(cond, a, b), and/or/not(...), sum/average/min/max(list) over arrays (relation/rollup values). The Formula model already stores expression + ast Json + returnType + dependencies String[]. This task is engine-only: the property/API/UI are TASK-0085; the recompute pipeline is TASK-0086.

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0085

Title

Formula property (config, AST storage, editor UI with autocomplete + live preview)

Objective

Make formulas usable: POST /v1/databases/:id/formulas (save-time validation via the TASK-0084 engine — parse + type inference + dependencies/usesNow extraction → formulas row + FORMULA property), the formula editor UI (input with function + prop() autocomplete, live error highlighting from the tokenizer's pos, live preview over a sample record), and the read-only formula cell with the red error badge (runtime FormulaError per record, e.g. a TYPE error that only manifests for a subset of records' values).

Background

PR-082 P1. formulas model: expression (source, the user's text), ast Json (pre-parsed, schema-validated on read), returnType, dependencies String[] (property names, extracted by extractDependencies), propertyId? (the FORMULA property it feeds). The Phase-5 placeholder cell (FORMULA = "Phase 6" chip) is replaced. Save-time contract (database-architecture §1.4): "an invalid formula is rejected with VALIDATION_ERROR (never stored)" — i.e. PARSE/TYPE (unknown property)/uninference errors → 400; RUNTIME errors are not save-time (they depend on data) — a formula that parses + infers is stored, and per-record runtime failures surface as the cell's error state. Read path: the query pipeline's ComputedValueProvider (TASK-0083's interface) gains OnReadFormulaProvider — evaluateFormula(ast, {now, properties: record's values by name}) per record, with the same Redis cache as rollups except formulas with usesNow (header note 3 — they bypass the cache: now() re-evaluates each read, the documented nondeterminism); the materialized path (TASK-0086) skips usesNow formulas the same way. The editor (functional-requirements §5.5): "expression input with function autocomplete; live preview evaluates against a sample record (first record of the db, or an empty-record fallback); errors highlighted inline (pos → caret + red squiggle); the return type badge (number/text/date/checkbox) updates as the user types."

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0086

Title

Formula/rollup evaluation pipeline (worker recompute, depth limit 5, cycle guard, materialization)

Objective

Make computed properties stay correct as data changes: the event-driven recompute pipeline — record.updated / relation.linked|unlinked → find the computed properties whose dependencies (formulas) or relation-target values (rollups) were affected → enqueue recompute jobs (BullMQ) with a depth limit of 5 and a cycle guard (formula → rollup → formula chains terminate) → recompute the affected records' values → write results (Redis cache invalidation on the small-dataset path; record_properties materialized rows on the large-dataset path per header note 2) → emit record.updated {changedProperties: [computed…], source: 'computed'} so downstream consumers (search, Phase-11 automations) see the final values.

Background

Header note 2 (on-read default + materialized above ROLLUP_MATERIALIZE_THRESHOLD = 5,000 records with ≥ 1 computed property, env-tunable) is implemented here: MaterializedRollupProvider/MaterializedFormulaProvider (the TASK-0083 interface's second path) read record_properties rows for computed properties when the db is materialized. The dependency graph: formulas depend on properties (their dependencies names) — a record.updated with changedProperties intersecting dependencies invalidates the record's formula values; rollups depend on the linked records' values + the link set itself (relation.linked/unlinked); a formula can reference a rollup property? — decision, recorded (scope): prop() resolves to direct properties only (text/number/select/…/relation) — a formula referencing a rollup or another formula's property is a save-time TYPE error in Phase 6 ("computed properties cannot be referenced by formulas; use rollups to combine relation data"). This makes the dependency graph acyclic by construction (formulas → direct properties; rollups → relation → target db's direct values), and the depth-5/cycle guard is a defense-in-depth assertion (it can never fire on a valid graph — it fires on data corruption or a Phase-7+ extension, and must be tested with a hand-crafted cyclic fixture to prove the guard works, not merely that the graph is acyclic). Phase-7+ (multi-db formula references) lifts the restriction and the guard becomes load-bearing — recorded for that phase's task file.

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0087

Title

Database buttons (7 action types, execution endpoint, row + panel button UI)

Objective

Implement BUTTON properties: POST /v1/databases/:id/buttons (config: name, icon, color, actions[]), the 7 action types (set_property, create_page, update_page, archive_page, duplicate_page, send_webhook, trigger_automation), the execution endpoint POST /v1/databases/:id/records/:rid/buttons/:pid/run (sequential execution with a per-action result report, caller's permissions, audited), and the button UI (row + record-page panel, with the per-action config forms).

Background

PR-083 P1; the Phase-6 exit criterion: "button actions E2E-tested." functional-requirements §5.5: "BUTTON: config {name, icon, color, actions[]}; action types: set_property, create_page, update_page, archive_page, duplicate_page, send_webhook (async), trigger_automation (async); executes with the caller's permissions (the button cannot escalate); runs are audited (database.button.executed)." Header note 1 (webhook/automation = Phase-13/11 contracts, Phase-6 stubs the worker side, the button reports "queued"). The buttons table exists (config Json, propertyId?). database.button.executed is not in the backend-architecture §7.2 frozen event catalog — it's an audit event (the §9 mandatory-list "automation runs" analog — audit rows, not stream events; recorded resolution: the execution writes an AuditLog row per the AGENTS.md mandatory rule, type database.button.executed, in-transaction with the run's effects where they're transactional, best-effort after the async enqueues).

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0088

Title

Sub-items (isSubItem records, child list in the parent page, navigation up, rollup dependencies across sub-items)

Objective

Implement sub-items: records with isSubItem = true that render inside their parent record's page (a "Sub-items" child list with inline create), an up-navigation back to the parent, sub-item creation (a record in the same db, flagged), and the dependency tracking that makes rollups computed over sub-items stay correct (a sub-item's record.updated invalidates the parent's rollups too — the dependency edge is record-level, not just database-level).

Background

functional-requirements §5.2: "Sub-items: records that are children of another record (isSubItem flag + parentRecordId? — schema check: database_records has isSubItem but the parent link is via a relation: the standard Notion pattern is a relation from the db to itself (self-relation) + the sub-item flag. The database_records model in prisma/schema.prisma carries isSubItem (flag) — the parent is modeled as a self-relation (the db's relation to itself), and "sub-items of R" = R's links via the self-relation where the linked record has isSubItem. This task therefore: (a) makes the self-relation first-class in the relation UI (the relation picker allows targetDatabaseId = the same db — TASK-0081's self_relation 400 is lifted for the sub-item use case only: the create endpoint gains purpose: 'sub_items'? — a self relation with that purpose is the db's sub-item relation, unique per db (409 if one exists), its property is hidden from the normal column list (isVisible: false, the cell renders as the sub-item list, not a link chip), recorded resolution against TASK-0081's 400 (the 400 stands for self-relations without the purpose); (b) the record-page sub-item list (the children of the record via the self-relation, filtered to isSubItem records); (c) the inline create (a new record, isSubItem: true, linked to the parent, the TITLE prefilled from the row input); (d) navigation up (a "Sub-item of: <parent title>" breadcrumb above the sub-item's record-page panel, click → the parent); (e) dependency tracking (TASK-0086's planner gains the sub-item edge: a sub-item's change invalidates the parent's rollups that roll up the self-relation — the rollup's link set includes the sub-item, so the rollup is already correct on recompute; the edge needed is: a sub-item's change must recompute the parent's formula values? no — formulas reference the parent's own direct properties only; the edge is: a sub-item's change recomputes the parent's rollups (already covered by the link-based invalidation — the sub-item is a linked record) AND recompute the sub-item's own rollups (its own relation data) — the genuinely new edge is the transitive one flagged in the roadmap line "dependency tracking for rollups across sub-items": a grandparent's rollup over a relation that targets the sub-item's db- self-links? — Phase-6 scope (recorded, bounded): invalidation is one hop (the TASK-0086 depth model — a sub-item change invalidates the direct parent's rollups; a chain of sub-items (sub-of-sub) invalidates each level in the next pass — the re-queue-once mechanism already in the planner handles it; the E2E asserts a 2-level sub-item chain converges in ≤ 2 passes).

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0089

Title

E2E relations suite (tests/e2e/relations.spec.ts) — Phase-6 behavioral exit

Objective

Author the Playwright E2E suite for Phase 6 covering the behavioral exit criteria: create two dbs + a relation both directions, link/unlink, rollup COUNT updates on a linked change < 5 s, formula recompute on dependency change, a button that sets a property + creates a page, sub-items rendering in the parent page — plus the permission matrix and the a11y passes. The engine coverage + zero-eval gate is TASK-0090.

Background

ROADMAP Phase-6 exit: "formula engine 100 % function coverage, zero eval (the TASK-0090 gate); rollups recompute on relation change (event-driven) — the < 5 s E2E; button actions E2E-tested." The behavioral scenarios below are the user-facing half; TASK-0090 is the engine-coverage half. The Phase-5 suite patterns (tests/e2e/databases.spec.ts, fixtures tests/e2e/fixtures/databases.ts) are reused (authed users, network spies, the record-seeding helper); the fixtures gain two standard databases ("Projects" with STATUS/NUMBER/DATE + a "Tasks" db with STATUS/ NUMBER + a self-relation) and the relation/rollup/formula/button builders (API-level, fast).

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done


TASK-0090

Title

Formula engine coverage + phase-exit verification (zero-eval CI gate)

Objective

Close Phase 6: prove the engine exit criteria (100 % function coverage with the structural gate, the fuzz suite, the type matrix — all green in CI), install the repo-wide zero-eval grep as a hard CI stage, run the full contract 3×, record the checklist evidence, and write the Phase-7 handoff note (the computed-value freshness follow-up + the multi-db formula-reference flag).

Background

ROADMAP Phase-6 exit: "formula engine 100 % function coverage, zero eval; rollups recompute on relation change (event-driven); button actions E2E-tested." The first is this task's gate; the second is TASK-0086 (integration) + TASK-0089 scenario 3 (E2E); the third is TASK-0089 scenarios 5–6. AGENTS.md rule 18 ("Never use arbitrary JavaScript execution for formulas") and rule 30 (no task complete until acceptance criteria are verified) make the zero-eval proof a CI stage, not a code-review promise: tests/ci/no-eval.sh greps the whole repo (source + packages, excluding node_modules, fixtures that legitimately contain the string as test data — the exclusion list is in the script, each exclusion justified in a comment) for eval(, new Function, Function(, and fails the build on a hit. The engine's own scope gate (TASK-0084's grep on src/formula/**) is subsumed by the repo-wide gate (kept as a faster pre-stage). Phase-5's close-out pattern (TASK-0080) is the template.

Requirements

Acceptance Criteria

Backend Changes

Frontend Changes

Database Changes

API Changes

Tests

Security

Documentation

Dependencies

Definition of Done