agileflow 4.0.0-alpha.2 → 4.0.0-alpha.21
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/CHANGELOG.md +51 -0
- package/content/plugins/accessibility/plugin.yaml +14 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/SKILL.md +392 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/references/aria-patterns.md +528 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/references/testing-checklist.md +457 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/references/wcag-guide.md +683 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/workflows/audit-page.md +310 -0
- package/content/plugins/accessibility/skills/agileflow-accessibility/workflows/implement-accessible-component.md +479 -0
- package/content/plugins/ads/agents/ads-audit-budget.md +185 -0
- package/content/plugins/ads/agents/ads-audit-compliance.md +171 -0
- package/content/plugins/ads/agents/ads-audit-creative.md +168 -0
- package/content/plugins/ads/agents/ads-audit-google.md +227 -0
- package/content/plugins/ads/agents/ads-audit-meta.md +184 -0
- package/content/plugins/ads/agents/ads-audit-tracking.md +205 -0
- package/content/plugins/ads/agents/ads-consensus.md +410 -0
- package/content/plugins/ads/agents/ads-generate.md +152 -0
- package/content/plugins/ads/agents/ads-performance-tracker.md +212 -0
- package/content/plugins/ads/plugin.yaml +23 -4
- package/content/plugins/ads/skills/agileflow-ads/SKILL.md +218 -0
- package/content/plugins/ads/skills/agileflow-ads/references/ad-copy-formula-guide.md +131 -0
- package/content/plugins/ads/skills/agileflow-ads/references/audience-targeting-guide.md +137 -0
- package/content/plugins/ads/skills/agileflow-ads/references/bid-strategy-guide.md +115 -0
- package/content/plugins/ads/skills/agileflow-ads/references/platform-benchmarks.md +100 -0
- package/content/plugins/ads/skills/agileflow-ads/workflows/audit.md +118 -0
- package/content/plugins/ads/skills/agileflow-ads/workflows/generate.md +84 -0
- package/content/plugins/audit/agents/a11y-analyzer-aria.md +173 -0
- package/content/plugins/audit/agents/a11y-analyzer-forms.md +173 -0
- package/content/plugins/audit/agents/a11y-analyzer-keyboard.md +183 -0
- package/content/plugins/audit/agents/a11y-analyzer-semantic.md +169 -0
- package/content/plugins/audit/agents/a11y-analyzer-visual.md +172 -0
- package/content/plugins/audit/agents/a11y-consensus.md +249 -0
- package/content/plugins/audit/agents/accessibility.md +558 -0
- package/content/plugins/audit/agents/api-quality-analyzer-conventions.md +156 -0
- package/content/plugins/audit/agents/api-quality-analyzer-docs.md +184 -0
- package/content/plugins/audit/agents/api-quality-analyzer-errors.md +191 -0
- package/content/plugins/audit/agents/api-quality-analyzer-pagination.md +179 -0
- package/content/plugins/audit/agents/api-quality-analyzer-versioning.md +150 -0
- package/content/plugins/audit/agents/api-quality-consensus.md +217 -0
- package/content/plugins/audit/agents/api-validator.md +191 -0
- package/content/plugins/audit/agents/arch-analyzer-circular.md +156 -0
- package/content/plugins/audit/agents/arch-analyzer-complexity.md +193 -0
- package/content/plugins/audit/agents/arch-analyzer-coupling.md +152 -0
- package/content/plugins/audit/agents/arch-analyzer-layering.md +160 -0
- package/content/plugins/audit/agents/arch-analyzer-patterns.md +210 -0
- package/content/plugins/audit/agents/arch-consensus.md +228 -0
- package/content/plugins/audit/agents/browser-qa.md +342 -0
- package/content/plugins/audit/agents/code-reviewer.md +298 -0
- package/content/plugins/audit/agents/completeness-analyzer-api.md +199 -0
- package/content/plugins/audit/agents/completeness-analyzer-conditional.md +211 -0
- package/content/plugins/audit/agents/completeness-analyzer-handlers.md +166 -0
- package/content/plugins/audit/agents/completeness-analyzer-imports.md +165 -0
- package/content/plugins/audit/agents/completeness-analyzer-routes.md +190 -0
- package/content/plugins/audit/agents/completeness-analyzer-state.md +196 -0
- package/content/plugins/audit/agents/completeness-analyzer-stubs.md +206 -0
- package/content/plugins/audit/agents/completeness-consensus.md +295 -0
- package/content/plugins/audit/agents/error-analyzer.md +213 -0
- package/content/plugins/audit/agents/flow-analyzer-authorization.md +182 -0
- package/content/plugins/audit/agents/flow-analyzer-discovery.md +174 -0
- package/content/plugins/audit/agents/flow-analyzer-errors.md +186 -0
- package/content/plugins/audit/agents/flow-analyzer-feedback.md +185 -0
- package/content/plugins/audit/agents/flow-analyzer-navigation.md +177 -0
- package/content/plugins/audit/agents/flow-analyzer-persistence.md +193 -0
- package/content/plugins/audit/agents/flow-analyzer-wiring.md +169 -0
- package/content/plugins/audit/agents/flow-consensus.md +237 -0
- package/content/plugins/audit/agents/legal-analyzer-a11y.md +114 -0
- package/content/plugins/audit/agents/legal-analyzer-ai.md +121 -0
- package/content/plugins/audit/agents/legal-analyzer-consumer.md +114 -0
- package/content/plugins/audit/agents/legal-analyzer-content.md +117 -0
- package/content/plugins/audit/agents/legal-analyzer-international.md +119 -0
- package/content/plugins/audit/agents/legal-analyzer-licensing.md +119 -0
- package/content/plugins/audit/agents/legal-analyzer-privacy.md +112 -0
- package/content/plugins/audit/agents/legal-analyzer-security.md +116 -0
- package/content/plugins/audit/agents/legal-analyzer-terms.md +115 -0
- package/content/plugins/audit/agents/legal-consensus.md +250 -0
- package/content/plugins/audit/agents/logic-analyzer-edge.md +179 -0
- package/content/plugins/audit/agents/logic-analyzer-flow.md +264 -0
- package/content/plugins/audit/agents/logic-analyzer-invariant.md +215 -0
- package/content/plugins/audit/agents/logic-analyzer-race.md +280 -0
- package/content/plugins/audit/agents/logic-analyzer-type.md +227 -0
- package/content/plugins/audit/agents/logic-consensus.md +259 -0
- package/content/plugins/audit/agents/perf-analyzer-assets.md +182 -0
- package/content/plugins/audit/agents/perf-analyzer-bundle.md +173 -0
- package/content/plugins/audit/agents/perf-analyzer-caching.md +170 -0
- package/content/plugins/audit/agents/perf-analyzer-compute.md +173 -0
- package/content/plugins/audit/agents/perf-analyzer-memory.md +193 -0
- package/content/plugins/audit/agents/perf-analyzer-network.md +165 -0
- package/content/plugins/audit/agents/perf-analyzer-queries.md +162 -0
- package/content/plugins/audit/agents/perf-analyzer-rendering.md +168 -0
- package/content/plugins/audit/agents/perf-consensus.md +287 -0
- package/content/plugins/audit/agents/qa.md +820 -0
- package/content/plugins/audit/agents/quality-analyzer-comments.md +159 -0
- package/content/plugins/audit/agents/quality-analyzer-duplication.md +184 -0
- package/content/plugins/audit/agents/quality-analyzer-naming.md +160 -0
- package/content/plugins/audit/agents/quality-consensus.md +241 -0
- package/content/plugins/audit/agents/schema-validator.md +473 -0
- package/content/plugins/audit/agents/security-analyzer-api.md +210 -0
- package/content/plugins/audit/agents/security-analyzer-auth.md +169 -0
- package/content/plugins/audit/agents/security-analyzer-authz.md +180 -0
- package/content/plugins/audit/agents/security-analyzer-deps.md +153 -0
- package/content/plugins/audit/agents/security-analyzer-infra.md +184 -0
- package/content/plugins/audit/agents/security-analyzer-injection.md +155 -0
- package/content/plugins/audit/agents/security-analyzer-input.md +201 -0
- package/content/plugins/audit/agents/security-analyzer-secrets.md +183 -0
- package/content/plugins/audit/agents/security-consensus.md +283 -0
- package/content/plugins/audit/agents/test-analyzer-assertions.md +188 -0
- package/content/plugins/audit/agents/test-analyzer-coverage.md +189 -0
- package/content/plugins/audit/agents/test-analyzer-fragility.md +193 -0
- package/content/plugins/audit/agents/test-analyzer-integration.md +161 -0
- package/content/plugins/audit/agents/test-analyzer-maintenance.md +180 -0
- package/content/plugins/audit/agents/test-analyzer-mocking.md +188 -0
- package/content/plugins/audit/agents/test-analyzer-patterns.md +196 -0
- package/content/plugins/audit/agents/test-analyzer-structure.md +184 -0
- package/content/plugins/audit/agents/test-consensus.md +301 -0
- package/content/plugins/audit/agents/testing.md +561 -0
- package/content/plugins/audit/agents/ui-validator.md +344 -0
- package/content/plugins/audit/plugin.yaml +186 -5
- package/content/plugins/audit/skills/agileflow-audit/SKILL.md +113 -0
- package/content/plugins/audit/skills/agileflow-audit/references/audit-depth-guide.md +151 -0
- package/content/plugins/audit/skills/agileflow-audit/references/dependency-risk-guide.md +139 -0
- package/content/plugins/audit/skills/agileflow-audit/references/owasp-top10.md +120 -0
- package/content/plugins/audit/skills/agileflow-audit/references/performance-budget-guide.md +143 -0
- package/content/plugins/audit/skills/agileflow-audit/references/wcag-criteria.md +117 -0
- package/content/plugins/audit/skills/agileflow-audit/workflows/run-audit.md +52 -0
- package/content/plugins/audit/skills/agileflow-audit/workflows/tdd.md +66 -0
- package/content/plugins/core/agents/adr-writer.md +521 -0
- package/content/plugins/core/agents/epic-planner.md +520 -0
- package/content/plugins/core/agents/mentor.md +709 -0
- package/content/plugins/core/agents/orchestrator.md +776 -0
- package/content/plugins/core/agents/team-coordinator.md +334 -0
- package/content/plugins/core/agents/team-lead.md +181 -0
- package/content/plugins/core/agents/workspace-orchestrator.md +146 -0
- package/content/plugins/core/hooks/context-loader.js +31 -4
- package/content/plugins/core/hooks/damage-control-bash.js +10 -2
- package/content/plugins/core/hooks/damage-control-edit.js +4 -1
- package/content/plugins/core/hooks/damage-control-patterns.yaml +1 -1
- package/content/plugins/core/hooks/damage-control-write.js +4 -1
- package/content/plugins/core/hooks/{pre-compact-state.js → post-compact-state.js} +25 -8
- package/content/plugins/core/hooks/preferences-injector.js +352 -0
- package/content/plugins/core/plugin.yaml +24 -28
- package/content/plugins/core/skills/agileflow-adr/SKILL.md +34 -8
- package/content/plugins/core/skills/agileflow-adr/references/madr-format-guide.md +86 -0
- package/content/plugins/core/skills/agileflow-adr/workflows/write-adr.md +57 -0
- package/content/plugins/core/skills/agileflow-babysit-mentor/SKILL.md +94 -27
- package/content/plugins/core/skills/agileflow-babysit-mentor/references/mentor-decision-guide.md +81 -0
- package/content/plugins/core/skills/agileflow-babysit-mentor/workflows/mentor-session.md +79 -0
- package/content/plugins/core/skills/agileflow-epic-planner/SKILL.md +37 -7
- package/content/plugins/core/skills/agileflow-epic-planner/references/epic-sizing-guide.md +81 -0
- package/content/plugins/core/skills/agileflow-epic-planner/workflows/plan-epic.md +55 -0
- package/content/plugins/core/skills/agileflow-status-updater/SKILL.md +36 -20
- package/content/plugins/core/skills/agileflow-status-updater/references/status-transitions.md +89 -0
- package/content/plugins/core/skills/agileflow-status-updater/workflows/update-status.md +56 -0
- package/content/plugins/core/skills/agileflow-story-writer/SKILL.md +39 -114
- package/content/plugins/core/skills/agileflow-story-writer/references/estimation-reference.md +36 -0
- package/content/plugins/core/skills/agileflow-story-writer/references/story-template.md +92 -0
- package/content/plugins/core/skills/agileflow-story-writer/workflows/write-story.md +138 -0
- package/content/plugins/council/agents/council-advocate.md +223 -0
- package/content/plugins/council/agents/council-analyst.md +278 -0
- package/content/plugins/council/agents/council-compounder.md +204 -0
- package/content/plugins/council/agents/council-contrarian.md +217 -0
- package/content/plugins/council/agents/council-moonshot.md +217 -0
- package/content/plugins/council/agents/council-optimist.md +185 -0
- package/content/plugins/council/agents/council-revenue.md +200 -0
- package/content/plugins/council/agents/council-technical.md +218 -0
- package/content/plugins/council/agents/multi-expert.md +334 -0
- package/content/plugins/council/plugin.yaml +23 -4
- package/content/plugins/council/skills/agileflow-council/SKILL.md +102 -0
- package/content/plugins/council/skills/agileflow-council/references/decision-log-template.md +109 -0
- package/content/plugins/council/skills/agileflow-council/references/perspective-guide.md +104 -0
- package/content/plugins/council/skills/agileflow-council/references/when-to-convene-guide.md +112 -0
- package/content/plugins/council/skills/agileflow-council/workflows/convene.md +73 -0
- package/content/plugins/council/skills/agileflow-council/workflows/multi-expert.md +75 -0
- package/content/plugins/database/plugin.yaml +14 -0
- package/content/plugins/database/skills/agileflow-database/SKILL.md +284 -0
- package/content/plugins/database/skills/agileflow-database/references/indexing-guide.md +313 -0
- package/content/plugins/database/skills/agileflow-database/references/migration-guide.md +328 -0
- package/content/plugins/database/skills/agileflow-database/references/schema-design-guide.md +467 -0
- package/content/plugins/database/skills/agileflow-database/workflows/design-schema.md +213 -0
- package/content/plugins/database/skills/agileflow-database/workflows/optimize-query.md +253 -0
- package/content/plugins/debugging/plugin.yaml +14 -0
- package/content/plugins/debugging/skills/agileflow-debug/SKILL.md +236 -0
- package/content/plugins/debugging/skills/agileflow-debug/references/common-patterns.md +350 -0
- package/content/plugins/debugging/skills/agileflow-debug/references/debugging-strategies.md +328 -0
- package/content/plugins/debugging/skills/agileflow-debug/workflows/debug-issue.md +187 -0
- package/content/plugins/debugging/skills/agileflow-debug/workflows/reproduce-bug.md +194 -0
- package/content/plugins/delivery/agents/ci.md +547 -0
- package/content/plugins/delivery/agents/devops.md +789 -0
- package/content/plugins/delivery/plugin.yaml +19 -0
- package/content/plugins/delivery/skills/agileflow-delivery/SKILL.md +111 -0
- package/content/plugins/delivery/skills/agileflow-delivery/references/changelog-format-guide.md +133 -0
- package/content/plugins/delivery/skills/agileflow-delivery/references/ci-pipeline-guide.md +158 -0
- package/content/plugins/delivery/skills/agileflow-delivery/references/pr-checklist-guide.md +133 -0
- package/content/plugins/delivery/skills/agileflow-delivery/references/release-checklist.md +142 -0
- package/content/plugins/delivery/skills/agileflow-delivery/workflows/changelog.md +72 -0
- package/content/plugins/delivery/skills/agileflow-delivery/workflows/deploy.md +74 -0
- package/content/plugins/delivery/skills/agileflow-delivery/workflows/pr.md +75 -0
- package/content/plugins/docs/agents/documentation.md +544 -0
- package/content/plugins/docs/agents/readme-updater.md +640 -0
- package/content/plugins/docs/plugin.yaml +19 -0
- package/content/plugins/docs/skills/agileflow-docs/SKILL.md +106 -0
- package/content/plugins/docs/skills/agileflow-docs/references/api-doc-template.md +167 -0
- package/content/plugins/docs/skills/agileflow-docs/references/doc-types-guide.md +141 -0
- package/content/plugins/docs/skills/agileflow-docs/references/readme-template.md +156 -0
- package/content/plugins/docs/skills/agileflow-docs/workflows/readme-sync.md +57 -0
- package/content/plugins/docs/skills/agileflow-docs/workflows/sync.md +64 -0
- package/content/plugins/engineering/agents/api.md +718 -0
- package/content/plugins/engineering/agents/codebase-query.md +285 -0
- package/content/plugins/engineering/agents/compliance.md +559 -0
- package/content/plugins/engineering/agents/database.md +644 -0
- package/content/plugins/engineering/agents/integrations.md +644 -0
- package/content/plugins/engineering/agents/mobile.md +552 -0
- package/content/plugins/engineering/agents/monitoring.md +585 -0
- package/content/plugins/engineering/agents/performance.md +529 -0
- package/content/plugins/engineering/agents/refactor.md +592 -0
- package/content/plugins/engineering/agents/security.md +524 -0
- package/content/plugins/engineering/agents/ui.md +1336 -0
- package/content/plugins/engineering/plugin.yaml +37 -0
- package/content/plugins/engineering/skills/agileflow-engineering/SKILL.md +127 -0
- package/content/plugins/engineering/skills/agileflow-engineering/references/code-review-guide.md +126 -0
- package/content/plugins/engineering/skills/agileflow-engineering/references/domain-routing-guide.md +89 -0
- package/content/plugins/engineering/skills/agileflow-engineering/references/refactoring-guide.md +136 -0
- package/content/plugins/engineering/skills/agileflow-engineering/workflows/diagnose.md +63 -0
- package/content/plugins/engineering/skills/agileflow-engineering/workflows/impact.md +60 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-features.md +179 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-growth.md +169 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-integration.md +181 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-market.md +150 -0
- package/content/plugins/ideation/agents/brainstorm-analyzer-ux.md +180 -0
- package/content/plugins/ideation/agents/brainstorm-consensus.md +245 -0
- package/content/plugins/ideation/agents/design.md +568 -0
- package/content/plugins/ideation/agents/product.md +582 -0
- package/content/plugins/ideation/plugin.yaml +31 -0
- package/content/plugins/ideation/skills/agileflow-ideation/SKILL.md +109 -0
- package/content/plugins/ideation/skills/agileflow-ideation/references/brainstorm-techniques.md +138 -0
- package/content/plugins/ideation/skills/agileflow-ideation/references/competitive-analysis-template.md +148 -0
- package/content/plugins/ideation/skills/agileflow-ideation/references/feature-prioritization-guide.md +147 -0
- package/content/plugins/ideation/skills/agileflow-ideation/references/user-story-patterns.md +152 -0
- package/content/plugins/ideation/skills/agileflow-ideation/workflows/features.md +65 -0
- package/content/plugins/ideation/skills/agileflow-ideation/workflows/ideate.md +54 -0
- package/content/plugins/migration/agents/datamigration.md +757 -0
- package/content/plugins/migration/plugin.yaml +17 -0
- package/content/plugins/migration/skills/agileflow-migration/SKILL.md +106 -0
- package/content/plugins/migration/skills/agileflow-migration/references/data-validation-checklist.md +154 -0
- package/content/plugins/migration/skills/agileflow-migration/references/migration-patterns.md +209 -0
- package/content/plugins/migration/skills/agileflow-migration/references/rollback-playbook.md +171 -0
- package/content/plugins/migration/skills/agileflow-migration/references/version-compatibility-matrix.md +155 -0
- package/content/plugins/migration/skills/agileflow-migration/workflows/plan.md +73 -0
- package/content/plugins/migration/skills/agileflow-migration/workflows/validate.md +71 -0
- package/content/plugins/performance/plugin.yaml +14 -0
- package/content/plugins/performance/skills/agileflow-performance/SKILL.md +224 -0
- package/content/plugins/performance/skills/agileflow-performance/references/optimization-patterns.md +554 -0
- package/content/plugins/performance/skills/agileflow-performance/references/profiling-guide.md +383 -0
- package/content/plugins/performance/skills/agileflow-performance/references/web-vitals-guide.md +360 -0
- package/content/plugins/performance/skills/agileflow-performance/workflows/improve-web-vitals.md +344 -0
- package/content/plugins/performance/skills/agileflow-performance/workflows/profile-and-fix.md +254 -0
- package/content/plugins/planning/agents/analytics.md +670 -0
- package/content/plugins/planning/agents/rlm-subcore.md +215 -0
- package/content/plugins/planning/plugin.yaml +19 -0
- package/content/plugins/planning/skills/agileflow-planning/SKILL.md +111 -0
- package/content/plugins/planning/skills/agileflow-planning/references/estimation-guide.md +114 -0
- package/content/plugins/planning/skills/agileflow-planning/references/rpi-workflow.md +119 -0
- package/content/plugins/planning/skills/agileflow-planning/references/sprint-planning-guide.md +145 -0
- package/content/plugins/planning/skills/agileflow-planning/workflows/impact.md +63 -0
- package/content/plugins/planning/skills/agileflow-planning/workflows/rpi.md +104 -0
- package/content/plugins/psychology/plugin.yaml +14 -0
- package/content/plugins/psychology/skills/agileflow-retention/SKILL.md +252 -0
- package/content/plugins/psychology/skills/agileflow-retention/references/competitor-analysis.md +240 -0
- package/content/plugins/psychology/skills/agileflow-retention/references/psychology-models.md +349 -0
- package/content/plugins/psychology/skills/agileflow-retention/references/retention-patterns.md +279 -0
- package/content/plugins/psychology/skills/agileflow-retention/workflows/design-retention-feature.md +287 -0
- package/content/plugins/psychology/skills/agileflow-retention/workflows/retention-audit.md +259 -0
- package/content/plugins/refactoring/plugin.yaml +14 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/SKILL.md +235 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/references/refactoring-patterns.md +405 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/references/safety-checks.md +177 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/workflows/extract-module.md +226 -0
- package/content/plugins/refactoring/skills/agileflow-refactor/workflows/safe-refactor.md +169 -0
- package/content/plugins/research/agents/research.md +503 -0
- package/content/plugins/research/plugin.yaml +17 -0
- package/content/plugins/research/skills/agileflow-research/SKILL.md +110 -0
- package/content/plugins/research/skills/agileflow-research/references/knowledge-decay-guide.md +121 -0
- package/content/plugins/research/skills/agileflow-research/references/research-prompt-guide.md +141 -0
- package/content/plugins/research/skills/agileflow-research/references/synthesis-template.md +154 -0
- package/content/plugins/research/skills/agileflow-research/workflows/analyze.md +60 -0
- package/content/plugins/research/skills/agileflow-research/workflows/ask.md +64 -0
- package/content/plugins/research/skills/agileflow-research/workflows/import.md +66 -0
- package/content/plugins/research/skills/agileflow-research/workflows/synthesize.md +66 -0
- package/content/plugins/reviews/plugin.yaml +14 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/SKILL.md +241 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/references/review-checklist.md +200 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/references/security-patterns.md +328 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/workflows/review-pr.md +153 -0
- package/content/plugins/reviews/skills/agileflow-pr-reviewer/workflows/security-review.md +177 -0
- package/content/plugins/seo/agents/seo-analyzer-content.md +169 -0
- package/content/plugins/seo/agents/seo-analyzer-images.md +198 -0
- package/content/plugins/seo/agents/seo-analyzer-performance.md +217 -0
- package/content/plugins/seo/agents/seo-analyzer-schema.md +184 -0
- package/content/plugins/seo/agents/seo-analyzer-sitemap.md +177 -0
- package/content/plugins/seo/agents/seo-analyzer-technical.md +151 -0
- package/content/plugins/seo/agents/seo-consensus.md +304 -0
- package/content/plugins/seo/plugin.yaml +19 -4
- package/content/plugins/seo/skills/agileflow-seo/SKILL.md +188 -0
- package/content/plugins/seo/skills/agileflow-seo/references/cwv-thresholds.md +110 -0
- package/content/plugins/seo/skills/agileflow-seo/references/eeat-framework.md +144 -0
- package/content/plugins/seo/skills/agileflow-seo/references/keyword-research-guide.md +125 -0
- package/content/plugins/seo/skills/agileflow-seo/references/schema-types.md +139 -0
- package/content/plugins/seo/skills/agileflow-seo/references/technical-seo-checklist.md +139 -0
- package/content/plugins/seo/skills/agileflow-seo/workflows/audit.md +98 -0
- package/content/plugins/seo/skills/agileflow-seo/workflows/page.md +118 -0
- package/content/plugins/testing/plugin.yaml +16 -0
- package/content/plugins/testing/skills/agileflow-test-writer/SKILL.md +260 -0
- package/content/plugins/testing/skills/agileflow-test-writer/references/coverage-targets.md +239 -0
- package/content/plugins/testing/skills/agileflow-test-writer/references/test-patterns.md +420 -0
- package/content/plugins/testing/skills/agileflow-test-writer/workflows/add-coverage.md +154 -0
- package/content/plugins/testing/skills/agileflow-test-writer/workflows/write-tests-from-ac.md +225 -0
- package/package.json +2 -2
- package/src/cli/commands/doctor.js +818 -30
- package/src/cli/commands/hook.js +17 -14
- package/src/cli/commands/launch.js +1454 -0
- package/src/cli/commands/learn.js +149 -0
- package/src/cli/commands/plugins.js +113 -0
- package/src/cli/commands/setup.js +455 -110
- package/src/cli/commands/skills.js +324 -0
- package/src/cli/commands/status.js +8 -10
- package/src/cli/commands/update.js +76 -15
- package/src/cli/index.js +90 -26
- package/src/cli/wizard/babysit-mode-picker.js +192 -0
- package/src/cli/wizard/behaviors-picker.js +208 -54
- package/src/cli/wizard/ide-picker.js +40 -28
- package/src/cli/wizard/install-scope-picker.js +57 -0
- package/src/cli/wizard/launch-alias-picker.js +50 -0
- package/src/cli/wizard/launch-cli-picker.js +129 -0
- package/src/cli/wizard/launch-tmux-picker.js +133 -0
- package/src/cli/wizard/learnings-picker.js +40 -0
- package/src/cli/wizard/plugin-picker.js +47 -16
- package/src/lib/brand.js +116 -0
- package/src/lib/errors.js +120 -0
- package/src/lib/path-check.js +39 -0
- package/src/runtime/config/defaults.js +22 -17
- package/src/runtime/config/loader.js +77 -8
- package/src/runtime/config/schema.json +43 -16
- package/src/runtime/config/writer.js +3 -1
- package/src/runtime/ide/babysit-skill.js +202 -0
- package/src/runtime/ide/capabilities.js +84 -29
- package/src/runtime/ide/claude-code-content.js +177 -0
- package/src/runtime/ide/claude-code-settings.js +67 -29
- package/src/runtime/ide/claude-code-skills.js +47 -32
- package/src/runtime/ide/codex-config.js +295 -0
- package/src/runtime/installer/install.js +252 -24
- package/src/runtime/launch/alias-installer.js +191 -0
- package/src/runtime/launch/cli-resume.js +244 -0
- package/src/runtime/launch/closed-windows.js +338 -0
- package/src/runtime/launch/defaults.js +66 -0
- package/src/runtime/launch/detect-clis.js +69 -0
- package/src/runtime/launch/doctor.js +464 -0
- package/src/runtime/launch/exec-wrapper.js +114 -0
- package/src/runtime/launch/parallel-session.js +247 -0
- package/src/runtime/launch/prefs.js +211 -0
- package/src/runtime/launch/project-prefs.js +234 -0
- package/src/runtime/launch/resolve-cli.js +56 -0
- package/src/runtime/launch/restore.js +152 -0
- package/src/runtime/launch/schema.json +75 -0
- package/src/runtime/launch/session-lifecycle.js +313 -0
- package/src/runtime/launch/session-registry.js +401 -0
- package/src/runtime/launch/spawn.js +103 -0
- package/src/runtime/launch/tabs.js +350 -0
- package/src/runtime/launch/tmux.js +764 -0
- package/src/runtime/launch/worktree.js +260 -0
- package/src/runtime/plugins/registry.js +16 -11
- package/src/runtime/plugins/validator.js +57 -43
- package/src/runtime/skills/learnings.js +308 -0
- package/content/plugins/core/hooks/babysit-mentor-injector.js +0 -55
- package/src/cli/wizard/personalization.js +0 -64
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
# Schema Design Guide
|
|
2
|
+
|
|
3
|
+
A practical reference for designing relational database schemas — from first principles to production patterns. Apply these rules whether you're greenfielding a new service or extending an existing data model.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Normalization
|
|
8
|
+
|
|
9
|
+
Normalization eliminates redundancy and anomalies. Work through the normal forms in order.
|
|
10
|
+
|
|
11
|
+
### First Normal Form (1NF)
|
|
12
|
+
|
|
13
|
+
- Every column holds atomic values — no arrays, no comma-separated lists, no JSON blobs as a workaround for missing columns
|
|
14
|
+
- No repeating groups (no `tag1`, `tag2`, `tag3` columns)
|
|
15
|
+
- Every row is uniquely identifiable (primary key exists)
|
|
16
|
+
|
|
17
|
+
```sql
|
|
18
|
+
-- Bad: repeating group
|
|
19
|
+
CREATE TABLE products (
|
|
20
|
+
id BIGSERIAL PRIMARY KEY,
|
|
21
|
+
name TEXT,
|
|
22
|
+
tag1 TEXT,
|
|
23
|
+
tag2 TEXT,
|
|
24
|
+
tag3 TEXT -- what happens with tag4?
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
-- Good: separate table
|
|
28
|
+
CREATE TABLE products (id BIGSERIAL PRIMARY KEY, name TEXT);
|
|
29
|
+
CREATE TABLE product_tags (
|
|
30
|
+
product_id BIGINT REFERENCES products(id),
|
|
31
|
+
tag TEXT NOT NULL,
|
|
32
|
+
PRIMARY KEY (product_id, tag)
|
|
33
|
+
);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Second Normal Form (2NF)
|
|
37
|
+
|
|
38
|
+
- Must already be in 1NF
|
|
39
|
+
- No partial dependencies on a composite primary key — every non-key column must depend on the whole key, not part of it
|
|
40
|
+
|
|
41
|
+
```sql
|
|
42
|
+
-- Bad: order_items with composite PK (order_id, product_id)
|
|
43
|
+
-- product_name depends only on product_id, not the full PK
|
|
44
|
+
CREATE TABLE order_items (
|
|
45
|
+
order_id BIGINT,
|
|
46
|
+
product_id BIGINT,
|
|
47
|
+
product_name TEXT, -- partial dependency on product_id only
|
|
48
|
+
quantity INT,
|
|
49
|
+
PRIMARY KEY (order_id, product_id)
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
-- Good: move product_name to products table
|
|
53
|
+
CREATE TABLE order_items (
|
|
54
|
+
order_id BIGINT REFERENCES orders(id),
|
|
55
|
+
product_id BIGINT REFERENCES products(id),
|
|
56
|
+
quantity INT NOT NULL,
|
|
57
|
+
PRIMARY KEY (order_id, product_id)
|
|
58
|
+
);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Third Normal Form (3NF)
|
|
62
|
+
|
|
63
|
+
- Must already be in 2NF
|
|
64
|
+
- No transitive dependencies — non-key columns must depend directly on the primary key, not on another non-key column
|
|
65
|
+
|
|
66
|
+
```sql
|
|
67
|
+
-- Bad: zip_code determines city and state (transitive dependency)
|
|
68
|
+
CREATE TABLE users (
|
|
69
|
+
id BIGSERIAL PRIMARY KEY,
|
|
70
|
+
name TEXT,
|
|
71
|
+
zip_code TEXT,
|
|
72
|
+
city TEXT, -- depends on zip_code, not id
|
|
73
|
+
state TEXT -- depends on zip_code, not id
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
-- Good: separate postal codes
|
|
77
|
+
CREATE TABLE postal_codes (zip_code TEXT PRIMARY KEY, city TEXT, state TEXT);
|
|
78
|
+
CREATE TABLE users (
|
|
79
|
+
id BIGSERIAL PRIMARY KEY,
|
|
80
|
+
name TEXT,
|
|
81
|
+
zip_code TEXT REFERENCES postal_codes(zip_code)
|
|
82
|
+
);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### When to denormalize
|
|
86
|
+
|
|
87
|
+
Denormalization is a deliberate performance trade-off. It introduces redundancy in exchange for read speed. Do it intentionally, not by accident.
|
|
88
|
+
|
|
89
|
+
| Signal | Denormalization approach |
|
|
90
|
+
| ----------------------------------------- | ---------------------------------------------------------- |
|
|
91
|
+
| Read-heavy analytics or reporting | Pre-computed aggregate table or materialized view |
|
|
92
|
+
| Query requires 5+ JOINs for common reads | Collapsed read-model table (updated via trigger or worker) |
|
|
93
|
+
| Full-text search across multiple fields | Denormalized `search_vector` column with GIN index |
|
|
94
|
+
| Display name shown on every list row | Cache `user_name` on `orders` (accept stale risk) |
|
|
95
|
+
| Leaderboard or ranking updated frequently | Sorted set in Redis, not a live SQL query |
|
|
96
|
+
|
|
97
|
+
**Practical rule:** normalize until it hurts writes or reads, then denormalize with full awareness of the consistency trade-off.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Naming Conventions
|
|
102
|
+
|
|
103
|
+
Consistent naming is self-documenting schema. Deviate only when an existing codebase has a strong established convention.
|
|
104
|
+
|
|
105
|
+
### Tables
|
|
106
|
+
|
|
107
|
+
- Lowercase snake_case
|
|
108
|
+
- Plural noun: `users`, `orders`, `order_items`, `payment_methods`
|
|
109
|
+
- Junction tables: combine both nouns: `user_roles`, `product_tags`, `post_categories`
|
|
110
|
+
- Avoid abbreviations: `organizations` not `orgs`, `addresses` not `addrs`
|
|
111
|
+
|
|
112
|
+
### Columns
|
|
113
|
+
|
|
114
|
+
- Lowercase snake_case, singular
|
|
115
|
+
- Primary key: `id`
|
|
116
|
+
- Foreign keys: `{referenced_table_singular}_id` — `user_id`, `order_id`, `organization_id`
|
|
117
|
+
- Boolean: prefix with `is_`, `has_`, `can_`, `should_` — `is_active`, `has_verified_email`, `can_publish`
|
|
118
|
+
- Timestamps: `created_at`, `updated_at`, `deleted_at`, `published_at`, `expires_at`
|
|
119
|
+
- Counters: `comment_count`, `view_count` (denormalized cache — document it)
|
|
120
|
+
- ENUM status: `status` column with named values, or `status_id` FK to a statuses table
|
|
121
|
+
|
|
122
|
+
### Constraints and indexes
|
|
123
|
+
|
|
124
|
+
Name constraints explicitly — anonymous constraints produce cryptic error messages.
|
|
125
|
+
|
|
126
|
+
```sql
|
|
127
|
+
-- Good: named constraints
|
|
128
|
+
ALTER TABLE order_items
|
|
129
|
+
ADD CONSTRAINT order_items_order_id_fkey
|
|
130
|
+
FOREIGN KEY (order_id) REFERENCES orders(id),
|
|
131
|
+
ADD CONSTRAINT order_items_quantity_positive
|
|
132
|
+
CHECK (quantity > 0);
|
|
133
|
+
|
|
134
|
+
CREATE INDEX idx_orders_user_id_status ON orders (user_id, status);
|
|
135
|
+
CREATE UNIQUE INDEX idx_users_email ON users (email);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Column Types
|
|
141
|
+
|
|
142
|
+
Choose the most specific type that fits the data. Loose types (TEXT everywhere, FLOAT for money) cause subtle bugs and missed optimizations.
|
|
143
|
+
|
|
144
|
+
### Primary Keys
|
|
145
|
+
|
|
146
|
+
| Option | Pros | Cons | Use when |
|
|
147
|
+
| --------- | ------------------------------------------ | -------------------------------------------------- | -------------------------------------- |
|
|
148
|
+
| BIGSERIAL | Compact (8 bytes), sequential, fast B-tree | Exposes count, not suitable across distributed DBs | Single-DB services, internal join keys |
|
|
149
|
+
| UUID v4 | Globally unique, safe to expose in APIs | 16 bytes, random = index bloat, slower inserts | Distributed systems, public-facing IDs |
|
|
150
|
+
| UUID v7 | Globally unique + time-ordered | Requires PG 17+ or extension | Best of both — use when available |
|
|
151
|
+
|
|
152
|
+
**Pragmatic default:** use BIGSERIAL internally, UUID v4 as a public identifier column if needed.
|
|
153
|
+
|
|
154
|
+
```sql
|
|
155
|
+
CREATE TABLE users (
|
|
156
|
+
id BIGSERIAL PRIMARY KEY,
|
|
157
|
+
public_id UUID NOT NULL DEFAULT gen_random_uuid() UNIQUE
|
|
158
|
+
);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Strings
|
|
162
|
+
|
|
163
|
+
| Type | When to use |
|
|
164
|
+
| ---------- | ------------------------------------------------------------ |
|
|
165
|
+
| TEXT | Arbitrary length — emails, names, descriptions, free text |
|
|
166
|
+
| VARCHAR(n) | When there is a meaningful enforced maximum (e.g., codes) |
|
|
167
|
+
| CHAR(n) | Almost never — pads with spaces, wastes space, confuses devs |
|
|
168
|
+
|
|
169
|
+
Do not use VARCHAR(255) as a default. It signals the developer didn't think about the constraint.
|
|
170
|
+
|
|
171
|
+
### Numbers
|
|
172
|
+
|
|
173
|
+
| Type | When to use |
|
|
174
|
+
| ------------- | --------------------------------------------------------------------------- |
|
|
175
|
+
| SMALLINT | Tiny integers (2 bytes) — age, rating 1–5 |
|
|
176
|
+
| INTEGER | General integer (4 bytes) |
|
|
177
|
+
| BIGINT | Large integers, IDs, counts that may exceed 2 billion |
|
|
178
|
+
| DECIMAL(p, s) | Money, precise decimals — use DECIMAL(19, 4) for currency |
|
|
179
|
+
| NUMERIC | Alias for DECIMAL — same behavior |
|
|
180
|
+
| FLOAT / REAL | Scientific calculations where approximation is acceptable — NEVER for money |
|
|
181
|
+
|
|
182
|
+
### Money
|
|
183
|
+
|
|
184
|
+
```sql
|
|
185
|
+
-- Bad: floating-point arithmetic errors accumulate
|
|
186
|
+
price FLOAT
|
|
187
|
+
|
|
188
|
+
-- Good option 1: integer cents
|
|
189
|
+
price_cents INTEGER NOT NULL -- $9.99 stored as 999
|
|
190
|
+
|
|
191
|
+
-- Good option 2: exact decimal
|
|
192
|
+
price DECIMAL(19, 4) NOT NULL -- supports up to $999,999,999,999,999.9999
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Timestamps
|
|
196
|
+
|
|
197
|
+
Always use `TIMESTAMPTZ` (timestamp with time zone) and store in UTC. `TIMESTAMP` without timezone is a footgun — it stores the wall clock time of the inserting server, which changes meaning across DST transitions and server migrations.
|
|
198
|
+
|
|
199
|
+
```sql
|
|
200
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
201
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
202
|
+
deleted_at TIMESTAMPTZ -- NULL means not deleted
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Booleans
|
|
206
|
+
|
|
207
|
+
Use `BOOLEAN`, not `SMALLINT` or `CHAR(1)`. Add NOT NULL with a default.
|
|
208
|
+
|
|
209
|
+
```sql
|
|
210
|
+
is_active BOOLEAN NOT NULL DEFAULT true,
|
|
211
|
+
has_verified_email BOOLEAN NOT NULL DEFAULT false
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### JSON (PostgreSQL)
|
|
215
|
+
|
|
216
|
+
| Type | When to use |
|
|
217
|
+
| ----- | ------------------------------------------------------------------------------ |
|
|
218
|
+
| JSONB | Semi-structured data you need to query, index, or update — use this by default |
|
|
219
|
+
| JSON | Preserve exact input format (key order, whitespace) — rarely needed |
|
|
220
|
+
|
|
221
|
+
Index JSONB with GIN for containment queries:
|
|
222
|
+
|
|
223
|
+
```sql
|
|
224
|
+
CREATE INDEX idx_events_payload ON events USING GIN (payload);
|
|
225
|
+
|
|
226
|
+
-- Then query efficiently:
|
|
227
|
+
SELECT * FROM events WHERE payload @> '{"type": "login"}';
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Relationships
|
|
233
|
+
|
|
234
|
+
### One-to-Many
|
|
235
|
+
|
|
236
|
+
Foreign key on the "many" side. Always index the FK column.
|
|
237
|
+
|
|
238
|
+
```sql
|
|
239
|
+
CREATE TABLE posts (
|
|
240
|
+
id BIGSERIAL PRIMARY KEY,
|
|
241
|
+
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
242
|
+
title TEXT NOT NULL,
|
|
243
|
+
body TEXT,
|
|
244
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
CREATE INDEX idx_posts_user_id ON posts (user_id);
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Many-to-Many
|
|
251
|
+
|
|
252
|
+
Junction table. Include timestamps so you know when the association was created.
|
|
253
|
+
|
|
254
|
+
```sql
|
|
255
|
+
CREATE TABLE user_roles (
|
|
256
|
+
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
257
|
+
role_id BIGINT NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
|
258
|
+
granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
259
|
+
granted_by BIGINT REFERENCES users(id),
|
|
260
|
+
PRIMARY KEY (user_id, role_id)
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
CREATE INDEX idx_user_roles_role_id ON user_roles (role_id);
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### One-to-One
|
|
267
|
+
|
|
268
|
+
Foreign key with a UNIQUE constraint, or shared primary key.
|
|
269
|
+
|
|
270
|
+
```sql
|
|
271
|
+
-- Option 1: FK + UNIQUE (more flexible, allows lazy creation)
|
|
272
|
+
CREATE TABLE user_profiles (
|
|
273
|
+
id BIGSERIAL PRIMARY KEY,
|
|
274
|
+
user_id BIGINT NOT NULL UNIQUE REFERENCES users(id) ON DELETE CASCADE,
|
|
275
|
+
bio TEXT,
|
|
276
|
+
avatar_url TEXT
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
-- Option 2: Shared PK (always created together)
|
|
280
|
+
CREATE TABLE user_preferences (
|
|
281
|
+
user_id BIGINT PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
|
282
|
+
theme TEXT NOT NULL DEFAULT 'light',
|
|
283
|
+
notifications_enabled BOOLEAN NOT NULL DEFAULT true
|
|
284
|
+
);
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Soft Delete
|
|
288
|
+
|
|
289
|
+
Add `deleted_at TIMESTAMPTZ NULL`. Filter every query with `WHERE deleted_at IS NULL`. Create a partial index.
|
|
290
|
+
|
|
291
|
+
```sql
|
|
292
|
+
CREATE INDEX idx_users_active ON users (id) WHERE deleted_at IS NULL;
|
|
293
|
+
|
|
294
|
+
-- All application queries should use this filter
|
|
295
|
+
SELECT * FROM users WHERE deleted_at IS NULL AND email = $1;
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Use a database view to encapsulate the filter:
|
|
299
|
+
|
|
300
|
+
```sql
|
|
301
|
+
CREATE VIEW active_users AS SELECT * FROM users WHERE deleted_at IS NULL;
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Cascade Rules
|
|
305
|
+
|
|
306
|
+
| Option | Behavior | Use when |
|
|
307
|
+
| ------------------- | ------------------------------------------------------------------------ | ------------------------------------------------- |
|
|
308
|
+
| ON DELETE CASCADE | Child rows deleted when parent deleted | Posts when user deleted, items when order deleted |
|
|
309
|
+
| ON DELETE RESTRICT | Prevents parent deletion if children exist | Don't delete a category that has products |
|
|
310
|
+
| ON DELETE SET NULL | Child FK set to NULL when parent deleted | Optional association — audit log user_id |
|
|
311
|
+
| ON DELETE NO ACTION | Error raised (default) — same as RESTRICT, checked at end of transaction | Default — be explicit to signal intent |
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Common Schema Patterns
|
|
316
|
+
|
|
317
|
+
### User Authentication
|
|
318
|
+
|
|
319
|
+
```sql
|
|
320
|
+
CREATE TABLE users (
|
|
321
|
+
id BIGSERIAL PRIMARY KEY,
|
|
322
|
+
public_id UUID NOT NULL DEFAULT gen_random_uuid() UNIQUE,
|
|
323
|
+
email TEXT NOT NULL UNIQUE,
|
|
324
|
+
email_verified_at TIMESTAMPTZ,
|
|
325
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
326
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
327
|
+
deleted_at TIMESTAMPTZ
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
CREATE TABLE sessions (
|
|
331
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
332
|
+
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
333
|
+
expires_at TIMESTAMPTZ NOT NULL,
|
|
334
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
335
|
+
ip_address INET,
|
|
336
|
+
user_agent TEXT
|
|
337
|
+
);
|
|
338
|
+
CREATE INDEX idx_sessions_user_id ON sessions (user_id);
|
|
339
|
+
CREATE INDEX idx_sessions_expires_at ON sessions (expires_at);
|
|
340
|
+
|
|
341
|
+
CREATE TABLE oauth_accounts (
|
|
342
|
+
id BIGSERIAL PRIMARY KEY,
|
|
343
|
+
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
344
|
+
provider TEXT NOT NULL,
|
|
345
|
+
provider_account_id TEXT NOT NULL,
|
|
346
|
+
access_token TEXT,
|
|
347
|
+
refresh_token TEXT,
|
|
348
|
+
token_expires_at TIMESTAMPTZ,
|
|
349
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
350
|
+
UNIQUE (provider, provider_account_id)
|
|
351
|
+
);
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Multi-Tenancy
|
|
355
|
+
|
|
356
|
+
Two main strategies:
|
|
357
|
+
|
|
358
|
+
**Shared schema with tenant_id (simpler, scales to hundreds of tenants):**
|
|
359
|
+
|
|
360
|
+
```sql
|
|
361
|
+
-- Every table gets tenant_id
|
|
362
|
+
CREATE TABLE organizations (id BIGSERIAL PRIMARY KEY, name TEXT NOT NULL);
|
|
363
|
+
|
|
364
|
+
CREATE TABLE projects (
|
|
365
|
+
id BIGSERIAL PRIMARY KEY,
|
|
366
|
+
organization_id BIGINT NOT NULL REFERENCES organizations(id),
|
|
367
|
+
name TEXT NOT NULL
|
|
368
|
+
);
|
|
369
|
+
CREATE INDEX idx_projects_organization_id ON projects (organization_id);
|
|
370
|
+
|
|
371
|
+
-- Row-level security enforces isolation
|
|
372
|
+
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
|
|
373
|
+
CREATE POLICY tenant_isolation ON projects
|
|
374
|
+
USING (organization_id = current_setting('app.current_org_id')::BIGINT);
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**Schema-per-tenant (stronger isolation, scales to thousands of tenants):**
|
|
378
|
+
|
|
379
|
+
```sql
|
|
380
|
+
-- Each tenant gets their own schema: tenant_123.projects
|
|
381
|
+
CREATE SCHEMA tenant_123;
|
|
382
|
+
SET search_path TO tenant_123, public;
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Hierarchical Data
|
|
386
|
+
|
|
387
|
+
| Pattern | Pros | Cons | Use when |
|
|
388
|
+
| ----------------- | -------------------------------- | --------------------------------------- | ---------------------------------- |
|
|
389
|
+
| Adjacency list | Simple, easy inserts/moves | Recursive queries required, N+1 risk | Small hierarchies, arbitrary depth |
|
|
390
|
+
| Materialized path | Fast reads, simple queries | Updates require string manipulation | Read-heavy trees, moderate depth |
|
|
391
|
+
| Closure table | Fast reads and writes, clean SQL | Extra storage, more complex inserts | Frequently read hierarchies |
|
|
392
|
+
| Nested sets | Extremely fast subtree reads | Slow inserts and moves, complex updates | Rarely — read-only taxonomies |
|
|
393
|
+
|
|
394
|
+
```sql
|
|
395
|
+
-- Adjacency list (simplest)
|
|
396
|
+
CREATE TABLE categories (
|
|
397
|
+
id BIGSERIAL PRIMARY KEY,
|
|
398
|
+
parent_id BIGINT REFERENCES categories(id),
|
|
399
|
+
name TEXT NOT NULL
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
-- PostgreSQL recursive CTE to get full path
|
|
403
|
+
WITH RECURSIVE path AS (
|
|
404
|
+
SELECT id, parent_id, name, 0 AS depth
|
|
405
|
+
FROM categories WHERE id = $1
|
|
406
|
+
UNION ALL
|
|
407
|
+
SELECT c.id, c.parent_id, c.name, path.depth + 1
|
|
408
|
+
FROM categories c JOIN path ON c.id = path.parent_id
|
|
409
|
+
)
|
|
410
|
+
SELECT * FROM path ORDER BY depth DESC;
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Event Sourcing
|
|
414
|
+
|
|
415
|
+
```sql
|
|
416
|
+
CREATE TABLE events (
|
|
417
|
+
id BIGSERIAL PRIMARY KEY,
|
|
418
|
+
aggregate_id UUID NOT NULL,
|
|
419
|
+
aggregate_type TEXT NOT NULL,
|
|
420
|
+
event_type TEXT NOT NULL,
|
|
421
|
+
payload JSONB NOT NULL,
|
|
422
|
+
metadata JSONB NOT NULL DEFAULT '{}',
|
|
423
|
+
version INT NOT NULL,
|
|
424
|
+
occurred_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
425
|
+
UNIQUE (aggregate_id, version)
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
CREATE INDEX idx_events_aggregate ON events (aggregate_id, version);
|
|
429
|
+
CREATE INDEX idx_events_type_occurred ON events (event_type, occurred_at);
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Audit Trail
|
|
433
|
+
|
|
434
|
+
```sql
|
|
435
|
+
CREATE TABLE audit_log (
|
|
436
|
+
id BIGSERIAL PRIMARY KEY,
|
|
437
|
+
table_name TEXT NOT NULL,
|
|
438
|
+
record_id BIGINT NOT NULL,
|
|
439
|
+
action TEXT NOT NULL CHECK (action IN ('INSERT', 'UPDATE', 'DELETE')),
|
|
440
|
+
old_values JSONB,
|
|
441
|
+
new_values JSONB,
|
|
442
|
+
performed_by BIGINT REFERENCES users(id),
|
|
443
|
+
performed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
444
|
+
ip_address INET
|
|
445
|
+
);
|
|
446
|
+
|
|
447
|
+
CREATE INDEX idx_audit_log_table_record ON audit_log (table_name, record_id);
|
|
448
|
+
CREATE INDEX idx_audit_log_performed_at ON audit_log (performed_at);
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## Schema Review Checklist
|
|
454
|
+
|
|
455
|
+
Before finalizing any schema:
|
|
456
|
+
|
|
457
|
+
- [ ] Every table has a primary key
|
|
458
|
+
- [ ] All foreign keys have a matching index
|
|
459
|
+
- [ ] Timestamps use TIMESTAMPTZ with DEFAULT NOW()
|
|
460
|
+
- [ ] Money columns use DECIMAL or integer cents
|
|
461
|
+
- [ ] No VARCHAR(255) without a meaningful constraint reason
|
|
462
|
+
- [ ] Nullable columns are intentionally nullable (not just forgotten NOT NULL)
|
|
463
|
+
- [ ] Cascade rules are explicit and correct
|
|
464
|
+
- [ ] Junction tables have both FK indexes
|
|
465
|
+
- [ ] Constraints are named
|
|
466
|
+
- [ ] Soft-delete strategy is consistent across the model
|
|
467
|
+
- [ ] Normalization reviewed — denormalization documented with rationale
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# Workflow: Design Schema
|
|
2
|
+
|
|
3
|
+
Follow this workflow when the user needs to design a new database schema or model entities from requirements. Work step-by-step and confirm with the user at key decision points before writing SQL.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Step 1: Gather Requirements
|
|
8
|
+
|
|
9
|
+
Ask these questions if the answers aren't already clear from context. Don't ask all at once — adapt based on what the user has already provided.
|
|
10
|
+
|
|
11
|
+
**What to understand:**
|
|
12
|
+
|
|
13
|
+
- What is this feature or system doing? What are the core user-facing actions?
|
|
14
|
+
- What data needs to be stored, and what are the relationships between entities?
|
|
15
|
+
- What are the read patterns? (List views, search, reporting, real-time, analytics)
|
|
16
|
+
- What are the write patterns? (How often does data change, at what volume)
|
|
17
|
+
- Are there multi-tenancy requirements?
|
|
18
|
+
- What is the expected data volume at launch vs. in 1 year?
|
|
19
|
+
- What database engine is in use?
|
|
20
|
+
- Does an ORM manage the schema, or is raw SQL preferred?
|
|
21
|
+
|
|
22
|
+
**Collect:**
|
|
23
|
+
|
|
24
|
+
- A rough list of entities mentioned by the user
|
|
25
|
+
- Any existing schema they want to extend
|
|
26
|
+
- Performance requirements or known constraints
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Step 2: Identify Entities
|
|
31
|
+
|
|
32
|
+
From the requirements, extract the core entities. For each entity:
|
|
33
|
+
|
|
34
|
+
- Name it as a plural table name (`users`, `orders`, `products`)
|
|
35
|
+
- Identify the primary key strategy (BIGSERIAL vs UUID — see `references/schema-design-guide.md`)
|
|
36
|
+
- Note what distinguishes one row from another
|
|
37
|
+
|
|
38
|
+
**Example output:**
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
Entities identified:
|
|
42
|
+
- users (authenticated people)
|
|
43
|
+
- organizations (multi-tenant accounts)
|
|
44
|
+
- projects (owned by an organization)
|
|
45
|
+
- tasks (belong to a project, assigned to a user)
|
|
46
|
+
- comments (belong to a task)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Present this list to the user and confirm before proceeding.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Step 3: Map Relationships
|
|
54
|
+
|
|
55
|
+
For each pair of entities, determine the cardinality:
|
|
56
|
+
|
|
57
|
+
| Relationship | Pattern |
|
|
58
|
+
| ---------------- | ------------------------------------------- |
|
|
59
|
+
| One-to-many | FK on the "many" side |
|
|
60
|
+
| Many-to-many | Junction table |
|
|
61
|
+
| One-to-one | FK + UNIQUE, or shared PK |
|
|
62
|
+
| Self-referential | Parent FK on same table (hierarchical data) |
|
|
63
|
+
|
|
64
|
+
Draw the relationships explicitly:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
organizations 1──< projects 1──< tasks >──M users (assignment)
|
|
68
|
+
1
|
|
69
|
+
|
|
|
70
|
+
M
|
|
71
|
+
comments
|
|
72
|
+
M
|
|
73
|
+
|
|
|
74
|
+
1
|
|
75
|
+
users (author)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Confirm the relationship map with the user. Surface any ambiguous cases:
|
|
79
|
+
|
|
80
|
+
- "Can a task have multiple assignees, or just one?"
|
|
81
|
+
- "Can a project belong to multiple organizations?"
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Step 4: Define Columns
|
|
86
|
+
|
|
87
|
+
For each entity, define the columns:
|
|
88
|
+
|
|
89
|
+
1. **Primary key**: `id BIGSERIAL PRIMARY KEY` or UUID strategy
|
|
90
|
+
2. **Foreign keys**: reference other entities using `{table_singular}_id`
|
|
91
|
+
3. **Required data**: columns that represent the core concept
|
|
92
|
+
4. **Optional data**: nullable columns for supplementary information
|
|
93
|
+
5. **Status/state**: ENUM or FK to statuses table
|
|
94
|
+
6. **Timestamps**: always include `created_at`, `updated_at`; add `deleted_at` if soft-delete is needed
|
|
95
|
+
7. **Constraints**: NOT NULL, UNIQUE, CHECK constraints
|
|
96
|
+
|
|
97
|
+
Apply naming conventions (see `references/schema-design-guide.md`):
|
|
98
|
+
|
|
99
|
+
- Tables: lowercase_snake_case, plural
|
|
100
|
+
- Columns: lowercase_snake_case, singular
|
|
101
|
+
- Booleans: `is_`, `has_`, `can_` prefix
|
|
102
|
+
- Timestamps: `_at` suffix
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Step 5: Normalization Review
|
|
107
|
+
|
|
108
|
+
Walk through the normal forms quickly:
|
|
109
|
+
|
|
110
|
+
**1NF check:** Are all values atomic? No arrays or comma-separated values stored in a single column?
|
|
111
|
+
|
|
112
|
+
**2NF check:** If using a composite PK, does every non-key column depend on the full key (not just part of it)?
|
|
113
|
+
|
|
114
|
+
**3NF check:** Do any non-key columns depend on another non-key column rather than the PK directly?
|
|
115
|
+
|
|
116
|
+
If normalization would create a query with 5+ JOINs for a very common read path, consider whether a read-model table or materialized view is appropriate. Document the denormalization decision with its rationale.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Step 6: Plan Indexes
|
|
121
|
+
|
|
122
|
+
For every table, identify which queries will run against it and define the index strategy:
|
|
123
|
+
|
|
124
|
+
1. **Primary key**: automatically indexed
|
|
125
|
+
2. **Foreign keys**: always add an index (check if ORM does this automatically)
|
|
126
|
+
3. **Filter columns**: columns in WHERE clauses for common queries
|
|
127
|
+
4. **Sort columns**: columns in ORDER BY for large result sets
|
|
128
|
+
5. **Unique constraints**: auto-creates an index
|
|
129
|
+
6. **Partial indexes**: if a large percentage of rows are inactive/deleted
|
|
130
|
+
|
|
131
|
+
Example index plan:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
tasks table:
|
|
135
|
+
- idx_tasks_project_id ON tasks (project_id) -- FK
|
|
136
|
+
- idx_tasks_assigned_user_id ON tasks (assigned_user_id) -- FK
|
|
137
|
+
- idx_tasks_project_status ON tasks (project_id, status) -- common filter
|
|
138
|
+
- idx_tasks_active ON tasks (project_id, due_date) -- WHERE deleted_at IS NULL (partial)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Step 7: Write the Migration
|
|
144
|
+
|
|
145
|
+
Write the `up` SQL. Apply zero-downtime patterns from `references/migration-guide.md`:
|
|
146
|
+
|
|
147
|
+
- New tables: always safe
|
|
148
|
+
- Adding columns to existing tables: nullable or with a default
|
|
149
|
+
- Indexes: use `CREATE INDEX CONCURRENTLY`
|
|
150
|
+
|
|
151
|
+
Write the `down` SQL immediately after the `up`. Verify the `down` restores the exact prior state.
|
|
152
|
+
|
|
153
|
+
```sql
|
|
154
|
+
-- up
|
|
155
|
+
CREATE TABLE projects (
|
|
156
|
+
id BIGSERIAL PRIMARY KEY,
|
|
157
|
+
organization_id BIGINT NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
|
|
158
|
+
name TEXT NOT NULL,
|
|
159
|
+
description TEXT,
|
|
160
|
+
status TEXT NOT NULL DEFAULT 'active'
|
|
161
|
+
CHECK (status IN ('active', 'archived', 'deleted')),
|
|
162
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
163
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
164
|
+
deleted_at TIMESTAMPTZ
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
CREATE INDEX CONCURRENTLY idx_projects_organization_id
|
|
168
|
+
ON projects (organization_id);
|
|
169
|
+
CREATE INDEX CONCURRENTLY idx_projects_org_active
|
|
170
|
+
ON projects (organization_id, created_at)
|
|
171
|
+
WHERE deleted_at IS NULL;
|
|
172
|
+
|
|
173
|
+
-- down
|
|
174
|
+
DROP INDEX IF EXISTS idx_projects_org_active;
|
|
175
|
+
DROP INDEX IF EXISTS idx_projects_organization_id;
|
|
176
|
+
DROP TABLE IF EXISTS projects;
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Step 8: Review Checklist
|
|
182
|
+
|
|
183
|
+
Run through this before presenting the final schema:
|
|
184
|
+
|
|
185
|
+
- [ ] Every table has a primary key
|
|
186
|
+
- [ ] All foreign keys have corresponding indexes
|
|
187
|
+
- [ ] Timestamps use TIMESTAMPTZ with DEFAULT NOW()
|
|
188
|
+
- [ ] Money columns use DECIMAL or integer cents — not FLOAT
|
|
189
|
+
- [ ] Nullable columns are intentionally nullable
|
|
190
|
+
- [ ] Cascade rules are explicit and correct for the domain
|
|
191
|
+
- [ ] Constraints are named explicitly
|
|
192
|
+
- [ ] Migration has both `up` and `down`
|
|
193
|
+
- [ ] New indexes use CONCURRENTLY
|
|
194
|
+
- [ ] Normalization reviewed — any denormalization is documented
|
|
195
|
+
- [ ] No comma-separated values in any column
|
|
196
|
+
- [ ] Soft-delete strategy is consistent if applicable
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Step 9: Present and Confirm
|
|
201
|
+
|
|
202
|
+
Present the schema with:
|
|
203
|
+
|
|
204
|
+
1. An entity-relationship summary in plain English
|
|
205
|
+
2. The full SQL for the migration
|
|
206
|
+
3. A list of design decisions made and why (e.g., "UUID chosen because IDs will appear in URLs", "JSONB used for metadata because the shape varies per record type")
|
|
207
|
+
4. Any open questions where the user's input is needed
|
|
208
|
+
|
|
209
|
+
Offer to:
|
|
210
|
+
|
|
211
|
+
- Add sample queries showing how the schema is accessed
|
|
212
|
+
- Identify additional indexes if the user shares their access patterns
|
|
213
|
+
- Write the ORM model definitions (Prisma schema, SQLAlchemy models, etc.)
|