@thierrynakoa/fire-flow 12.2.1 → 13.0.1
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/CREDITS.md +25 -0
- package/DOMINION-FLOW-OVERVIEW.md +182 -38
- package/README.md +399 -455
- package/TROUBLESHOOTING.md +264 -264
- package/agents/fire-debugger.md +54 -0
- package/agents/fire-executor.md +1610 -1033
- package/agents/fire-fact-checker.md +1 -1
- package/agents/fire-planner.md +85 -17
- package/agents/fire-project-researcher.md +1 -1
- package/agents/fire-researcher.md +4 -22
- package/agents/{fire-phoenix-analyst.md → fire-resurrection-analyst.md} +394 -394
- package/agents/fire-reviewer.md +552 -499
- package/agents/fire-verifier.md +114 -19
- package/bin/cli.js +18 -101
- package/commands/fire-0-orient.md +2 -2
- package/commands/fire-1a-new.md +50 -15
- package/commands/fire-1c-setup.md +33 -5
- package/commands/fire-1d-discuss.md +87 -1
- package/commands/fire-2-plan.md +556 -527
- package/commands/fire-3-execute.md +2046 -1356
- package/commands/fire-4-verify.md +975 -906
- package/commands/fire-5-handoff.md +46 -5
- package/commands/fire-6-resume.md +2 -31
- package/commands/fire-add-new-skill.md +138 -19
- package/commands/fire-autonomous.md +14 -2
- package/commands/fire-complete-milestone.md +1 -1
- package/commands/fire-cost.md +179 -183
- package/commands/fire-debug.md +1 -6
- package/commands/fire-loop-resume.md +2 -2
- package/commands/fire-loop-stop.md +1 -1
- package/commands/fire-loop.md +2 -15
- package/commands/fire-map-codebase.md +1 -1
- package/commands/fire-migrate-database.md +548 -0
- package/commands/fire-new-milestone.md +1 -1
- package/commands/fire-reflect.md +1 -2
- package/commands/fire-research.md +142 -21
- package/commands/{fire-phoenix.md → fire-resurrect.md} +859 -603
- package/commands/fire-scaffold.md +297 -0
- package/commands/fire-search.md +1 -2
- package/commands/fire-security-scan.md +483 -484
- package/commands/fire-setup.md +359 -0
- package/commands/fire-skill.md +770 -0
- package/commands/fire-skills-diff.md +506 -506
- package/commands/fire-skills-history.md +388 -388
- package/commands/fire-skills-rollback.md +7 -7
- package/commands/fire-skills-sync.md +470 -470
- package/commands/fire-test.md +5 -5
- package/commands/fire-todos.md +1 -1
- package/commands/fire-update.md +5 -5
- package/commands/fire-validate-skills.md +282 -0
- package/commands/fire-vuln-scan.md +492 -493
- package/hooks/run-hook.sh +8 -8
- package/hooks/run-session-end.sh +7 -7
- package/hooks/session-end.sh +90 -90
- package/hooks/session-start.sh +1 -1
- package/package.json +4 -24
- package/plugin.json +7 -7
- package/references/autonomy-levels.md +235 -0
- package/references/behavioral-directives.md +95 -3
- package/references/blocker-tracking.md +1 -1
- package/references/circuit-breaker.md +93 -2
- package/references/context-engineering.md +227 -9
- package/references/honesty-protocols.md +70 -1
- package/references/issue-to-pr-pipeline.md +149 -150
- package/references/metrics-and-trends.md +1 -2
- package/references/research-improvements.md +4 -108
- package/references/sdlc-mapping.md +73 -0
- package/references/state-machine.md +151 -0
- package/skills-library/AVAILABLE_TOOLS_REFERENCE.md +333 -0
- package/skills-library/SKILLS-INDEX.md +57 -558
- package/skills-library/SKILLS_LIBRARY_INDEX.md +532 -0
- package/skills-library/_general/api-patterns/api-field-name-mismatch.md +107 -0
- package/skills-library/_general/api-patterns/streaming-command-timeout.md +122 -0
- package/skills-library/_general/api-patterns/streaming-proxy-cors-bypass.md +102 -0
- package/skills-library/_general/automation/settings-gui-generator.md +172 -0
- package/skills-library/_general/database-solutions/data-type-mapping-reference.md +181 -0
- package/skills-library/_general/database-solutions/mysql-limit-offset-string-coercion.md +102 -0
- package/skills-library/_general/database-solutions/mysql-to-pg-migration.md +195 -0
- package/skills-library/_general/database-solutions/orm-schema-portability.md +193 -0
- package/skills-library/_general/database-solutions/persistent-analysis-storage.md +207 -0
- package/skills-library/_general/database-solutions/pg-to-mysql-schema-migration-methodology.md +190 -0
- package/skills-library/_general/database-solutions/sql-dialect-compatibility-matrix.md +306 -0
- package/skills-library/_general/database-solutions/sqlite-to-pg-migration.md +219 -0
- package/skills-library/_general/frontend/canvas-bubble-animation-grouping.md +270 -0
- package/skills-library/_general/frontend/color-token-migration.md +112 -0
- package/skills-library/_general/frontend/framer-motion-layoutid-grouping.md +150 -0
- package/skills-library/_general/frontend/pyqt6-settings-dialog.md +191 -0
- package/skills-library/_general/frontend/react-flow-animated-layout-switching.md +101 -0
- package/skills-library/_general/frontend/react-hooks-order-debugging.md +141 -0
- package/skills-library/_general/frontend/redux-localstorage-auth-desync.md +126 -0
- package/skills-library/_general/frontend/safari-csp-theme-color-debugging.md +124 -0
- package/skills-library/_general/frontend/safari-sw-cache-poisoning.md +138 -0
- package/skills-library/_general/frontend/svg-sparkline-no-charting-library.md +131 -0
- package/skills-library/_general/growth-marketing/oss-daily-growth-intelligence.md +224 -0
- package/skills-library/_general/integrations/claude-code-local-mcp-integration.md +250 -0
- package/skills-library/_general/integrations/mcp-composite-tool-orchestration.md +200 -0
- package/skills-library/_general/methodology/AGENT_SDK_STANDALONE_TOOLING.md +181 -0
- package/skills-library/_general/methodology/AGENT_TEAMS_GUIDE.md +169 -0
- package/skills-library/_general/methodology/ALAS_STATEFUL_EXECUTION.md +207 -0
- package/skills-library/_general/methodology/AUTO_REVIEWER_SUBAGENT.md +211 -0
- package/skills-library/_general/methodology/CONSISTENCY_CHECK_AMBIGUITY_GATE.md +96 -0
- package/skills-library/_general/methodology/DEAD_ENDS_SHELF.md +4 -4
- package/skills-library/_general/methodology/DISTILL_NOT_DUMP.md +108 -0
- package/skills-library/_general/methodology/EXECUTION_PROGRESS_MONITOR.md +157 -0
- package/skills-library/_general/methodology/HIERARCHICAL_REVIEW_MARS.md +122 -0
- package/skills-library/_general/methodology/MCP_INTER_AGENT_BRIDGE.md +207 -0
- package/skills-library/_general/methodology/MERMAID_WIZARD_DIAGRAMS.md +77 -0
- package/skills-library/_general/methodology/MISSING_DIMENSION_DETECTOR.md +89 -0
- package/skills-library/_general/methodology/MULTI_AGENT_COORDINATION.md +397 -0
- package/skills-library/_general/methodology/OBSERVATION_MASKING.md +100 -0
- package/skills-library/_general/methodology/PHOENIX_REBUILD_METHODOLOGY.md +82 -11
- package/skills-library/_general/methodology/REVIEW_BACKTRACK_PANEL.md +140 -0
- package/skills-library/_general/methodology/REVIEW_FIX_LOOP.md +117 -0
- package/skills-library/_general/methodology/VOTING_VERDICT_ARBITRATION.md +155 -0
- package/skills-library/_general/methodology/ZERO_FRICTION_CLI_SETUP.md +2 -2
- package/skills-library/_general/methodology/dead-code-activation.md +123 -0
- package/skills-library/_general/methodology/debug-swarm-researcher-escape-hatch.md +240 -240
- package/skills-library/_general/methodology/shell-autonomous-loop-fixplan.md +1 -1
- package/skills-library/_general/patterns-standards/GOF_DESIGN_PATTERNS_FOR_AI_AGENTS.md +5 -5
- package/skills-library/_general/patterns-standards/cascading-failure-diagnosis.md +119 -0
- package/skills-library/_general/patterns-standards/domain-specific-layout-algorithms.md +209 -0
- package/skills-library/_general/patterns-standards/python-desktop-app-architecture.md +399 -0
- package/skills-library/_general/patterns-standards/realtime-monitoring-dashboard.md +457 -0
- package/skills-library/_general/patterns-standards/togglable-processing-pipeline.md +169 -0
- package/skills-library/_general/performance/liveclock-extraction.md +112 -0
- package/skills-library/_general/performance/ref-based-canvas-animation.md +117 -0
- package/skills-library/_general/performance/use-visible-interval.md +131 -0
- package/skills-library/_general/testing/playwright-firefox-withcredentials-auth-issue.md +104 -0
- package/skills-library/_quarantine/README.md +30 -0
- package/skills-library/api-patterns/BROADCAST_SCHEDULER_SHARED_EXECUTE_FUNCTION.md +150 -0
- package/skills-library/api-patterns/ERROR_RESPONSE_STANDARDS.md +145 -0
- package/skills-library/api-patterns/EXPRESS_ROUTE_ORDERING_MIDDLEWARE_INTERCEPTION.md +326 -0
- package/skills-library/api-patterns/PAGINATION_PATTERNS.md +137 -0
- package/skills-library/api-patterns/PODCAST_PROGRESS_TRACKING_THREE_ROOT_CAUSES.md +277 -0
- package/skills-library/api-patterns/RATE_LIMITING_TOGGLE.md +155 -0
- package/skills-library/api-patterns/graphql-content-queries.md +708 -0
- package/skills-library/appointment-scheduler-design.md +423 -0
- package/skills-library/automation/AUTO_POPULATE_COMPLETE_GUIDE.md +631 -0
- package/skills-library/automation/CC_WORKFLOW_STUDIO.md +83 -0
- package/skills-library/automation/CLAUDE_CODE_SWARM_MODE.md +95 -0
- package/skills-library/automation/DAEMON_TRIGGER_FILE_IPC.md +195 -0
- package/skills-library/automation/scheduled-content-publishing.md +608 -0
- package/skills-library/awesome-workflows/Blogging-Platform-Instructions/view_commands.md +25 -0
- package/skills-library/awesome-workflows/CREDENTIAL-SECURITY-WORKFLOW.md +109 -0
- package/skills-library/awesome-workflows/DEBUGGING-WORKFLOW.md +124 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/README.md +31 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-principles-example.md +129 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-agent.md +107 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-claude-md-snippet.md +24 -0
- package/skills-library/awesome-workflows/Design-Review-Workflow/design-review-slash-command.md +38 -0
- package/skills-library/awesome-workflows/PARALLEL-RESEARCH-WORKFLOW.md +89 -0
- package/skills-library/awesome-workflows/PHASE-EXECUTION-WORKFLOW.md +97 -0
- package/skills-library/awesome-workflows/SESSION-HANDOFF-WORKFLOW.md +116 -0
- package/skills-library/cms-patterns/content-branch-preview.md +515 -0
- package/skills-library/cms-patterns/inline-visual-editing.md +666 -0
- package/skills-library/cms-patterns/mdx-component-content.md +649 -0
- package/skills-library/cms-patterns/media-manager-abstraction.md +827 -0
- package/skills-library/cms-patterns/schema-driven-form-generator.md +838 -0
- package/skills-library/complexity-metrics/complexity-divider.md +707 -0
- package/skills-library/complexity-metrics/work-with-complexity.md +193 -0
- package/skills-library/creative-multimedia/animation-stack-guide.md +577 -0
- package/skills-library/creative-multimedia/audio-enhancement-pipeline.md +625 -0
- package/skills-library/creative-multimedia/content-repurposing-pipeline.md +1146 -0
- package/skills-library/creative-multimedia/data-visualization-generator.md +862 -0
- package/skills-library/creative-multimedia/doc-to-podcast-pipeline.md +2184 -0
- package/skills-library/creative-multimedia/ffmpeg-command-generator.md +405 -0
- package/skills-library/creative-multimedia/image-optimization-pipeline.md +605 -0
- package/skills-library/creative-multimedia/multi-format-content-generator.md +1759 -0
- package/skills-library/creative-multimedia/og-image-generator.md +635 -0
- package/skills-library/creative-multimedia/podcast-audio-composition.md +1355 -0
- package/skills-library/creative-multimedia/podcast-quality-evaluation.md +1452 -0
- package/skills-library/creative-multimedia/podcast-script-generation.md +1841 -0
- package/skills-library/creative-multimedia/svg-generation.md +750 -0
- package/skills-library/creative-multimedia/text-to-speech-provider-selector.md +1414 -0
- package/skills-library/creative-multimedia/transcription-pipeline-selector.md +677 -0
- package/skills-library/creative-multimedia/video-streaming-setup.md +559 -0
- package/skills-library/database-solutions/AI_RESPONSE_DATABASE_CACHING.md +520 -0
- package/skills-library/database-solutions/CONDITIONAL_SQL_MIGRATION_PATTERN.md +119 -0
- package/skills-library/database-solutions/DATABASE_COLUMN_NAME_MISMATCH.md +393 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA.md +394 -0
- package/skills-library/database-solutions/DATABASE_SCHEMA_VERIFICATION_GUIDE.md +348 -0
- package/skills-library/database-solutions/DATABASE_STRATEGY.md +71 -0
- package/skills-library/database-solutions/ES_MODULE_SEED_SCRIPT_PATTERN.md +52 -0
- package/skills-library/database-solutions/MIGRATION_GUIDE.md +3 -0
- package/skills-library/database-solutions/PLPGSQL_VARIABLE_CONFLICT_FIX.md +208 -0
- package/skills-library/database-solutions/POSTGRESQL_JSONB_DOUBLE_STRINGIFY_FIX.md +245 -0
- package/skills-library/database-solutions/POSTGRESQL_LICENSE_TABLE_DESIGN.md +393 -0
- package/skills-library/database-solutions/POSTGRESQL_UUID_DOCUMENT_RAG_DUAL_SCOPE.md +732 -0
- package/skills-library/database-solutions/POSTGRES_SQL_TEMPLATE_BINDING_ERROR.md +240 -0
- package/skills-library/database-solutions/PRISMA_DB_PUSH_DATA_LOSS_PREVENTION.md +141 -0
- package/skills-library/database-solutions/PRODUCTION_QUERY_OPTIMIZATION_RESTART_FIX.md +389 -0
- package/skills-library/database-solutions/RLS_SECURITY_GUIDE.md +107 -0
- package/skills-library/database-solutions/SCHEMA_ENHANCEMENTS_GUIDE.md +373 -0
- package/skills-library/database-solutions/SCHEMA_MIGRATION_GUIDE.md +368 -0
- package/skills-library/database-solutions/SCHEMA_VERIFICATION_QUICK_REFERENCE.md +104 -0
- package/skills-library/database-solutions/ai-erd-generator.md +1213 -0
- package/skills-library/database-solutions/content-publishing-states.md +631 -0
- package/skills-library/database-solutions/database-schema-designer.md +522 -0
- package/skills-library/database-solutions/er-diagram-components.md +569 -0
- package/skills-library/database-solutions/er-to-ddl-mapping.md +1405 -0
- package/skills-library/database-solutions/erd-creator-textbook-research.md +433 -0
- package/skills-library/database-solutions/erd-react-flow-architecture.md +1965 -0
- package/skills-library/database-solutions/mariadb-aggregate-function-replacement.md +145 -0
- package/skills-library/database-solutions/normalization-validator.md +778 -0
- package/skills-library/database-solutions/postgres-full-text-search-content.md +494 -0
- package/skills-library/database-solutions/postgresql-to-mysql-runtime-translation.md +286 -0
- package/skills-library/database-solutions/regex-alternation-ordering-sql-types.md +92 -0
- package/skills-library/database-solutions/reserved-word-context-aware-quoting.md +142 -0
- package/skills-library/database-solutions/sql-ddl-generator.md +756 -0
- package/skills-library/database-solutions/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/deployment-security/CPANEL_NODE_DEPLOYMENT.md +166 -0
- package/skills-library/deployment-security/DEPLOYMENT.md +275 -0
- package/skills-library/deployment-security/DEPLOYMENT_CHECKLIST.md +363 -0
- package/skills-library/deployment-security/DEPLOYMENT_PLAN.md +669 -0
- package/skills-library/deployment-security/KNEX_DATABASE_ABSTRACTION.md +444 -0
- package/skills-library/deployment-security/LICENSE_KEY_SYSTEM.md +206 -0
- package/skills-library/deployment-security/NODE18_DEPENDENCY_COMPATIBILITY.md +284 -0
- package/skills-library/deployment-security/PHP_INSTALLER_WIZARD_GUIDE.md +315 -0
- package/skills-library/deployment-security/PM2_ENVIRONMENT_VARIABLE_CACHING.md +256 -0
- package/skills-library/deployment-security/PM2_MEMORY_EXHAUSTION_FIX.md +370 -0
- package/skills-library/deployment-security/PRODUCTION_DEPLOYMENT_GUIDE.md +592 -0
- package/skills-library/deployment-security/PRODUCTION_HARDENING_DOCUMENTATION.md +307 -0
- package/skills-library/deployment-security/PRODUCTION_RECOVERY_CHERRY_PICK_PATTERN.md +202 -0
- package/skills-library/deployment-security/PYINSTALLER_CUDA_WHISPER_BUNDLING.md +236 -0
- package/skills-library/deployment-security/SECURITY.md +41 -0
- package/skills-library/deployment-security/SMTP_SSL_HOSTNAME_MISMATCH_SHARED_HOSTING.md +220 -0
- package/skills-library/deployment-security/SPA_SEO_OPTIMIZATION_CPANEL.md +200 -0
- package/skills-library/deployment-security/SUPABASE_EDGE_FUNCTIONS.md +338 -0
- package/skills-library/deployment-security/VERCEL_GITHUB_DEPLOYMENT_GUIDE.md +858 -0
- package/skills-library/deployment-security/VPS_DEPLOYMENT_READINESS.md +356 -0
- package/skills-library/deployment-security/deployment-changes-not-applying.md +241 -0
- package/skills-library/deployment-security/env-file-management-production-local.md +203 -0
- package/skills-library/deployment-security/express-secure-file-downloads.md +413 -0
- package/skills-library/deployment-security/react-production-deployment-desktop-guide.md +2011 -0
- package/skills-library/deployment-security/self-hosted-supabase-coolify-guide.md +1684 -0
- package/skills-library/deployment-security/unique-features-ai-strategy-plaid-security.md +1613 -0
- package/skills-library/deployment-security/vps-deployment.md +135 -0
- package/skills-library/document-processing/WORD_EXPORT_MARKDOWN_FORMATTING.md +482 -0
- package/skills-library/document-processing/document-ai-landingai-integration.md +677 -0
- package/skills-library/document-processing/express-secure-file-downloads-mern.md +413 -0
- package/skills-library/document-processing/express-secure-file-downloads.md +413 -0
- package/skills-library/document-processing/md-to-word-converter.md +318 -0
- package/skills-library/document-processing/pdf-forms-integration/README.md +101 -0
- package/skills-library/document-processing/pdf-forms-integration/SKILL.md +662 -0
- package/skills-library/ecommerce/ADMIN_PRODUCTS_GUIDE.md +428 -0
- package/skills-library/ecommerce/ECOMMERCE_API_REFERENCE.md +776 -0
- package/skills-library/ecommerce/ECOMMERCE_COMPLETION_SUMMARY.md +673 -0
- package/skills-library/ecommerce/ECOMMERCE_IMPLEMENTATION_GUIDE.md +729 -0
- package/skills-library/ecommerce/ECOMMERCE_QUICK_REFERENCE.md +521 -0
- package/skills-library/ecommerce/ECOMMERCE_TESTING_CHECKLIST.md +565 -0
- package/skills-library/ecommerce/ECOMMERCE_WORKFLOW_GUIDE.md +1059 -0
- package/skills-library/ecommerce/PRODUCT_CREATION_EXPANDED.md +522 -0
- package/skills-library/ecommerce/agentic-commerce-protocol.md +203 -0
- package/skills-library/ecommerce/cart-abandonment-recovery.md +236 -0
- package/skills-library/ecommerce/cart-architecture-patterns.md +300 -0
- package/skills-library/ecommerce/cart-item-count-indicator.md +264 -0
- package/skills-library/ecommerce/checkout-ux-conversion.md +227 -0
- package/skills-library/ecommerce/composable-commerce-selection.md +166 -0
- package/skills-library/ecommerce/ecommerce-analytics-patterns.md +167 -0
- package/skills-library/ecommerce/fraud-detection-patterns.md +179 -0
- package/skills-library/ecommerce/inventory-stock-management.md +270 -0
- package/skills-library/ecommerce/order-saga-state-machine.md +336 -0
- package/skills-library/ecommerce/payment-provider-abstraction.md +245 -0
- package/skills-library/ecommerce/pci-compliance-checklist.md +192 -0
- package/skills-library/ecommerce/refund-chargeback-handling.md +177 -0
- package/skills-library/ecommerce/shipping-carrier-integration.md +218 -0
- package/skills-library/ecommerce/webhook-idempotency-patterns.md +253 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/ci.yml +558 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/prompt-gallery.yml +448 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/release.yml +42 -0
- package/skills-library/excalidraw-diagrams/.github/workflows/test-reusable-ci.yml +25 -0
- package/skills-library/excalidraw-diagrams/CLAUDE.md +57 -0
- package/skills-library/excalidraw-diagrams/LICENSE +21 -0
- package/skills-library/excalidraw-diagrams/README.md +178 -0
- package/skills-library/excalidraw-diagrams/SKILL.md +715 -0
- package/skills-library/form-solutions/BUTTON_TYPE_FORM_SUBMISSION.md +336 -0
- package/skills-library/form-solutions/FILLABLE_PDF_IMPLEMENTATION.md +226 -0
- package/skills-library/form-solutions/SURVEYJS_QUESTIONNAIRE_SYSTEM.md +367 -0
- package/skills-library/form-solutions/tiptap-minimal-setup.md +690 -0
- package/skills-library/frontend/scholarly-classification-bubble-map.md +149 -0
- package/skills-library/infrastructure/ci-cd-pipeline-builder.md +517 -0
- package/skills-library/infrastructure/observability-designer.md +264 -0
- package/skills-library/infrastructure/performance-profiler.md +621 -0
- package/skills-library/installer-wizard-patterns.md +249 -0
- package/skills-library/integrations/CLAUDE_CODE_TOKEN_ANALYTICS.md +160 -0
- package/skills-library/integrations/CONFIGURABLE_AI_PROVIDER_SELECTION.md +728 -0
- package/skills-library/integrations/SOCKET_IO_BROADCAST_ALL_VS_ROOM.md +141 -0
- package/skills-library/integrations/VIRTUAL_MEETINGS_IMPLEMENTATION.md +374 -0
- package/skills-library/integrations/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/integrations/ai-ml/GEMINI_AI_RAG_PIPELINE_COMPLETE_GUIDE.md +195 -0
- package/skills-library/integrations/ai-ml/GEMINI_IMAGE_GENERATION_SETUP.md +64 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/cloudflare-turnstile-debugging.md +202 -0
- package/skills-library/integrations/cloudflare-turnstile-implementation.md +476 -0
- package/skills-library/integrations/ghost-creator-monetization-pattern.md +454 -0
- package/skills-library/integrations/headless-cms-architecture.md +484 -0
- package/skills-library/integrations/headless-cms-stack-selection.md +183 -0
- package/skills-library/integrations/payload-cms-patterns.md +674 -0
- package/skills-library/integrations/realtimestt-openwakeword-cuda-windows.md +229 -0
- package/skills-library/integrations/rss-podcast-integration.md +300 -0
- package/skills-library/integrations/wordpress/WORDPRESS_LEARNDASH_DATA_RECOVERY.md +53 -0
- package/skills-library/integrations/youtube/YOUTUBE_API_SETUP.md +141 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_EXPLANATION.md +252 -0
- package/skills-library/integrations/youtube/YOUTUBE_BOOKMARKING_SOLUTION.md +268 -0
- package/skills-library/integrations/youtube/YOUTUBE_OAUTH_SETUP_GUIDE.md +200 -0
- package/skills-library/integrations/youtube/YOUTUBE_VIDEO_FIX_COMPLETE.md +192 -0
- package/skills-library/marketing/campaign-analytics.md +97 -0
- package/skills-library/marketing/content-creator.md +105 -0
- package/skills-library/marketing/marketing-strategy-pmm.md +94 -0
- package/skills-library/marketing/social-media-analyzer.md +81 -0
- package/skills-library/methodology/ADVANCED_ORCHESTRATION_PATTERNS.md +401 -0
- package/skills-library/methodology/AGENT_SELF_IMPROVEMENT_LOOP.md +179 -0
- package/skills-library/methodology/BREATH_BASED_PARALLEL_EXECUTION.md +1 -1
- package/skills-library/methodology/CLEANSING_CYCLE.md +358 -0
- package/skills-library/methodology/CONFIDENCE_ANNOTATION_PATTERN.md +143 -0
- package/skills-library/methodology/CRITICAL_PATTERNS_DOCUMENTATION_COMPLETE.md +204 -0
- package/skills-library/methodology/DELIVERABLES_SUMMARY.md +341 -0
- package/skills-library/methodology/DIFFICULTY_AWARE_AGENT_ROUTING.md +252 -0
- package/skills-library/methodology/EVOLUTIONARY_SKILL_SYNTHESIS.md +219 -0
- package/skills-library/methodology/GLOMERULUS_DECISION_GATE.md +223 -0
- package/skills-library/methodology/HIBERNATION_SYSTEM.md +231 -0
- package/skills-library/methodology/INSTRUMENTATION_OVER_RESTRICTION.md +192 -0
- package/skills-library/methodology/MASTER_COMPLETION_SUMMARY.md +444 -0
- package/skills-library/methodology/MASTER_SESSION_COMPLETION.md +743 -0
- package/skills-library/methodology/MERN_QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/ORGAN_AGENT_MAPPING.md +177 -0
- package/skills-library/methodology/PARALLEL_WAVE_BASED_REFACTORING.md +440 -0
- package/skills-library/methodology/QUICK_REFERENCE.md +358 -0
- package/skills-library/methodology/SDFT_ONPOLICY_SELF_DISTILLATION.md +186 -0
- package/skills-library/methodology/SELF_QUESTIONING_TASK_GENERATION.md +270 -0
- package/skills-library/methodology/SESSION_COMPLETION_SUMMARY.md +304 -0
- package/skills-library/methodology/SESSION_SUMMARY.md +432 -0
- package/skills-library/methodology/WARRIOR_WORKFLOW_DEBUGGING_PROTOCOL.md +252 -0
- package/skills-library/methodology/tech-debt-tracker.md +570 -0
- package/skills-library/parallel-debug/SKILL.md +60 -0
- package/skills-library/patterns-standards/API_PATTERN_FIX_SUMMARY.md +236 -0
- package/skills-library/patterns-standards/BATCH_OPERATIONS_WITH_PROGRESS_MODAL.md +362 -0
- package/skills-library/patterns-standards/CRITICAL_CODING_PATTERNS.md +639 -0
- package/skills-library/patterns-standards/DARK_MODE_MODAL_VISIBILITY.md +258 -0
- package/skills-library/patterns-standards/ERROR_RESILIENCE_IMPLEMENTATION.md +375 -0
- package/skills-library/patterns-standards/ES_MODULE_IMPORT_HOISTING_DOTENV.md +298 -0
- package/skills-library/patterns-standards/NESTED_BACKDROP_FILTER_CSS_ARTIFACT_FIX.md +76 -0
- package/skills-library/patterns-standards/ORDERED_DETECTOR_PIPELINE_GRACEFUL_FALLBACK.md +333 -0
- package/skills-library/patterns-standards/PHASE_IMPORT_ERROR_DEBUGGING.md +271 -0
- package/skills-library/patterns-standards/PYNPUT_GLOBAL_HOTKEY_VK_MATCHING.md +252 -0
- package/skills-library/patterns-standards/REACT_USEEFFECT_CASCADE_RESET_FIX.md +132 -0
- package/skills-library/patterns-standards/SUBMENU_HOVER_DROPDOWN_PATTERN.md +225 -0
- package/skills-library/patterns-standards/TAILWIND_TEXT_VISIBILITY_OVERRIDE.md +322 -0
- package/skills-library/patterns-standards/THEME_AWARE_CSS_VARIABLES_PATTERN.md +209 -0
- package/skills-library/patterns-standards/THEME_USER_OBJECT_PROPERTY_NAMING.md +194 -0
- package/skills-library/patterns-standards/TOOLTIP_BLOCKING_CLICKS_FIX.md +267 -0
- package/skills-library/patterns-standards/claude-code-plugin-structure.md +235 -0
- package/skills-library/patterns-standards/react-i18next-setup.md +429 -0
- package/skills-library/patterns-standards/thesys-c1-generative-ui-integration.md +967 -0
- package/skills-library/plugin-development/CLAUDE_CODE_COMMAND_REGISTRATION_SILENT_FAILURE.md +315 -0
- package/skills-library/plugin-development/plugin-command-namespace-vs-global.md +390 -0
- package/skills-library/plugin-development/plugin-doc-auto-generation.md +172 -0
- package/skills-library/security/GITHUB_REPO_SECURITY_AUDIT.md +115 -0
- package/skills-library/security/admin-deletion-safety.md +396 -0
- package/skills-library/security/application-vuln-patterns.md +477 -0
- package/skills-library/security/env-secrets-manager.md +686 -0
- package/skills-library/security/secure-ai-application-templates.md +347 -0
- package/skills-library/security/sql-injection-prevention-postgresjs.md +151 -0
- package/skills-library/supabase-connection-pooler-fix.md +102 -0
- package/skills-library/system-context/POWERSHELL_BASH_INTEROP.md +82 -0
- package/skills-library/system-context/SERVICE_LIFECYCLE_MANAGEMENT.md +119 -0
- package/skills-library/system-context/SKILL.md +40 -0
- package/skills-library/system-context/WINDOWS_DEV_ENVIRONMENT.md +73 -0
- package/skills-library/testing/E2E_PLAYWRIGHT_PATTERNS.md +99 -0
- package/skills-library/testing/INTEGRATION_TEST_STRATEGY.md +82 -0
- package/skills-library/testing/RED_GREEN_BUGFIX_GATE.md +203 -0
- package/skills-library/testing/TEST_DATA_MANAGEMENT.md +69 -0
- package/skills-library/testing/VITEST_UNIT_TEST_PATTERNS.md +75 -0
- package/skills-library/testing/playwright-api-security-tests.md +202 -0
- package/skills-library/toolbox/SKILL.md +84 -0
- package/skills-library/toolbox/code-graph-and-web-scraping-mcps.md +237 -0
- package/skills-library/ui-ux-pro-max/ACCESSIBILITY_ESSENTIALS.md +115 -0
- package/skills-library/ui-ux-pro-max/DESIGN_SYSTEM_SCAFFOLDING.md +133 -0
- package/skills-library/ui-ux-pro-max/RESPONSIVE_LAYOUT_PATTERNS.md +119 -0
- package/skills-library/ui-ux-pro-max/SKILL.md +386 -0
- package/skills-library/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills-library/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills-library/ui-ux-pro-max/data/products.csv +97 -0
- package/skills-library/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills-library/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills-library/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills-library/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills-library/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills-library/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills-library/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills-library/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills-library/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills-library/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills-library/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills-library/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills-library/wordpress-style-theme-components.md +1526 -0
- package/templates/ASSUMPTIONS.md +1 -1
- package/templates/DECISION_LOG.md +0 -1
- package/templates/phase-prompt.md +1 -1
- package/templates/phoenix-comparison.md +6 -6
- package/templates/skill-api-integration.md +106 -0
- package/templates/skill-architecture-pattern.md +92 -0
- package/templates/skill-debug-pattern.md +98 -0
- package/templates/skill-devops-recipe.md +107 -0
- package/templates/skill-general.md +65 -0
- package/templates/skill-ui-component.md +113 -0
- package/tools/uat-runner.py +179 -0
- package/version.json +7 -3
- package/workflows/handoff-session.md +2 -2
- package/workflows/new-project.md +2 -2
- package/workflows/plan-phase.md +1 -1
- package/.claude-plugin/plugin.json +0 -64
- package/skills-library/_general/methodology/LIVE_BREADCRUMB_PROTOCOL.md +0 -242
- package/skills-library/_general/methodology/llm-judge-memory-crud.md +0 -241
- package/skills-library/methodology/REFLEXION_MEMORY_PATTERN.md +0 -183
- package/skills-library/methodology/RESEARCH_BACKED_WORKFLOW_UPGRADE.md +0 -263
- package/skills-library/methodology/SABBATH_REST_PATTERN.md +0 -267
- package/skills-library/methodology/STONE_AND_SCAFFOLD.md +0 -220
- package/skills-library/specialists/api-architecture/api-designer.md +0 -49
- package/skills-library/specialists/api-architecture/graphql-architect.md +0 -49
- package/skills-library/specialists/api-architecture/mcp-developer.md +0 -51
- package/skills-library/specialists/api-architecture/microservices-architect.md +0 -50
- package/skills-library/specialists/api-architecture/websocket-engineer.md +0 -48
- package/skills-library/specialists/backend/django-expert.md +0 -52
- package/skills-library/specialists/backend/fastapi-expert.md +0 -52
- package/skills-library/specialists/backend/laravel-specialist.md +0 -52
- package/skills-library/specialists/backend/nestjs-expert.md +0 -51
- package/skills-library/specialists/backend/rails-expert.md +0 -53
- package/skills-library/specialists/backend/spring-boot-engineer.md +0 -56
- package/skills-library/specialists/data-ml/fine-tuning-expert.md +0 -48
- package/skills-library/specialists/data-ml/ml-pipeline.md +0 -47
- package/skills-library/specialists/data-ml/pandas-pro.md +0 -47
- package/skills-library/specialists/data-ml/rag-architect.md +0 -51
- package/skills-library/specialists/data-ml/spark-engineer.md +0 -47
- package/skills-library/specialists/frontend/angular-architect.md +0 -52
- package/skills-library/specialists/frontend/flutter-expert.md +0 -51
- package/skills-library/specialists/frontend/nextjs-developer.md +0 -54
- package/skills-library/specialists/frontend/react-native-expert.md +0 -50
- package/skills-library/specialists/frontend/vue-expert.md +0 -51
- package/skills-library/specialists/infrastructure/chaos-engineer.md +0 -74
- package/skills-library/specialists/infrastructure/cloud-architect.md +0 -70
- package/skills-library/specialists/infrastructure/database-optimizer.md +0 -64
- package/skills-library/specialists/infrastructure/devops-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/kubernetes-specialist.md +0 -52
- package/skills-library/specialists/infrastructure/monitoring-expert.md +0 -70
- package/skills-library/specialists/infrastructure/sre-engineer.md +0 -70
- package/skills-library/specialists/infrastructure/terraform-engineer.md +0 -51
- package/skills-library/specialists/languages/cpp-pro.md +0 -74
- package/skills-library/specialists/languages/csharp-developer.md +0 -69
- package/skills-library/specialists/languages/dotnet-core-expert.md +0 -54
- package/skills-library/specialists/languages/golang-pro.md +0 -51
- package/skills-library/specialists/languages/java-architect.md +0 -49
- package/skills-library/specialists/languages/javascript-pro.md +0 -68
- package/skills-library/specialists/languages/kotlin-specialist.md +0 -68
- package/skills-library/specialists/languages/php-pro.md +0 -49
- package/skills-library/specialists/languages/python-pro.md +0 -52
- package/skills-library/specialists/languages/react-expert.md +0 -51
- package/skills-library/specialists/languages/rust-engineer.md +0 -50
- package/skills-library/specialists/languages/sql-pro.md +0 -56
- package/skills-library/specialists/languages/swift-expert.md +0 -69
- package/skills-library/specialists/languages/typescript-pro.md +0 -51
- package/skills-library/specialists/platform/atlassian-mcp.md +0 -52
- package/skills-library/specialists/platform/embedded-systems.md +0 -53
- package/skills-library/specialists/platform/game-developer.md +0 -53
- package/skills-library/specialists/platform/salesforce-developer.md +0 -53
- package/skills-library/specialists/platform/shopify-expert.md +0 -49
- package/skills-library/specialists/platform/wordpress-pro.md +0 -49
- package/skills-library/specialists/quality/code-documenter.md +0 -51
- package/skills-library/specialists/quality/code-reviewer.md +0 -67
- package/skills-library/specialists/quality/debugging-wizard.md +0 -51
- package/skills-library/specialists/quality/fullstack-guardian.md +0 -51
- package/skills-library/specialists/quality/legacy-modernizer.md +0 -50
- package/skills-library/specialists/quality/playwright-expert.md +0 -65
- package/skills-library/specialists/quality/spec-miner.md +0 -56
- package/skills-library/specialists/quality/test-master.md +0 -65
- package/skills-library/specialists/security/secure-code-guardian.md +0 -55
- package/skills-library/specialists/security/security-reviewer.md +0 -53
- package/skills-library/specialists/workflow/architecture-designer.md +0 -53
- package/skills-library/specialists/workflow/cli-developer.md +0 -70
- package/skills-library/specialists/workflow/feature-forge.md +0 -65
- package/skills-library/specialists/workflow/prompt-engineer.md +0 -54
- package/skills-library/specialists/workflow/the-fool.md +0 -62
- /package/skills-library/{performance → _general/performance}/cache-augmented-generation.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/FAILURE_TAXONOMY_CLASSIFICATION.md +0 -0
- /package/skills-library/{debugging → parallel-debug}/THREE_AGENT_HYPOTHESIS_DEBUGGING.md +0 -0
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: normalization-validator
|
|
3
|
+
category: database-solutions
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-03-09
|
|
6
|
+
contributor: fire-research
|
|
7
|
+
last_updated: 2026-03-09
|
|
8
|
+
tags: [normalization, 1nf, 2nf, 3nf, database-quality, validation, ai-normalization]
|
|
9
|
+
difficulty: hard
|
|
10
|
+
usage_count: 0
|
|
11
|
+
success_rate: 100
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Normalization Validator
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Problem
|
|
18
|
+
|
|
19
|
+
Normalization violations in database schemas cause three categories of data anomalies:
|
|
20
|
+
|
|
21
|
+
1. **Insert anomalies** -- Cannot add data without unrelated data (e.g., cannot add a department without an employee)
|
|
22
|
+
2. **Update anomalies** -- Changing one fact requires updating multiple rows (e.g., renaming a department touches every employee row)
|
|
23
|
+
3. **Delete anomalies** -- Removing data destroys unrelated facts (e.g., deleting the last employee in a department loses the department name)
|
|
24
|
+
|
|
25
|
+
These violations are easy to introduce and hard to detect without systematic validation. LLM-generated schemas (per NOMAD) exhibit structural, relationship, and semantic/logical errors at rates high enough to require automated checking.
|
|
26
|
+
|
|
27
|
+
## First Normal Form (1NF)
|
|
28
|
+
|
|
29
|
+
A table is in 1NF when every column contains only atomic (indivisible) values, every row is unique, and there is a defined primary key.
|
|
30
|
+
|
|
31
|
+
### 1NF Violations to Detect
|
|
32
|
+
|
|
33
|
+
| Violation | Detection Signal | Severity |
|
|
34
|
+
|-----------|-----------------|----------|
|
|
35
|
+
| **Repeating groups** | Multiple values in a single cell: arrays, comma-separated lists, JSON arrays in non-JSONB columns | ERROR |
|
|
36
|
+
| **Missing primary key** | No PK constraint defined on the table | ERROR |
|
|
37
|
+
| **Mixed data types** | Column accepts heterogeneous types (e.g., VARCHAR storing both numbers and text interchangeably where a typed column is appropriate) | WARN |
|
|
38
|
+
| **Duplicate rows** | No unique constraint and no PK; identical rows can exist | ERROR |
|
|
39
|
+
| **Numbered column pattern** | Columns like `phone1`, `phone2`, `phone3` or `skill_a`, `skill_b`, `skill_c` | WARN |
|
|
40
|
+
|
|
41
|
+
### 1NF Detection Algorithm
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
FOR each table in schema:
|
|
45
|
+
IF table has no PRIMARY KEY → ERROR: "No primary key defined"
|
|
46
|
+
IF table has no UNIQUE constraint AND no PK → ERROR: "Duplicate rows possible"
|
|
47
|
+
|
|
48
|
+
FOR each column in table:
|
|
49
|
+
IF column type is TEXT/VARCHAR AND column name suggests plurality
|
|
50
|
+
(ends in 's', contains 'list', 'tags', 'items', 'values') → WARN: "Possible multivalued attribute"
|
|
51
|
+
IF column type is TEXT AND default contains ',' or '[' → WARN: "Possible repeating group"
|
|
52
|
+
|
|
53
|
+
IF columns match pattern (name + digit) with 2+ sequential occurrences → WARN: "Numbered column pattern (repeating group)"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 1NF Fix Pattern
|
|
57
|
+
|
|
58
|
+
Repeating groups become a separate table with a foreign key back to the parent:
|
|
59
|
+
|
|
60
|
+
```sql
|
|
61
|
+
-- BEFORE (violates 1NF): phone_numbers = "555-1234,555-5678"
|
|
62
|
+
CREATE TABLE employees (
|
|
63
|
+
id INT PRIMARY KEY,
|
|
64
|
+
name VARCHAR(100),
|
|
65
|
+
phone_numbers TEXT -- comma-separated = 1NF violation
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
-- AFTER (1NF compliant):
|
|
69
|
+
CREATE TABLE employees (
|
|
70
|
+
id INT PRIMARY KEY,
|
|
71
|
+
name VARCHAR(100)
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
CREATE TABLE employee_phones (
|
|
75
|
+
id INT PRIMARY KEY,
|
|
76
|
+
employee_id INT REFERENCES employees(id),
|
|
77
|
+
phone_number VARCHAR(20),
|
|
78
|
+
phone_type VARCHAR(10) -- 'home', 'work', 'mobile'
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Second Normal Form (2NF)
|
|
83
|
+
|
|
84
|
+
A table is in 2NF when it is in 1NF AND every non-key attribute depends on the **entire** primary key (no partial dependencies). This rule only applies to tables with composite primary keys.
|
|
85
|
+
|
|
86
|
+
### 2NF Violations to Detect
|
|
87
|
+
|
|
88
|
+
| Violation | Detection Signal | Severity |
|
|
89
|
+
|-----------|-----------------|----------|
|
|
90
|
+
| **Partial dependency** | Non-key column depends on only part of a composite PK | ERROR |
|
|
91
|
+
| **Junction table bloat** | Junction table has attributes that depend on only one FK | WARN |
|
|
92
|
+
|
|
93
|
+
### 2NF Detection Algorithm
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
FOR each table with composite primary key (pk_col_1, pk_col_2, ...):
|
|
97
|
+
FOR each non-key column C:
|
|
98
|
+
FOR each individual PK component pk_col_i:
|
|
99
|
+
IF C is functionally determined by pk_col_i alone
|
|
100
|
+
→ ERROR: "Partial dependency: {C} depends only on {pk_col_i}, not the full key"
|
|
101
|
+
|
|
102
|
+
-- Heuristic: if a non-key column name contains or matches a PK column's
|
|
103
|
+
-- referenced table name, it likely depends only on that FK
|
|
104
|
+
FOR each non-key column C:
|
|
105
|
+
IF C.name starts with or contains the entity name of exactly one PK component
|
|
106
|
+
→ WARN: "Possible partial dependency: {C} may belong in the {entity} table"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 2NF Fix Pattern
|
|
110
|
+
|
|
111
|
+
Move partially-dependent columns to the table they actually depend on:
|
|
112
|
+
|
|
113
|
+
```sql
|
|
114
|
+
-- BEFORE (violates 2NF): student_name depends only on student_id
|
|
115
|
+
CREATE TABLE enrollments (
|
|
116
|
+
student_id INT,
|
|
117
|
+
course_id INT,
|
|
118
|
+
student_name VARCHAR(100), -- depends only on student_id (partial dependency)
|
|
119
|
+
enrollment_date DATE,
|
|
120
|
+
PRIMARY KEY (student_id, course_id)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
-- AFTER (2NF compliant):
|
|
124
|
+
CREATE TABLE students (
|
|
125
|
+
student_id INT PRIMARY KEY,
|
|
126
|
+
student_name VARCHAR(100)
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
CREATE TABLE enrollments (
|
|
130
|
+
student_id INT REFERENCES students(student_id),
|
|
131
|
+
course_id INT,
|
|
132
|
+
enrollment_date DATE,
|
|
133
|
+
PRIMARY KEY (student_id, course_id)
|
|
134
|
+
);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Third Normal Form (3NF)
|
|
138
|
+
|
|
139
|
+
A table is in 3NF when it is in 2NF AND no non-key attribute transitively depends on the primary key. In other words: every non-key column must depend on "the key, the whole key, and nothing but the key."
|
|
140
|
+
|
|
141
|
+
### 3NF Violations to Detect
|
|
142
|
+
|
|
143
|
+
| Violation | Detection Signal | Severity |
|
|
144
|
+
|-----------|-----------------|----------|
|
|
145
|
+
| **Transitive dependency** | A non-key column B determines another non-key column C (PK->B->C) | ERROR |
|
|
146
|
+
| **Lookup value embedded** | A table stores both a code/ID and its human-readable name (e.g., `dept_id` + `dept_name`) | WARN |
|
|
147
|
+
|
|
148
|
+
### Common 3NF Violation Patterns
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
Employee table:
|
|
152
|
+
PK: employee_id
|
|
153
|
+
dept_id → dept_name, dept_manager (transitive: employee_id → dept_id → dept_name)
|
|
154
|
+
|
|
155
|
+
Order table:
|
|
156
|
+
PK: order_id
|
|
157
|
+
product_id → product_name, product_category (transitive)
|
|
158
|
+
|
|
159
|
+
Invoice table:
|
|
160
|
+
PK: invoice_id
|
|
161
|
+
customer_id → customer_name, customer_address (transitive)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 3NF Detection Algorithm
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
FOR each table T:
|
|
168
|
+
FOR each pair of non-key columns (B, C):
|
|
169
|
+
IF B appears to be a foreign key (name ends in '_id', '_code', '_key')
|
|
170
|
+
AND C's name shares a prefix/entity with B (e.g., dept_id and dept_name):
|
|
171
|
+
→ WARN: "Possible transitive dependency: {B} → {C}. Consider a separate {entity} table."
|
|
172
|
+
|
|
173
|
+
IF B has a UNIQUE constraint AND C correlates with B:
|
|
174
|
+
→ WARN: "Non-key determinant {B} may create transitive dependency on {C}"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### 3NF Fix Pattern
|
|
178
|
+
|
|
179
|
+
Extract transitive dependencies into their own table:
|
|
180
|
+
|
|
181
|
+
```sql
|
|
182
|
+
-- BEFORE (violates 3NF): dept_name depends on dept_id, not employee_id
|
|
183
|
+
CREATE TABLE employees (
|
|
184
|
+
employee_id INT PRIMARY KEY,
|
|
185
|
+
employee_name VARCHAR(100),
|
|
186
|
+
dept_id INT,
|
|
187
|
+
dept_name VARCHAR(100), -- transitive dependency
|
|
188
|
+
dept_manager_name VARCHAR(100) -- transitive dependency
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
-- AFTER (3NF compliant):
|
|
192
|
+
CREATE TABLE departments (
|
|
193
|
+
dept_id INT PRIMARY KEY,
|
|
194
|
+
dept_name VARCHAR(100),
|
|
195
|
+
dept_manager_name VARCHAR(100)
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
CREATE TABLE employees (
|
|
199
|
+
employee_id INT PRIMARY KEY,
|
|
200
|
+
employee_name VARCHAR(100),
|
|
201
|
+
dept_id INT REFERENCES departments(dept_id)
|
|
202
|
+
);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Anomaly Types with Concrete Examples
|
|
206
|
+
|
|
207
|
+
### Insert Anomaly
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
-- With the un-normalized employees table above:
|
|
211
|
+
-- Cannot record a new department "Marketing" until we hire someone into it.
|
|
212
|
+
INSERT INTO employees (employee_id, employee_name, dept_id, dept_name)
|
|
213
|
+
VALUES (NULL, NULL, 5, 'Marketing'); -- Fails: employee_id is PK, cannot be NULL
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Update Anomaly
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
-- Department "Engineering" renames to "Product Engineering"
|
|
220
|
+
-- Must update EVERY employee row in that department
|
|
221
|
+
UPDATE employees SET dept_name = 'Product Engineering' WHERE dept_id = 3;
|
|
222
|
+
-- If one row is missed → inconsistent data (some say "Engineering", some say "Product Engineering")
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Delete Anomaly
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
-- Delete the last employee in the "Legal" department
|
|
229
|
+
DELETE FROM employees WHERE employee_id = 42;
|
|
230
|
+
-- The fact that department "Legal" (dept_id=7) exists is now lost entirely
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Automated Validation Checklist
|
|
234
|
+
|
|
235
|
+
Complete list of checks with severity levels, organized by NOMAD error taxonomy categories.
|
|
236
|
+
|
|
237
|
+
### Structural Checks
|
|
238
|
+
|
|
239
|
+
| # | Check | Severity | NF |
|
|
240
|
+
|---|-------|----------|----|
|
|
241
|
+
| 1 | Entity has no primary key defined | ERROR | 1NF |
|
|
242
|
+
| 2 | Duplicate rows possible (no PK, no UNIQUE) | ERROR | 1NF |
|
|
243
|
+
| 3 | Numbered column pattern detected (`col1`, `col2`, `col3`) | WARN | 1NF |
|
|
244
|
+
| 4 | Column name suggests multivalued data (plural, 'list', 'tags', 'items') | WARN | 1NF |
|
|
245
|
+
| 5 | Table has >15 columns (may need decomposition) | INFO | -- |
|
|
246
|
+
| 6 | Column stores comma-separated or array values in non-array type | ERROR | 1NF |
|
|
247
|
+
|
|
248
|
+
### Relationship Checks
|
|
249
|
+
|
|
250
|
+
| # | Check | Severity | NF |
|
|
251
|
+
|---|-------|----------|----|
|
|
252
|
+
| 7 | M:N relationship has no junction table | WARN | -- |
|
|
253
|
+
| 8 | Weak entity has no identifying relationship | WARN | -- |
|
|
254
|
+
| 9 | Circular FK dependency without proper cascade strategy | ERROR | -- |
|
|
255
|
+
| 10 | Junction table contains non-key attributes depending on single FK | WARN | 2NF |
|
|
256
|
+
|
|
257
|
+
### Semantic/Logical Checks
|
|
258
|
+
|
|
259
|
+
| # | Check | Severity | NF |
|
|
260
|
+
|---|-------|----------|----|
|
|
261
|
+
| 11 | Composite PK with non-key column not depending on full key | WARN | 2NF |
|
|
262
|
+
| 12 | Non-key column pair suggests transitive dependency (`x_id` + `x_name`) | WARN | 3NF |
|
|
263
|
+
| 13 | Non-key column with UNIQUE constraint determines other non-key columns | WARN | 3NF |
|
|
264
|
+
| 14 | Table stores derived/calculated data that could be computed from other columns | INFO | -- |
|
|
265
|
+
| 15 | Column has misleading type (e.g., VARCHAR for what should be INT/DATE) | INFO | -- |
|
|
266
|
+
|
|
267
|
+
## AI-Powered Normalization (Miffie Pattern)
|
|
268
|
+
|
|
269
|
+
Based on Miffie (arXiv 2508.17693): a dual-LLM self-refinement architecture that achieves high normalization accuracy with zero-shot prompts and no fine-tuning.
|
|
270
|
+
|
|
271
|
+
### Architecture
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
Schema Input → LLM1 (Suggester) → Normalization Suggestions → LLM2 (Validator) → Refined Output
|
|
275
|
+
↑ |
|
|
276
|
+
└────────────── Feedback Loop ───────────────────────┘
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### LLM1: Suggester Prompt
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
You are a database normalization expert. Analyze the following schema and identify
|
|
283
|
+
all normalization violations up to 3NF.
|
|
284
|
+
|
|
285
|
+
Schema:
|
|
286
|
+
{schema_definition}
|
|
287
|
+
|
|
288
|
+
For each violation found, provide:
|
|
289
|
+
1. The table and columns involved
|
|
290
|
+
2. Which normal form is violated (1NF, 2NF, or 3NF)
|
|
291
|
+
3. The specific functional dependency causing the violation
|
|
292
|
+
4. A concrete fix: the new table structure(s) needed
|
|
293
|
+
|
|
294
|
+
Format your response as a structured list. Be thorough — check every table for
|
|
295
|
+
every normal form sequentially (1NF first, then 2NF, then 3NF).
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### LLM2: Validator Prompt
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
You are a database normalization reviewer. A colleague analyzed a schema and
|
|
302
|
+
proposed normalization fixes. Your job is to validate their analysis.
|
|
303
|
+
|
|
304
|
+
Original schema:
|
|
305
|
+
{schema_definition}
|
|
306
|
+
|
|
307
|
+
Proposed violations and fixes:
|
|
308
|
+
{llm1_output}
|
|
309
|
+
|
|
310
|
+
For each proposed violation:
|
|
311
|
+
1. CONFIRM or REJECT — is this actually a violation?
|
|
312
|
+
2. If rejected, explain why (false positive detection)
|
|
313
|
+
3. If confirmed, verify the fix is correct and complete
|
|
314
|
+
4. Check if the fix introduces any NEW violations
|
|
315
|
+
5. Identify any violations the original analysis MISSED
|
|
316
|
+
|
|
317
|
+
Provide your final validated list of violations and corrected fixes.
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Integration: "Normalize My Schema" Flow
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
async function normalizeSchema(
|
|
324
|
+
schema: SchemaDefinition,
|
|
325
|
+
llm: LLMClient
|
|
326
|
+
): Promise<NormalizationReport> {
|
|
327
|
+
// Round 1: Suggest
|
|
328
|
+
const suggestions = await llm.generate({
|
|
329
|
+
model: 'claude-sonnet-4-20250514', // or gemini-2.5-pro
|
|
330
|
+
prompt: buildSuggesterPrompt(schema),
|
|
331
|
+
temperature: 0.2, // low for precision
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// Round 2: Validate
|
|
335
|
+
const validated = await llm.generate({
|
|
336
|
+
model: 'claude-sonnet-4-20250514',
|
|
337
|
+
prompt: buildValidatorPrompt(schema, suggestions),
|
|
338
|
+
temperature: 0.1, // even lower for validation
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// Round 3 (optional): Self-refinement if validator found missed violations
|
|
342
|
+
if (validated.missedViolations.length > 0) {
|
|
343
|
+
const refined = await llm.generate({
|
|
344
|
+
model: 'claude-sonnet-4-20250514',
|
|
345
|
+
prompt: buildRefinementPrompt(schema, suggestions, validated),
|
|
346
|
+
temperature: 0.1,
|
|
347
|
+
});
|
|
348
|
+
return parseNormalizationReport(refined);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return parseNormalizationReport(validated);
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## AI-Powered Profiling (Cocoon Pattern)
|
|
356
|
+
|
|
357
|
+
Based on Cocoon (ACM HILDA 2024): combines statistical profiling with LLM semantic understanding to produce human-verifiable explanations for schema issues.
|
|
358
|
+
|
|
359
|
+
### Approach
|
|
360
|
+
|
|
361
|
+
1. **Statistical analysis** -- Compute column distributions, null rates, cardinality, pattern frequency
|
|
362
|
+
2. **Semantic enrichment** -- Ask the LLM to interpret what the statistics mean for normalization
|
|
363
|
+
3. **Human-verifiable output** -- Show concrete data examples that prove each violation
|
|
364
|
+
|
|
365
|
+
### Profiling Prompt
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
Given these column statistics for table "{table_name}":
|
|
369
|
+
|
|
370
|
+
{column_statistics_json}
|
|
371
|
+
|
|
372
|
+
And these sample rows:
|
|
373
|
+
{sample_rows}
|
|
374
|
+
|
|
375
|
+
Analyze for normalization violations. For each violation you find:
|
|
376
|
+
1. State the violation type (1NF/2NF/3NF) and the columns involved
|
|
377
|
+
2. Quote the SPECIFIC sample rows that demonstrate the violation
|
|
378
|
+
3. Explain in plain English WHY this is a violation
|
|
379
|
+
4. Show what anomaly (insert/update/delete) would result from this structure
|
|
380
|
+
|
|
381
|
+
Example output format:
|
|
382
|
+
VIOLATION: 3NF transitive dependency in "orders" table
|
|
383
|
+
COLUMNS: customer_id → customer_name
|
|
384
|
+
EVIDENCE: Rows 3 and 7 both have customer_id=42 with customer_name="Alice"
|
|
385
|
+
— if Alice changes her name, both rows must be updated (update anomaly)
|
|
386
|
+
FIX: Extract customer_name to a "customers" table keyed by customer_id
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Why Cocoon Explanations Matter
|
|
390
|
+
|
|
391
|
+
Raw normalization rules are abstract. Cocoon-style output tells the developer: "Here is row 3 and row 7 from YOUR data that prove this is a problem." This turns theoretical violations into concrete evidence that justifies the refactoring cost.
|
|
392
|
+
|
|
393
|
+
## Implementation: Validator Function
|
|
394
|
+
|
|
395
|
+
TypeScript implementation that takes a schema model and returns findings. Designed for integration with an ERD tool or standalone CLI.
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
// normalization-validator.ts
|
|
399
|
+
|
|
400
|
+
interface Column {
|
|
401
|
+
name: string;
|
|
402
|
+
type: string;
|
|
403
|
+
isPrimaryKey: boolean;
|
|
404
|
+
isForeignKey: boolean;
|
|
405
|
+
isUnique: boolean;
|
|
406
|
+
isNullable: boolean;
|
|
407
|
+
referencesTable?: string;
|
|
408
|
+
referencesColumn?: string;
|
|
409
|
+
defaultValue?: string;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
interface Table {
|
|
413
|
+
name: string;
|
|
414
|
+
columns: Column[];
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
interface Relationship {
|
|
418
|
+
fromTable: string;
|
|
419
|
+
toTable: string;
|
|
420
|
+
type: 'one-to-one' | 'one-to-many' | 'many-to-many';
|
|
421
|
+
throughTable?: string; // junction table name if M:N
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
interface SchemaModel {
|
|
425
|
+
tables: Table[];
|
|
426
|
+
relationships: Relationship[];
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
type Severity = 'ERROR' | 'WARN' | 'INFO';
|
|
430
|
+
type NormalForm = '1NF' | '2NF' | '3NF' | 'structural' | 'relationship';
|
|
431
|
+
|
|
432
|
+
interface Finding {
|
|
433
|
+
severity: Severity;
|
|
434
|
+
normalForm: NormalForm;
|
|
435
|
+
table: string;
|
|
436
|
+
columns: string[];
|
|
437
|
+
message: string;
|
|
438
|
+
fix: string;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Patterns that suggest multivalued attributes
|
|
442
|
+
const PLURAL_HINTS = /(?:tags|items|values|skills|phones|emails|addresses|categories|roles|permissions|features|list|array|set)$/i;
|
|
443
|
+
const NUMBERED_COL = /^(.+?)(\d+)$/;
|
|
444
|
+
const FK_PATTERN = /^(.+?)_(?:id|code|key|fk)$/i;
|
|
445
|
+
|
|
446
|
+
function validateNormalization(schema: SchemaModel): Finding[] {
|
|
447
|
+
const findings: Finding[] = [];
|
|
448
|
+
|
|
449
|
+
for (const table of schema.tables) {
|
|
450
|
+
// === 1NF Checks ===
|
|
451
|
+
findings.push(...check1NF(table));
|
|
452
|
+
|
|
453
|
+
// === 2NF Checks ===
|
|
454
|
+
findings.push(...check2NF(table));
|
|
455
|
+
|
|
456
|
+
// === 3NF Checks ===
|
|
457
|
+
findings.push(...check3NF(table));
|
|
458
|
+
|
|
459
|
+
// === Structural Checks ===
|
|
460
|
+
findings.push(...checkStructural(table));
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// === Relationship Checks ===
|
|
464
|
+
findings.push(...checkRelationships(schema));
|
|
465
|
+
|
|
466
|
+
return findings;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function check1NF(table: Table): Finding[] {
|
|
470
|
+
const findings: Finding[] = [];
|
|
471
|
+
const pkColumns = table.columns.filter((c) => c.isPrimaryKey);
|
|
472
|
+
|
|
473
|
+
// Check 1: No primary key
|
|
474
|
+
if (pkColumns.length === 0) {
|
|
475
|
+
findings.push({
|
|
476
|
+
severity: 'ERROR',
|
|
477
|
+
normalForm: '1NF',
|
|
478
|
+
table: table.name,
|
|
479
|
+
columns: [],
|
|
480
|
+
message: `Table "${table.name}" has no primary key defined.`,
|
|
481
|
+
fix: `Add a PRIMARY KEY column (e.g., "id INT PRIMARY KEY AUTO_INCREMENT" or "id UUID PRIMARY KEY DEFAULT gen_random_uuid()").`,
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Check 2: Multivalued attribute hints
|
|
486
|
+
for (const col of table.columns) {
|
|
487
|
+
if (PLURAL_HINTS.test(col.name) && !col.isForeignKey) {
|
|
488
|
+
findings.push({
|
|
489
|
+
severity: 'WARN',
|
|
490
|
+
normalForm: '1NF',
|
|
491
|
+
table: table.name,
|
|
492
|
+
columns: [col.name],
|
|
493
|
+
message: `Column "${col.name}" name suggests multivalued data. If it stores multiple values, this violates 1NF.`,
|
|
494
|
+
fix: `Create a separate table (e.g., "${table.name}_${col.name}") with a foreign key back to "${table.name}".`,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Check for comma-separated defaults or array-like types stored as TEXT
|
|
499
|
+
if (
|
|
500
|
+
col.type.match(/^(TEXT|VARCHAR|CHAR)/i) &&
|
|
501
|
+
col.defaultValue &&
|
|
502
|
+
(col.defaultValue.includes(',') || col.defaultValue.startsWith('['))
|
|
503
|
+
) {
|
|
504
|
+
findings.push({
|
|
505
|
+
severity: 'ERROR',
|
|
506
|
+
normalForm: '1NF',
|
|
507
|
+
table: table.name,
|
|
508
|
+
columns: [col.name],
|
|
509
|
+
message: `Column "${col.name}" default value suggests comma-separated or array data in a text column.`,
|
|
510
|
+
fix: `Extract repeating values into a related table with a foreign key.`,
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Check 3: Numbered column pattern (phone1, phone2, phone3)
|
|
516
|
+
const basenames = new Map<string, string[]>();
|
|
517
|
+
for (const col of table.columns) {
|
|
518
|
+
const match = col.name.match(NUMBERED_COL);
|
|
519
|
+
if (match) {
|
|
520
|
+
const base = match[1];
|
|
521
|
+
if (!basenames.has(base)) basenames.set(base, []);
|
|
522
|
+
basenames.get(base)!.push(col.name);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
for (const [base, cols] of basenames) {
|
|
526
|
+
if (cols.length >= 2) {
|
|
527
|
+
findings.push({
|
|
528
|
+
severity: 'WARN',
|
|
529
|
+
normalForm: '1NF',
|
|
530
|
+
table: table.name,
|
|
531
|
+
columns: cols,
|
|
532
|
+
message: `Numbered column pattern detected: ${cols.join(', ')}. This is a repeating group (1NF violation).`,
|
|
533
|
+
fix: `Create a separate "${table.name}_${base}" table. Each numbered column becomes a row in the new table.`,
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
return findings;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
function check2NF(table: Table): Finding[] {
|
|
542
|
+
const findings: Finding[] = [];
|
|
543
|
+
const pkColumns = table.columns.filter((c) => c.isPrimaryKey);
|
|
544
|
+
|
|
545
|
+
// 2NF only applies to composite primary keys
|
|
546
|
+
if (pkColumns.length < 2) return findings;
|
|
547
|
+
|
|
548
|
+
const nonKeyColumns = table.columns.filter((c) => !c.isPrimaryKey);
|
|
549
|
+
const pkFKColumns = pkColumns.filter((c) => c.isForeignKey);
|
|
550
|
+
|
|
551
|
+
for (const col of nonKeyColumns) {
|
|
552
|
+
// Heuristic: if column name shares entity prefix with exactly one PK component
|
|
553
|
+
for (const pkCol of pkFKColumns) {
|
|
554
|
+
const fkMatch = pkCol.name.match(FK_PATTERN);
|
|
555
|
+
if (!fkMatch) continue;
|
|
556
|
+
|
|
557
|
+
const entityName = fkMatch[1]; // e.g., "student" from "student_id"
|
|
558
|
+
if (
|
|
559
|
+
col.name.startsWith(entityName + '_') ||
|
|
560
|
+
col.name.startsWith(entityName)
|
|
561
|
+
) {
|
|
562
|
+
findings.push({
|
|
563
|
+
severity: 'WARN',
|
|
564
|
+
normalForm: '2NF',
|
|
565
|
+
table: table.name,
|
|
566
|
+
columns: [pkCol.name, col.name],
|
|
567
|
+
message: `Possible partial dependency: "${col.name}" may depend only on "${pkCol.name}", not the full composite key.`,
|
|
568
|
+
fix: `Move "${col.name}" to the "${entityName}" table if it depends solely on "${pkCol.name}".`,
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
return findings;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function check3NF(table: Table): Finding[] {
|
|
578
|
+
const findings: Finding[] = [];
|
|
579
|
+
const nonKeyColumns = table.columns.filter((c) => !c.isPrimaryKey);
|
|
580
|
+
|
|
581
|
+
// Look for FK + related attribute pairs (e.g., dept_id + dept_name)
|
|
582
|
+
const fkColumns = nonKeyColumns.filter((c) => c.isForeignKey);
|
|
583
|
+
|
|
584
|
+
for (const fkCol of fkColumns) {
|
|
585
|
+
const fkMatch = fkCol.name.match(FK_PATTERN);
|
|
586
|
+
if (!fkMatch) continue;
|
|
587
|
+
|
|
588
|
+
const entityName = fkMatch[1]; // e.g., "dept" from "dept_id"
|
|
589
|
+
|
|
590
|
+
for (const otherCol of nonKeyColumns) {
|
|
591
|
+
if (otherCol.name === fkCol.name) continue;
|
|
592
|
+
|
|
593
|
+
if (
|
|
594
|
+
otherCol.name.startsWith(entityName + '_') &&
|
|
595
|
+
otherCol.name !== fkCol.name
|
|
596
|
+
) {
|
|
597
|
+
findings.push({
|
|
598
|
+
severity: 'WARN',
|
|
599
|
+
normalForm: '3NF',
|
|
600
|
+
table: table.name,
|
|
601
|
+
columns: [fkCol.name, otherCol.name],
|
|
602
|
+
message: `Possible transitive dependency: "${otherCol.name}" likely depends on "${fkCol.name}", not the primary key. (PK → ${fkCol.name} → ${otherCol.name})`,
|
|
603
|
+
fix: `Move "${otherCol.name}" to the "${fkCol.referencesTable || entityName}" table. Keep only "${fkCol.name}" as the foreign key reference.`,
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Look for non-FK UNIQUE columns that determine other columns
|
|
610
|
+
const uniqueNonFK = nonKeyColumns.filter(
|
|
611
|
+
(c) => c.isUnique && !c.isForeignKey
|
|
612
|
+
);
|
|
613
|
+
for (const uCol of uniqueNonFK) {
|
|
614
|
+
const uMatch = uCol.name.match(FK_PATTERN);
|
|
615
|
+
if (!uMatch) continue;
|
|
616
|
+
|
|
617
|
+
const entityName = uMatch[1];
|
|
618
|
+
for (const otherCol of nonKeyColumns) {
|
|
619
|
+
if (otherCol.name === uCol.name) continue;
|
|
620
|
+
if (otherCol.name.startsWith(entityName + '_')) {
|
|
621
|
+
findings.push({
|
|
622
|
+
severity: 'WARN',
|
|
623
|
+
normalForm: '3NF',
|
|
624
|
+
table: table.name,
|
|
625
|
+
columns: [uCol.name, otherCol.name],
|
|
626
|
+
message: `Non-key determinant: "${uCol.name}" (UNIQUE) may transitively determine "${otherCol.name}".`,
|
|
627
|
+
fix: `Extract "${uCol.name}" and "${otherCol.name}" into their own table with "${uCol.name}" as primary key.`,
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
return findings;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
function checkStructural(table: Table): Finding[] {
|
|
637
|
+
const findings: Finding[] = [];
|
|
638
|
+
|
|
639
|
+
// Column count check
|
|
640
|
+
if (table.columns.length > 15) {
|
|
641
|
+
findings.push({
|
|
642
|
+
severity: 'INFO',
|
|
643
|
+
normalForm: 'structural',
|
|
644
|
+
table: table.name,
|
|
645
|
+
columns: [],
|
|
646
|
+
message: `Table "${table.name}" has ${table.columns.length} columns. Tables with >15 columns often benefit from decomposition.`,
|
|
647
|
+
fix: `Review whether columns can be grouped into related entities (vertical partitioning).`,
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
return findings;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
function checkRelationships(schema: SchemaModel): Finding[] {
|
|
655
|
+
const findings: Finding[] = [];
|
|
656
|
+
|
|
657
|
+
// Check M:N without junction table
|
|
658
|
+
for (const rel of schema.relationships) {
|
|
659
|
+
if (rel.type === 'many-to-many' && !rel.throughTable) {
|
|
660
|
+
findings.push({
|
|
661
|
+
severity: 'WARN',
|
|
662
|
+
normalForm: 'relationship',
|
|
663
|
+
table: `${rel.fromTable} <-> ${rel.toTable}`,
|
|
664
|
+
columns: [],
|
|
665
|
+
message: `Many-to-many relationship between "${rel.fromTable}" and "${rel.toTable}" has no junction table.`,
|
|
666
|
+
fix: `Create a junction table (e.g., "${rel.fromTable}_${rel.toTable}") with foreign keys to both tables.`,
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// Check circular FK dependencies
|
|
672
|
+
const fkGraph = new Map<string, Set<string>>();
|
|
673
|
+
for (const table of schema.tables) {
|
|
674
|
+
for (const col of table.columns) {
|
|
675
|
+
if (col.isForeignKey && col.referencesTable) {
|
|
676
|
+
if (!fkGraph.has(table.name)) fkGraph.set(table.name, new Set());
|
|
677
|
+
fkGraph.get(table.name)!.add(col.referencesTable);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Cycle detection via recursive DFS with path tracking
|
|
683
|
+
const globalVisited = new Set<string>();
|
|
684
|
+
function detectCycle(node: string, path: string[], visiting: Set<string>): void {
|
|
685
|
+
if (visiting.has(node)) {
|
|
686
|
+
// Found cycle — extract only the cycle portion from the path
|
|
687
|
+
const cycleStart = path.indexOf(node);
|
|
688
|
+
const cyclePath = [...path.slice(cycleStart), node];
|
|
689
|
+
findings.push({
|
|
690
|
+
severity: 'ERROR',
|
|
691
|
+
normalForm: 'relationship',
|
|
692
|
+
table: node,
|
|
693
|
+
columns: [],
|
|
694
|
+
message: `Circular foreign key dependency: ${cyclePath.join(' → ')}.`,
|
|
695
|
+
fix: `Break the cycle by making one FK nullable, using a bridge table, or implementing application-level referential integrity for one link.`,
|
|
696
|
+
});
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
if (globalVisited.has(node)) return;
|
|
700
|
+
visiting.add(node);
|
|
701
|
+
path.push(node);
|
|
702
|
+
|
|
703
|
+
const neighbors = fkGraph.get(node);
|
|
704
|
+
if (neighbors) {
|
|
705
|
+
for (const neighbor of neighbors) {
|
|
706
|
+
detectCycle(neighbor, path, visiting);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
path.pop();
|
|
710
|
+
visiting.delete(node);
|
|
711
|
+
globalVisited.add(node);
|
|
712
|
+
}
|
|
713
|
+
for (const startTable of fkGraph.keys()) {
|
|
714
|
+
detectCycle(startTable, [], new Set());
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
return findings;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// === Entry point for ERD tool integration ===
|
|
721
|
+
function runValidator(schema: SchemaModel): {
|
|
722
|
+
findings: Finding[];
|
|
723
|
+
summary: { errors: number; warnings: number; info: number };
|
|
724
|
+
} {
|
|
725
|
+
const findings = validateNormalization(schema);
|
|
726
|
+
return {
|
|
727
|
+
findings,
|
|
728
|
+
summary: {
|
|
729
|
+
errors: findings.filter((f) => f.severity === 'ERROR').length,
|
|
730
|
+
warnings: findings.filter((f) => f.severity === 'WARN').length,
|
|
731
|
+
info: findings.filter((f) => f.severity === 'INFO').length,
|
|
732
|
+
},
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
export {
|
|
737
|
+
validateNormalization,
|
|
738
|
+
runValidator,
|
|
739
|
+
type SchemaModel,
|
|
740
|
+
type Table,
|
|
741
|
+
type Column,
|
|
742
|
+
type Relationship,
|
|
743
|
+
type Finding,
|
|
744
|
+
type Severity,
|
|
745
|
+
type NormalForm,
|
|
746
|
+
};
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
## When to Use
|
|
750
|
+
|
|
751
|
+
- Designing a new database schema (run before writing migrations)
|
|
752
|
+
- Reviewing an LLM-generated schema (NOMAD shows these have high error rates)
|
|
753
|
+
- Porting between databases (PG to MySQL, Mongo to SQL) where schema was informally designed
|
|
754
|
+
- Adding an ERD validation step to a design tool
|
|
755
|
+
- Teaching normalization concepts with concrete, automated feedback
|
|
756
|
+
|
|
757
|
+
## When NOT to Use
|
|
758
|
+
|
|
759
|
+
- **Intentional denormalization for read performance** -- Data warehouses, materialized views, and OLAP schemas deliberately violate 3NF for query speed. Document the intent and skip validation.
|
|
760
|
+
- **JSONB/document columns in PostgreSQL** -- Storing structured JSON in a JSONB column is not a 1NF violation when the column is queried as a unit or via JSON operators. Only flag it if individual JSON fields are being extracted in WHERE clauses repeatedly.
|
|
761
|
+
- **Audit/log tables** -- These are append-only and never updated, so update/delete anomalies do not apply.
|
|
762
|
+
- **Schemas already validated by a migration tool with constraints** -- If Prisma/Knex/TypeORM generates the schema from a well-typed model, most structural checks are already covered.
|
|
763
|
+
|
|
764
|
+
## Related Skills
|
|
765
|
+
|
|
766
|
+
- `database-solutions/database-schema-designer.md` -- ERD creation tool that can consume these validation results
|
|
767
|
+
- `database-solutions/erd-creator-textbook-research.md` -- Research foundation for ERD tooling
|
|
768
|
+
- `database-solutions/postgresql-to-mysql-runtime-translation.md` -- Cross-dialect translation where normalization issues surface
|
|
769
|
+
- `database-solutions/reserved-word-context-aware-quoting.md` -- SQL dialect handling
|
|
770
|
+
- `database-solutions/CONDITIONAL_SQL_MIGRATION_PATTERN.md` -- Idempotent migration patterns for fixes
|
|
771
|
+
|
|
772
|
+
## References
|
|
773
|
+
|
|
774
|
+
1. LibreTexts, *Database Design* -- Canonical normalization rules (1NF through BCNF)
|
|
775
|
+
2. Miffie -- Dual-LLM Self-Refinement for Database Normalization (arXiv 2508.17693, August 2025)
|
|
776
|
+
3. Cocoon -- LLM-Powered Data Profiling (ACM HILDA 2024, arXiv preprint)
|
|
777
|
+
4. NOMAD -- Error Taxonomy for LLM-Generated Database Schemas (arXiv 2025)
|
|
778
|
+
5. Codd, E.F. -- "A Relational Model of Data for Large Shared Data Banks" (1970) -- foundational normalization theory
|