cfsa-antigravity 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.mjs +324 -0
- package/package.json +34 -0
- package/template/.agent/instructions/commands.md +48 -0
- package/template/.agent/instructions/patterns.md +61 -0
- package/template/.agent/instructions/structure.md +29 -0
- package/template/.agent/instructions/tech-stack.md +43 -0
- package/template/.agent/instructions/workflow.md +41 -0
- package/template/.agent/kit-sync.md +15 -0
- package/template/.agent/rules/boundary-not-placeholder.md +146 -0
- package/template/.agent/rules/completion-checklist.md +48 -0
- package/template/.agent/rules/decision-classification.md +103 -0
- package/template/.agent/rules/extensibility.md +47 -0
- package/template/.agent/rules/question-vs-command.md +81 -0
- package/template/.agent/rules/security-first.md +43 -0
- package/template/.agent/rules/specificity-standards.md +54 -0
- package/template/.agent/rules/tdd-contract-first.md +57 -0
- package/template/.agent/rules/vertical-slices.md +42 -0
- package/template/.agent/skill-library/MANIFEST.md +480 -0
- package/template/.agent/skill-library/README.md +38 -0
- package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
- package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
- package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
- package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
- package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
- package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
- package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.agent/skills/accessibility/SKILL.md +522 -0
- package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
- package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
- package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
- package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.agent/skills/api-versioning/SKILL.md +420 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
- package/template/.agent/skills/brainstorming/SKILL.md +236 -0
- package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.agent/skills/clean-code/SKILL.md +94 -0
- package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
- package/template/.agent/skills/concise-planning/SKILL.md +68 -0
- package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
- package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.agent/skills/design-direction/SKILL.md +45 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
- package/template/.agent/skills/find-skills/SKILL.md +145 -0
- package/template/.agent/skills/git-advanced/SKILL.md +972 -0
- package/template/.agent/skills/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
- package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
- package/template/.agent/skills/migration-management/SKILL.md +384 -0
- package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
- package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
- package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
- package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
- package/template/.agent/skills/prd-templates/SKILL.md +88 -0
- package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
- package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
- package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
- package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
- package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
- package/template/.agent/skills/prompt-engineer/README.md +659 -0
- package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
- package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.agent/skills/session-continuity/SKILL.md +730 -0
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
- package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
- package/template/.agent/skills/skill-creator/README.md +270 -0
- package/template/.agent/skills/skill-creator/SKILL.md +590 -0
- package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
- package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
- package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
- package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
- package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/template/.agent/skills/spec-writing/SKILL.md +110 -0
- package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
- package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
- package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.agent/skills/technical-writer/SKILL.md +242 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
- package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
- package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
- package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
- package/template/.agent/workflows/audit-ambiguity.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
- package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
- package/template/.agent/workflows/bootstrap-agents.md +66 -0
- package/template/.agent/workflows/create-prd-architecture.md +119 -0
- package/template/.agent/workflows/create-prd-compile.md +138 -0
- package/template/.agent/workflows/create-prd-design-system.md +135 -0
- package/template/.agent/workflows/create-prd-security.md +113 -0
- package/template/.agent/workflows/create-prd-stack.md +91 -0
- package/template/.agent/workflows/create-prd.md +168 -0
- package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
- package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
- package/template/.agent/workflows/decompose-architecture.md +111 -0
- package/template/.agent/workflows/evolve-contract.md +98 -0
- package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
- package/template/.agent/workflows/evolve-feature-classify.md +116 -0
- package/template/.agent/workflows/evolve-feature.md +56 -0
- package/template/.agent/workflows/ideate-discover.md +144 -0
- package/template/.agent/workflows/ideate-extract.md +129 -0
- package/template/.agent/workflows/ideate-validate.md +117 -0
- package/template/.agent/workflows/ideate.md +113 -0
- package/template/.agent/workflows/implement-slice-setup.md +113 -0
- package/template/.agent/workflows/implement-slice-tdd.md +198 -0
- package/template/.agent/workflows/implement-slice.md +50 -0
- package/template/.agent/workflows/plan-phase.md +202 -0
- package/template/.agent/workflows/propagate-decision-apply.md +135 -0
- package/template/.agent/workflows/propagate-decision-scan.md +147 -0
- package/template/.agent/workflows/propagate-decision.md +56 -0
- package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
- package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
- package/template/.agent/workflows/remediate-pipeline.md +55 -0
- package/template/.agent/workflows/resolve-ambiguity.md +82 -0
- package/template/.agent/workflows/sync-kit.md +209 -0
- package/template/.agent/workflows/update-architecture-map.md +74 -0
- package/template/.agent/workflows/validate-phase.md +219 -0
- package/template/.agent/workflows/verify-infrastructure.md +207 -0
- package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
- package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
- package/template/.agent/workflows/write-architecture-spec.md +63 -0
- package/template/.agent/workflows/write-be-spec-classify.md +165 -0
- package/template/.agent/workflows/write-be-spec-write.md +98 -0
- package/template/.agent/workflows/write-be-spec.md +76 -0
- package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
- package/template/.agent/workflows/write-fe-spec-write.md +94 -0
- package/template/.agent/workflows/write-fe-spec.md +71 -0
- package/template/AGENTS.md +176 -0
- package/template/GEMINI.md +177 -0
- package/template/docs/README.md +187 -0
- package/template/docs/audits/.gitkeep +0 -0
- package/template/docs/audits/README.md +10 -0
- package/template/docs/plans/.gitkeep +0 -0
- package/template/docs/plans/README.md +21 -0
- package/template/docs/plans/be/.gitkeep +0 -0
- package/template/docs/plans/be/README.md +11 -0
- package/template/docs/plans/fe/.gitkeep +0 -0
- package/template/docs/plans/fe/README.md +11 -0
- package/template/docs/plans/ia/.gitkeep +0 -0
- package/template/docs/plans/ia/README.md +17 -0
- package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
- package/template/docs/plans/ia/deep-dives/README.md +5 -0
- package/template/docs/plans/phases/.gitkeep +0 -0
- package/template/docs/plans/phases/README.md +11 -0
|
@@ -0,0 +1,945 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: surrealdb-expert
|
|
3
|
+
description: "Expert SurrealDB 3.0 guide covering multi-model database design (document, graph, vector, KV), SurrealQL 3.0 syntax, DEFINE ACCESS authentication, DEFINE API custom endpoints, computed fields, record references, HNSW vector indexing, schema design, cross-store coordination, and security hardening. Use when building SurrealDB 3.0 applications or integrating SurrealDB into a polyglot persistence architecture."
|
|
4
|
+
version: 3.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# SurrealDB 3.0 Expert Guide
|
|
8
|
+
|
|
9
|
+
> Use this skill when designing multi-model schemas, writing SurrealQL queries, implementing authentication with `DEFINE ACCESS`, creating custom API endpoints, working with graph relations, vector search, computed fields, record references, or hardening a SurrealDB 3.0 deployment. **This skill targets SurrealDB 3.0 GA (February 2026).**
|
|
10
|
+
|
|
11
|
+
## When to Use This Skill
|
|
12
|
+
|
|
13
|
+
- Designing schemas that span document, graph, key-value, and vector models in one database
|
|
14
|
+
- Writing or reviewing SurrealQL queries (SELECT, CREATE, UPDATE, RELATE, DEFINE)
|
|
15
|
+
- Implementing authentication (DEFINE ACCESS TYPE RECORD — replaces deprecated DEFINE SCOPE)
|
|
16
|
+
- Building custom HTTP endpoints directly in the database (DEFINE API)
|
|
17
|
+
- Creating graph schemas with bidirectional record references (REFERENCE keyword)
|
|
18
|
+
- Using vector search with HNSW indexing for AI/embedding workloads
|
|
19
|
+
- Integrating SurrealDB as primary or multi-role store in a polyglot persistence architecture
|
|
20
|
+
- Hardening SurrealDB for production deployment
|
|
21
|
+
|
|
22
|
+
## When NOT to Use This Skill
|
|
23
|
+
|
|
24
|
+
- Time-series analytics with compression/retention/continuous aggregates → use TimescaleDB
|
|
25
|
+
- Dedicated full-text search with ranking/faceting → use Meilisearch or Elasticsearch
|
|
26
|
+
- Pure file/blob storage → use S3/object storage (SurrealDB file support is still experimental)
|
|
27
|
+
- Simple relational-only workloads with no graph/vector needs → may be simpler with PostgreSQL
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 1. Schema Design
|
|
32
|
+
|
|
33
|
+
### Table Definitions
|
|
34
|
+
|
|
35
|
+
SurrealDB 3.0 tables can be `SCHEMAFULL` (strict) or `SCHEMALESS` (flexible):
|
|
36
|
+
|
|
37
|
+
```surql
|
|
38
|
+
-- Strict schema — all fields must be defined
|
|
39
|
+
DEFINE TABLE user SCHEMAFULL
|
|
40
|
+
PERMISSIONS
|
|
41
|
+
FOR select, update, delete WHERE id = $auth.id
|
|
42
|
+
FOR create FULL;
|
|
43
|
+
|
|
44
|
+
DEFINE FIELD email ON user TYPE string
|
|
45
|
+
ASSERT string::is::email($value);
|
|
46
|
+
DEFINE FIELD password ON user TYPE string
|
|
47
|
+
VALUE crypto::argon2::generate($value);
|
|
48
|
+
DEFINE FIELD role ON user TYPE string
|
|
49
|
+
DEFAULT 'user'
|
|
50
|
+
ASSERT $value IN ['user', 'admin', 'moderator'];
|
|
51
|
+
DEFINE FIELD created_at ON user TYPE datetime
|
|
52
|
+
DEFAULT time::now();
|
|
53
|
+
|
|
54
|
+
-- Unique index
|
|
55
|
+
DEFINE INDEX user_email_idx ON user FIELDS email UNIQUE;
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
> ⚠️ **3.0 Change:** Use `FIELDS` keyword for indexes, not ~~`COLUMNS`~~. The old `COLUMNS` syntax is deprecated.
|
|
59
|
+
|
|
60
|
+
### Field Types
|
|
61
|
+
|
|
62
|
+
```surql
|
|
63
|
+
-- Scalar types
|
|
64
|
+
DEFINE FIELD name ON user TYPE string;
|
|
65
|
+
DEFINE FIELD age ON user TYPE int;
|
|
66
|
+
DEFINE FIELD balance ON user TYPE decimal;
|
|
67
|
+
DEFINE FIELD active ON user TYPE bool DEFAULT true;
|
|
68
|
+
DEFINE FIELD bio ON user TYPE option<string>; -- nullable
|
|
69
|
+
|
|
70
|
+
-- Complex types
|
|
71
|
+
DEFINE FIELD tags ON post TYPE array<string> DEFAULT [];
|
|
72
|
+
DEFINE FIELD metadata ON post TYPE object;
|
|
73
|
+
DEFINE FIELD metadata.source ON post TYPE option<string>;
|
|
74
|
+
|
|
75
|
+
-- Record links (foreign keys)
|
|
76
|
+
DEFINE FIELD author ON post TYPE record<user>;
|
|
77
|
+
DEFINE FIELD category ON post TYPE record<category>;
|
|
78
|
+
|
|
79
|
+
-- Arrays of record links
|
|
80
|
+
DEFINE FIELD collaborators ON project TYPE array<record<user>> DEFAULT [];
|
|
81
|
+
|
|
82
|
+
-- Geometry types
|
|
83
|
+
DEFINE FIELD location ON venue TYPE geometry<point>;
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Computed Fields (NEW in 3.0)
|
|
87
|
+
|
|
88
|
+
Computed fields replace the deprecated "futures" system. They are defined once in the schema and evaluated **at query time** — never stored.
|
|
89
|
+
|
|
90
|
+
```surql
|
|
91
|
+
-- Computed field: age based on birthdate
|
|
92
|
+
DEFINE FIELD age ON user COMPUTED time::now() - born;
|
|
93
|
+
|
|
94
|
+
-- Computed field: can drive
|
|
95
|
+
DEFINE FIELD can_drive ON user COMPUTED time::now() - born > 18y;
|
|
96
|
+
|
|
97
|
+
-- Computed field: full name
|
|
98
|
+
DEFINE FIELD full_name ON user COMPUTED string::concat(first_name, ' ', last_name);
|
|
99
|
+
|
|
100
|
+
-- Computed field: post count via subquery
|
|
101
|
+
DEFINE FIELD post_count ON user COMPUTED count(SELECT id FROM post WHERE author = $this.id);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Rules:**
|
|
105
|
+
- Computed fields use the `COMPUTED` keyword (not `VALUE` — `VALUE` is for transforms on write)
|
|
106
|
+
- They are top-level fields only — no nested computed fields
|
|
107
|
+
- They cannot be written to — they are read-only by definition
|
|
108
|
+
- They are evaluated every time the field is accessed
|
|
109
|
+
|
|
110
|
+
### Record References (NEW in 3.0)
|
|
111
|
+
|
|
112
|
+
Record references make record links **bidirectional** at the schema level:
|
|
113
|
+
|
|
114
|
+
```surql
|
|
115
|
+
-- Forward link: post has an author (record<user>)
|
|
116
|
+
DEFINE FIELD author ON post TYPE record<user> REFERENCE;
|
|
117
|
+
|
|
118
|
+
-- The REFERENCE keyword means: user records can now "see" which posts link to them
|
|
119
|
+
-- No manual reverse lookups needed
|
|
120
|
+
|
|
121
|
+
-- ON DELETE handlers
|
|
122
|
+
DEFINE FIELD author ON post TYPE record<user> REFERENCE ON DELETE CASCADE;
|
|
123
|
+
-- Options: REJECT, CASCADE, IGNORE, UNSET, or THEN { custom logic }
|
|
124
|
+
|
|
125
|
+
-- Custom ON DELETE logic
|
|
126
|
+
DEFINE FIELD comments ON person TYPE option<array<record<comment>>> REFERENCE ON DELETE THEN {
|
|
127
|
+
UPDATE $this SET
|
|
128
|
+
deleted_comments += $reference,
|
|
129
|
+
comments -= $reference;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
-- Array of references
|
|
133
|
+
DEFINE FIELD members ON team TYPE array<record<user>> REFERENCE ON DELETE UNSET;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Reference traversal with the `<~` operator:**
|
|
137
|
+
|
|
138
|
+
```surql
|
|
139
|
+
-- Author field on comment — computed from the reverse reference
|
|
140
|
+
DEFINE FIELD author ON comment COMPUTED <~person;
|
|
141
|
+
|
|
142
|
+
-- Query: find all posts that reference a user (via any REFERENCE field)
|
|
143
|
+
SELECT <~post FROM user:john;
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Record IDs
|
|
147
|
+
|
|
148
|
+
```surql
|
|
149
|
+
-- String IDs
|
|
150
|
+
CREATE user:john CONTENT { email: 'john@example.com' };
|
|
151
|
+
|
|
152
|
+
-- UUID IDs
|
|
153
|
+
CREATE user:⟨550e8400-e29b-41d4-a716-446655440000⟩ CONTENT { ... };
|
|
154
|
+
|
|
155
|
+
-- Auto-generated IDs
|
|
156
|
+
CREATE user CONTENT { email: 'auto@example.com' };
|
|
157
|
+
-- Returns: user:randomid
|
|
158
|
+
|
|
159
|
+
-- Numeric IDs
|
|
160
|
+
CREATE product:1 CONTENT { name: 'Widget' };
|
|
161
|
+
|
|
162
|
+
-- Complex IDs with arrays or objects
|
|
163
|
+
CREATE event:['2026-01-01', 'concert'] CONTENT { ... };
|
|
164
|
+
CREATE event:{ city: 'Berlin', date: '2026-01-01' } CONTENT { ... };
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 2. SurrealQL Query Patterns
|
|
170
|
+
|
|
171
|
+
### CRUD Operations
|
|
172
|
+
|
|
173
|
+
```surql
|
|
174
|
+
-- CREATE
|
|
175
|
+
CREATE user CONTENT {
|
|
176
|
+
email: $email,
|
|
177
|
+
password: $password,
|
|
178
|
+
role: 'user'
|
|
179
|
+
} RETURN id, email, role, created_at;
|
|
180
|
+
|
|
181
|
+
-- SELECT with filtering
|
|
182
|
+
SELECT id, email, role FROM user
|
|
183
|
+
WHERE active = true AND role = 'admin'
|
|
184
|
+
ORDER BY created_at DESC
|
|
185
|
+
LIMIT 20;
|
|
186
|
+
|
|
187
|
+
-- UPDATE (merge by default)
|
|
188
|
+
UPDATE user:john SET role = 'admin', updated_at = time::now();
|
|
189
|
+
|
|
190
|
+
-- UPDATE with MERGE (explicit)
|
|
191
|
+
UPDATE user:john MERGE { role: 'admin', updated_at: time::now() };
|
|
192
|
+
|
|
193
|
+
-- UPDATE with PATCH (JSON Patch)
|
|
194
|
+
UPDATE user:john PATCH [
|
|
195
|
+
{ op: 'replace', path: '/role', value: 'admin' }
|
|
196
|
+
];
|
|
197
|
+
|
|
198
|
+
-- DELETE
|
|
199
|
+
DELETE user:john;
|
|
200
|
+
|
|
201
|
+
-- DELETE with condition
|
|
202
|
+
DELETE post WHERE created_at < time::now() - 1y AND archived = true;
|
|
203
|
+
|
|
204
|
+
-- UPSERT
|
|
205
|
+
UPSERT user:john CONTENT {
|
|
206
|
+
email: 'john@example.com',
|
|
207
|
+
name: 'John Doe',
|
|
208
|
+
updated_at: time::now()
|
|
209
|
+
};
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Graph Relations with RELATE
|
|
213
|
+
|
|
214
|
+
```surql
|
|
215
|
+
-- Define edge tables
|
|
216
|
+
DEFINE TABLE follows SCHEMAFULL;
|
|
217
|
+
DEFINE FIELD in ON follows TYPE record<user>;
|
|
218
|
+
DEFINE FIELD out ON follows TYPE record<user>;
|
|
219
|
+
DEFINE FIELD since ON follows TYPE datetime DEFAULT time::now();
|
|
220
|
+
|
|
221
|
+
DEFINE TABLE authored SCHEMAFULL;
|
|
222
|
+
DEFINE FIELD in ON authored TYPE record<user>;
|
|
223
|
+
DEFINE FIELD out ON authored TYPE record<post>;
|
|
224
|
+
|
|
225
|
+
-- Create relationships
|
|
226
|
+
RELATE user:john -> follows -> user:jane SET since = time::now();
|
|
227
|
+
RELATE user:john -> authored -> post:first_post;
|
|
228
|
+
|
|
229
|
+
-- Graph traversal: get posts by a user
|
|
230
|
+
SELECT ->authored->post.* FROM user:john;
|
|
231
|
+
|
|
232
|
+
-- Reverse traversal: get author of a post
|
|
233
|
+
SELECT <-authored<-user.* FROM post:first_post;
|
|
234
|
+
|
|
235
|
+
-- Multi-hop: get comments on a user's posts
|
|
236
|
+
SELECT ->authored->post->has_comment->comment.* FROM user:john;
|
|
237
|
+
|
|
238
|
+
-- Filter during traversal
|
|
239
|
+
SELECT ->authored->post[WHERE published = true AND created_at > $since].* FROM user:john;
|
|
240
|
+
|
|
241
|
+
-- Limit traversal results
|
|
242
|
+
SELECT ->follows->user[0:10].name FROM user:john;
|
|
243
|
+
|
|
244
|
+
-- Bidirectional with aggregation
|
|
245
|
+
SELECT
|
|
246
|
+
count(<-follows<-user) AS follower_count,
|
|
247
|
+
count(->follows->user) AS following_count,
|
|
248
|
+
count(->authored->post) AS post_count
|
|
249
|
+
FROM user:john;
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Subqueries and LET
|
|
253
|
+
|
|
254
|
+
```surql
|
|
255
|
+
-- LET for variables
|
|
256
|
+
LET $active_users = SELECT id FROM user WHERE active = true;
|
|
257
|
+
SELECT ->authored->post.* FROM $active_users;
|
|
258
|
+
|
|
259
|
+
-- Inline subquery
|
|
260
|
+
SELECT *,
|
|
261
|
+
(SELECT count() FROM post WHERE author = $parent.id GROUP ALL) AS post_count
|
|
262
|
+
FROM user;
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Transactions
|
|
266
|
+
|
|
267
|
+
```surql
|
|
268
|
+
-- Server-side transaction
|
|
269
|
+
BEGIN TRANSACTION;
|
|
270
|
+
CREATE product:widget CONTENT { name: 'Widget', stock: 100 };
|
|
271
|
+
CREATE order:1 CONTENT { product: product:widget, quantity: 5 };
|
|
272
|
+
UPDATE product:widget SET stock -= 5;
|
|
273
|
+
COMMIT TRANSACTION;
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
> **3.0 NEW:** Client-side transactions — group operations across multiple requests with full ACID guarantees, managed from application code.
|
|
277
|
+
|
|
278
|
+
### Pagination (Cursor-Based)
|
|
279
|
+
|
|
280
|
+
```surql
|
|
281
|
+
-- GOOD: Cursor-based (constant performance)
|
|
282
|
+
SELECT * FROM post
|
|
283
|
+
WHERE created_at < $cursor
|
|
284
|
+
ORDER BY created_at DESC
|
|
285
|
+
LIMIT 20;
|
|
286
|
+
|
|
287
|
+
-- BAD: OFFSET-based (gets slower as offset grows)
|
|
288
|
+
SELECT * FROM post
|
|
289
|
+
ORDER BY created_at DESC
|
|
290
|
+
LIMIT 20 START 10000;
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
## 3. DEFINE ACCESS — Authentication (Replaces DEFINE SCOPE)
|
|
296
|
+
|
|
297
|
+
> ⚠️ **3.0 Breaking Change:** `DEFINE SCOPE` is **removed**. Use `DEFINE ACCESS ... TYPE RECORD` instead. If migrating from 2.x, all `DEFINE SCOPE` statements must be rewritten.
|
|
298
|
+
|
|
299
|
+
### Record Access Method
|
|
300
|
+
|
|
301
|
+
```surql
|
|
302
|
+
-- Define user authentication
|
|
303
|
+
DEFINE ACCESS user ON DATABASE TYPE RECORD
|
|
304
|
+
SIGNUP (
|
|
305
|
+
CREATE user SET
|
|
306
|
+
email = $email,
|
|
307
|
+
password = crypto::argon2::generate($password),
|
|
308
|
+
role = 'user',
|
|
309
|
+
created_at = time::now()
|
|
310
|
+
)
|
|
311
|
+
SIGNIN (
|
|
312
|
+
SELECT * FROM user
|
|
313
|
+
WHERE email = $email
|
|
314
|
+
AND crypto::argon2::compare(password, $password)
|
|
315
|
+
)
|
|
316
|
+
DURATION FOR TOKEN 15m, FOR SESSION 12h;
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### With Refresh Tokens
|
|
320
|
+
|
|
321
|
+
```surql
|
|
322
|
+
DEFINE ACCESS user ON DATABASE TYPE RECORD
|
|
323
|
+
SIGNUP (
|
|
324
|
+
CREATE user SET
|
|
325
|
+
email = $email,
|
|
326
|
+
password = crypto::argon2::generate($password)
|
|
327
|
+
)
|
|
328
|
+
SIGNIN (
|
|
329
|
+
SELECT * FROM user
|
|
330
|
+
WHERE email = $email
|
|
331
|
+
AND crypto::argon2::compare(password, $password)
|
|
332
|
+
)
|
|
333
|
+
WITH REFRESH
|
|
334
|
+
DURATION FOR GRANT 15d, FOR TOKEN 1m, FOR SESSION 12h;
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### With JWT (External Provider)
|
|
338
|
+
|
|
339
|
+
```surql
|
|
340
|
+
DEFINE ACCESS user ON DATABASE TYPE RECORD
|
|
341
|
+
WITH JWT ALGORITHM HS512 KEY 'your-jwt-secret'
|
|
342
|
+
AUTHENTICATE {
|
|
343
|
+
IF $auth.id {
|
|
344
|
+
RETURN $auth.id;
|
|
345
|
+
} ELSE IF $token.email {
|
|
346
|
+
RETURN SELECT * FROM user WHERE email = $token.email;
|
|
347
|
+
};
|
|
348
|
+
};
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Client-Side Authentication
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
// Sign up
|
|
355
|
+
const token = await db.signup({
|
|
356
|
+
access: 'user', // NOT 'scope' — that's the old 2.x API
|
|
357
|
+
namespace: 'app',
|
|
358
|
+
database: 'production',
|
|
359
|
+
variables: {
|
|
360
|
+
email: 'user@example.com',
|
|
361
|
+
password: 'secure-password'
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// Sign in
|
|
366
|
+
const token = await db.signin({
|
|
367
|
+
access: 'user',
|
|
368
|
+
namespace: 'app',
|
|
369
|
+
database: 'production',
|
|
370
|
+
variables: {
|
|
371
|
+
email: 'user@example.com',
|
|
372
|
+
password: 'secure-password'
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### System Users (RBAC)
|
|
378
|
+
|
|
379
|
+
```surql
|
|
380
|
+
-- Root-level admin
|
|
381
|
+
DEFINE USER admin ON ROOT PASSWORD 'strong-password' ROLES OWNER;
|
|
382
|
+
|
|
383
|
+
-- Namespace-level user
|
|
384
|
+
DEFINE USER ns_admin ON NAMESPACE PASSWORD 'strong-password' ROLES OWNER;
|
|
385
|
+
|
|
386
|
+
-- Database-level users with least privilege
|
|
387
|
+
DEFINE USER reader ON DATABASE PASSWORD 'strong-password' ROLES VIEWER;
|
|
388
|
+
DEFINE USER editor ON DATABASE PASSWORD 'strong-password' ROLES EDITOR;
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Row-Level Security
|
|
392
|
+
|
|
393
|
+
```surql
|
|
394
|
+
-- Table-level permissions using $auth context
|
|
395
|
+
DEFINE TABLE document SCHEMAFULL
|
|
396
|
+
PERMISSIONS
|
|
397
|
+
FOR select WHERE public = true OR owner = $auth.id
|
|
398
|
+
FOR create WHERE $auth.id != NONE
|
|
399
|
+
FOR update, delete WHERE owner = $auth.id;
|
|
400
|
+
|
|
401
|
+
DEFINE FIELD owner ON document TYPE record<user>
|
|
402
|
+
DEFAULT $auth.id;
|
|
403
|
+
DEFINE FIELD public ON document TYPE bool DEFAULT false;
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## 4. DEFINE API — Custom Endpoints (NEW in 3.0)
|
|
409
|
+
|
|
410
|
+
Custom API endpoints let you define HTTP routes directly in the database, eliminating the need for an external API layer for simple cases.
|
|
411
|
+
|
|
412
|
+
### Basic Endpoint
|
|
413
|
+
|
|
414
|
+
```surql
|
|
415
|
+
DEFINE API "/health" FOR get
|
|
416
|
+
THEN {
|
|
417
|
+
{
|
|
418
|
+
status: 200,
|
|
419
|
+
body: { status: "ok", version: "3.0.0" }
|
|
420
|
+
};
|
|
421
|
+
};
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**Access:** `GET /api/:namespace/:database/health`
|
|
425
|
+
|
|
426
|
+
### Endpoint with Query Logic
|
|
427
|
+
|
|
428
|
+
```surql
|
|
429
|
+
DEFINE API "/users" FOR get
|
|
430
|
+
MIDDLEWARE api::timeout(5s)
|
|
431
|
+
THEN {
|
|
432
|
+
LET $users = SELECT id, email, role FROM user WHERE active = true LIMIT 100;
|
|
433
|
+
{
|
|
434
|
+
status: 200,
|
|
435
|
+
body: { users: $users, count: count($users) }
|
|
436
|
+
};
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
DEFINE API "/users/:id" FOR get
|
|
440
|
+
THEN {
|
|
441
|
+
LET $user = SELECT * FROM type::thing('user', $request.params.id);
|
|
442
|
+
IF $user {
|
|
443
|
+
{ status: 200, body: $user }
|
|
444
|
+
} ELSE {
|
|
445
|
+
{ status: 404, body: { error: "User not found" } }
|
|
446
|
+
};
|
|
447
|
+
};
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### POST Endpoint
|
|
451
|
+
|
|
452
|
+
```surql
|
|
453
|
+
DEFINE API "/posts" FOR post
|
|
454
|
+
MIDDLEWARE api::timeout(3s)
|
|
455
|
+
PERMISSIONS $auth.id != NONE
|
|
456
|
+
THEN {
|
|
457
|
+
LET $post = CREATE post CONTENT {
|
|
458
|
+
title: $request.body.title,
|
|
459
|
+
body: $request.body.body,
|
|
460
|
+
author: $auth.id,
|
|
461
|
+
published: false
|
|
462
|
+
};
|
|
463
|
+
{
|
|
464
|
+
status: 201,
|
|
465
|
+
body: $post[0],
|
|
466
|
+
headers: { 'location': string::concat('/api/ns/db/posts/', $post[0].id) }
|
|
467
|
+
};
|
|
468
|
+
};
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Response Format
|
|
472
|
+
|
|
473
|
+
```surql
|
|
474
|
+
-- API endpoints return an object with:
|
|
475
|
+
{
|
|
476
|
+
status: 200, -- HTTP status code (required)
|
|
477
|
+
body: { ... }, -- Response body (any type)
|
|
478
|
+
headers: { ... }, -- Custom response headers (optional)
|
|
479
|
+
context: { ... } -- Additional context (optional)
|
|
480
|
+
}
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
### Global API Configuration
|
|
484
|
+
|
|
485
|
+
```surql
|
|
486
|
+
-- Set global middleware and permissions for all API endpoints
|
|
487
|
+
DEFINE CONFIG API
|
|
488
|
+
MIDDLEWARE api::cors('*'), api::timeout(10s)
|
|
489
|
+
PERMISSIONS $auth.id != NONE;
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
## 5. Index Strategy
|
|
495
|
+
|
|
496
|
+
### Standard Indexes
|
|
497
|
+
|
|
498
|
+
```surql
|
|
499
|
+
-- Range index (default)
|
|
500
|
+
DEFINE INDEX user_email ON user FIELDS email UNIQUE;
|
|
501
|
+
|
|
502
|
+
-- Composite index
|
|
503
|
+
DEFINE INDEX post_author_created ON post FIELDS author, created_at;
|
|
504
|
+
|
|
505
|
+
-- Non-unique index
|
|
506
|
+
DEFINE INDEX user_role ON user FIELDS role;
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Full-Text Search (BM25)
|
|
510
|
+
|
|
511
|
+
```surql
|
|
512
|
+
-- Define search analyzer and index
|
|
513
|
+
DEFINE INDEX post_search ON post
|
|
514
|
+
FIELDS title, content
|
|
515
|
+
SEARCH ANALYZER simple BM25;
|
|
516
|
+
|
|
517
|
+
-- Query with scoring
|
|
518
|
+
SELECT *, search::score(1) AS relevance
|
|
519
|
+
FROM post
|
|
520
|
+
WHERE title @1@ 'database tutorial' OR content @1@ 'database tutorial'
|
|
521
|
+
ORDER BY relevance DESC
|
|
522
|
+
LIMIT 20;
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### Vector Index (HNSW) — AI/Embeddings
|
|
526
|
+
|
|
527
|
+
```surql
|
|
528
|
+
-- Define a vector field
|
|
529
|
+
DEFINE FIELD embedding ON document TYPE array<float>
|
|
530
|
+
ASSERT array::len($value) = 1536; -- OpenAI ada-002 dimension
|
|
531
|
+
|
|
532
|
+
-- Create HNSW vector index
|
|
533
|
+
DEFINE INDEX document_embedding_idx ON document FIELDS embedding
|
|
534
|
+
MTREE DIMENSION 1536 TYPE F32;
|
|
535
|
+
|
|
536
|
+
-- Vector similarity search
|
|
537
|
+
SELECT id, title,
|
|
538
|
+
vector::similarity::cosine(embedding, $query_embedding) AS score
|
|
539
|
+
FROM document
|
|
540
|
+
WHERE embedding <|10,128|> $query_embedding
|
|
541
|
+
ORDER BY score DESC;
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### Deferred Index Building
|
|
545
|
+
|
|
546
|
+
```surql
|
|
547
|
+
-- Build index in background (3.0 feature — useful for large datasets)
|
|
548
|
+
DEFINE INDEX DEFER large_idx ON events FIELDS timestamp;
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Verifying Index Usage
|
|
552
|
+
|
|
553
|
+
```surql
|
|
554
|
+
-- Check if query uses an index
|
|
555
|
+
EXPLAIN SELECT * FROM user WHERE email = $email;
|
|
556
|
+
-- Look for "IndexSeek" vs "TableScan"
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
|
|
561
|
+
## 6. Driver Setup
|
|
562
|
+
|
|
563
|
+
### JavaScript/TypeScript SDK
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
import Surreal from 'surrealdb';
|
|
567
|
+
|
|
568
|
+
// Create client
|
|
569
|
+
const db = new Surreal();
|
|
570
|
+
|
|
571
|
+
// Connect
|
|
572
|
+
await db.connect('ws://localhost:8000');
|
|
573
|
+
|
|
574
|
+
// Select namespace and database
|
|
575
|
+
await db.use({ namespace: 'app', database: 'production' });
|
|
576
|
+
|
|
577
|
+
// Authenticate as root (admin operations)
|
|
578
|
+
await db.signin({ username: 'root', password: 'root' });
|
|
579
|
+
|
|
580
|
+
// Or authenticate as record user
|
|
581
|
+
await db.signin({
|
|
582
|
+
access: 'user',
|
|
583
|
+
namespace: 'app',
|
|
584
|
+
database: 'production',
|
|
585
|
+
variables: {
|
|
586
|
+
email: 'user@example.com',
|
|
587
|
+
password: 'secure-password'
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
// Parameterized query (ALWAYS use parameters)
|
|
592
|
+
const users = await db.query(
|
|
593
|
+
'SELECT id, email, role FROM user WHERE role = $role LIMIT $limit',
|
|
594
|
+
{ role: 'admin', limit: 10 }
|
|
595
|
+
);
|
|
596
|
+
|
|
597
|
+
// CRUD operations
|
|
598
|
+
const user = await db.create('user', {
|
|
599
|
+
email: 'new@example.com',
|
|
600
|
+
password: 'hashed-by-schema'
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
await db.update('user:john', { role: 'admin' });
|
|
604
|
+
await db.delete('user:john');
|
|
605
|
+
|
|
606
|
+
// Live queries
|
|
607
|
+
const uuid = await db.live('post', (action, result) => {
|
|
608
|
+
console.log(`${action}:`, result);
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
// ALWAYS clean up live queries
|
|
612
|
+
await db.kill(uuid);
|
|
613
|
+
|
|
614
|
+
// Close connection
|
|
615
|
+
await db.close();
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### Python SDK
|
|
619
|
+
|
|
620
|
+
```python
|
|
621
|
+
from surrealdb import Surreal
|
|
622
|
+
|
|
623
|
+
async with Surreal("ws://localhost:8000") as db:
|
|
624
|
+
await db.use("app", "production")
|
|
625
|
+
await db.signin({"username": "root", "password": "root"})
|
|
626
|
+
|
|
627
|
+
# Parameterized query
|
|
628
|
+
users = await db.query(
|
|
629
|
+
"SELECT * FROM user WHERE role = $role",
|
|
630
|
+
{"role": "admin"}
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
# Create
|
|
634
|
+
user = await db.create("user", {
|
|
635
|
+
"email": "new@example.com",
|
|
636
|
+
"password": "secure"
|
|
637
|
+
})
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Go SDK (1.0 GA in 3.0)
|
|
641
|
+
|
|
642
|
+
```go
|
|
643
|
+
package main
|
|
644
|
+
|
|
645
|
+
import (
|
|
646
|
+
"github.com/surrealdb/surrealdb.go"
|
|
647
|
+
"github.com/surrealdb/surrealdb.go/pkg/models"
|
|
648
|
+
)
|
|
649
|
+
|
|
650
|
+
func main() {
|
|
651
|
+
db, err := surrealdb.New("ws://localhost:8000")
|
|
652
|
+
if err != nil {
|
|
653
|
+
panic(err)
|
|
654
|
+
}
|
|
655
|
+
defer db.Close()
|
|
656
|
+
|
|
657
|
+
if _, err = db.Use("app", "production"); err != nil {
|
|
658
|
+
panic(err)
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
if _, err = db.Signin(models.Auth{
|
|
662
|
+
Username: "root",
|
|
663
|
+
Password: "root",
|
|
664
|
+
}); err != nil {
|
|
665
|
+
panic(err)
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// Query
|
|
669
|
+
result, err := db.Query(
|
|
670
|
+
"SELECT * FROM user WHERE role = $role",
|
|
671
|
+
map[string]interface{}{"role": "admin"},
|
|
672
|
+
)
|
|
673
|
+
}
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
### Connection Lifecycle Rules
|
|
677
|
+
|
|
678
|
+
1. **Create one client per application** — reuse across request handlers
|
|
679
|
+
2. **Use parameterized queries** — never string-interpolate user input
|
|
680
|
+
3. **Always close live query subscriptions** — leaked subscriptions cause memory pressure
|
|
681
|
+
4. **Handle reconnection** — WebSocket connections can drop; implement retry logic
|
|
682
|
+
5. **Close on shutdown** — `db.close()` in shutdown handlers
|
|
683
|
+
|
|
684
|
+
---
|
|
685
|
+
|
|
686
|
+
## 7. Cross-Store Coordination
|
|
687
|
+
|
|
688
|
+
When SurrealDB is one store in a polyglot persistence architecture:
|
|
689
|
+
|
|
690
|
+
### Canonical ID Rule
|
|
691
|
+
|
|
692
|
+
The canonical identifier is generated by whichever store creates the entity first. If SurrealDB IS the primary store, its record IDs are canonical. If SurrealDB is a secondary store (e.g., for graph enrichment alongside PostgreSQL), store the primary store's UUID as a field.
|
|
693
|
+
|
|
694
|
+
```surql
|
|
695
|
+
-- SurrealDB as primary: use its native record IDs
|
|
696
|
+
CREATE user:john CONTENT { email: 'john@example.com' };
|
|
697
|
+
-- Canonical ID: user:john
|
|
698
|
+
|
|
699
|
+
-- SurrealDB as secondary: store external UUID
|
|
700
|
+
CREATE user_graph CONTENT {
|
|
701
|
+
external_id: $postgres_uuid, -- from primary store
|
|
702
|
+
username: $username
|
|
703
|
+
};
|
|
704
|
+
DEFINE INDEX ext_id ON user_graph FIELDS external_id UNIQUE;
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### SurrealDB as Multi-Role Store
|
|
708
|
+
|
|
709
|
+
SurrealDB 3.0 can serve multiple roles simultaneously:
|
|
710
|
+
|
|
711
|
+
```surql
|
|
712
|
+
-- Document storage (primary)
|
|
713
|
+
DEFINE TABLE user SCHEMAFULL;
|
|
714
|
+
DEFINE FIELD email ON user TYPE string;
|
|
715
|
+
|
|
716
|
+
-- Graph relations
|
|
717
|
+
RELATE user:john -> follows -> user:jane;
|
|
718
|
+
SELECT ->follows->user.* FROM user:john;
|
|
719
|
+
|
|
720
|
+
-- Vector search (AI)
|
|
721
|
+
DEFINE FIELD embedding ON document TYPE array<float>;
|
|
722
|
+
DEFINE INDEX doc_vec ON document FIELDS embedding MTREE DIMENSION 1536 TYPE F32;
|
|
723
|
+
SELECT * FROM document WHERE embedding <|5,128|> $query_vec;
|
|
724
|
+
|
|
725
|
+
-- All in one query (multi-model)
|
|
726
|
+
SELECT
|
|
727
|
+
*,
|
|
728
|
+
->authored->post[WHERE published = true].title AS posts,
|
|
729
|
+
(SELECT id FROM document WHERE embedding <|3,64|> $vec) AS similar_docs
|
|
730
|
+
FROM user:john;
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
### When to Pair with Another Store
|
|
734
|
+
|
|
735
|
+
| Need | SurrealDB Handles It? | Alternative |
|
|
736
|
+
|------|----------------------|-------------|
|
|
737
|
+
| ACID documents | ✅ Yes | — |
|
|
738
|
+
| Graph traversal | ✅ Yes | — |
|
|
739
|
+
| Vector similarity | ✅ Yes (HNSW) | Qdrant (if vector-only workload at massive scale) |
|
|
740
|
+
| KV cache | ✅ Yes (in-memory engine) | Redis (if sub-ms latency is critical) |
|
|
741
|
+
| Time-series analytics | ❌ No native chunking | TimescaleDB |
|
|
742
|
+
| File/blob storage | ⚠️ Experimental | S3 |
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
## 8. Security
|
|
747
|
+
|
|
748
|
+
### Query Injection Prevention
|
|
749
|
+
|
|
750
|
+
```surql
|
|
751
|
+
-- GOOD: Parameterized query
|
|
752
|
+
SELECT * FROM user WHERE email = $email;
|
|
753
|
+
|
|
754
|
+
-- BAD: String interpolation — VULNERABLE TO INJECTION
|
|
755
|
+
-- NEVER do this in application code:
|
|
756
|
+
-- `SELECT * FROM user WHERE email = '${userInput}'`
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
In every SDK, always use the parameters argument:
|
|
760
|
+
|
|
761
|
+
```typescript
|
|
762
|
+
// GOOD
|
|
763
|
+
await db.query('SELECT * FROM user WHERE email = $email', { email });
|
|
764
|
+
|
|
765
|
+
// BAD — NEVER DO THIS
|
|
766
|
+
await db.query(`SELECT * FROM user WHERE email = '${email}'`);
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
### Network Restrictions
|
|
770
|
+
|
|
771
|
+
```bash
|
|
772
|
+
# Production: restrict outbound network access
|
|
773
|
+
surreal start --allow-net api.example.com --deny-net 10.0.0.0/8
|
|
774
|
+
|
|
775
|
+
# NEVER use in production
|
|
776
|
+
surreal start --allow-all # Unrestricted — dangerous
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### Password Hashing
|
|
780
|
+
|
|
781
|
+
```surql
|
|
782
|
+
-- Always hash on write using VALUE transform
|
|
783
|
+
DEFINE FIELD password ON user TYPE string
|
|
784
|
+
VALUE crypto::argon2::generate($value);
|
|
785
|
+
|
|
786
|
+
-- Verify during signin
|
|
787
|
+
DEFINE ACCESS user ON DATABASE TYPE RECORD
|
|
788
|
+
SIGNIN (
|
|
789
|
+
SELECT * FROM user
|
|
790
|
+
WHERE email = $email
|
|
791
|
+
AND crypto::argon2::compare(password, $password)
|
|
792
|
+
)
|
|
793
|
+
DURATION FOR TOKEN 15m, FOR SESSION 12h;
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
### Permissions Checklist
|
|
797
|
+
|
|
798
|
+
| Resource | Rule |
|
|
799
|
+
|----------|------|
|
|
800
|
+
| Every table with user data | Must have explicit `PERMISSIONS` |
|
|
801
|
+
| `DEFINE ACCESS` | Must set `DURATION` — never unlimited sessions |
|
|
802
|
+
| `DEFINE API` endpoints | Must set `PERMISSIONS` on mutation endpoints |
|
|
803
|
+
| System users | Least privilege: use `VIEWER` unless writes needed |
|
|
804
|
+
| Network | `--allow-net` with explicit domains, `--deny-net` for internals |
|
|
805
|
+
|
|
806
|
+
---
|
|
807
|
+
|
|
808
|
+
## 9. Common Anti-Patterns
|
|
809
|
+
|
|
810
|
+
### 1. Using Deprecated DEFINE SCOPE
|
|
811
|
+
|
|
812
|
+
```surql
|
|
813
|
+
-- ❌ REMOVED in 3.0 — will not work
|
|
814
|
+
DEFINE SCOPE user_scope SESSION 2h SIGNUP (...) SIGNIN (...);
|
|
815
|
+
|
|
816
|
+
-- ✅ Use DEFINE ACCESS instead
|
|
817
|
+
DEFINE ACCESS user ON DATABASE TYPE RECORD
|
|
818
|
+
SIGNUP (...) SIGNIN (...)
|
|
819
|
+
DURATION FOR TOKEN 15m, FOR SESSION 2h;
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
### 2. Old COLUMNS Syntax for Indexes
|
|
823
|
+
|
|
824
|
+
```surql
|
|
825
|
+
-- ❌ Deprecated
|
|
826
|
+
DEFINE INDEX email_idx ON TABLE user COLUMNS email UNIQUE;
|
|
827
|
+
|
|
828
|
+
-- ✅ 3.0 syntax
|
|
829
|
+
DEFINE INDEX email_idx ON user FIELDS email UNIQUE;
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
### 3. No Permissions on Tables
|
|
833
|
+
|
|
834
|
+
```surql
|
|
835
|
+
-- ❌ No permissions — record users get NONE access by default,
|
|
836
|
+
-- but system users get FULL access, which may over-grant
|
|
837
|
+
DEFINE TABLE sensitive_data SCHEMAFULL;
|
|
838
|
+
|
|
839
|
+
-- ✅ Explicit permissions
|
|
840
|
+
DEFINE TABLE sensitive_data SCHEMAFULL
|
|
841
|
+
PERMISSIONS
|
|
842
|
+
FOR select WHERE $auth.role = 'admin'
|
|
843
|
+
FOR create, update, delete NONE;
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
### 4. N+1 Query Pattern
|
|
847
|
+
|
|
848
|
+
```surql
|
|
849
|
+
-- ❌ Multiple queries in a loop
|
|
850
|
+
LET $users = SELECT * FROM user;
|
|
851
|
+
FOR $user IN $users {
|
|
852
|
+
SELECT * FROM post WHERE author = $user.id; -- N queries!
|
|
853
|
+
};
|
|
854
|
+
|
|
855
|
+
-- ✅ Single query with graph traversal
|
|
856
|
+
SELECT *, ->authored->post.* AS posts FROM user;
|
|
857
|
+
|
|
858
|
+
-- ✅ Or use subquery
|
|
859
|
+
SELECT *,
|
|
860
|
+
(SELECT * FROM post WHERE author = $parent.id) AS posts
|
|
861
|
+
FROM user;
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
### 5. Unbounded Graph Traversals
|
|
865
|
+
|
|
866
|
+
```surql
|
|
867
|
+
-- ❌ Can traverse the entire graph
|
|
868
|
+
SELECT ->follows->user->follows->user->follows->user.* FROM user:john;
|
|
869
|
+
|
|
870
|
+
-- ✅ Limit depth and results
|
|
871
|
+
SELECT ->follows->user[0:10].name FROM user:john;
|
|
872
|
+
SELECT ->follows->user[WHERE active = true][0:20].* FROM user:john;
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
### 6. Missing Indexes on Queried Fields
|
|
876
|
+
|
|
877
|
+
```surql
|
|
878
|
+
-- ❌ Full table scan
|
|
879
|
+
SELECT * FROM user WHERE email = $email;
|
|
880
|
+
|
|
881
|
+
-- ✅ Create index first
|
|
882
|
+
DEFINE INDEX user_email ON user FIELDS email UNIQUE;
|
|
883
|
+
SELECT * FROM user WHERE email = $email; -- Uses index
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
### 7. Not Cleaning Up LIVE Queries
|
|
887
|
+
|
|
888
|
+
```typescript
|
|
889
|
+
// ❌ Memory leak — subscription never killed
|
|
890
|
+
const uuid = await db.live('user', callback);
|
|
891
|
+
// Component unmounts, page navigates away... subscription leaks
|
|
892
|
+
|
|
893
|
+
// ✅ Always clean up
|
|
894
|
+
const uuid = await db.live('user', callback);
|
|
895
|
+
// On cleanup:
|
|
896
|
+
await db.kill(uuid);
|
|
897
|
+
await db.close();
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
### 8. Plain Text Passwords
|
|
901
|
+
|
|
902
|
+
```surql
|
|
903
|
+
-- ❌ Password stored as plain text
|
|
904
|
+
DEFINE FIELD password ON user TYPE string;
|
|
905
|
+
|
|
906
|
+
-- ✅ Auto-hash on write
|
|
907
|
+
DEFINE FIELD password ON user TYPE string
|
|
908
|
+
VALUE crypto::argon2::generate($value);
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
### 9. Using Futures Instead of Computed Fields
|
|
912
|
+
|
|
913
|
+
```surql
|
|
914
|
+
-- ❌ Removed in 3.0 — futures no longer work
|
|
915
|
+
DEFINE FIELD age ON user VALUE <future> { time::now() - born };
|
|
916
|
+
|
|
917
|
+
-- ✅ Use COMPUTED keyword
|
|
918
|
+
DEFINE FIELD age ON user COMPUTED time::now() - born;
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
---
|
|
922
|
+
|
|
923
|
+
## 10. Migration from 2.x to 3.0
|
|
924
|
+
|
|
925
|
+
### Breaking Changes Checklist
|
|
926
|
+
|
|
927
|
+
| 2.x Syntax | 3.0 Replacement |
|
|
928
|
+
|-------------|----------------|
|
|
929
|
+
| `DEFINE SCOPE name SESSION ...` | `DEFINE ACCESS name ON DATABASE TYPE RECORD ... DURATION ...` |
|
|
930
|
+
| `DEFINE INDEX ... COLUMNS ...` | `DEFINE INDEX ... FIELDS ...` |
|
|
931
|
+
| `<future> { expr }` / futures | `COMPUTED expr` |
|
|
932
|
+
| `scope: 'name'` in SDK signin | `access: 'name'` in SDK signin |
|
|
933
|
+
| Unidirectional record links | Bidirectional with `REFERENCE` keyword |
|
|
934
|
+
| No custom endpoints | `DEFINE API` for HTTP routes |
|
|
935
|
+
| No computed fields | `DEFINE FIELD ... COMPUTED ...` |
|
|
936
|
+
|
|
937
|
+
### Migration Steps
|
|
938
|
+
|
|
939
|
+
1. **Search-and-replace** `DEFINE SCOPE` → `DEFINE ACCESS ... TYPE RECORD`
|
|
940
|
+
2. **Update all indexes** from `COLUMNS` → `FIELDS`
|
|
941
|
+
3. **Replace futures** with `COMPUTED` fields
|
|
942
|
+
4. **Update SDK calls**: `scope:` → `access:` in signin/signup
|
|
943
|
+
5. **Add `REFERENCE`** to record link fields where bidirectional access is needed
|
|
944
|
+
6. **Add `ON DELETE`** handlers to reference fields to define cascade behavior
|
|
945
|
+
7. **Test thoroughly** — auth flows are the most likely breakage point
|