.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
blocks.mddocs/api/blocks.md← api22,049 B← Back to the app

Blocks API

Blocks are the atomic content units inside a page. A page's content is a block tree: blocks have an optional parentId (parent block or null for page-top level) and a fractional position that defines order among siblings. There are no array indexes anywhere.

Shared conventions (auth, error model, pagination, rate limits): authentication.md.

Permission note: reading blocks requires VIEW on the page; creating, updating, deleting, or moving blocks requires EDIT. Commenting on blocks requires at least COMMENT (see comments.md).


1. Block JSON Schema

{
  "id": "blk_01J9ZKQ6A9B2C4D6E8F0A2B4C6",
  "pageId": "pg_01J9ZKQ4F8H5I7J9L1M3N5P7Q9",
  "workspaceId": "wks_01J9ZKP5C9H7J9K1L3M5N7P9Q1",
  "parentId": null,
  "type": "paragraph",
  "position": "a1",
  "properties": {},
  "content": { "text": "Reach GA for the new database engine by 2025-04-30." },
  "isSynced": false,
  "syncedSourceId": null,
  "createdBy": "usr_01J9ZKQX4V2M8N3P5R7T9W1Y3A",
  "updatedBy": "usr_01J9ZKQ2V4W6X8Y0Z2A4B6C8D0",
  "version": 3,
  "createdAt": "2025-01-02T09:16:00.000Z",
  "updatedAt": "2025-01-02T14:40:12.000Z"
}
Field Type Notes
id string blk_…, stable for the lifetime of the block.
pageId string Owning page. Blocks cannot cross pages except via synced_block.
parentId string | null Parent block id; null = direct child of the page.
type BlockType One of the 30 types in §2.
position string Fractional order among siblings (see §5).
properties object Type-agnostic decoration: colors, alignment, width, language, checked state, callout emoji, etc.
content object Type-specific payload (table below).
isSynced boolean true for synced_block instances.
syncedSourceId string | null For synced_block: the source block it mirrors.
version int Optimistic concurrency counter (bumped per mutation).

Text content is stored as rich text:

{
  "text": "Hello **world** and a @mention",
  "marks": [
    { "type": "bold", "from": 6, "to": 12 },
    { "type": "mention", "from": 20, "to": 31, "attrs": { "mentionId": "usr_01J9ZKQ2V4W6X8Y0Z2A4B6C8D0", "mentionType": "user" } }
  ]
}

Marks: bold, italic, underline, strikethrough, code, highlight, link (attrs.url), mention (attrs.mentionType: user|team|page|database), equation (inline). Offsets are UTF-16 code units into text.


2. Block Types — Content Shapes

All 30 BlockType values (matching prisma/schema.prisma). content is the type-specific payload; properties holds the shared decorations listed per type.

# type Group content shape (example) properties (type-specific)
1 paragraph Text { "text": "Hello world", "marks": [] } align, color
2 heading_1 Text { "text": "Objectives", "marks": [] } align, showDivider
3 heading_2 Text { "text": "Goals", "marks": [] } align
4 heading_3 Text { "text": "Scope", "marks": [] } align
5 quote Text { "text": "The first principle is…", "marks": [], "citation": "Galileo" } align
6 callout Text { "text": "Ship it before the deadline.", "marks": [] } emoji: "⚠️", backgroundColor, textColor
7 bulleted_list Lists { "text": "Board view", "marks": [] } —
8 numbered_list Lists { "text": "Set up CI", "marks": [], "start": 1 } —
9 todo Lists { "text": "Ship board view", "marks": [] } checked: false
10 toggle Lists { "text": "Design decisions", "marks": [] } collapsed: true
11 image Media { "fileId": "fil_01J9ZKP…", "caption": "Architecture sketch" } align, widthPct (10–100), display: "fullPage" | "pageWidth" | "auto"
12 video Media { "fileId": "fil_01J9ZKP…", "url": null, "caption": null } align, widthPct
13 audio Media { "fileId": "fil_01J9ZKP…", "url": null } —
14 file Media { "fileId": "fil_01J9ZKP…", "name": "spec.pdf", "size": 482113, "mimeType": "application/pdf" } caption
15 bookmark Media { "url": "https://www.rfc-editor.org/rfc/rfc9110", "title": null, "description": null } —
16 embed Media { "url": "https://www.youtube.com/embed/dQw4w9WgXcQ" } heightPx (120–800)
17 code Code { "code": "curl -s /api/v1/pages", "language": "bash" } showLineNumbers: true, wrap: false
18 equation Code { "latex": "E = mc^2" } align
19 column Layout { "text": null } — a column is a container: its child blocks (parentId = this column's id) render side-by-side. widthPct (20–100)
20 column_list Layout { "text": null } — container that lays out its column children horizontally. background, padding
21 divider Layout {} —
22 spacer Layout { "heightPx": 32 } (8–200) —
23 database Advanced { "databaseId": "db_01J9ZKQ7E4F6A8B0C2D4E6F8A0" } — embeds a database (created at the same time, see databases.md POST /databases with pageId). viewId (which view to show)
24 linked_database Advanced { "databaseId": "db_01J9ZKQ7E4F6A8B0C2D4E6F8A0", "viewId": "view_01J9ZKQ8F5A7B9C1D3E5F7A9B1" } —
25 table Advanced { "rows": [ [ { "text": "ID", "marks": [] }, { "text": "Owner", "marks": [] } ], [ { "text": "1", "marks": [] }, { "text": "Ada", "marks": [] } ] ], "headerRow": true } columnWidths: [160, 160], align
26 chart Advanced { "chartId": "cht_01J9ZKQ9G6B8C0D2E4F6A8B0C2", "databaseId": "db_01J9ZKQ7E4F6A8B0C2D4E6F8A0" } widthPct
27 form Advanced { "formId": "frm_01J9ZKQA7C9D1E3F5A7B9C1D3E5", "databaseId": "db_01J9ZKQ7E4F6A8B0C2D4E6F8A0" } —
28 synced_block Advanced { "text": "…(mirrors source)", "marks": [] } — content is read-only and always equal to its source block; only the source can be edited. sourceSynced: true
29 child_page Advanced { "pageId": "pg_01J9ZKQ8G2H4I6J8L0M2N4P6Q8" } — a page link rendered as a block (row of the page tree). —
30 child_database Advanced { "databaseId": "db_01J9ZKQ7E4F6A8B0C2D4E6F8A0", "title": "Tasks (linked)" } — embeds another database's records in this page's block flow. viewId

Container rules (enforced server-side):


3. Read Blocks

GET /pages/:pageId/blocks

Query params:

Param Type Default Notes
parentBlockId string "" (empty = page top level) Only this parent's direct children.
flat boolean false false → nested tree (each node has children: []); true → flat list, ordered by tree position (parent before children, depth-first).
includeDeleted boolean false Admin/Owner only.
cursor, limit – – Applies to the top level only (default 100, max 500). Deeper levels always fully expanded up to limit.

200 OK (tree mode)

{
  "data": [
    {
      "id": "blk_01J9ZKQ6A9B2C4D6E8F0A2B4C6",
      "type": "heading_1",
      "parentId": null,
      "position": "a0",
      "properties": {},
      "content": { "text": "Objectives", "marks": [] },
      "isSynced": false,
      "version": 1,
      "createdAt": "2025-01-02T09:16:00.000Z",
      "updatedAt": "2025-01-02T09:16:00.000Z",
      "children": []
    },
    {
      "id": "blk_01J9ZKQ6E4F6A8B0C2D4E6F8A0",
      "type": "toggle",
      "parentId": null,
      "position": "a2",
      "properties": { "collapsed": true },
      "content": { "text": "Design decisions", "marks": [] },
      "isSynced": false,
      "version": 2,
      "createdAt": "2025-01-02T09:17:00.000Z",
      "updatedAt": "2025-01-02T10:02:00.000Z",
      "children": [
        {
          "id": "blk_01J9ZKQ6F5A7B9C1D3E5F7A9B1",
          "type": "paragraph",
          "parentId": "blk_01J9ZKQ6E4F6A8B0C2D4E6F8A0",
          "position": "a0",
          "properties": {},
          "content": { "text": "We chose CRDTs for offline sync.", "marks": [] },
          "isSynced": false,
          "version": 1,
          "createdAt": "2025-01-02T09:17:30.000Z",
          "updatedAt": "2025-01-02T09:17:30.000Z",
          "children": []
        }
      ]
    }
  ],
  "nextCursor": null
}

Errors: 401 UNAUTHORIZED, 403 FORBIDDEN, 404 NOT_FOUND, 400 VALIDATION_ERROR (bad parentBlockId not in this page).


GET /blocks/:blockId

Fetch one block with its full subtree (children nested).

200 OK — one block object (shape as above, with children).

Errors: 401 UNAUTHORIZED, 403 FORBIDDEN, 404 NOT_FOUND.


4. Write Blocks — Single & Batch Operations

All block writes go through one endpoint: POST /blocks. It accepts either a single operation or a batch of operations, and batches are transactional (all-or-nothing): any validation or permission failure rolls the entire batch back — no partial application, no error codes interleaved in a success response.

POST /blocks

Request — a batch of 1–200 operations (≤ 1 MB body), applied in a single Postgres transaction in list order (FIFO — an op may reference rows created by an earlier op in the same batch):

{
  "pageId": "pg_01J9ZKQ4F8H5I7J9L1M3N5P7Q9",
  "baseVersion": 3,
  "ops": [
    {
      "op": "upsert",
      "block": {
        "id": "blk_aaaa1111aaaa1111aaaa1111aaaa1111",
        "type": "toggle",
        "content": "<p>Toggle <b>title</b></p>",
        "properties": { "collapsed": false },
        "parentId": null
      }
    },
    {
      "op": "upsert",
      "block": {
        "id": "blk_bbbb2222bbbb2222bbbb2222bbbb2222",
        "type": "bulleted_list",
        "content": "<p>Child</p>",
        "properties": {},
        "parentId": "blk_aaaa1111aaaa1111aaaa1111aaaa1111",
        "afterBlockId": "blk_aaaa1111aaaa1111aaaa1111aaaa1111"
      }
    },
    {
      "op": "update",
      "blockId": "blk_01J9ZKQ6B1C3D5E7F9A1B3C5D7",
      "patch": { "content": "<p>Reach GA by 2025-05-15.</p>" }
    },
    {
      "op": "move",
      "blockId": "blk_01J9ZKQ6C2D4E6F8A0B2C4D6E8",
      "move": { "parentId": "blk_01J9ZKQ6E4F6A8B0C2D4E6F8A0", "afterBlockId": null }
    },
    {
      "op": "delete",
      "blockId": "blk_01J9ZKQ6Z9Y8X7W6V5"
    }
  ]
}

Operation fields:

Op Required fields Optional fields Semantics
upsert block.type block.id (client id), block.content (string or record, default {}), block.properties (default {}), block.parentId (null = top level), block.afterBlockId / block.beforeBlockId (id anchors), block.position (explicit fractional; mutually exclusive with the id anchors) Create the block (no update-in-place — "upsert" = insert with an optional client id). The server resolves the fractional position from the anchors; a missing parent → 404.
update blockId, patch patch.type ("turn into" — content is re-validated and type-specific properties are cleared), patch.content (string or record), patch.properties (REPLACES the bag — send the full object), patch.parentId, patch.position Merge-patch of the named fields only.
delete blockId — Deletes the block and its subtree (soft delete; recoverable via page versions).
move blockId move.parentId, move.afterBlockId / move.beforeBlockId (mutually exclusive with move.position), move.position Re-parents and/or reorders via id anchors. Moving a block into its own descendant → 422 (cycle_detected).

Constraints:

201 Created ({ applied, blockIds, version } — blockIds lists the created/upserted ids in op order; version is the new pages.version; clients that sent a stale baseVersion get 409 with the fresh version):

{ "applied": 5, "blockIds": ["blk_aaaa1111aaaa1111aaaa1111aaaa1111", "blk_bbbb2222bbbb2222bbbb2222bbbb2222"], "version": 4 }

Batch transaction behavior:

Error codes: 400 VALIDATION_ERROR, 401 UNAUTHORIZED, 403 FORBIDDEN, 404 NOT_FOUND (block/page not visible), 409 CONFLICT (stale version), 413 PAYLOAD_TOO_LARGE (batch > 1 MB or > 200 ops), 422 UNPROCESSABLE_ENTITY (invalid nesting, cycle), 429 RATE_LIMITED.


Convenience: top-level aliases

The following routes are thin aliases over the batch endpoint (same semantics, same transaction rules):

Alias Equivalent operation
POST /pages/:pageId/blocks upsert (body: the block object directly — type, content (string or record), properties?, id?, parentId?, afterBlockId?/beforeBlockId? or position?)
PATCH /blocks/:blockId update (body: the patch object directly — type?, content?, properties? (full replacement), archived?, baseVersion?)
DELETE /blocks/:blockId delete (recursive by definition — the subtree goes with it)
POST /blocks/:blockId/move move (body: { parentId?, afterBlockId?/beforeBlockId?, position? })
POST /blocks/:blockId/duplicate copies the block's WHOLE subtree with fresh ids (body: { parentId? (null = same parent), afterBlockId? }; the copy is anchored after afterBlockId ?? the source block in the same or the given parent). Response: { duplicated: true, newRootId, blockIds }

5. Position Semantics

Same fractional scheme as pages §9, applied per sibling set (children of a page, children of a block):

Worked example — inserting between two blocks:

Current:  "Alpha: internal dogfooding."      a0
          "Beta: 50 external teams."         a1

Request:  insert with after: <id of a0>
Computed: new position a0M (midpoint of a0, a1)

Result:   "Alpha: internal dogfooding."      a0
          "Second milestone: beta with 50 external teams."  a0M
          "Beta: 50 external teams."         a1

6. Synced Blocks

A synced block is an instance that mirrors one source block. The source may live on any page in the workspace.


7. Events Emitted

All block mutations are batched into one event per HTTP request (so a 5-op batch emits one event whose payload lists 5 changes) — this keeps the search indexer and webhook dispatcher from being spammed per block.

Operation(s) Domain event(s)
insert (one or more) blocks.changed with changes: [{op: "insert", blockId, pageId, type}]
update (one or more) blocks.changed with op: "update" per changed block
delete (one or more) blocks.changed with op: "delete" per deleted block
move (one or more) blocks.changed with op: "move" (old/new parentId + position)
Any batch Additionally page.updated (page's updatedAt and block count bumped), which drives search re-indexing of the page.

blocks.changed also carries actor (user id or api key id), workspaceId, and pageId. Webhook subscribers can filter by workspaceId (webhooks.md).


8. curl Examples

# Read a page's block tree
curl -s "https://factory.example.com/api/v1/pages/pg_01J9ZKQ4F8H5I7J9L1M3N5P7Q9/blocks" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# Insert a paragraph after a specific block
curl -s -X POST https://factory.example.com/api/v1/blocks \
  -H "Authorization: Bearer $ACCESS_TOKEN" -H 'Content-Type: application/json' \
  -d '{
    "op": "insert",
    "pageId": "pg_01J9ZKQ4F8H5I7J9L1M3N5P7Q9",
    "after": "blk_01J9ZKQ6B1C3D5E7F9A1B3C5D7",
    "block": { "type": "paragraph", "content": { "text": "Second milestone: beta with 50 external teams.", "marks": [] } }
  }'

# Batch: insert + update + move + delete, all-or-nothing
curl -s -X POST https://factory.example.com/api/v1/blocks \
  -H "Authorization: Bearer $ACCESS_TOKEN" -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 7c1e2f3a-4b5c-4d6e-8f7a-9b0c1d2e3f4a' \
  -d '{
    "operations": [
      { "op": "insert", "pageId": "pg_01J9ZKQ4F8H5I7J9L1M3N5P7Q9", "after": "blk_01J9ZKQ6A9B2C4D6E8F0A2B4C6",
        "block": { "type": "heading_2", "content": { "text": "Milestones", "marks": [] } } },
      { "op": "update", "pageId": "pg_01J9ZKQ4F8H5I7J9L1M3N5P7Q9", "blockId": "blk_01J9ZKQ6B1C3D5E7F9A1B3C5D7", "version": 3,
        "block": { "content": { "text": "Reach GA for the new database engine by 2025-05-15.", "marks": [] } } },
      { "op": "move", "pageId": "pg_01J9ZKQ4F8H5I7J9L1M3N5P7Q9", "blockId": "blk_01J9ZKQ6C2D4E6F8A0B2C4D6E8",
        "target": { "parentId": "blk_01J9ZKQ6E4F6A8B0C2D4E6F8A0" } },
      { "op": "delete", "pageId": "pg_01J9ZKQ4F8H5I7J9L1M3N5P7Q9", "blockId": "blk_01J9ZKQ6Z9Y8X7W6V5" }
    ]
  }'

# Turn a block into a todo (update with type change)
curl -s -X PATCH https://factory.example.com/api/v1/blocks/blk_01J9ZKQ6B1C3D5E7F9A1B3C5D7 \
  -H "Authorization: Bearer $ACCESS_TOKEN" -H 'Content-Type: application/json' \
  -d '{ "block": { "type": "todo", "properties": { "checked": false } } }'

# Create a synced block instance
curl -s -X POST https://factory.example.com/api/v1/blocks \
  -H "Authorization: Bearer $ACCESS_TOKEN" -H 'Content-Type: application/json' \
  -d '{
    "op": "insert",
    "pageId": "pg_01J9ZKQ8G2H4I6J8L0M2N4P6Q8",
    "block": { "type": "synced_block", "content": { "sourceBlockId": "blk_01J9ZKQ6E4F6A8B0C2D4E6F8A0" } }
  }'