.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
functional-requirements.mddocs/product/functional-requirements.md← product50,641 B← Back to the app

Functional Requirements — AI Software Factory

Exhaustive per-domain functional requirements. Every requirement carries the canonical ID from product-requirements.md (this file does not mint new IDs — it expands them). Section references PS§n cite PRODUCT-SPEC.md; schema references cite database-architecture.md; visual/interaction details defer to ux-requirements.md.

Notation — "MUST/SHOULD/MAY" per RFC 2119. "Actor" defaults to an authenticated member with the minimum level stated. All permissions are re-validated server-side (PR-115).


1. Authentication (PS§2.1, PS§24)

ID Requirement
FR-PR-001 Registration POSTs {email, password, name}. Email normalized to lowercase. Password MUST be ≥ 10 chars with ≥ 2 of {lower, upper, digit, symbol}; server re-validates with the shared Zod schema (packages/shared). On success: user created with status=ACTIVE, emailVerification=PENDING, personal workspace created (PR-013), verification email queued. Duplicate email → 409 EMAIL_TAKEN (no account-existence oracle beyond that).
FR-PR-002 Verification email contains a single-use token (stored hashed, 24 h TTL). Clicking verifies (emailVerification=VERIFIED, emailVerifiedAt set). Resending is rate-limited (≤ 3/hour/email). Unverified users may sign in but the client pins a "verify your email" banner on every page and blocks invites/exports.
FR-PR-003 Login POSTs {email, password} → 200 {accessToken (JWT, 15 min), refreshToken (opaque, 30 d)}. Access token claims: sub (user id), ws (workspace id, when bound), role, jti, iat, exp. Refresh token stored as SHA-256 hash in refresh_tokens; the plaintext token travels in an HttpOnly; Secure; SameSite=Strict cookie (factory_rt) and is never returned in the body.
FR-PR-004 Refresh rotation: POST /auth/refresh with a valid token hashes it, looks it up, marks revokedAt + sets replacedBy, and issues a new token (same family id). If the presented token was already rotated (replay), the whole family is revoked and the user is signed out everywhere, with audit event auth.refresh.replayed.
FR-PR-005 POST /auth/logout revokes the presented refresh token + session. GET /auth/sessions lists active sessions (UA, IP, created, last seen); DELETE /auth/sessions/:id revokes one; "sign out everywhere" revokes all.
FR-PR-006 Password reset: POST /auth/password/forgot {email} always returns 200 (no oracle) but emails a 1 h single-use token when the account exists. POST /auth/password/reset {token, password} sets the new hash, marks token USED, revokes all refresh tokens + sessions, emits user.password.reset.
FR-PR-007 Hashing uses bcrypt with cost from BCRYPT_ROUNDS (default 12). Password comparison is the library's constant-time compare. Passwords are never logged, never in audit metadata, never in URLs.
FR-PR-008 Profile: GET/PATCH /users/me for name, displayName, avatarUrl, locale, timezone, theme. Avatar upload goes through the file pipeline (PR-105) with a 5 MB cap and image-only mime allow-list.
FR-PR-009 Auth endpoints sit behind the strictest rate-limit tier: 5/min per IP for login, 3/min per IP for forgot-password, 3/day per IP for registration (see security-architecture §10 for the full tier table).
FR-PR-010 Audit events (mandatory): user.login.success, user.login.failed (with reason: bad_password, suspended, not_verified), user.logout, user.registered, user.password.reset, auth.refresh.replayed, session.revoked. Each carries actor, IP, UA, timestamp (schema: audit_logs).
FR-PR-011 OIDC: GET /sso/oidc/:orgSlug/start → authorization-code + PKCE flow → callback validates id_token signature/nonce → maps to user via sso_identities. SAML: ACS endpoint validates assertion signature, NameID → sso_identities.externalId. When sso_provider.enforce = true, password login for the org returns 403 SSO_REQUIRED.
FR-PR-012 SSO linking rules: email match → link identities to existing user; no match → create user with status=INVITED and deliver invitation email. De-provisioning (SCIM deactivate) sets User.status=SUSPENDED and revokes all sessions/refresh tokens.

2. Workspaces & tenancy (PS§1)

ID Requirement
FR-PR-013 Registration transaction creates: users row, workspaces row (isPersonal=true, slug personal-<userSlug>, ownerId), and workspace_members row with role=OWNER. Failure of any step rolls back the whole registration.
FR-PR-014 POST /workspaces {name, slug, iconUrl?}. Slug: lowercase kebab, 3–40 chars, unique platform-wide; on conflict the API suggests alternatives. Owner becomes OWNER member.
FR-PR-015 Delete (owner only) requires typed confirmation ("DELETE <name>"); workspace enters soft-delete (deletedAt); after 30 days a purge job removes workspaces, pages, blocks, files (object keys deleted), search docs, and orphans audit rows set workspaceId=NULL (kept for forensics).
FR-PR-016 Role model per product-requirements §4. Role is stored per membership (workspace_members.role, team_members.role inherits workspace role as ceiling).
FR-PR-017 Role change rules: only OWNER/ADMIN may change roles; an ADMIN may not grant/strip OWNER; the last active OWNER cannot be demoted or removed (API error 409 LAST_OWNER). Every change → audit workspace.role.changed.
FR-PR-018 Invitation lifecycle: create (POST /workspaces/:id/invitations {email, role, expiresAt}) → email with signed token link (token hashed in invitations) → accept (must be a registered user or register first) creates membership → decline / revoke / expire (job marks EXPIRED after expiresAt). Unique constraint (workspaceId, email, role) on PENDING invitations.
FR-PR-019 Teams: POST /workspaces/:id/teams {name, slug, color, iconUrl}; members added by workspace member+; isPrivate teams visible only to their members. Team position is fractional (a0, a1, …) and reorderable by drag.
FR-PR-020 Sidebar data: one query returns Home (workspace root page), Inbox (unread notification count), Search, Favorites (user favorites), Teamspaces (teams ordered by position), Private (user's private root), Shared (pages shared with user), Trash. Page tree is virtualized and lazy-loaded per folder.
FR-PR-021 Settings routes: /settings/profile, /settings/members, /settings/teams, /settings/security (sessions, API keys, 2FA placeholder), /settings/billing (plan display, limits), /settings/integrations (placeholder list). Each section gated by role.
FR-PR-022 Organization: POST /organizations {name, slug}; workspaces may be attached (organizationId); org members get org-level role. Org policy JSON keys: sso.enforce, sharing.publicAllowed, password.minLength, retention.*.
FR-PR-023 SCIM endpoints (/scim/v2/Users, /scim/v2/Groups) behind a SCIM bearer token: create (→ user INVITED or link), update (name, email, active flag), deactivate (suspend), group sync → team membership.
FR-PR-024 Usage limits enforced in repositories: membership count before invite/accept; storage bytes before file READY; AI tokens before gateway call (budget reset monthly); API rps from workspace.usageLimits.apiRps (default from plan). Over-limit → 402 LIMIT_EXCEEDED with the limit name.

3. Pages (PS§3)

ID Requirement
FR-PR-025 Page CRUD under /workspaces/:ws/pages. Create accepts {parentId?, title, icon?, coverUrl?, description?, teamId?, isPrivate?}. parentId MUST be in the same workspace (server-validated) — cross-tenant parent links are impossible.
FR-PR-026 Sibling ordering: new page at index i between siblings with positions p_a and p_b gets position = mid(p_a, p_b) (fractional algorithm, database-architecture §7). Root-level pages of a workspace: parentId = null.
FR-PR-027 Page surface (see PS§3): icon (emoji or file id), cover (file id/URL), title (required, ≤ 200 chars), description (≤ 500), blocks, comments, shares/permissions, versions, child pages.
FR-PR-028 Trash: delete sets trashedAt (blocks remain, deletedAt unset). Restore clears trashedAt and, if the parent was deleted, reparents to the parent's former parent. Purge (owner/admin, or any user for their own after policy) hard-deletes page + blocks + comments + share rows; file object keys deleted asynchronously.
FR-PR-029 Archive: archivedAt set → hidden from sidebar tree and search (until unarchived); trash and archive are mutually exclusive states.
FR-PR-030 Favorites: POST /pages/:id/favorite (position = fractional append); sidebar "Favorites" sorts by position; unfavorite removes the row. Guests may favorite pages they can view.
FR-PR-031 Versions: an explicit "save version" (page menu) plus automatic snapshots when title or structure (block tree shape) changes, max 100 versions kept per page (oldest dropped). GET /pages/:id/versions?limit=, GET .../:version, POST .../restore {versionId} — restore writes a new version (non-destructive).
FR-PR-032 Private pages: isPrivate=true means only the creator and explicit grants may view (workspace members see nothing in search/sidebar). Toggling private on a page with children cascades the flag to children unless they have their own grants.
FR-PR-033 Tree performance: sidebar fetches depth-limited subtrees (?depth=2 default) with nextCursor; full tree never fetched client-side. Target: 100k-block workspace tree interactive in < 2 s (NFR-NF1).

4. Blocks & editor (PS§4, PS§5)

4.1 Block model (PR-034)

Block (schema blocks): id (cuid, stable), pageId, workspaceId, parentId (self-referencing), type (BlockType enum), position (fractional), content JSONB (type-specific), properties JSONB (colors, alignment, width, checkbox state), isSynced + syncedSourceId, createdBy/updatedBy, version (optimistic concurrency), deletedAt.

4.2 All 28 block types

# Type content shape properties shape Behavior
1 paragraph {text: RichText} {align?, color?} Plain text; empty paragraph shows placeholder "Type '/' for commands…"
2 heading_1 {text: RichText} {align?, color?, showAnchor?} 1.875× title scale; anchor link on hover when showAnchor
3 heading_2 same same 1.5× scale
4 heading_3 same same 1.25× scale
5 quote {text: RichText} {borderColor?} Left-border accent, muted text
6 callout {text: RichText} {icon: emoji, background: token color} Bordered card, icon left, tinted background
7 bulleted_list {text: RichText} {level} Indent by level; Enter continues list
8 numbered_list {text: RichText} {level} Numbering computed from consecutive same-level siblings; unnumbering on gap
9 todo {text: RichText} {checked: bool, level} Checkbox toggles strikethrough; "x" prefix on paste converts
10 toggle {text: RichText} {open: bool, level} Collapsible; children are blocks with parentId = toggle.id; chevron + ⋮⋮ handle; Enter inside opens
11 image {fileId, alt?, caption?} {width?: %, align?} Renders file thumbnail; width drag handle; caption below; loading skeleton while file.status=UPLOADING
12 video {fileId? | url} {align?, autoplay?} Native player for files; embed for URLs; poster = thumbnail
13 audio {fileId} {loop?} Custom minimal player (play/seek/time)
14 file {fileId} — Card: icon by mime, name, size, download (signed URL), preview link
15 bookmark {url, title?, description?} — Card with favicon, domain, title, description; fetches OpenGraph on insert (cached in file metadata)
16 embed {url, provider} {height?} iframe sandbox (sandbox="allow-scripts allow-same-origin", no allow-top-navigation); provider presets (Loom, Figma, Airtable, generic)
17 code {code: string, language} {language, showLineNumbers: true} 40+ languages, syntax highlight, copy button, overflow-x scroll; no line wrapping by default
18 equation {latex: string} — Rendered via KaTeX; block mode; invalid LaTeX shows error styling + raw text
19 column_list — {widths: number[] (sum=1)} Container; children are column blocks; resizable via drag handle between columns; stacks below 768 px
20 column — {width?: inherited} Layout child of column_list; holds arbitrary blocks
21 divider — {color?} Horizontal rule, 16 px vertical margin
22 spacer — `{height: 8 16
23 database {databaseId} {viewId? (initial view)} Inline database render (all 9 view types); properties/views owned by the databases row
24 linked_database {databaseId, viewId?, filter?} — Read/query projection of another database (not a copy); edits flow through the same engine
25 table {rows: [[Cell]], cols: int} {colWidths?} Static table; cell editing; add/remove rows/cols; not queryable (use database)
26 chart {chartId} — Renders charts row (see §12)
27 form {formId} — Renders published form inline; submissions create records in the form's database
28 synced_block {masterId | null} — Master renders own content; copies render master's content live; "synced" badge; breaking sync makes the copy independent
— child_page {pageId} — Sidebar-row-style block in the page body; click opens the child page (used by templates & TOCs)
— child_database {databaseId} — Row that opens a linked database's record list

child_page / child_database are listed in the BlockType enum and the slash menu even though they are not in the PS§4 table grouping; the enum is authoritative (30 values; 28 "authoring" types + 2 structural rows).

4.3 Editor interactions

Mouse (PR-042):

Interaction Behavior
Hover block Left gutter shows ⋮⋮ drag handle + "+" add-below button (appears at ≥ 150 ms hover, no animation jank)
Click handle, drag Drag preview follows cursor; drop indicator: line (sibling) or box (into toggle/column/child); valid targets highlight
Click block Places caret; selects text on second click, triple-click selects block content
Shift+click block Extends multi-selection (contiguous)
Right-click block / selected blocks Block context menu (§4.5)
Drag image edge Resizes width (snaps at 25/50/66/75/100 %)
Drag column divider Resizes column widths (live, min 10 %)
Drag OS file onto editor Upload → insert image/file/video/audio/code (.txt/.md) at drop point

Keyboard (PR-041) — full master table in ux-requirements §10; the load-bearing rules:

Key Effect
Enter Split block: new empty block of same list type below; empty list item on Enter exits list; in toggle: opens if empty, else new child
Shift+Enter Soft line break (line break node) inside the block
Backspace at block start Merge with previous block (inherit its type); if previous is a toggle heading, un-indent instead
Delete at block end Merge next block upward
Tab / Shift+Tab Indent (make child of previous list/toggle) / un-indent; in table cells move focus
↑ / ↓ Move caret across blocks; at edge, scroll; inside columns moves between columns at column edges
Cmd/Ctrl+A 1st: select block content; 2nd: select whole block; 3rd: all blocks
Cmd/Ctrl+C/X/V Internal: copy block JSON (content + properties + subtree); external: copy rendered markdown/HTML; paste: detect markdown/HTML/RTF → convert to blocks (plain text → split on newlines)
Cmd/Ctrl+Z / Shift+Z / Cmd+Y Undo / redo (block-operation history, in-memory 100 steps; versions are the durable history)
Cmd/Ctrl+B/I/U Bold / italic / underline on selection (also: Ctrl+Shift+S strikethrough, Ctrl+E code)
Cmd/Ctrl+K Command palette (global)
Cmd/Ctrl+Shift+L Link on selection
Cmd/Ctrl+Shift+1/2/3 Convert to H1/H2/H3; Cmd+Shift+0 → paragraph

Slash commands (PR-045…PR-047): typing / at a block start (or / mid-text with the word selected) opens the menu; fuzzy-matches command names + synonyms ("h1", "heading one", "bulleted"); grouped Text / Lists / Media / Code / Data / Layout / Embeds; ↑↓ + Enter selects; Esc closes; results with database targets open the property-picker dialog before insertion.

Context menus (PR-048…PR-049):

Block menu (right-click / ⋮⋮ menu): Turn into ▸ (grouped list of convertible types) · Duplicate · Copy · Copy link (deep #blockId) · Move to ▸ (page picker) · Delete · ── · Comment · Ask AI ▸ (summarize/rewrite/improve/translate — present only when AI enabled) · ── · Color ▸ (text color palette) · Background ▸ (background palette) · ── · Convert to ▸ (heading 1–3 / quote / callout / todo — quick path) · ── · More ▸ (save as template, permissions (if page root), duplicate as synced block).

Page menu (sidebar row / page top-bar ⋯): Open · Open in new tab · Duplicate · Rename · Move ▸ (page picker) · Copy link · Favorite (toggle) · Archive · Delete (→ trash) · Export ▸ (Markdown/HTML/PDF) · Share (share dialog) · Permissions (grant editor).

Drag & drop (PR-050…PR-056): dnd-kit sensors (pointer + keyboard); drop targets: sibling position, toggle children, column, other page (sidebar row, child_page block, or page mentioned in "Move to"); drop of a block onto a database creates a record from the block (markdown → title + first property); multi-block drag preserves relative order and nesting; auto-scroll when dragging near viewport edges; all drops write fractional positions in one API batch (single transaction) — partial failure rolls back the whole move.

5. Databases (PS§9)

5.1 Property types (24) — PR-058

# Type config JSON Value JSON (record_properties.value) Editor widget
1 TITLE — not stored (page title) Page title input (exactly one, required, isTitle=true)
2 TEXT — "plain string" Inline single-line
3 RICH_TEXT — RichText (markdown source) Multi-line markdown
4 NUMBER {format: int|float, precision, prefix?, suffix?, currency?} 42 | 19.99 | null Right-aligned numeric, format-aware display
5 SELECT {options: [{id, name, color}]} "opt-id" Dropdown with colored pill
6 MULTI_SELECT same ["opt-a","opt-b"] Multi-pick popover, colored pills
7 STATUS {options: [{id, name, color}]} (ordered) "opt-id" Dropdown; option order = board column order; per-option color
8 DATE {format?} ISO 8601 2025-09-30T00:00:00Z Date picker (+ optional time)
9 DATE_RANGE — {start: ISO, end: ISO} Dual date picker; calendar/timeline render span
10 PERSON {multiple?: bool} "userId" | ["userId"] User picker (workspace members)
11 EMAIL — "a@b.co" Text + mailto link + client validation
12 PHONE — "+1 555…" Text + tel link
13 URL — "https://…" Link field, favicon preview
14 CHECKBOX — true | false Toggle
15 FILES {maxCount?: 10} ["fileId"] Upload button + chips, thumbnails
16 CREATED_TIME — read-only ISO (auto) Timestamp, not editable
17 CREATED_BY — read-only "userId" Avatar + name, not editable
18 LAST_EDITED_TIME — read-only ISO (auto) Timestamp, not editable
19 LAST_EDITED_BY — read-only "userId" Avatar, not editable
20 RELATION {relationId, multiple} ["recordId"] Multi-select popover of linked records (search)
21 ROLLUP {rollupId} computed: number/number[]/text/date Read-only computed badge
22 FORMULA {formulaId} computed value Read-only; error state shows formula parse error
+ BUTTON {buttonId} n/a Action button (see §5.6)
+ UNIQUE_ID {format: sequential|uuid, prefix?} "PRJ-0001" Auto, read-only

The PropertyType enum in schema.prisma is the source of truth (24 values, TITLE … UNIQUE_ID, incl. BUTTON and UNIQUE_ID); this table lists all 24. The table's # column numbers the 22 "stored/computed" types and marks BUTTON and UNIQUE_ID with + — the implemented set is the full enum.

5.2 Records (PR-060, PR-061)

5.3 Views (9) — PR-062…PR-070

Each DatabaseView row keeps: name, type, position, config (visible property ids + order, column widths, card layout, color, density), filter (tree), sort ([{propertyId, direction}]), group ([{propertyId, direction}]), pageSize.

View UX rules (full spec in ux-requirements §6)
TABLE Virtualized rows (100k+), virtualized columns, sticky title column + first visible column, inline editing, row hover actions (open page, duplicate, archive, add comment), multi-select (shift-click) with bulk toolbar (archive, duplicate, assign, delete), row height from density, column width drag (min 80 px), "show more columns" chevron
LIST Compact rows: title + up to 2 secondary properties; row click opens page; same filter/sort/group as table; no inline editing except quick actions
BOARD Exactly one group property (default: first STATUS/SELECT; picker if none); columns = option values in option order; ungrouped records → "Empty" column; cards show title + configured properties; card click opens page; drag card to column = status update (one API call); "+" per column creates record pre-set to that option
CALENDAR Day/week/month switch; source property = first DATE or DATE_RANGE (picker); month grid with record dots/mini-cards; week/day list; click day → new-record dialog (date pre-filled); multi-day ranges render as spans; "today" highlighted
GALLERY Card grid (cover = record cover, fallback icon); card layout config: cover on/off, size (S/M/L), property rows (≤ 3); click opens page; drag reorder within view
TIMELINE Source = DATE_RANGE (or DATE + optional duration property); horizontal time axis with month/week ticks; zoom (day/week/month/quarter); bars draggable to move (updates property); resize edges (updates end); today line; swimlanes per group property
CHART Embeds a chart (§12) bound to this database; config picker = chart config
DASHBOARD Embeds a dashboard widget grid (§12)
FORM Renders the form (§10) bound to this database

View rules: views are per-database, not per-page (a linked_database block re-uses the same views); view creation via "+" with type picker; view rename/ duplicate/delete (last view cannot be deleted); per-view settings persist independently (changing one view's filter never affects others).

5.4 Filters, sort, group (PR-071…PR-073)

5.5 Relations, rollups, formulas (PR-075…PR-083)

6. Automation (PS§10)

Triggers (PR-135) — AutomationTrigger {type, config}:

Type config Fires when
RECORD_CREATED {databaseId} a record created in the database
RECORD_UPDATED {databaseId} any property of a record changed
PROPERTY_CHANGED {databaseId, propertyId, toValue?} that property changed (optionally to a value)
PAGE_CREATED {teamId? | null} a page created (optionally inside a team)
FORM_SUBMITTED {formId} that form receives a submission
SCHEDULE {cron: "0 9 * * 1-5", timezone?} cron match (server TZ default; per-trigger override)
WEBHOOK {path: "auto-xyz"} POST /api/v1/webhooks/inbound/:path (HMAC or token-validated)
MANUAL — "Run now" in UI or API

Conditions (PR-139): AND/OR/NOT tree over predicates {propertyId|field, operator, value} (same operator table as §5.4, plus field ∈ {createdBy, createdAt, lastEditedBy, lastEditedTime}); evaluated against the trigger event payload; empty conditions = always true.

Actions (PR-136) — ordered, each {type, config, retries=3, timeoutMs=30000}:

Type config Effect
UPDATE_RECORD {recordRef: "trigger", propertyId, value} Patch the triggering record (or a looked-up record)
CREATE_PAGE {title, parentId?, templateId?, teamId?} Create a page (template optional)
SEND_EMAIL {to: userRef[] | email, template, vars} Transactional email via SMTP worker
SEND_WEBHOOK {webhookId | url, secretRef?} Enqueue webhook delivery (signed)
CREATE_NOTIFICATION {to: userRef[] | team, type, title, body, link} In-app (+email per preferences) notification
ASSIGN_USER {propertyId, to: userRef} Set a PERSON property
CHANGE_STATUS {propertyId, toValue} Set a STATUS property
CALL_INTEGRATION {integrationId, action, params} Provider call (Slack/GitHub/custom) with encrypted credentials
RUN_AI_ACTION {prompt, context: "record"} AI gateway call (summarize/extract), result → property or email

Runtime: trigger match on domain events (Redis stream consumer); run row created (PENDING → RUNNING → SUCCEEDED/FAILED); actions execute sequentially in a BullMQ job; failure of action k retries up to action.retries with exponential backoff (1 s, 2 s, 4 s…); exhausted retries → action FAILED, run DEAD_LETTER (visible, re-runnable manually); every step appends automation_logs (info/warn/error + structured data). Concurrency: one run per automation at a time (dedup key) — re-triggers while running are queued, not dropped. Paused/archived automations are skipped by the matcher. All runs carry the triggering actor (or SYSTEM for schedules) and its permissions are used by the actions (no privilege escalation).

7. Forms (PS§11) — PR-127…PR-130

8. Dashboards & charts (PS§12) — PR-131…PR-133

9. Collaboration & realtime (PS§13) — PR-084…PR-090

10. Comments, mentions, notifications (PS§14) — PR-091…PR-097

11. Search (PS§15) — PR-098…PR-104

12. Files (PS§16) — PR-105…PR-111

13. Permissions & sharing (PS§17, PS§18) — PR-112…PR-120

14. Templates (PS§19) — PR-121…PR-123

15. Import / export (PS§20) — PR-124…PR-126

16. AI (PS§21) — PR-141…PR-147

17. Public API & webhooks (PS§22) — PR-148…PR-153

18. Audit (PS§23) — PR-010, PR-154 (+ per-feature audit rows)

19. Offline (PS§25) — PR-090 (details in §9 above)