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,640 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: supabase
|
|
3
|
+
description: Comprehensive Supabase skill covering PostgreSQL database, authentication (GoTrue), realtime subscriptions, file storage, edge functions, row-level security, client libraries, database functions, webhooks, and TypeScript type generation. Use when building with Supabase as your backend-as-a-service.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Supabase
|
|
8
|
+
|
|
9
|
+
Open-source Firebase alternative built on PostgreSQL, providing auth, realtime, storage, and edge functions with a unified client library.
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Install and Initialize
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @supabase/supabase-js
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// src/lib/supabase.ts
|
|
21
|
+
import { createClient } from '@supabase/supabase-js';
|
|
22
|
+
import type { Database } from './database.types';
|
|
23
|
+
|
|
24
|
+
export const supabase = createClient<Database>(
|
|
25
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
26
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
|
|
27
|
+
);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Server-Side Client (with Service Role)
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// src/lib/supabase-admin.ts
|
|
34
|
+
import { createClient } from '@supabase/supabase-js';
|
|
35
|
+
import type { Database } from './database.types';
|
|
36
|
+
|
|
37
|
+
// Service role bypasses RLS — use only on server
|
|
38
|
+
export const supabaseAdmin = createClient<Database>(
|
|
39
|
+
process.env.SUPABASE_URL!,
|
|
40
|
+
process.env.SUPABASE_SERVICE_ROLE_KEY!
|
|
41
|
+
);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**CRITICAL**: The service role key bypasses all Row Level Security. Never expose it to the client. Never include it in `NEXT_PUBLIC_*` variables.
|
|
45
|
+
|
|
46
|
+
### Server-Side Client (per-request, with user context)
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// Next.js App Router — server component or route handler
|
|
50
|
+
import { createServerClient } from '@supabase/ssr';
|
|
51
|
+
import { cookies } from 'next/headers';
|
|
52
|
+
import type { Database } from '@/lib/database.types';
|
|
53
|
+
|
|
54
|
+
export function createServerSupabase() {
|
|
55
|
+
const cookieStore = cookies();
|
|
56
|
+
return createServerClient<Database>(
|
|
57
|
+
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
|
58
|
+
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
|
59
|
+
{
|
|
60
|
+
cookies: {
|
|
61
|
+
getAll() {
|
|
62
|
+
return cookieStore.getAll();
|
|
63
|
+
},
|
|
64
|
+
setAll(cookiesToSet) {
|
|
65
|
+
cookiesToSet.forEach(({ name, value, options }) => {
|
|
66
|
+
cookieStore.set(name, value, options);
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Authentication
|
|
76
|
+
|
|
77
|
+
### Email/Password
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Sign up
|
|
81
|
+
const { data, error } = await supabase.auth.signUp({
|
|
82
|
+
email: 'user@example.com',
|
|
83
|
+
password: 'secure-password',
|
|
84
|
+
options: {
|
|
85
|
+
data: { display_name: 'Alice' }, // stored in auth.users.raw_user_meta_data
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Sign in
|
|
90
|
+
const { data, error } = await supabase.auth.signInWithPassword({
|
|
91
|
+
email: 'user@example.com',
|
|
92
|
+
password: 'secure-password',
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Sign out
|
|
96
|
+
const { error } = await supabase.auth.signOut();
|
|
97
|
+
|
|
98
|
+
// Get current user
|
|
99
|
+
const { data: { user } } = await supabase.auth.getUser();
|
|
100
|
+
|
|
101
|
+
// Listen for auth changes
|
|
102
|
+
const { data: { subscription } } = supabase.auth.onAuthStateChange(
|
|
103
|
+
(event, session) => {
|
|
104
|
+
// event: 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED' | 'USER_UPDATED' | 'PASSWORD_RECOVERY'
|
|
105
|
+
console.log(event, session);
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
// Cleanup: subscription.unsubscribe();
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### OAuth Providers
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// Google
|
|
115
|
+
const { data, error } = await supabase.auth.signInWithOAuth({
|
|
116
|
+
provider: 'google',
|
|
117
|
+
options: {
|
|
118
|
+
redirectTo: `${window.location.origin}/auth/callback`,
|
|
119
|
+
queryParams: {
|
|
120
|
+
access_type: 'offline',
|
|
121
|
+
prompt: 'consent',
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// GitHub
|
|
127
|
+
const { data, error } = await supabase.auth.signInWithOAuth({
|
|
128
|
+
provider: 'github',
|
|
129
|
+
options: {
|
|
130
|
+
redirectTo: `${window.location.origin}/auth/callback`,
|
|
131
|
+
scopes: 'read:user user:email',
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Auth Callback Handler (Next.js)
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// app/auth/callback/route.ts
|
|
140
|
+
import { createServerSupabase } from '@/lib/supabase-server';
|
|
141
|
+
import { NextResponse } from 'next/server';
|
|
142
|
+
|
|
143
|
+
export async function GET(request: Request) {
|
|
144
|
+
const { searchParams } = new URL(request.url);
|
|
145
|
+
const code = searchParams.get('code');
|
|
146
|
+
const next = searchParams.get('next') ?? '/dashboard';
|
|
147
|
+
|
|
148
|
+
if (code) {
|
|
149
|
+
const supabase = createServerSupabase();
|
|
150
|
+
const { error } = await supabase.auth.exchangeCodeForSession(code);
|
|
151
|
+
if (!error) {
|
|
152
|
+
return NextResponse.redirect(new URL(next, request.url));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return NextResponse.redirect(new URL('/auth/error', request.url));
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Password Reset
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
// Request reset
|
|
164
|
+
await supabase.auth.resetPasswordForEmail('user@example.com', {
|
|
165
|
+
redirectTo: `${window.location.origin}/auth/reset-password`,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Update password (after redirect)
|
|
169
|
+
await supabase.auth.updateUser({ password: 'new-secure-password' });
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Database Queries
|
|
173
|
+
|
|
174
|
+
### CRUD Operations
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// SELECT
|
|
178
|
+
const { data, error } = await supabase
|
|
179
|
+
.from('posts')
|
|
180
|
+
.select('id, title, content, created_at, author:profiles(name, avatar_url)')
|
|
181
|
+
.eq('published', true)
|
|
182
|
+
.order('created_at', { ascending: false })
|
|
183
|
+
.range(0, 9); // pagination: first 10 rows
|
|
184
|
+
|
|
185
|
+
// INSERT
|
|
186
|
+
const { data, error } = await supabase
|
|
187
|
+
.from('posts')
|
|
188
|
+
.insert({ title: 'New Post', content: 'Body text', author_id: userId })
|
|
189
|
+
.select()
|
|
190
|
+
.single();
|
|
191
|
+
|
|
192
|
+
// UPDATE
|
|
193
|
+
const { data, error } = await supabase
|
|
194
|
+
.from('posts')
|
|
195
|
+
.update({ title: 'Updated Title' })
|
|
196
|
+
.eq('id', postId)
|
|
197
|
+
.select()
|
|
198
|
+
.single();
|
|
199
|
+
|
|
200
|
+
// DELETE
|
|
201
|
+
const { error } = await supabase
|
|
202
|
+
.from('posts')
|
|
203
|
+
.delete()
|
|
204
|
+
.eq('id', postId);
|
|
205
|
+
|
|
206
|
+
// UPSERT
|
|
207
|
+
const { data, error } = await supabase
|
|
208
|
+
.from('profiles')
|
|
209
|
+
.upsert({ id: userId, name: 'Alice', updated_at: new Date().toISOString() })
|
|
210
|
+
.select()
|
|
211
|
+
.single();
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Advanced Queries
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
// Full-text search
|
|
218
|
+
const { data } = await supabase
|
|
219
|
+
.from('posts')
|
|
220
|
+
.select()
|
|
221
|
+
.textSearch('title', 'serverless functions', { type: 'websearch' });
|
|
222
|
+
|
|
223
|
+
// Filter with OR
|
|
224
|
+
const { data } = await supabase
|
|
225
|
+
.from('posts')
|
|
226
|
+
.select()
|
|
227
|
+
.or('status.eq.published,status.eq.featured');
|
|
228
|
+
|
|
229
|
+
// Filter with IN
|
|
230
|
+
const { data } = await supabase
|
|
231
|
+
.from('posts')
|
|
232
|
+
.select()
|
|
233
|
+
.in('category', ['tech', 'science']);
|
|
234
|
+
|
|
235
|
+
// Count without fetching rows
|
|
236
|
+
const { count } = await supabase
|
|
237
|
+
.from('posts')
|
|
238
|
+
.select('*', { count: 'exact', head: true })
|
|
239
|
+
.eq('published', true);
|
|
240
|
+
|
|
241
|
+
// JSON column filtering
|
|
242
|
+
const { data } = await supabase
|
|
243
|
+
.from('posts')
|
|
244
|
+
.select()
|
|
245
|
+
.contains('tags', ['typescript']);
|
|
246
|
+
|
|
247
|
+
// Nested selects (joins via foreign keys)
|
|
248
|
+
const { data } = await supabase
|
|
249
|
+
.from('posts')
|
|
250
|
+
.select(`
|
|
251
|
+
id, title,
|
|
252
|
+
comments (
|
|
253
|
+
id, body,
|
|
254
|
+
author:profiles (name)
|
|
255
|
+
)
|
|
256
|
+
`)
|
|
257
|
+
.eq('id', postId)
|
|
258
|
+
.single();
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Row Level Security (RLS)
|
|
262
|
+
|
|
263
|
+
### Enable and Create Policies
|
|
264
|
+
|
|
265
|
+
```sql
|
|
266
|
+
-- Enable RLS on a table
|
|
267
|
+
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
|
|
268
|
+
|
|
269
|
+
-- Allow anyone to read published posts
|
|
270
|
+
CREATE POLICY "Public can read published posts"
|
|
271
|
+
ON posts FOR SELECT
|
|
272
|
+
USING (published = true);
|
|
273
|
+
|
|
274
|
+
-- Users can read their own drafts
|
|
275
|
+
CREATE POLICY "Users can read own drafts"
|
|
276
|
+
ON posts FOR SELECT
|
|
277
|
+
USING (auth.uid() = author_id);
|
|
278
|
+
|
|
279
|
+
-- Users can insert their own posts
|
|
280
|
+
CREATE POLICY "Users can create posts"
|
|
281
|
+
ON posts FOR INSERT
|
|
282
|
+
WITH CHECK (auth.uid() = author_id);
|
|
283
|
+
|
|
284
|
+
-- Users can update their own posts
|
|
285
|
+
CREATE POLICY "Users can update own posts"
|
|
286
|
+
ON posts FOR UPDATE
|
|
287
|
+
USING (auth.uid() = author_id)
|
|
288
|
+
WITH CHECK (auth.uid() = author_id);
|
|
289
|
+
|
|
290
|
+
-- Users can delete their own posts
|
|
291
|
+
CREATE POLICY "Users can delete own posts"
|
|
292
|
+
ON posts FOR DELETE
|
|
293
|
+
USING (auth.uid() = author_id);
|
|
294
|
+
|
|
295
|
+
-- Admin role can do anything
|
|
296
|
+
CREATE POLICY "Admins have full access"
|
|
297
|
+
ON posts FOR ALL
|
|
298
|
+
USING (
|
|
299
|
+
EXISTS (
|
|
300
|
+
SELECT 1 FROM profiles
|
|
301
|
+
WHERE profiles.id = auth.uid()
|
|
302
|
+
AND profiles.role = 'admin'
|
|
303
|
+
)
|
|
304
|
+
);
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### RLS with JWT Claims
|
|
308
|
+
|
|
309
|
+
```sql
|
|
310
|
+
-- Access based on custom JWT claims (set via supabase.auth.admin.updateUserById)
|
|
311
|
+
CREATE POLICY "Org members can read org data"
|
|
312
|
+
ON org_data FOR SELECT
|
|
313
|
+
USING (
|
|
314
|
+
org_id = (auth.jwt() -> 'app_metadata' ->> 'org_id')::uuid
|
|
315
|
+
);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**CRITICAL**: Always enable RLS on every table that stores user data. Without RLS, the anon key grants unrestricted read/write access to the table.
|
|
319
|
+
|
|
320
|
+
## Realtime Subscriptions
|
|
321
|
+
|
|
322
|
+
### Listen for Changes
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
// Subscribe to all changes on a table
|
|
326
|
+
const channel = supabase
|
|
327
|
+
.channel('posts-changes')
|
|
328
|
+
.on(
|
|
329
|
+
'postgres_changes',
|
|
330
|
+
{ event: '*', schema: 'public', table: 'posts' },
|
|
331
|
+
(payload) => {
|
|
332
|
+
console.log('Change:', payload.eventType, payload.new, payload.old);
|
|
333
|
+
}
|
|
334
|
+
)
|
|
335
|
+
.subscribe();
|
|
336
|
+
|
|
337
|
+
// Filter by specific rows
|
|
338
|
+
const channel = supabase
|
|
339
|
+
.channel('my-posts')
|
|
340
|
+
.on(
|
|
341
|
+
'postgres_changes',
|
|
342
|
+
{
|
|
343
|
+
event: 'UPDATE',
|
|
344
|
+
schema: 'public',
|
|
345
|
+
table: 'posts',
|
|
346
|
+
filter: `author_id=eq.${userId}`,
|
|
347
|
+
},
|
|
348
|
+
(payload) => {
|
|
349
|
+
console.log('Updated:', payload.new);
|
|
350
|
+
}
|
|
351
|
+
)
|
|
352
|
+
.subscribe();
|
|
353
|
+
|
|
354
|
+
// Cleanup
|
|
355
|
+
supabase.removeChannel(channel);
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Broadcast (Ephemeral Messages)
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// Send cursor position to other users
|
|
362
|
+
const channel = supabase.channel('room-1');
|
|
363
|
+
|
|
364
|
+
channel.on('broadcast', { event: 'cursor' }, (payload) => {
|
|
365
|
+
console.log('Cursor:', payload.payload);
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
await channel.subscribe();
|
|
369
|
+
|
|
370
|
+
channel.send({
|
|
371
|
+
type: 'broadcast',
|
|
372
|
+
event: 'cursor',
|
|
373
|
+
payload: { x: 100, y: 200, userId },
|
|
374
|
+
});
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Presence (Online Users)
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
const channel = supabase.channel('room-1');
|
|
381
|
+
|
|
382
|
+
channel.on('presence', { event: 'sync' }, () => {
|
|
383
|
+
const state = channel.presenceState();
|
|
384
|
+
console.log('Online users:', Object.keys(state));
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
channel.on('presence', { event: 'join' }, ({ key, newPresences }) => {
|
|
388
|
+
console.log('Joined:', newPresences);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
channel.on('presence', { event: 'leave' }, ({ key, leftPresences }) => {
|
|
392
|
+
console.log('Left:', leftPresences);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
await channel.subscribe(async (status) => {
|
|
396
|
+
if (status === 'SUBSCRIBED') {
|
|
397
|
+
await channel.track({ user_id: userId, online_at: new Date().toISOString() });
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
## Storage
|
|
403
|
+
|
|
404
|
+
### Upload and Download
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
// Upload file
|
|
408
|
+
const { data, error } = await supabase.storage
|
|
409
|
+
.from('avatars')
|
|
410
|
+
.upload(`${userId}/avatar.png`, file, {
|
|
411
|
+
cacheControl: '3600',
|
|
412
|
+
upsert: true,
|
|
413
|
+
contentType: 'image/png',
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
// Get public URL
|
|
417
|
+
const { data: { publicUrl } } = supabase.storage
|
|
418
|
+
.from('avatars')
|
|
419
|
+
.getPublicUrl(`${userId}/avatar.png`);
|
|
420
|
+
|
|
421
|
+
// Get signed URL (private buckets)
|
|
422
|
+
const { data: { signedUrl }, error } = await supabase.storage
|
|
423
|
+
.from('documents')
|
|
424
|
+
.createSignedUrl(`${userId}/report.pdf`, 3600); // expires in 1 hour
|
|
425
|
+
|
|
426
|
+
// Download file
|
|
427
|
+
const { data, error } = await supabase.storage
|
|
428
|
+
.from('documents')
|
|
429
|
+
.download(`${userId}/report.pdf`);
|
|
430
|
+
|
|
431
|
+
// Delete file
|
|
432
|
+
const { error } = await supabase.storage
|
|
433
|
+
.from('avatars')
|
|
434
|
+
.remove([`${userId}/avatar.png`]);
|
|
435
|
+
|
|
436
|
+
// List files
|
|
437
|
+
const { data, error } = await supabase.storage
|
|
438
|
+
.from('avatars')
|
|
439
|
+
.list(userId, { limit: 100, offset: 0 });
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Storage Policies (RLS for Storage)
|
|
443
|
+
|
|
444
|
+
```sql
|
|
445
|
+
-- Users can upload to their own folder
|
|
446
|
+
CREATE POLICY "Users can upload own avatar"
|
|
447
|
+
ON storage.objects FOR INSERT
|
|
448
|
+
WITH CHECK (
|
|
449
|
+
bucket_id = 'avatars'
|
|
450
|
+
AND (storage.foldername(name))[1] = auth.uid()::text
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
-- Public read access
|
|
454
|
+
CREATE POLICY "Public can read avatars"
|
|
455
|
+
ON storage.objects FOR SELECT
|
|
456
|
+
USING (bucket_id = 'avatars');
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
## Edge Functions (Deno)
|
|
460
|
+
|
|
461
|
+
### Create and Deploy
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
supabase functions new my-function
|
|
465
|
+
supabase functions deploy my-function
|
|
466
|
+
supabase functions serve # local development
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Function Code
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
// supabase/functions/my-function/index.ts
|
|
473
|
+
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
|
|
474
|
+
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
|
|
475
|
+
|
|
476
|
+
serve(async (req) => {
|
|
477
|
+
const supabase = createClient(
|
|
478
|
+
Deno.env.get('SUPABASE_URL')!,
|
|
479
|
+
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
// Get user from auth header
|
|
483
|
+
const authHeader = req.headers.get('Authorization');
|
|
484
|
+
if (!authHeader) {
|
|
485
|
+
return new Response(JSON.stringify({ error: 'No auth header' }), {
|
|
486
|
+
status: 401,
|
|
487
|
+
headers: { 'Content-Type': 'application/json' },
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
const { data: { user }, error } = await supabase.auth.getUser(
|
|
492
|
+
authHeader.replace('Bearer ', '')
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
if (error || !user) {
|
|
496
|
+
return new Response(JSON.stringify({ error: 'Invalid token' }), {
|
|
497
|
+
status: 401,
|
|
498
|
+
headers: { 'Content-Type': 'application/json' },
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return new Response(JSON.stringify({ message: `Hello ${user.email}` }), {
|
|
503
|
+
headers: { 'Content-Type': 'application/json' },
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Invoke from Client
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
const { data, error } = await supabase.functions.invoke('my-function', {
|
|
512
|
+
body: { name: 'Alice' },
|
|
513
|
+
headers: { 'x-custom-header': 'value' },
|
|
514
|
+
});
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
## Database Functions and Triggers
|
|
518
|
+
|
|
519
|
+
### PostgreSQL Functions
|
|
520
|
+
|
|
521
|
+
```sql
|
|
522
|
+
-- Function called via RPC
|
|
523
|
+
CREATE OR REPLACE FUNCTION get_user_stats(target_user_id uuid)
|
|
524
|
+
RETURNS json
|
|
525
|
+
LANGUAGE plpgsql
|
|
526
|
+
SECURITY DEFINER -- runs with function creator's privileges
|
|
527
|
+
SET search_path = public
|
|
528
|
+
AS $$
|
|
529
|
+
DECLARE
|
|
530
|
+
result json;
|
|
531
|
+
BEGIN
|
|
532
|
+
SELECT json_build_object(
|
|
533
|
+
'post_count', (SELECT count(*) FROM posts WHERE author_id = target_user_id),
|
|
534
|
+
'comment_count', (SELECT count(*) FROM comments WHERE author_id = target_user_id)
|
|
535
|
+
) INTO result;
|
|
536
|
+
RETURN result;
|
|
537
|
+
END;
|
|
538
|
+
$$;
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
// Call via RPC
|
|
543
|
+
const { data, error } = await supabase.rpc('get_user_stats', {
|
|
544
|
+
target_user_id: userId,
|
|
545
|
+
});
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Database Triggers
|
|
549
|
+
|
|
550
|
+
```sql
|
|
551
|
+
-- Auto-update updated_at timestamp
|
|
552
|
+
CREATE OR REPLACE FUNCTION update_modified_column()
|
|
553
|
+
RETURNS trigger
|
|
554
|
+
LANGUAGE plpgsql
|
|
555
|
+
AS $$
|
|
556
|
+
BEGIN
|
|
557
|
+
NEW.updated_at = now();
|
|
558
|
+
RETURN NEW;
|
|
559
|
+
END;
|
|
560
|
+
$$;
|
|
561
|
+
|
|
562
|
+
CREATE TRIGGER set_updated_at
|
|
563
|
+
BEFORE UPDATE ON posts
|
|
564
|
+
FOR EACH ROW
|
|
565
|
+
EXECUTE FUNCTION update_modified_column();
|
|
566
|
+
|
|
567
|
+
-- Create profile on user signup
|
|
568
|
+
CREATE OR REPLACE FUNCTION handle_new_user()
|
|
569
|
+
RETURNS trigger
|
|
570
|
+
LANGUAGE plpgsql
|
|
571
|
+
SECURITY DEFINER
|
|
572
|
+
SET search_path = public
|
|
573
|
+
AS $$
|
|
574
|
+
BEGIN
|
|
575
|
+
INSERT INTO profiles (id, name, avatar_url)
|
|
576
|
+
VALUES (
|
|
577
|
+
NEW.id,
|
|
578
|
+
NEW.raw_user_meta_data ->> 'display_name',
|
|
579
|
+
NEW.raw_user_meta_data ->> 'avatar_url'
|
|
580
|
+
);
|
|
581
|
+
RETURN NEW;
|
|
582
|
+
END;
|
|
583
|
+
$$;
|
|
584
|
+
|
|
585
|
+
CREATE TRIGGER on_auth_user_created
|
|
586
|
+
AFTER INSERT ON auth.users
|
|
587
|
+
FOR EACH ROW
|
|
588
|
+
EXECUTE FUNCTION handle_new_user();
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
## TypeScript Type Generation
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
# Generate types from your database schema
|
|
595
|
+
npx supabase gen types typescript --project-id YOUR_PROJECT_ID > src/lib/database.types.ts
|
|
596
|
+
|
|
597
|
+
# Or from local database
|
|
598
|
+
npx supabase gen types typescript --local > src/lib/database.types.ts
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
The generated types integrate with the client:
|
|
602
|
+
|
|
603
|
+
```typescript
|
|
604
|
+
import type { Database } from './database.types';
|
|
605
|
+
|
|
606
|
+
type Post = Database['public']['Tables']['posts']['Row'];
|
|
607
|
+
type PostInsert = Database['public']['Tables']['posts']['Insert'];
|
|
608
|
+
type PostUpdate = Database['public']['Tables']['posts']['Update'];
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
## CLI Commands
|
|
612
|
+
|
|
613
|
+
```bash
|
|
614
|
+
supabase init # initialize project
|
|
615
|
+
supabase start # start local dev environment
|
|
616
|
+
supabase stop # stop local dev environment
|
|
617
|
+
supabase db reset # reset local database
|
|
618
|
+
supabase db push # push migrations to remote
|
|
619
|
+
supabase db pull # pull schema from remote
|
|
620
|
+
supabase migration new <name> # create new migration
|
|
621
|
+
supabase gen types typescript # generate TypeScript types
|
|
622
|
+
supabase functions serve # serve edge functions locally
|
|
623
|
+
supabase functions deploy <name> # deploy edge function
|
|
624
|
+
supabase secrets set KEY=value # set edge function secret
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
## Anti-Patterns
|
|
628
|
+
|
|
629
|
+
| Anti-Pattern | Correct Approach |
|
|
630
|
+
|-------------|-----------------|
|
|
631
|
+
| Using service role key on the client | Use anon key on client, service role only on server |
|
|
632
|
+
| Tables without RLS enabled | Enable RLS on every table with user data |
|
|
633
|
+
| `SELECT *` in production queries | Select only needed columns for performance |
|
|
634
|
+
| Storing files without storage policies | Always define storage policies for upload/read/delete |
|
|
635
|
+
| Not using TypeScript type generation | Run `supabase gen types` after every schema change |
|
|
636
|
+
| Polling for changes instead of realtime | Use `postgres_changes` subscription for live updates |
|
|
637
|
+
| Putting business logic in RLS policies | Keep RLS policies simple, put complex logic in database functions |
|
|
638
|
+
| Ignoring the `error` return value | Always check `error` before using `data` |
|
|
639
|
+
| Using `auth.uid()` without RLS | `auth.uid()` only works inside RLS policies and security definer functions |
|
|
640
|
+
| Embedding secrets in edge functions source | Use `supabase secrets set` for edge function environment variables |
|