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,744 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prisma
|
|
3
|
+
description: |
|
|
4
|
+
Build with Prisma ORM — schema-first database access with type-safe queries, relations, migrations, and transactions. Use when: defining database schemas (models, relations, enums), writing queries (findMany, create, update, upsert, delete), filtering/sorting/pagination, managing relations (include, select, nested writes), running migrations, implementing transactions, using raw SQL, optimizing performance (select vs include, N+1), testing with mocks, or deploying with Prisma Accelerate.
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Prisma ORM
|
|
9
|
+
|
|
10
|
+
**Status**: Production Ready
|
|
11
|
+
**Last Updated**: 2026-02-16
|
|
12
|
+
**Package**: `prisma@6.x`, `@prisma/client@6.x`
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm add @prisma/client
|
|
20
|
+
pnpm add -D prisma
|
|
21
|
+
|
|
22
|
+
# Initialize (creates prisma/schema.prisma)
|
|
23
|
+
npx prisma init
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Database Connection
|
|
27
|
+
|
|
28
|
+
```prisma
|
|
29
|
+
// prisma/schema.prisma
|
|
30
|
+
generator client {
|
|
31
|
+
provider = "prisma-client-js"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
datasource db {
|
|
35
|
+
provider = "postgresql" // or "mysql", "sqlite", "mongodb", "cockroachdb"
|
|
36
|
+
url = env("DATABASE_URL")
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# .env
|
|
42
|
+
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Client Singleton
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// src/lib/prisma.ts
|
|
49
|
+
import { PrismaClient } from "@prisma/client";
|
|
50
|
+
|
|
51
|
+
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
|
52
|
+
|
|
53
|
+
export const prisma =
|
|
54
|
+
globalForPrisma.prisma ??
|
|
55
|
+
new PrismaClient({
|
|
56
|
+
log: process.env.NODE_ENV === "development" ? ["query", "warn", "error"] : ["error"],
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This singleton pattern prevents creating multiple PrismaClient instances during hot reload in development.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Schema Definition
|
|
67
|
+
|
|
68
|
+
### Models and Fields
|
|
69
|
+
|
|
70
|
+
```prisma
|
|
71
|
+
model User {
|
|
72
|
+
id String @id @default(cuid())
|
|
73
|
+
email String @unique
|
|
74
|
+
name String?
|
|
75
|
+
role Role @default(USER)
|
|
76
|
+
posts Post[]
|
|
77
|
+
profile Profile?
|
|
78
|
+
createdAt DateTime @default(now())
|
|
79
|
+
updatedAt DateTime @updatedAt
|
|
80
|
+
|
|
81
|
+
@@index([email])
|
|
82
|
+
@@map("users") // Custom table name
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
model Post {
|
|
86
|
+
id String @id @default(cuid())
|
|
87
|
+
title String @db.VarChar(255)
|
|
88
|
+
content String?
|
|
89
|
+
published Boolean @default(false)
|
|
90
|
+
author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
|
|
91
|
+
authorId String
|
|
92
|
+
categories Category[]
|
|
93
|
+
tags String[] // Array field (PostgreSQL)
|
|
94
|
+
metadata Json? // JSON field
|
|
95
|
+
publishedAt DateTime?
|
|
96
|
+
createdAt DateTime @default(now())
|
|
97
|
+
|
|
98
|
+
@@index([authorId, published])
|
|
99
|
+
@@index([createdAt(sort: Desc)])
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
model Profile {
|
|
103
|
+
id String @id @default(cuid())
|
|
104
|
+
bio String?
|
|
105
|
+
avatar String?
|
|
106
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
107
|
+
userId String @unique
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
model Category {
|
|
111
|
+
id String @id @default(cuid())
|
|
112
|
+
name String @unique
|
|
113
|
+
posts Post[]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
enum Role {
|
|
117
|
+
USER
|
|
118
|
+
ADMIN
|
|
119
|
+
MODERATOR
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Relations Summary
|
|
124
|
+
|
|
125
|
+
| Type | Prisma Syntax | Example |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| One-to-one | `@relation` with `@unique` on FK | User <-> Profile |
|
|
128
|
+
| One-to-many | `@relation` with FK on "many" side | User -> Post[] |
|
|
129
|
+
| Many-to-many | Implicit join table (array on both sides) | Post <-> Category |
|
|
130
|
+
| Self-relation | Same model referenced | User -> User (followers) |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Prisma Client Queries
|
|
135
|
+
|
|
136
|
+
### Read Operations
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { prisma } from "@/lib/prisma";
|
|
140
|
+
|
|
141
|
+
// Find many with filtering, sorting, pagination
|
|
142
|
+
const posts = await prisma.post.findMany({
|
|
143
|
+
where: {
|
|
144
|
+
published: true,
|
|
145
|
+
author: { role: "ADMIN" }, // Filter through relation
|
|
146
|
+
title: { contains: "prisma", mode: "insensitive" },
|
|
147
|
+
createdAt: { gte: new Date("2024-01-01") },
|
|
148
|
+
OR: [
|
|
149
|
+
{ title: { contains: "tutorial" } },
|
|
150
|
+
{ content: { contains: "guide" } },
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
orderBy: [
|
|
154
|
+
{ publishedAt: "desc" },
|
|
155
|
+
{ title: "asc" },
|
|
156
|
+
],
|
|
157
|
+
skip: 0, // Offset pagination
|
|
158
|
+
take: 20, // Limit
|
|
159
|
+
distinct: ["authorId"], // Unique authors only
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Find unique (by unique field or compound unique)
|
|
163
|
+
const user = await prisma.user.findUnique({
|
|
164
|
+
where: { email: "user@example.com" },
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Find unique or throw
|
|
168
|
+
const user = await prisma.user.findUniqueOrThrow({
|
|
169
|
+
where: { id: userId },
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Find first matching
|
|
173
|
+
const post = await prisma.post.findFirst({
|
|
174
|
+
where: { published: true },
|
|
175
|
+
orderBy: { createdAt: "desc" },
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Count
|
|
179
|
+
const count = await prisma.post.count({
|
|
180
|
+
where: { published: true },
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Aggregate
|
|
184
|
+
const stats = await prisma.post.aggregate({
|
|
185
|
+
_count: true,
|
|
186
|
+
_avg: { views: true },
|
|
187
|
+
_max: { views: true },
|
|
188
|
+
where: { published: true },
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Group by
|
|
192
|
+
const postsByAuthor = await prisma.post.groupBy({
|
|
193
|
+
by: ["authorId"],
|
|
194
|
+
_count: { id: true },
|
|
195
|
+
orderBy: { _count: { id: "desc" } },
|
|
196
|
+
having: { id: { _count: { gt: 5 } } },
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Write Operations
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// Create
|
|
204
|
+
const user = await prisma.user.create({
|
|
205
|
+
data: {
|
|
206
|
+
email: "new@example.com",
|
|
207
|
+
name: "New User",
|
|
208
|
+
profile: {
|
|
209
|
+
create: { bio: "Hello world" }, // Nested create
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
include: { profile: true }, // Return with relation
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// Create many
|
|
216
|
+
const result = await prisma.user.createMany({
|
|
217
|
+
data: [
|
|
218
|
+
{ email: "a@example.com", name: "User A" },
|
|
219
|
+
{ email: "b@example.com", name: "User B" },
|
|
220
|
+
],
|
|
221
|
+
skipDuplicates: true, // Ignore duplicate key errors
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// Update
|
|
225
|
+
const updated = await prisma.post.update({
|
|
226
|
+
where: { id: postId },
|
|
227
|
+
data: {
|
|
228
|
+
title: "Updated Title",
|
|
229
|
+
published: true,
|
|
230
|
+
publishedAt: new Date(),
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Update many
|
|
235
|
+
const result = await prisma.post.updateMany({
|
|
236
|
+
where: { authorId: userId, published: false },
|
|
237
|
+
data: { published: true },
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Upsert (create if not exists, update if exists)
|
|
241
|
+
const user = await prisma.user.upsert({
|
|
242
|
+
where: { email: "user@example.com" },
|
|
243
|
+
update: { name: "Updated Name" },
|
|
244
|
+
create: { email: "user@example.com", name: "New Name" },
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
// Delete
|
|
248
|
+
await prisma.post.delete({ where: { id: postId } });
|
|
249
|
+
|
|
250
|
+
// Delete many
|
|
251
|
+
await prisma.post.deleteMany({
|
|
252
|
+
where: { authorId: userId, published: false },
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Relations (include vs select)
|
|
259
|
+
|
|
260
|
+
### include — Fetch Whole Related Objects
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
const user = await prisma.user.findUnique({
|
|
264
|
+
where: { id: userId },
|
|
265
|
+
include: {
|
|
266
|
+
posts: {
|
|
267
|
+
where: { published: true },
|
|
268
|
+
orderBy: { createdAt: "desc" },
|
|
269
|
+
take: 10,
|
|
270
|
+
},
|
|
271
|
+
profile: true,
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
// user.posts is Post[] with ALL fields
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### select — Fetch Only Specific Fields
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
const user = await prisma.user.findUnique({
|
|
281
|
+
where: { id: userId },
|
|
282
|
+
select: {
|
|
283
|
+
id: true,
|
|
284
|
+
name: true,
|
|
285
|
+
email: true,
|
|
286
|
+
posts: {
|
|
287
|
+
select: { id: true, title: true },
|
|
288
|
+
where: { published: true },
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
// user has ONLY id, name, email, posts (with only id, title)
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**Key decision**: Use `select` when you need a few fields (leaner query, less data). Use `include` when you need all fields plus relations.
|
|
296
|
+
|
|
297
|
+
### Nested Writes
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
// Create user with related records in one transaction
|
|
301
|
+
const user = await prisma.user.create({
|
|
302
|
+
data: {
|
|
303
|
+
email: "author@example.com",
|
|
304
|
+
name: "Author",
|
|
305
|
+
profile: { create: { bio: "Writer" } },
|
|
306
|
+
posts: {
|
|
307
|
+
create: [
|
|
308
|
+
{ title: "First Post", content: "Hello" },
|
|
309
|
+
{ title: "Second Post", content: "World" },
|
|
310
|
+
],
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
include: { posts: true, profile: true },
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// Connect existing related records
|
|
317
|
+
const post = await prisma.post.create({
|
|
318
|
+
data: {
|
|
319
|
+
title: "New Post",
|
|
320
|
+
author: { connect: { id: authorId } },
|
|
321
|
+
categories: {
|
|
322
|
+
connect: [{ id: "cat1" }, { id: "cat2" }], // Connect existing categories
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
// Disconnect, set, connectOrCreate
|
|
328
|
+
await prisma.post.update({
|
|
329
|
+
where: { id: postId },
|
|
330
|
+
data: {
|
|
331
|
+
categories: {
|
|
332
|
+
set: [{ id: "cat1" }], // Replace all connections
|
|
333
|
+
disconnect: [{ id: "cat2" }], // Remove connection
|
|
334
|
+
connectOrCreate: { // Connect or create if not exists
|
|
335
|
+
where: { name: "New Category" },
|
|
336
|
+
create: { name: "New Category" },
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Transactions
|
|
346
|
+
|
|
347
|
+
### Sequential (Batch) Transactions
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
// All operations succeed or all fail
|
|
351
|
+
const [user, post] = await prisma.$transaction([
|
|
352
|
+
prisma.user.create({ data: { email: "a@b.com", name: "A" } }),
|
|
353
|
+
prisma.post.create({ data: { title: "Post", authorId: "existing-id" } }),
|
|
354
|
+
]);
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Interactive Transactions
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
const result = await prisma.$transaction(async (tx) => {
|
|
361
|
+
// Use tx instead of prisma inside the transaction
|
|
362
|
+
const user = await tx.user.findUniqueOrThrow({ where: { id: userId } });
|
|
363
|
+
|
|
364
|
+
if (user.balance < amount) {
|
|
365
|
+
throw new Error("Insufficient balance"); // Rolls back entire transaction
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const updatedUser = await tx.user.update({
|
|
369
|
+
where: { id: userId },
|
|
370
|
+
data: { balance: { decrement: amount } },
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const payment = await tx.payment.create({
|
|
374
|
+
data: { userId, amount, status: "completed" },
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
return { user: updatedUser, payment };
|
|
378
|
+
}, {
|
|
379
|
+
maxWait: 5000, // Max time to wait for transaction slot
|
|
380
|
+
timeout: 10000, // Max transaction duration
|
|
381
|
+
isolationLevel: "Serializable", // Optional: default is ReadCommitted
|
|
382
|
+
});
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Migrations
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
# Create and apply migration (development)
|
|
391
|
+
npx prisma migrate dev --name add_user_role
|
|
392
|
+
|
|
393
|
+
# Apply migrations (production — CI/CD)
|
|
394
|
+
npx prisma migrate deploy
|
|
395
|
+
|
|
396
|
+
# Reset database (drops all data!)
|
|
397
|
+
npx prisma migrate reset
|
|
398
|
+
|
|
399
|
+
# Check migration status
|
|
400
|
+
npx prisma migrate status
|
|
401
|
+
|
|
402
|
+
# Resolve failed migration
|
|
403
|
+
npx prisma migrate resolve --applied "20240101000000_failed_migration"
|
|
404
|
+
|
|
405
|
+
# Generate client after schema changes (no migration)
|
|
406
|
+
npx prisma generate
|
|
407
|
+
|
|
408
|
+
# Introspect existing database into schema
|
|
409
|
+
npx prisma db pull
|
|
410
|
+
|
|
411
|
+
# Push schema changes without migration (prototyping)
|
|
412
|
+
npx prisma db push
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## Seeding
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
// prisma/seed.ts
|
|
421
|
+
import { PrismaClient } from "@prisma/client";
|
|
422
|
+
|
|
423
|
+
const prisma = new PrismaClient();
|
|
424
|
+
|
|
425
|
+
async function main() {
|
|
426
|
+
// Upsert to make seeding idempotent
|
|
427
|
+
const admin = await prisma.user.upsert({
|
|
428
|
+
where: { email: "admin@example.com" },
|
|
429
|
+
update: {},
|
|
430
|
+
create: {
|
|
431
|
+
email: "admin@example.com",
|
|
432
|
+
name: "Admin",
|
|
433
|
+
role: "ADMIN",
|
|
434
|
+
profile: { create: { bio: "System administrator" } },
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
console.log({ admin });
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
main()
|
|
442
|
+
.catch((e) => {
|
|
443
|
+
console.error(e);
|
|
444
|
+
process.exit(1);
|
|
445
|
+
})
|
|
446
|
+
.finally(async () => {
|
|
447
|
+
await prisma.$disconnect();
|
|
448
|
+
});
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
```json
|
|
452
|
+
// package.json
|
|
453
|
+
{
|
|
454
|
+
"prisma": {
|
|
455
|
+
"seed": "tsx prisma/seed.ts"
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
```bash
|
|
461
|
+
npx prisma db seed
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## Raw Queries
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
// Typed raw query
|
|
470
|
+
const users = await prisma.$queryRaw<User[]>`
|
|
471
|
+
SELECT id, email, name
|
|
472
|
+
FROM users
|
|
473
|
+
WHERE role = ${role}
|
|
474
|
+
ORDER BY created_at DESC
|
|
475
|
+
LIMIT ${limit}
|
|
476
|
+
`;
|
|
477
|
+
|
|
478
|
+
// Execute raw (INSERT, UPDATE, DELETE) — returns affected rows count
|
|
479
|
+
const affected = await prisma.$executeRaw`
|
|
480
|
+
UPDATE users SET last_login = NOW() WHERE id = ${userId}
|
|
481
|
+
`;
|
|
482
|
+
|
|
483
|
+
// Unsafe raw (for dynamic table/column names — use with extreme caution)
|
|
484
|
+
import { Prisma } from "@prisma/client";
|
|
485
|
+
|
|
486
|
+
const column = Prisma.raw(sanitizedColumnName);
|
|
487
|
+
const result = await prisma.$queryRawUnsafe(
|
|
488
|
+
`SELECT ${column} FROM users WHERE id = $1`,
|
|
489
|
+
userId
|
|
490
|
+
);
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## Middleware
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
// Query middleware — runs before/after queries
|
|
499
|
+
prisma.$use(async (params, next) => {
|
|
500
|
+
// Soft delete: convert delete to update
|
|
501
|
+
if (params.action === "delete") {
|
|
502
|
+
params.action = "update";
|
|
503
|
+
params.args.data = { deletedAt: new Date() };
|
|
504
|
+
}
|
|
505
|
+
if (params.action === "deleteMany") {
|
|
506
|
+
params.action = "updateMany";
|
|
507
|
+
params.args.data = { deletedAt: new Date() };
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Auto-filter soft-deleted records
|
|
511
|
+
if (params.action === "findMany" || params.action === "findFirst") {
|
|
512
|
+
if (!params.args.where) params.args.where = {};
|
|
513
|
+
params.args.where.deletedAt = null;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
const before = Date.now();
|
|
517
|
+
const result = await next(params);
|
|
518
|
+
const after = Date.now();
|
|
519
|
+
|
|
520
|
+
console.log(`${params.model}.${params.action} took ${after - before}ms`);
|
|
521
|
+
|
|
522
|
+
return result;
|
|
523
|
+
});
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## Type Generation and Inference
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
import { Prisma } from "@prisma/client";
|
|
532
|
+
|
|
533
|
+
// Infer types from Prisma schema
|
|
534
|
+
type UserWithPosts = Prisma.UserGetPayload<{
|
|
535
|
+
include: { posts: true; profile: true };
|
|
536
|
+
}>;
|
|
537
|
+
|
|
538
|
+
// Validator for create input
|
|
539
|
+
type UserCreateInput = Prisma.UserCreateInput;
|
|
540
|
+
|
|
541
|
+
// Select specific fields
|
|
542
|
+
type UserSummary = Prisma.UserGetPayload<{
|
|
543
|
+
select: { id: true; name: true; email: true };
|
|
544
|
+
}>;
|
|
545
|
+
|
|
546
|
+
// Use with Zod for runtime validation
|
|
547
|
+
import { z } from "zod";
|
|
548
|
+
|
|
549
|
+
const CreateUserSchema = z.object({
|
|
550
|
+
email: z.string().email(),
|
|
551
|
+
name: z.string().min(2).max(100),
|
|
552
|
+
role: z.enum(["USER", "ADMIN", "MODERATOR"]).default("USER"),
|
|
553
|
+
}) satisfies z.ZodType<Prisma.UserCreateInput>;
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
---
|
|
557
|
+
|
|
558
|
+
## Connection Pooling
|
|
559
|
+
|
|
560
|
+
```bash
|
|
561
|
+
# PostgreSQL — connection_limit controls pool size per PrismaClient instance
|
|
562
|
+
DATABASE_URL="postgresql://user:pass@host:5432/db?connection_limit=10&pool_timeout=10"
|
|
563
|
+
|
|
564
|
+
# For serverless (Vercel, Lambda) — use external pooler
|
|
565
|
+
# PgBouncer or Prisma Accelerate
|
|
566
|
+
DATABASE_URL="prisma://accelerate.prisma-data.net/?api_key=..."
|
|
567
|
+
DIRECT_URL="postgresql://user:pass@host:5432/db" # For migrations
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
```prisma
|
|
571
|
+
datasource db {
|
|
572
|
+
provider = "postgresql"
|
|
573
|
+
url = env("DATABASE_URL")
|
|
574
|
+
directUrl = env("DIRECT_URL") // Used for migrations (bypasses pooler)
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## Prisma Accelerate (Edge / Caching)
|
|
581
|
+
|
|
582
|
+
```bash
|
|
583
|
+
pnpm add @prisma/extension-accelerate
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
```typescript
|
|
587
|
+
import { PrismaClient } from "@prisma/client/edge";
|
|
588
|
+
import { withAccelerate } from "@prisma/extension-accelerate";
|
|
589
|
+
|
|
590
|
+
const prisma = new PrismaClient().$extends(withAccelerate());
|
|
591
|
+
|
|
592
|
+
// Query with caching
|
|
593
|
+
const posts = await prisma.post.findMany({
|
|
594
|
+
where: { published: true },
|
|
595
|
+
cacheStrategy: {
|
|
596
|
+
ttl: 60, // Cache for 60 seconds
|
|
597
|
+
swr: 120, // Serve stale while revalidating for 120 seconds
|
|
598
|
+
},
|
|
599
|
+
});
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
---
|
|
603
|
+
|
|
604
|
+
## Testing Patterns
|
|
605
|
+
|
|
606
|
+
### Mock Prisma Client
|
|
607
|
+
|
|
608
|
+
```typescript
|
|
609
|
+
// src/lib/__mocks__/prisma.ts
|
|
610
|
+
import { PrismaClient } from "@prisma/client";
|
|
611
|
+
import { mockDeep, DeepMockProxy } from "jest-mock-extended";
|
|
612
|
+
|
|
613
|
+
export const prismaMock = mockDeep<PrismaClient>();
|
|
614
|
+
|
|
615
|
+
// In test
|
|
616
|
+
import { prismaMock } from "@/lib/__mocks__/prisma";
|
|
617
|
+
|
|
618
|
+
vi.mock("@/lib/prisma", () => ({ prisma: prismaMock }));
|
|
619
|
+
|
|
620
|
+
test("creates user", async () => {
|
|
621
|
+
const mockUser = { id: "1", email: "test@example.com", name: "Test" };
|
|
622
|
+
prismaMock.user.create.mockResolvedValue(mockUser as any);
|
|
623
|
+
|
|
624
|
+
const result = await createUser("test@example.com", "Test");
|
|
625
|
+
expect(result.email).toBe("test@example.com");
|
|
626
|
+
expect(prismaMock.user.create).toHaveBeenCalledWith({
|
|
627
|
+
data: expect.objectContaining({ email: "test@example.com" }),
|
|
628
|
+
});
|
|
629
|
+
});
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### Integration Tests (Real Database)
|
|
633
|
+
|
|
634
|
+
```typescript
|
|
635
|
+
// Use a test database or docker container
|
|
636
|
+
import { PrismaClient } from "@prisma/client";
|
|
637
|
+
|
|
638
|
+
const prisma = new PrismaClient({
|
|
639
|
+
datasources: { db: { url: process.env.TEST_DATABASE_URL } },
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
beforeEach(async () => {
|
|
643
|
+
// Clean tables before each test (order matters for FK constraints)
|
|
644
|
+
await prisma.post.deleteMany();
|
|
645
|
+
await prisma.user.deleteMany();
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
afterAll(async () => {
|
|
649
|
+
await prisma.$disconnect();
|
|
650
|
+
});
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
---
|
|
654
|
+
|
|
655
|
+
## Performance Considerations
|
|
656
|
+
|
|
657
|
+
### select vs include
|
|
658
|
+
|
|
659
|
+
```typescript
|
|
660
|
+
// BAD — fetches ALL fields including large ones you do not need
|
|
661
|
+
const users = await prisma.user.findMany({
|
|
662
|
+
include: { posts: true },
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
// GOOD — fetch only what you need
|
|
666
|
+
const users = await prisma.user.findMany({
|
|
667
|
+
select: {
|
|
668
|
+
id: true,
|
|
669
|
+
name: true,
|
|
670
|
+
_count: { select: { posts: true } }, // Just the count, not all posts
|
|
671
|
+
},
|
|
672
|
+
});
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### Avoiding N+1
|
|
676
|
+
|
|
677
|
+
```typescript
|
|
678
|
+
// BAD — N+1 queries
|
|
679
|
+
const users = await prisma.user.findMany();
|
|
680
|
+
for (const user of users) {
|
|
681
|
+
const posts = await prisma.post.findMany({ where: { authorId: user.id } });
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// GOOD — single query with include
|
|
685
|
+
const users = await prisma.user.findMany({
|
|
686
|
+
include: { posts: true },
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
// GOOD — separate batch query (for large datasets)
|
|
690
|
+
const users = await prisma.user.findMany();
|
|
691
|
+
const userIds = users.map((u) => u.id);
|
|
692
|
+
const posts = await prisma.post.findMany({
|
|
693
|
+
where: { authorId: { in: userIds } },
|
|
694
|
+
});
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
### Cursor-Based Pagination (Better Than Offset)
|
|
698
|
+
|
|
699
|
+
```typescript
|
|
700
|
+
const posts = await prisma.post.findMany({
|
|
701
|
+
take: 20,
|
|
702
|
+
cursor: lastPostId ? { id: lastPostId } : undefined,
|
|
703
|
+
skip: lastPostId ? 1 : 0, // Skip the cursor record itself
|
|
704
|
+
orderBy: { createdAt: "desc" },
|
|
705
|
+
});
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
---
|
|
709
|
+
|
|
710
|
+
## Anti-Patterns
|
|
711
|
+
|
|
712
|
+
| Anti-Pattern | Why It Breaks | Correct Approach |
|
|
713
|
+
|---|---|---|
|
|
714
|
+
| Creating PrismaClient per request | Exhausts DB connections | Use singleton pattern |
|
|
715
|
+
| Using `include` for everything | Over-fetching, slow queries | Use `select` for what you need |
|
|
716
|
+
| N+1 queries in loops | Performance disaster at scale | Use `include`, `in` filter, or batch |
|
|
717
|
+
| Not handling `$disconnect()` in scripts | Connection pool exhaustion | Always disconnect in finally block |
|
|
718
|
+
| Using `db push` in production | No migration history, data loss risk | Use `prisma migrate deploy` |
|
|
719
|
+
| Raw SQL for queries Prisma handles | Loses type safety, harder to maintain | Use Prisma Client API unless SQL is required |
|
|
720
|
+
| Offset pagination on large datasets | Gets slower with higher offsets | Use cursor-based pagination |
|
|
721
|
+
| Not using `@updatedAt` | Manual timestamp management | Add `updatedAt DateTime @updatedAt` |
|
|
722
|
+
| Ignoring `skipDuplicates` in createMany | Crashes on unique constraint violations | Use `skipDuplicates: true` or upsert |
|
|
723
|
+
| Not setting `onDelete` on relations | Orphaned records when parent deleted | Set `onDelete: Cascade` or `SetNull` explicitly |
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
727
|
+
## CLI Reference
|
|
728
|
+
|
|
729
|
+
```bash
|
|
730
|
+
npx prisma generate # Regenerate Prisma Client
|
|
731
|
+
npx prisma migrate dev # Create + apply migration (dev)
|
|
732
|
+
npx prisma migrate deploy # Apply pending migrations (prod)
|
|
733
|
+
npx prisma migrate reset # Reset database (dev only)
|
|
734
|
+
npx prisma db push # Push schema without migration (prototyping)
|
|
735
|
+
npx prisma db pull # Introspect existing DB
|
|
736
|
+
npx prisma db seed # Run seed script
|
|
737
|
+
npx prisma studio # Open visual DB browser (localhost:5555)
|
|
738
|
+
npx prisma format # Format schema file
|
|
739
|
+
npx prisma validate # Validate schema syntax
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
---
|
|
743
|
+
|
|
744
|
+
**Last verified**: 2026-02-16 | **Skill version**: 1.0.0
|