@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,245 @@
|
|
|
1
|
+
# PostgreSQL JSONB Double-Stringified JSON - Solution & Prevention
|
|
2
|
+
|
|
3
|
+
## The Problem
|
|
4
|
+
|
|
5
|
+
When exporting or displaying data from PostgreSQL JSONB columns, JavaScript's `Object.entries()` iterates **character-by-character** instead of returning key-value pairs.
|
|
6
|
+
|
|
7
|
+
### Error Symptoms
|
|
8
|
+
```
|
|
9
|
+
PDF/Screen Output:
|
|
10
|
+
0: {
|
|
11
|
+
1: "
|
|
12
|
+
2: e
|
|
13
|
+
3: m
|
|
14
|
+
4: a
|
|
15
|
+
5: i
|
|
16
|
+
6: l
|
|
17
|
+
...
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Instead of:
|
|
21
|
+
```
|
|
22
|
+
email: user@example.com
|
|
23
|
+
name: John Doe
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Why It Was Hard
|
|
27
|
+
|
|
28
|
+
- No error is thrown - code "works" but output is wrong
|
|
29
|
+
- Happens silently in production
|
|
30
|
+
- Requires understanding of JavaScript type coercion
|
|
31
|
+
- PostgreSQL JSONB can return data as stringified JSON string
|
|
32
|
+
|
|
33
|
+
### Impact
|
|
34
|
+
|
|
35
|
+
- Export documents (PDF, CSV) are unusable
|
|
36
|
+
- Legal documents become invalid for court records
|
|
37
|
+
- User-facing data displays garbage
|
|
38
|
+
- Silent data corruption in reports
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## The Solution
|
|
43
|
+
|
|
44
|
+
### Root Cause
|
|
45
|
+
|
|
46
|
+
PostgreSQL JSONB columns sometimes return **double-stringified JSON**:
|
|
47
|
+
```javascript
|
|
48
|
+
// What you expect:
|
|
49
|
+
responses = { email: "user@example.com" }
|
|
50
|
+
|
|
51
|
+
// What you get from database:
|
|
52
|
+
responses = '{"email":"user@example.com"}' // stringified once
|
|
53
|
+
// OR
|
|
54
|
+
responses = '"{\\"email\\":\\"user@example.com\\"}"' // double-stringified!
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
When you call `Object.entries()` on a STRING:
|
|
58
|
+
```javascript
|
|
59
|
+
Object.entries('hello')
|
|
60
|
+
// Returns: [["0", "h"], ["1", "e"], ["2", "l"], ["3", "l"], ["4", "o"]]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### How to Fix
|
|
64
|
+
|
|
65
|
+
Always parse JSONB data with **double-parse protection**:
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
// Helper to safely parse JSONB responses
|
|
69
|
+
const parseResponses = (resp) => {
|
|
70
|
+
let parsed = resp || {};
|
|
71
|
+
|
|
72
|
+
// First parse (if string)
|
|
73
|
+
if (typeof parsed === 'string') {
|
|
74
|
+
try { parsed = JSON.parse(parsed); } catch { parsed = {}; }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Second parse (if still string - double-stringified)
|
|
78
|
+
if (typeof parsed === 'string') {
|
|
79
|
+
try { parsed = JSON.parse(parsed); } catch { parsed = {}; }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return parsed;
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Code Example
|
|
87
|
+
|
|
88
|
+
**Before (broken):**
|
|
89
|
+
```javascript
|
|
90
|
+
// WRONG - crashes if responses is a string
|
|
91
|
+
data.forEach(r => {
|
|
92
|
+
Object.entries(r.responses).forEach(([key, value]) => {
|
|
93
|
+
console.log(`${key}: ${value}`);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
// Output: 0: {, 1: ", 2: e, 3: m...
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**After (fixed):**
|
|
100
|
+
```javascript
|
|
101
|
+
// CORRECT - handles all cases
|
|
102
|
+
const parseResponses = (resp) => {
|
|
103
|
+
let parsed = resp || {};
|
|
104
|
+
if (typeof parsed === 'string') {
|
|
105
|
+
try { parsed = JSON.parse(parsed); } catch { parsed = {}; }
|
|
106
|
+
}
|
|
107
|
+
if (typeof parsed === 'string') {
|
|
108
|
+
try { parsed = JSON.parse(parsed); } catch { parsed = {}; }
|
|
109
|
+
}
|
|
110
|
+
return parsed;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
data.forEach(r => {
|
|
114
|
+
const responses = parseResponses(r.responses);
|
|
115
|
+
Object.entries(responses).forEach(([key, value]) => {
|
|
116
|
+
console.log(`${key}: ${value}`);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
// Output: email: user@example.com, name: John Doe
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Testing the Fix
|
|
125
|
+
|
|
126
|
+
### Before
|
|
127
|
+
```
|
|
128
|
+
PDF Export shows:
|
|
129
|
+
0: {
|
|
130
|
+
1: "
|
|
131
|
+
2: e
|
|
132
|
+
...
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### After
|
|
136
|
+
```
|
|
137
|
+
PDF Export shows:
|
|
138
|
+
Question 1: What is your email?
|
|
139
|
+
Answer: user@example.com
|
|
140
|
+
|
|
141
|
+
Question 2: What is your name?
|
|
142
|
+
Answer: John Doe
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Quick Test
|
|
146
|
+
```javascript
|
|
147
|
+
// Test helper function
|
|
148
|
+
const testCases = [
|
|
149
|
+
{ email: 'test@test.com' }, // Object
|
|
150
|
+
'{"email":"test@test.com"}', // Single stringify
|
|
151
|
+
'"{\\"email\\":\\"test@test.com\\"}"', // Double stringify
|
|
152
|
+
null, // Null
|
|
153
|
+
undefined, // Undefined
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
testCases.forEach((input, i) => {
|
|
157
|
+
const result = parseResponses(input);
|
|
158
|
+
console.log(`Case ${i}: ${typeof result} - email: ${result.email}`);
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Prevention
|
|
165
|
+
|
|
166
|
+
1. **Always use parseResponses helper** for any JSONB column data
|
|
167
|
+
2. **Check typeof before Object.entries/keys/values**
|
|
168
|
+
3. **Add defensive parsing** at the data access layer
|
|
169
|
+
4. **Log types during debugging**: `console.log(typeof responses, responses)`
|
|
170
|
+
5. **Consider normalizing** at the API/model level
|
|
171
|
+
|
|
172
|
+
### API-Level Fix (Optional)
|
|
173
|
+
```javascript
|
|
174
|
+
// In your model or controller
|
|
175
|
+
const getResponses = async (id) => {
|
|
176
|
+
const result = await sql`SELECT * FROM questionnaire_responses WHERE id = ${id}`;
|
|
177
|
+
const row = result[0];
|
|
178
|
+
|
|
179
|
+
// Normalize at data layer
|
|
180
|
+
if (row && typeof row.responses === 'string') {
|
|
181
|
+
try { row.responses = JSON.parse(row.responses); } catch {}
|
|
182
|
+
}
|
|
183
|
+
if (row && typeof row.responses === 'string') {
|
|
184
|
+
try { row.responses = JSON.parse(row.responses); } catch {}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return row;
|
|
188
|
+
};
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Related Patterns
|
|
194
|
+
|
|
195
|
+
- [JSON Data Handling](../patterns-standards/JSON_DATA_HANDLING.md)
|
|
196
|
+
- [PostgreSQL JSONB Best Practices](../database-solutions/POSTGRESQL_JSONB_PATTERNS.md)
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Common Mistakes to Avoid
|
|
201
|
+
|
|
202
|
+
- ❌ **Assuming JSONB always returns objects** - It can return strings
|
|
203
|
+
- ❌ **Single JSON.parse** - May need double parse
|
|
204
|
+
- ❌ **Not handling null/undefined** - Always default to empty object
|
|
205
|
+
- ❌ **Catching parse errors silently** - Log them for debugging
|
|
206
|
+
- ❌ **Trusting Object.entries blindly** - Check type first
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## When This Happens
|
|
211
|
+
|
|
212
|
+
Common scenarios where double-stringify occurs:
|
|
213
|
+
1. **ORM serialization** - Some ORMs double-serialize
|
|
214
|
+
2. **API responses** - JSON within JSON
|
|
215
|
+
3. **Database migrations** - Data inserted as strings
|
|
216
|
+
4. **Copy/paste data** - Manual data entry as string
|
|
217
|
+
5. **Legacy data** - Old records stored differently
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Resources
|
|
222
|
+
|
|
223
|
+
- [MDN Object.entries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries)
|
|
224
|
+
- [PostgreSQL JSONB Docs](https://www.postgresql.org/docs/current/datatype-json.html)
|
|
225
|
+
- [postgres.js library](https://github.com/porsager/postgres)
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Time to Implement
|
|
230
|
+
|
|
231
|
+
**5 minutes** - Add helper function and use it where needed
|
|
232
|
+
|
|
233
|
+
## Difficulty Level
|
|
234
|
+
|
|
235
|
+
⭐⭐ (2/5) - Easy fix once identified, but hard to diagnose initially
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
**Author Notes:**
|
|
240
|
+
|
|
241
|
+
This bug wasted 30+ minutes of debugging time. The symptoms (vertical characters in PDF) were bizarre and didn't immediately point to JSON parsing. The key insight was checking `typeof responses` before iterating.
|
|
242
|
+
|
|
243
|
+
Always ask: **"Is this actually an object, or is it a string that looks like an object?"**
|
|
244
|
+
|
|
245
|
+
Real-world example: QuestionnaireManager.jsx PDF export for legal documents.
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# PostgreSQL License Table Design - Best Practices & Patterns
|
|
2
|
+
|
|
3
|
+
## The Problem
|
|
4
|
+
|
|
5
|
+
Designing a software licensing system database that supports:
|
|
6
|
+
- License key generation and validation
|
|
7
|
+
- Multi-site activation tracking
|
|
8
|
+
- Tier-based feature limits
|
|
9
|
+
- Payment tracking
|
|
10
|
+
- Audit trail
|
|
11
|
+
|
|
12
|
+
### Why It Was Hard
|
|
13
|
+
|
|
14
|
+
- Many design decisions with performance implications
|
|
15
|
+
- Need to handle case-insensitive domain matching
|
|
16
|
+
- Activation counts must stay synchronized
|
|
17
|
+
- Money storage has precision/rounding issues
|
|
18
|
+
- Foreign key types must match referenced tables
|
|
19
|
+
|
|
20
|
+
### Impact
|
|
21
|
+
|
|
22
|
+
Poor database design leads to:
|
|
23
|
+
- Race conditions with activation counting
|
|
24
|
+
- Case-sensitivity bugs with domain matching
|
|
25
|
+
- Rounding errors with money calculations
|
|
26
|
+
- Performance issues with missing indexes
|
|
27
|
+
- Type mismatches breaking queries
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## The Solution
|
|
32
|
+
|
|
33
|
+
### Key Design Principles Applied
|
|
34
|
+
|
|
35
|
+
1. **Match FK types to referenced tables** - Use UUID if profiles/orders use UUID
|
|
36
|
+
2. **Use ENUM for constrained values** - Prevents invalid data
|
|
37
|
+
3. **Store money as integer cents** - Avoids floating-point precision issues
|
|
38
|
+
4. **Use functional indexes for case-insensitivity** - `lower(domain)`
|
|
39
|
+
5. **Auto-sync counts via triggers** - Prevents drift
|
|
40
|
+
6. **Row-level locking in triggers** - Prevents race conditions
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Complete Migration Example
|
|
45
|
+
|
|
46
|
+
```sql
|
|
47
|
+
-- =====================================================
|
|
48
|
+
-- Migration: Create Licenses Table (Best Practices)
|
|
49
|
+
-- =====================================================
|
|
50
|
+
|
|
51
|
+
-- Create ENUM types if they don't exist
|
|
52
|
+
DO $$
|
|
53
|
+
BEGIN
|
|
54
|
+
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'license_tier') THEN
|
|
55
|
+
CREATE TYPE license_tier AS ENUM ('trial', 'pro', 'enterprise');
|
|
56
|
+
END IF;
|
|
57
|
+
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'license_status') THEN
|
|
58
|
+
CREATE TYPE license_status AS ENUM ('pending', 'active', 'expired', 'revoked', 'suspended');
|
|
59
|
+
END IF;
|
|
60
|
+
END$$ LANGUAGE plpgsql;
|
|
61
|
+
|
|
62
|
+
-- Create licenses table
|
|
63
|
+
CREATE TABLE IF NOT EXISTS licenses (
|
|
64
|
+
-- UUID matches profiles/orders/products tables
|
|
65
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
66
|
+
|
|
67
|
+
license_key text NOT NULL UNIQUE,
|
|
68
|
+
|
|
69
|
+
-- ENUM constrains valid values
|
|
70
|
+
tier license_tier NOT NULL DEFAULT 'trial',
|
|
71
|
+
status license_status NOT NULL DEFAULT 'pending',
|
|
72
|
+
|
|
73
|
+
-- FK types match referenced tables (uuid)
|
|
74
|
+
user_id uuid REFERENCES profiles(id) ON DELETE SET NULL,
|
|
75
|
+
order_id uuid REFERENCES orders(id) ON DELETE SET NULL,
|
|
76
|
+
product_id uuid REFERENCES products(id) ON DELETE SET NULL,
|
|
77
|
+
|
|
78
|
+
-- Denormalized for audit trail (survives user deletion)
|
|
79
|
+
user_email text,
|
|
80
|
+
user_name text,
|
|
81
|
+
order_number text,
|
|
82
|
+
|
|
83
|
+
-- JSONB for flexible feature flags
|
|
84
|
+
features jsonb NOT NULL DEFAULT '[]'::jsonb,
|
|
85
|
+
|
|
86
|
+
-- License limits
|
|
87
|
+
max_students integer NOT NULL DEFAULT 100,
|
|
88
|
+
max_sites integer NOT NULL DEFAULT 1,
|
|
89
|
+
max_courses integer NOT NULL DEFAULT 5,
|
|
90
|
+
max_activations integer NOT NULL DEFAULT 1, -- -1 = unlimited
|
|
91
|
+
|
|
92
|
+
-- Activation tracking (count auto-synced by trigger)
|
|
93
|
+
activation_count integer NOT NULL DEFAULT 0,
|
|
94
|
+
activated_at timestamptz,
|
|
95
|
+
activated_domain text,
|
|
96
|
+
|
|
97
|
+
-- Validity period
|
|
98
|
+
valid_from timestamptz NOT NULL DEFAULT now(),
|
|
99
|
+
expires_at timestamptz,
|
|
100
|
+
duration_days integer NOT NULL DEFAULT 365,
|
|
101
|
+
|
|
102
|
+
-- Money as integer cents (avoids rounding!)
|
|
103
|
+
amount_paid_cents bigint,
|
|
104
|
+
currency varchar(3) NOT NULL DEFAULT 'USD', -- varchar avoids char padding
|
|
105
|
+
stripe_payment_intent_id text,
|
|
106
|
+
|
|
107
|
+
-- Audit trail
|
|
108
|
+
revoked_at timestamptz,
|
|
109
|
+
revoked_reason text,
|
|
110
|
+
revoked_by uuid REFERENCES profiles(id) ON DELETE SET NULL,
|
|
111
|
+
|
|
112
|
+
-- Timestamps
|
|
113
|
+
created_at timestamptz NOT NULL DEFAULT now(),
|
|
114
|
+
updated_at timestamptz NOT NULL DEFAULT now()
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
-- Activations table (no table-level functional constraints!)
|
|
118
|
+
CREATE TABLE IF NOT EXISTS license_activations (
|
|
119
|
+
id bigserial PRIMARY KEY,
|
|
120
|
+
license_id uuid NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
|
|
121
|
+
|
|
122
|
+
domain text NOT NULL, -- Stored as-is, uniqueness via index
|
|
123
|
+
site_name text,
|
|
124
|
+
|
|
125
|
+
activated_at timestamptz NOT NULL DEFAULT now(),
|
|
126
|
+
deactivated_at timestamptz,
|
|
127
|
+
|
|
128
|
+
server_ip inet, -- Proper IP type
|
|
129
|
+
php_version text,
|
|
130
|
+
node_version text,
|
|
131
|
+
|
|
132
|
+
is_active boolean NOT NULL DEFAULT true
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
-- =====================================================
|
|
136
|
+
-- INDEXES
|
|
137
|
+
-- =====================================================
|
|
138
|
+
|
|
139
|
+
-- Case-insensitive unique constraint (NOT table constraint!)
|
|
140
|
+
-- WRONG: UNIQUE(license_id, lower(domain)) -- syntax error
|
|
141
|
+
-- RIGHT: Functional unique index
|
|
142
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ux_license_activations_license_domain
|
|
143
|
+
ON license_activations (license_id, lower(domain));
|
|
144
|
+
|
|
145
|
+
-- Composite indexes for common queries
|
|
146
|
+
CREATE INDEX IF NOT EXISTS idx_licenses_user_id_status
|
|
147
|
+
ON licenses(user_id, status);
|
|
148
|
+
CREATE INDEX IF NOT EXISTS idx_licenses_tier_expires_at
|
|
149
|
+
ON licenses(tier, expires_at);
|
|
150
|
+
|
|
151
|
+
-- Partial indexes (only index what you query)
|
|
152
|
+
CREATE INDEX IF NOT EXISTS idx_licenses_expires_at
|
|
153
|
+
ON licenses(expires_at) WHERE expires_at IS NOT NULL;
|
|
154
|
+
CREATE INDEX IF NOT EXISTS idx_licenses_is_active
|
|
155
|
+
ON licenses(is_active) WHERE is_active = true;
|
|
156
|
+
|
|
157
|
+
-- GIN index for JSONB queries
|
|
158
|
+
CREATE INDEX IF NOT EXISTS idx_licenses_features_gin
|
|
159
|
+
ON licenses USING GIN (features);
|
|
160
|
+
|
|
161
|
+
-- =====================================================
|
|
162
|
+
-- TRIGGERS
|
|
163
|
+
-- =====================================================
|
|
164
|
+
|
|
165
|
+
-- Auto-update updated_at timestamp
|
|
166
|
+
CREATE OR REPLACE FUNCTION set_updated_at_column()
|
|
167
|
+
RETURNS TRIGGER AS $$
|
|
168
|
+
BEGIN
|
|
169
|
+
NEW.updated_at = now();
|
|
170
|
+
RETURN NEW;
|
|
171
|
+
END;
|
|
172
|
+
$$ LANGUAGE plpgsql;
|
|
173
|
+
|
|
174
|
+
CREATE TRIGGER trg_licenses_set_updated_at
|
|
175
|
+
BEFORE UPDATE ON licenses
|
|
176
|
+
FOR EACH ROW EXECUTE FUNCTION set_updated_at_column();
|
|
177
|
+
|
|
178
|
+
-- Enforce activation_count <= max_activations
|
|
179
|
+
CREATE OR REPLACE FUNCTION enforce_activation_count()
|
|
180
|
+
RETURNS TRIGGER AS $$
|
|
181
|
+
BEGIN
|
|
182
|
+
IF NEW.max_activations != -1 AND NEW.activation_count > NEW.max_activations THEN
|
|
183
|
+
RAISE EXCEPTION 'activation_count (%) cannot exceed max_activations (%)',
|
|
184
|
+
NEW.activation_count, NEW.max_activations;
|
|
185
|
+
END IF;
|
|
186
|
+
RETURN NEW;
|
|
187
|
+
END;
|
|
188
|
+
$$ LANGUAGE plpgsql;
|
|
189
|
+
|
|
190
|
+
CREATE TRIGGER trg_licenses_check_activation_count
|
|
191
|
+
BEFORE INSERT OR UPDATE ON licenses
|
|
192
|
+
FOR EACH ROW EXECUTE FUNCTION enforce_activation_count();
|
|
193
|
+
|
|
194
|
+
-- Auto-sync activation_count (with row locking!)
|
|
195
|
+
CREATE OR REPLACE FUNCTION sync_license_activation_count()
|
|
196
|
+
RETURNS TRIGGER AS $$
|
|
197
|
+
DECLARE
|
|
198
|
+
active_count integer;
|
|
199
|
+
target_license_id uuid;
|
|
200
|
+
BEGIN
|
|
201
|
+
target_license_id := COALESCE(NEW.license_id, OLD.license_id);
|
|
202
|
+
|
|
203
|
+
-- Lock row to prevent race conditions
|
|
204
|
+
PERFORM 1 FROM licenses WHERE id = target_license_id FOR UPDATE;
|
|
205
|
+
|
|
206
|
+
-- Recount active activations
|
|
207
|
+
SELECT COUNT(*) INTO active_count
|
|
208
|
+
FROM license_activations
|
|
209
|
+
WHERE license_id = target_license_id AND is_active = true;
|
|
210
|
+
|
|
211
|
+
-- Update the count
|
|
212
|
+
UPDATE licenses SET activation_count = active_count
|
|
213
|
+
WHERE id = target_license_id;
|
|
214
|
+
|
|
215
|
+
-- AFTER triggers should return NULL
|
|
216
|
+
RETURN NULL;
|
|
217
|
+
END;
|
|
218
|
+
$$ LANGUAGE plpgsql;
|
|
219
|
+
|
|
220
|
+
CREATE TRIGGER trg_sync_activation_count
|
|
221
|
+
AFTER INSERT OR UPDATE OR DELETE ON license_activations
|
|
222
|
+
FOR EACH ROW EXECUTE FUNCTION sync_license_activation_count();
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Common Mistakes to Avoid
|
|
228
|
+
|
|
229
|
+
### ❌ Using SERIAL when tables use UUID
|
|
230
|
+
```sql
|
|
231
|
+
-- BAD: Type mismatch with profiles(id) which is uuid
|
|
232
|
+
user_id INTEGER REFERENCES profiles(id)
|
|
233
|
+
|
|
234
|
+
-- GOOD: Match the referenced type
|
|
235
|
+
user_id uuid REFERENCES profiles(id)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### ❌ Table-level functional UNIQUE constraint
|
|
239
|
+
```sql
|
|
240
|
+
-- BAD: Syntax error - can't use functions in table constraints
|
|
241
|
+
CONSTRAINT uq_domain UNIQUE(license_id, lower(domain))
|
|
242
|
+
|
|
243
|
+
-- GOOD: Create a functional unique index instead
|
|
244
|
+
CREATE UNIQUE INDEX ON table (license_id, lower(domain));
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### ❌ Storing money as DECIMAL
|
|
248
|
+
```sql
|
|
249
|
+
-- BAD: Floating-point precision issues
|
|
250
|
+
amount_paid DECIMAL(10, 2) -- $99.99 might become 99.98999...
|
|
251
|
+
|
|
252
|
+
-- GOOD: Store as integer cents
|
|
253
|
+
amount_paid_cents bigint -- $99.99 = 9999 cents
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### ❌ Using char(n) for short strings
|
|
257
|
+
```sql
|
|
258
|
+
-- BAD: char pads with spaces, causes comparison issues
|
|
259
|
+
currency char(3) -- 'USD' becomes 'USD ' internally
|
|
260
|
+
|
|
261
|
+
-- GOOD: varchar doesn't pad
|
|
262
|
+
currency varchar(3)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### ❌ Manual count management
|
|
266
|
+
```sql
|
|
267
|
+
-- BAD: Counts can drift out of sync
|
|
268
|
+
UPDATE licenses SET activation_count = activation_count + 1
|
|
269
|
+
|
|
270
|
+
-- GOOD: Trigger auto-syncs from actual data
|
|
271
|
+
-- (see sync_license_activation_count trigger above)
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### ❌ AFTER trigger returning non-NULL
|
|
275
|
+
```sql
|
|
276
|
+
-- BAD: Return value is ignored for AFTER triggers
|
|
277
|
+
RETURN NEW;
|
|
278
|
+
|
|
279
|
+
-- GOOD: Return NULL for AFTER triggers
|
|
280
|
+
RETURN NULL;
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Application Code Integration
|
|
286
|
+
|
|
287
|
+
### Converting dollars to cents
|
|
288
|
+
```javascript
|
|
289
|
+
// When storing
|
|
290
|
+
const amountCents = Math.round(dollarAmount * 100);
|
|
291
|
+
|
|
292
|
+
// When displaying
|
|
293
|
+
const displayAmount = (amountCents / 100).toFixed(2);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Checking unlimited activations
|
|
297
|
+
```javascript
|
|
298
|
+
const isUnlimited = license.max_activations === -1;
|
|
299
|
+
const canActivate = isUnlimited ||
|
|
300
|
+
license.activation_count < license.max_activations;
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
### Domain normalization
|
|
304
|
+
```javascript
|
|
305
|
+
// Always lowercase domains before storing/comparing
|
|
306
|
+
const normalizedDomain = domain.toLowerCase().trim();
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Testing the Design
|
|
312
|
+
|
|
313
|
+
### Verify triggers work
|
|
314
|
+
```sql
|
|
315
|
+
-- Insert an activation
|
|
316
|
+
INSERT INTO license_activations (license_id, domain)
|
|
317
|
+
VALUES ('uuid-here', 'Example.COM');
|
|
318
|
+
|
|
319
|
+
-- Check count was auto-updated
|
|
320
|
+
SELECT activation_count FROM licenses WHERE id = 'uuid-here';
|
|
321
|
+
-- Should be 1
|
|
322
|
+
|
|
323
|
+
-- Verify case-insensitive uniqueness
|
|
324
|
+
INSERT INTO license_activations (license_id, domain)
|
|
325
|
+
VALUES ('uuid-here', 'EXAMPLE.com');
|
|
326
|
+
-- Should fail: duplicate key violation
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Verify enum constraints
|
|
330
|
+
```sql
|
|
331
|
+
INSERT INTO licenses (license_key, tier)
|
|
332
|
+
VALUES ('TEST-KEY', 'invalid_tier');
|
|
333
|
+
-- Should fail: invalid input value for enum
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Prevention Checklist
|
|
339
|
+
|
|
340
|
+
Before creating any database table:
|
|
341
|
+
|
|
342
|
+
- [ ] Check FK column types match referenced tables
|
|
343
|
+
- [ ] Use ENUM for columns with fixed valid values
|
|
344
|
+
- [ ] Store money as integer cents
|
|
345
|
+
- [ ] Use `varchar` not `char` for short strings
|
|
346
|
+
- [ ] Use `inet` type for IP addresses
|
|
347
|
+
- [ ] Functional constraints → use indexes, not table constraints
|
|
348
|
+
- [ ] Add `updated_at` trigger for audit trails
|
|
349
|
+
- [ ] Use row locking in count-sync triggers
|
|
350
|
+
- [ ] Add partial indexes for common filtered queries
|
|
351
|
+
- [ ] Add GIN index for JSONB columns you'll query
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Related Patterns
|
|
356
|
+
|
|
357
|
+
- Database Migration Best Practices
|
|
358
|
+
- Knex.js Database Abstraction
|
|
359
|
+
- Stripe Webhook Integration (for payment flow)
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Resources
|
|
364
|
+
|
|
365
|
+
- [PostgreSQL ENUM Types](https://www.postgresql.org/docs/current/datatype-enum.html)
|
|
366
|
+
- [PostgreSQL Partial Indexes](https://www.postgresql.org/docs/current/indexes-partial.html)
|
|
367
|
+
- [PostgreSQL Triggers](https://www.postgresql.org/docs/current/plpgsql-trigger.html)
|
|
368
|
+
- [Money Storage Best Practices](https://stackoverflow.com/questions/224462/storing-money-in-a-decimal-column-what-precision-and-scale)
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Time to Implement
|
|
373
|
+
|
|
374
|
+
**Initial design:** 2-3 hours
|
|
375
|
+
**Applying to existing table:** 30-60 minutes
|
|
376
|
+
**With inspector review:** Add 30 minutes for improvements
|
|
377
|
+
|
|
378
|
+
## Difficulty Level
|
|
379
|
+
|
|
380
|
+
⭐⭐⭐ (3/5) - Requires understanding of PostgreSQL features, but patterns are reusable
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
**Author Notes:**
|
|
385
|
+
|
|
386
|
+
This pattern emerged from a Supabase database inspector review. The inspector caught several issues:
|
|
387
|
+
1. Table-level functional UNIQUE constraint (syntax error)
|
|
388
|
+
2. Missing LANGUAGE clause on DO block
|
|
389
|
+
3. char(3) padding issues
|
|
390
|
+
4. AFTER trigger return values
|
|
391
|
+
5. Race conditions in count sync
|
|
392
|
+
|
|
393
|
+
The key insight: **PostgreSQL has the right tool for every job** - ENUM for constrained values, functional indexes for case-insensitivity, triggers for derived data, partial indexes for selective queries. Use them!
|