@thierrynakoa/fire-flow 12.2.2 → 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 -690
- package/TROUBLESHOOTING.md +264 -367
- 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-verify-uat.md +9 -177
- 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 -25
- 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/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/browser-use-expert.md +0 -210
- 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,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: liveclock-extraction
|
|
3
|
+
category: performance
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-03-12
|
|
6
|
+
contributor: claude-mission-control
|
|
7
|
+
last_updated: 2026-03-12
|
|
8
|
+
contributors:
|
|
9
|
+
- claude-mission-control
|
|
10
|
+
tags: [react, performance, re-renders, state-isolation, composition]
|
|
11
|
+
difficulty: easy
|
|
12
|
+
usage_count: 0
|
|
13
|
+
success_rate: 100
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# LiveClock Extraction — Isolating High-Frequency Timers
|
|
17
|
+
|
|
18
|
+
## Problem
|
|
19
|
+
|
|
20
|
+
A `useEffect` + `setInterval` that updates a clock or timer every second in a parent component (like `App.tsx` or a layout wrapper) causes the **entire component tree** to re-render once per second. If the parent renders a sidebar, header, navigation, and multiple panels, all of them re-render 60 times per minute for a single clock display.
|
|
21
|
+
|
|
22
|
+
**Symptoms:**
|
|
23
|
+
- React DevTools shows App re-rendering every ~1000ms
|
|
24
|
+
- All child components flash in Profiler even though only the clock changed
|
|
25
|
+
- Input fields lose focus or feel laggy
|
|
26
|
+
- `useCurrentTime()` or similar hook used in a large parent
|
|
27
|
+
|
|
28
|
+
## Solution Pattern
|
|
29
|
+
|
|
30
|
+
Extract the timer into the smallest possible leaf component. The leaf owns the state and the interval. The parent never re-renders from clock ticks.
|
|
31
|
+
|
|
32
|
+
**Principle:** State should live in the component that renders it, not in a parent that passes it down.
|
|
33
|
+
|
|
34
|
+
## Code Example
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// Before (1Hz full-tree re-renders)
|
|
38
|
+
function App() {
|
|
39
|
+
const [time, setTime] = useState(new Date())
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const id = setInterval(() => setTime(new Date()), 1000)
|
|
42
|
+
return () => clearInterval(id)
|
|
43
|
+
}, [])
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div>
|
|
47
|
+
<Header /> {/* re-renders every second */}
|
|
48
|
+
<Sidebar /> {/* re-renders every second */}
|
|
49
|
+
<span>{time.toLocaleTimeString()}</span>
|
|
50
|
+
<MainContent /> {/* re-renders every second */}
|
|
51
|
+
</div>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// After (only LiveClock re-renders)
|
|
56
|
+
function LiveClock() {
|
|
57
|
+
const [time, setTime] = useState(new Date())
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const id = setInterval(() => setTime(new Date()), 1000)
|
|
60
|
+
return () => clearInterval(id)
|
|
61
|
+
}, [])
|
|
62
|
+
return (
|
|
63
|
+
<span className="text-xs font-mono">
|
|
64
|
+
{time.toLocaleTimeString('en-US', {
|
|
65
|
+
hour: '2-digit', minute: '2-digit', second: '2-digit'
|
|
66
|
+
})}
|
|
67
|
+
</span>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function App() {
|
|
72
|
+
return (
|
|
73
|
+
<div>
|
|
74
|
+
<Header />
|
|
75
|
+
<Sidebar />
|
|
76
|
+
<LiveClock /> {/* only this re-renders */}
|
|
77
|
+
<MainContent />
|
|
78
|
+
</div>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Implementation Steps
|
|
84
|
+
|
|
85
|
+
1. Find any `useState` + `setInterval` pattern in large parent components
|
|
86
|
+
2. Create a small leaf component that owns both the state and the render
|
|
87
|
+
3. Replace the inline rendering in the parent with the new component
|
|
88
|
+
4. Verify: React DevTools Profiler should show only the leaf re-rendering
|
|
89
|
+
|
|
90
|
+
## When to Use
|
|
91
|
+
|
|
92
|
+
- Clocks, timers, countdowns, "X minutes ago" displays in layout components
|
|
93
|
+
- Any high-frequency state update (polling status indicators, progress bars) in a parent
|
|
94
|
+
- Animated indicators (blinking dots, pulse effects) driven by `setInterval`
|
|
95
|
+
|
|
96
|
+
## When NOT to Use
|
|
97
|
+
|
|
98
|
+
- When the time/value is genuinely needed by siblings (lift state or use context)
|
|
99
|
+
- When the parent component is already small and cheap to render
|
|
100
|
+
- Server components (no client-side intervals)
|
|
101
|
+
|
|
102
|
+
## Common Mistakes
|
|
103
|
+
|
|
104
|
+
- Extracting the component but still passing time as a prop from parent — defeats the purpose
|
|
105
|
+
- Using a custom hook like `useCurrentTime()` in the parent — the hook's state still lives in the parent
|
|
106
|
+
- Creating the leaf component but wrapping it in `React.memo` on the parent side — unnecessary, the fix is isolation not memoization
|
|
107
|
+
|
|
108
|
+
## References
|
|
109
|
+
|
|
110
|
+
- React docs: "Extracting State Logic into Components"
|
|
111
|
+
- Dan Abramov: "Before You memo()" — restructure before optimizing
|
|
112
|
+
- Contributed from: claude-mission-control App.tsx (eliminated 1Hz full-tree re-renders)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ref-based-canvas-animation
|
|
3
|
+
category: performance
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-03-12
|
|
6
|
+
contributor: claude-mission-control
|
|
7
|
+
last_updated: 2026-03-12
|
|
8
|
+
contributors:
|
|
9
|
+
- claude-mission-control
|
|
10
|
+
tags: [react, canvas, animation, requestAnimationFrame, performance, refs]
|
|
11
|
+
difficulty: medium
|
|
12
|
+
usage_count: 0
|
|
13
|
+
success_rate: 100
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Ref-Based Canvas Animation — Avoiding State in rAF Loops
|
|
17
|
+
|
|
18
|
+
## Problem
|
|
19
|
+
|
|
20
|
+
Using `useState` + `setNodes()` inside a `requestAnimationFrame` loop triggers a full React re-render on every frame (~60fps = ~60 re-renders/second). For canvas-based visualizations (knowledge graphs, particle systems, physics simulations), this causes severe jank, dropped frames, and cascading re-renders in parent components.
|
|
21
|
+
|
|
22
|
+
**Symptoms:**
|
|
23
|
+
- React DevTools Profiler shows 300+ re-renders in 5 seconds from one component
|
|
24
|
+
- Canvas animation stutters or freezes
|
|
25
|
+
- Other UI elements (inputs, buttons) become unresponsive during animation
|
|
26
|
+
- `setNodes([...nodes])` called every animation frame
|
|
27
|
+
|
|
28
|
+
## Solution Pattern
|
|
29
|
+
|
|
30
|
+
Store simulation state in `useRef` instead of `useState`. The rAF loop reads and mutates refs directly, drawing to canvas via `CanvasRenderingContext2D`. React state is synced **once** when animation ends (or on a debounced timer), not every frame.
|
|
31
|
+
|
|
32
|
+
**Why this works:** Refs don't trigger re-renders. The canvas is an imperative API — you draw directly to it, bypassing React's virtual DOM entirely. React only needs to know the final state for event handlers and conditional rendering.
|
|
33
|
+
|
|
34
|
+
## Code Example
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// Before (300 re-renders in 5 seconds)
|
|
38
|
+
const [nodes, setNodes] = useState(initialNodes)
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const loop = () => {
|
|
41
|
+
simulatePhysics(nodes)
|
|
42
|
+
setNodes([...nodes]) // RE-RENDER EVERY FRAME
|
|
43
|
+
requestAnimationFrame(loop)
|
|
44
|
+
}
|
|
45
|
+
loop()
|
|
46
|
+
}, [nodes.length > 0]) // Also: boolean dependency never changes
|
|
47
|
+
|
|
48
|
+
// After (1 re-render at animation end)
|
|
49
|
+
const nodesRef = useRef(initialNodes)
|
|
50
|
+
const edgesRef = useRef(initialEdges)
|
|
51
|
+
const [nodes, setNodes] = useState(initialNodes)
|
|
52
|
+
|
|
53
|
+
const simulateStep = useCallback(() => {
|
|
54
|
+
const ns = nodesRef.current
|
|
55
|
+
// ... physics calculations mutate ns directly ...
|
|
56
|
+
}, [])
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (nodes.length === 0) return
|
|
60
|
+
nodesRef.current = [...nodes]
|
|
61
|
+
let running = true
|
|
62
|
+
|
|
63
|
+
const loop = () => {
|
|
64
|
+
if (!running) return
|
|
65
|
+
simulateStep()
|
|
66
|
+
drawCanvas(ctx, nodesRef.current, edgesRef.current) // Direct canvas draw
|
|
67
|
+
requestAnimationFrame(loop)
|
|
68
|
+
}
|
|
69
|
+
loop()
|
|
70
|
+
|
|
71
|
+
const timeout = setTimeout(() => {
|
|
72
|
+
running = false
|
|
73
|
+
setNodes([...nodesRef.current]) // Sync once at end
|
|
74
|
+
}, 5000)
|
|
75
|
+
|
|
76
|
+
return () => { running = false; clearTimeout(timeout) }
|
|
77
|
+
}, [nodes.length]) // Number dependency, not boolean
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Implementation Steps
|
|
81
|
+
|
|
82
|
+
1. Create `useRef` mirrors for all animation state (nodes, edges, particles, etc.)
|
|
83
|
+
2. Extract canvas drawing into a standalone function: `drawCanvas(ctx, ...refs)`
|
|
84
|
+
3. Move physics/simulation logic to operate on refs, not state
|
|
85
|
+
4. In the rAF loop: mutate refs → draw canvas → repeat
|
|
86
|
+
5. Sync refs back to state once when animation completes or pauses
|
|
87
|
+
6. Fix dependency arrays: use `.length` (number), not `.length > 0` (boolean)
|
|
88
|
+
|
|
89
|
+
## When to Use
|
|
90
|
+
|
|
91
|
+
- Canvas-based visualizations (graphs, charts, particles, physics)
|
|
92
|
+
- Any `requestAnimationFrame` loop in React
|
|
93
|
+
- Drag-and-drop with real-time position updates
|
|
94
|
+
- Game loops or interactive simulations in React
|
|
95
|
+
|
|
96
|
+
## When NOT to Use
|
|
97
|
+
|
|
98
|
+
- DOM-based animations (use CSS transitions or Framer Motion instead)
|
|
99
|
+
- Simple animations where React's render cycle is fast enough (opacity, transforms)
|
|
100
|
+
- Components where other parts of the tree need frame-by-frame state updates
|
|
101
|
+
|
|
102
|
+
## Common Mistakes
|
|
103
|
+
|
|
104
|
+
- Forgetting to sync refs back to state — event handlers (click, hover) read stale state
|
|
105
|
+
- Using `[nodes.length > 0]` as dependency — boolean `true` never changes, so the effect only runs once even if nodes are replaced
|
|
106
|
+
- Not cleaning up `requestAnimationFrame` on unmount — causes "setState on unmounted component" warnings
|
|
107
|
+
- Directly mutating state arrays instead of refs — still triggers re-renders
|
|
108
|
+
|
|
109
|
+
## Related Skills
|
|
110
|
+
|
|
111
|
+
- use-visible-interval - Visibility-aware polling to reduce unnecessary work
|
|
112
|
+
- liveclock-extraction - Isolating high-frequency updates to leaf components
|
|
113
|
+
|
|
114
|
+
## References
|
|
115
|
+
|
|
116
|
+
- React docs: "You Might Not Need an Effect" (imperative APIs)
|
|
117
|
+
- Contributed from: claude-mission-control KnowledgeGraph visualization
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: use-visible-interval
|
|
3
|
+
category: performance
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-03-12
|
|
6
|
+
contributor: claude-mission-control
|
|
7
|
+
last_updated: 2026-03-12
|
|
8
|
+
contributors:
|
|
9
|
+
- claude-mission-control
|
|
10
|
+
tags: [react, intersection-observer, polling, performance, hooks]
|
|
11
|
+
difficulty: medium
|
|
12
|
+
usage_count: 0
|
|
13
|
+
success_rate: 100
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# useVisibleInterval — Visibility-Aware Polling Hook
|
|
17
|
+
|
|
18
|
+
## Problem
|
|
19
|
+
|
|
20
|
+
Dashboard panels that poll APIs on intervals (5s, 10s, 30s) continue fetching even when scrolled off-screen. With 6+ panels each polling independently, this creates unnecessary network traffic, server load, and wasted CPU cycles. On mobile or constrained devices, this compounds into visible jank.
|
|
21
|
+
|
|
22
|
+
**Symptoms:**
|
|
23
|
+
- Network tab shows constant API calls from off-screen components
|
|
24
|
+
- Server logs show polling from panels the user isn't viewing
|
|
25
|
+
- Battery drain on laptops/mobile from unnecessary background fetches
|
|
26
|
+
|
|
27
|
+
## Solution Pattern
|
|
28
|
+
|
|
29
|
+
Create a custom hook that wraps `setInterval` with `IntersectionObserver`. The interval only runs while the component's container element is visible in the viewport. When scrolled off-screen, polling pauses. When scrolled back, it resumes immediately with a fresh fetch.
|
|
30
|
+
|
|
31
|
+
**Why IntersectionObserver?** It's browser-native, non-blocking (runs off main thread), and has zero performance cost compared to scroll event listeners or `getBoundingClientRect()` polling.
|
|
32
|
+
|
|
33
|
+
## Code Example
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// Before (wasteful — polls even when off-screen)
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
fetchData()
|
|
39
|
+
const id = setInterval(fetchData, 10000)
|
|
40
|
+
return () => clearInterval(id)
|
|
41
|
+
}, [])
|
|
42
|
+
|
|
43
|
+
// After (visibility-aware — pauses when off-screen)
|
|
44
|
+
const containerRef = useRef<HTMLDivElement>(null)
|
|
45
|
+
useVisibleInterval(fetchData, 10000, containerRef)
|
|
46
|
+
// ... <div ref={containerRef}>...</div>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Full hook implementation:**
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { useRef, useEffect } from 'react'
|
|
53
|
+
|
|
54
|
+
export function useVisibleInterval(
|
|
55
|
+
callback: () => void,
|
|
56
|
+
ms: number,
|
|
57
|
+
containerRef?: React.RefObject<HTMLElement | null>,
|
|
58
|
+
) {
|
|
59
|
+
const savedCallback = useRef(callback)
|
|
60
|
+
savedCallback.current = callback
|
|
61
|
+
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
// No container ref = fall back to standard interval
|
|
64
|
+
if (!containerRef?.current) {
|
|
65
|
+
savedCallback.current()
|
|
66
|
+
const id = setInterval(() => savedCallback.current(), ms)
|
|
67
|
+
return () => clearInterval(id)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let intervalId: ReturnType<typeof setInterval> | null = null
|
|
71
|
+
|
|
72
|
+
const observer = new IntersectionObserver(([entry]) => {
|
|
73
|
+
if (entry.isIntersecting) {
|
|
74
|
+
// Visible: fire immediately + start interval
|
|
75
|
+
savedCallback.current()
|
|
76
|
+
intervalId = setInterval(() => savedCallback.current(), ms)
|
|
77
|
+
} else {
|
|
78
|
+
// Hidden: stop interval
|
|
79
|
+
if (intervalId !== null) {
|
|
80
|
+
clearInterval(intervalId)
|
|
81
|
+
intervalId = null
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}, { threshold: 0 })
|
|
85
|
+
|
|
86
|
+
observer.observe(containerRef.current)
|
|
87
|
+
|
|
88
|
+
return () => {
|
|
89
|
+
observer.disconnect()
|
|
90
|
+
if (intervalId !== null) clearInterval(intervalId)
|
|
91
|
+
}
|
|
92
|
+
}, [ms, containerRef])
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Implementation Steps
|
|
97
|
+
|
|
98
|
+
1. Create the hook file (e.g., `src/hooks/useVisibleInterval.ts`)
|
|
99
|
+
2. Add a `containerRef` to each polling component's root element
|
|
100
|
+
3. Replace `useEffect` + `setInterval` with `useVisibleInterval(callback, ms, containerRef)`
|
|
101
|
+
4. Verify: scroll panel off-screen, confirm no network calls; scroll back, confirm immediate fetch
|
|
102
|
+
|
|
103
|
+
## When to Use
|
|
104
|
+
|
|
105
|
+
- Dashboard panels that poll APIs on intervals
|
|
106
|
+
- Any component with periodic data refresh that may be off-screen
|
|
107
|
+
- Long scrollable pages with multiple independent data sources
|
|
108
|
+
- Tab-based layouts where inactive tabs still mount components
|
|
109
|
+
|
|
110
|
+
## When NOT to Use
|
|
111
|
+
|
|
112
|
+
- Global state that must stay current regardless of visibility (e.g., auth token refresh)
|
|
113
|
+
- WebSocket/SSE connections (those are push-based, not poll-based)
|
|
114
|
+
- Components that are always visible (just use `setInterval`)
|
|
115
|
+
- Server-side rendering (IntersectionObserver is browser-only)
|
|
116
|
+
|
|
117
|
+
## Common Mistakes
|
|
118
|
+
|
|
119
|
+
- Forgetting to attach `containerRef` to the component's root `<div>` — hook falls back to standard interval silently
|
|
120
|
+
- Using `threshold: 1` instead of `0` — component must be 100% visible to trigger, causing missed polls for partially-visible panels
|
|
121
|
+
- Not cleaning up the observer on unmount — causes memory leaks
|
|
122
|
+
|
|
123
|
+
## Related Skills
|
|
124
|
+
|
|
125
|
+
- ref-based-canvas-animation - Another React performance pattern using refs
|
|
126
|
+
- liveclock-extraction - Isolating high-frequency state to leaf components
|
|
127
|
+
|
|
128
|
+
## References
|
|
129
|
+
|
|
130
|
+
- MDN IntersectionObserver API
|
|
131
|
+
- Contributed from: claude-mission-control (Command & Control dashboard)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: playwright-firefox-withcredentials-auth-issue
|
|
3
|
+
category: testing
|
|
4
|
+
description: Firefox E2E auth fails when API uses withCredentials + httpOnly cookie + Bearer token simultaneously
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
tags: [playwright, firefox, e2e, authentication, cookies, cors, storageState]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Playwright Firefox: withCredentials + httpOnly Cookie Auth Issue
|
|
10
|
+
|
|
11
|
+
## Problem
|
|
12
|
+
|
|
13
|
+
In Playwright E2E tests, a React app that uses axios with `withCredentials: true` AND
|
|
14
|
+
stores JWT tokens in both:
|
|
15
|
+
1. An `httpOnly` cookie (set by server), AND
|
|
16
|
+
2. localStorage (read by axios interceptor as `Authorization: Bearer`)
|
|
17
|
+
|
|
18
|
+
...causes Firefox E2E tests to fail with an auth redirect even though the
|
|
19
|
+
`storageState` is correctly applied. The storageState contains both the cookie and
|
|
20
|
+
the localStorage token, but Firefox's handling causes a 401 on protected API calls,
|
|
21
|
+
triggering the axios response interceptor to clear auth and redirect to `/login`.
|
|
22
|
+
|
|
23
|
+
**Symptom:**
|
|
24
|
+
- `beforeEach` passes (`waitForSelector` finds the authenticated page element)
|
|
25
|
+
- Test assertion fails immediately (element not found)
|
|
26
|
+
- Playwright screenshot shows the homepage or login page (not the protected page)
|
|
27
|
+
- Same tests pass in Chromium and WebKit
|
|
28
|
+
|
|
29
|
+
## Root Cause
|
|
30
|
+
|
|
31
|
+
Firefox's interaction between Playwright storageState restoration and
|
|
32
|
+
`withCredentials: true` requests differs from Chromium/WebKit. When both a
|
|
33
|
+
cookie and Authorization header are sent, Firefox's timing or cookie validation
|
|
34
|
+
may cause the server to reject the request with 401.
|
|
35
|
+
|
|
36
|
+
The `axios` response interceptor then fires:
|
|
37
|
+
```javascript
|
|
38
|
+
if (error.response?.status === 401) {
|
|
39
|
+
localStorage.removeItem('token');
|
|
40
|
+
window.location.href = '/login'; // Hard redirect, React Router can't prevent it
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This clears auth and redirects, causing subsequent assertions to fail on the
|
|
45
|
+
homepage/login page.
|
|
46
|
+
|
|
47
|
+
## Solution
|
|
48
|
+
|
|
49
|
+
### Option 1: Skip affected tests in Firefox (pragmatic)
|
|
50
|
+
|
|
51
|
+
Use `test.skip()` at the describe level for tests that require authenticated API data:
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
test.describe('Feature requiring authenticated API', () => {
|
|
55
|
+
// Firefox E2E: withCredentials + httpOnly cookie conflict causes auth redirect
|
|
56
|
+
// Verified passing in Chromium and WebKit
|
|
57
|
+
test.skip(({ browserName }) => browserName === 'firefox',
|
|
58
|
+
'Firefox E2E: API auth cookie/token conflict — passes in Chromium & WebKit');
|
|
59
|
+
|
|
60
|
+
test.beforeEach(async ({ page }) => { /* ... */ });
|
|
61
|
+
// tests...
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Note:** `test.skip()` inside the test body may not abort fast enough (redirect
|
|
66
|
+
happens before skip fires). Use describe-level skip.
|
|
67
|
+
|
|
68
|
+
### Option 2: Separate Firefox storageState (thorough)
|
|
69
|
+
|
|
70
|
+
Create a Firefox-specific auth setup that uses a different auth strategy:
|
|
71
|
+
```javascript
|
|
72
|
+
// playwright.config.ts
|
|
73
|
+
{
|
|
74
|
+
name: 'firefox',
|
|
75
|
+
use: {
|
|
76
|
+
...devices['Desktop Firefox'],
|
|
77
|
+
storageState: TEACHER_AUTH_FILE_FIREFOX, // Firefox-specific file
|
|
78
|
+
},
|
|
79
|
+
dependencies: ['setup-firefox'],
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Option 3: Remove httpOnly cookie, use localStorage only
|
|
84
|
+
|
|
85
|
+
Change server auth to NOT set httpOnly cookies, relying solely on the
|
|
86
|
+
Authorization header. This eliminates the conflict entirely but may reduce
|
|
87
|
+
security.
|
|
88
|
+
|
|
89
|
+
## Detection Signals
|
|
90
|
+
|
|
91
|
+
- Tests pass in Chromium, fail in Firefox
|
|
92
|
+
- Screenshot shows homepage or login page (not the protected route)
|
|
93
|
+
- `waitForSelector` in `beforeEach` passes (page briefly renders)
|
|
94
|
+
- Failure at the assertion level (element not found on the page)
|
|
95
|
+
- React app has `axios.interceptors.response` with `window.location.href = '/login'`
|
|
96
|
+
on 401 responses
|
|
97
|
+
- API calls use `withCredentials: true`
|
|
98
|
+
- Auth uses BOTH cookies and localStorage JWT
|
|
99
|
+
|
|
100
|
+
## Applied In
|
|
101
|
+
|
|
102
|
+
- `mern-community-lms/client/e2e/SessionWizard.podcast.spec.js`
|
|
103
|
+
- Fixed 2026-03-08: used describe-level `test.skip()` for the podcast dropdown tests
|
|
104
|
+
- Chromium 9/9 + WebKit 9/9 passing; Firefox 7 skipped + 2 passing
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Skills Quarantine
|
|
2
|
+
|
|
3
|
+
Auto-extracted skill candidates land here for review before promotion to the main library.
|
|
4
|
+
|
|
5
|
+
## Lifecycle
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Auto-extracted → _quarantine/ → Review → Promote to category/ OR Delete
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Review Criteria
|
|
12
|
+
|
|
13
|
+
- Is the pattern generalizable (not project-specific)?
|
|
14
|
+
- Does it solve a non-trivial problem?
|
|
15
|
+
- Has it passed the security gate?
|
|
16
|
+
- Is it a duplicate of an existing skill?
|
|
17
|
+
|
|
18
|
+
## Auto-Promotion
|
|
19
|
+
|
|
20
|
+
Skills applied successfully in 2+ different projects with confidence > 0.85
|
|
21
|
+
are auto-promoted from `_quarantine/` to their proper category folder.
|
|
22
|
+
|
|
23
|
+
## Security Gate
|
|
24
|
+
|
|
25
|
+
All quarantined skills must pass:
|
|
26
|
+
- No `exec()`, `eval()`, `child_process` in code examples
|
|
27
|
+
- No hardcoded credentials or API keys
|
|
28
|
+
- No destructive operations (DROP, DELETE, rm -rf)
|
|
29
|
+
|
|
30
|
+
See: `methodology/EVOLUTIONARY_SKILL_SYNTHESIS.md` for full pipeline details.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: broadcast-scheduler-shared-execute-function
|
|
3
|
+
category: api-patterns
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
contributed: 2026-02-21
|
|
6
|
+
contributor: my-other-project
|
|
7
|
+
last_updated: 2026-02-21
|
|
8
|
+
tags: [node.js, cron, scheduler, broadcast, express, dry]
|
|
9
|
+
difficulty: easy
|
|
10
|
+
usage_count: 1
|
|
11
|
+
success_rate: 100
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Broadcast Scheduler: Shared Execute Function
|
|
15
|
+
|
|
16
|
+
## Problem
|
|
17
|
+
|
|
18
|
+
When building a feature that can be triggered both **immediately** (by an admin action) and **on a schedule** (by a cron job), naively duplicating the execution logic creates two maintenance surfaces. If the logic changes, you must update it in two places and keep them in sync.
|
|
19
|
+
|
|
20
|
+
Typical anti-pattern:
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
// broadcastController.js — duplicate logic
|
|
24
|
+
export const sendNow = async (req, res) => {
|
|
25
|
+
const announcement = await BroadcastAnnouncement.getAnnouncementById(req.params.id);
|
|
26
|
+
if (announcement.send_popup) socketService.broadcastAnnouncement(announcement);
|
|
27
|
+
if (announcement.send_email) await sendBroadcastEmail(announcement);
|
|
28
|
+
await BroadcastAnnouncement.markAsSent(announcement.id, count);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// broadcastSchedulerJob.js — same logic duplicated
|
|
32
|
+
cron.schedule('* * * * *', async () => {
|
|
33
|
+
const due = await getDueAnnouncements();
|
|
34
|
+
for (const a of due) {
|
|
35
|
+
if (a.send_popup) socketService.broadcastAnnouncement(a);
|
|
36
|
+
if (a.send_email) await sendBroadcastEmail(a);
|
|
37
|
+
await BroadcastAnnouncement.markAsSent(a.id, count);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Solution Pattern
|
|
43
|
+
|
|
44
|
+
Export the execution logic as a named function from the **scheduler job file**. Both the cron handler AND the controller import and call the same function. The cron job calls it for scheduled items; the controller calls it directly for "Send Now."
|
|
45
|
+
|
|
46
|
+
This makes the scheduler job the **single source of truth** for how a broadcast is executed.
|
|
47
|
+
|
|
48
|
+
## Code Example
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
// server/jobs/broadcastSchedulerJob.js
|
|
52
|
+
|
|
53
|
+
import cron from 'node-cron';
|
|
54
|
+
import { getDueAnnouncements, markAsSent } from '../models/BroadcastAnnouncement.pg.js';
|
|
55
|
+
import { sendBroadcastEmail } from '../services/broadcastEmailService.js';
|
|
56
|
+
import socketService from '../services/SocketService.js';
|
|
57
|
+
|
|
58
|
+
let schedulerStarted = false;
|
|
59
|
+
|
|
60
|
+
export const startBroadcastScheduler = () => {
|
|
61
|
+
if (schedulerStarted) return;
|
|
62
|
+
schedulerStarted = true;
|
|
63
|
+
|
|
64
|
+
cron.schedule('* * * * *', async () => {
|
|
65
|
+
try {
|
|
66
|
+
const due = await getDueAnnouncements();
|
|
67
|
+
for (const announcement of due) {
|
|
68
|
+
await executeSend(announcement); // Uses shared function
|
|
69
|
+
}
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.error('[BroadcastScheduler] Error:', err.message);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// EXPORTED — both scheduler and controller call this
|
|
77
|
+
export const executeSend = async (announcement) => {
|
|
78
|
+
let recipientCount = 0;
|
|
79
|
+
|
|
80
|
+
if (announcement.send_popup || announcement.send_in_app) {
|
|
81
|
+
socketService.broadcastAnnouncement(announcement);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (announcement.send_email) {
|
|
85
|
+
const result = await sendBroadcastEmail(announcement);
|
|
86
|
+
recipientCount = result.sent;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
await markAsSent(announcement.id, recipientCount);
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
// server/controllers/broadcastController.js
|
|
95
|
+
|
|
96
|
+
import { executeSend } from '../jobs/broadcastSchedulerJob.js';
|
|
97
|
+
|
|
98
|
+
export const sendNow = async (req, res) => {
|
|
99
|
+
const announcement = await BroadcastAnnouncement.getAnnouncementById(req.params.id);
|
|
100
|
+
if (!announcement) return res.status(404).json({ success: false, message: 'Not found' });
|
|
101
|
+
if (announcement.status === 'sent') {
|
|
102
|
+
return res.status(400).json({ success: false, message: 'Already sent' });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Set status to 'sending' first to prevent duplicate sends by the cron job
|
|
106
|
+
await BroadcastAnnouncement.updateAnnouncement(req.params.id, { status: 'sending' });
|
|
107
|
+
|
|
108
|
+
// Fire async — don't await (email delivery can take time for large lists)
|
|
109
|
+
executeSend(announcement).catch(err =>
|
|
110
|
+
console.error('[Broadcast] sendNow error:', err.message)
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
res.json({ success: true, message: 'Announcement sending' });
|
|
114
|
+
};
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Implementation Steps
|
|
118
|
+
|
|
119
|
+
1. Write the execution logic as a standalone async function `executeSend(item)` in the scheduler file
|
|
120
|
+
2. Export it with `export const executeSend = async (item) => { ... }`
|
|
121
|
+
3. Import it in the controller: `import { executeSend } from '../jobs/schedulerJob.js'`
|
|
122
|
+
4. In the controller's "Send Now" handler, set status to `'sending'` (or equivalent) **before** calling `executeSend()` — this prevents the cron job from double-sending the same item in the next minute
|
|
123
|
+
5. Call `executeSend()` without `await` in the controller (fire-and-forget), since large email sends could take minutes
|
|
124
|
+
|
|
125
|
+
## When to Use
|
|
126
|
+
|
|
127
|
+
- Any feature where items can be sent/triggered both immediately AND on a schedule
|
|
128
|
+
- Email newsletters, announcement broadcasts, report generation jobs
|
|
129
|
+
- Any pattern where "send now" is a button in the UI AND a cron job checks a DB table
|
|
130
|
+
|
|
131
|
+
## When NOT to Use
|
|
132
|
+
|
|
133
|
+
- When the immediate vs. scheduled paths have meaningfully different logic (e.g., different recipients, different templates)
|
|
134
|
+
- When the job file has no natural ownership of the logic (put `executeSend` in a service instead)
|
|
135
|
+
|
|
136
|
+
## Common Mistakes
|
|
137
|
+
|
|
138
|
+
- **Forgetting the status guard**: Without setting status to `'sending'` before firing, the cron job running in the same minute will double-execute
|
|
139
|
+
- **Awaiting in controller**: `executeSend()` may take minutes for large email batches — fire-and-forget with `.catch()` for error logging
|
|
140
|
+
- **Circular imports**: If the model imports from the scheduler (or vice versa), you'll get circular dependency errors. Keep the data layer (model) import-free from job files.
|
|
141
|
+
|
|
142
|
+
## Related Skills
|
|
143
|
+
|
|
144
|
+
- [EXPRESS_ROUTE_ORDERING_MIDDLEWARE_INTERCEPTION.md](../api-patterns/EXPRESS_ROUTE_ORDERING_MIDDLEWARE_INTERCEPTION.md) — Static routes before dynamic `:id` params
|
|
145
|
+
- [PODCAST_PROGRESS_TRACKING_THREE_ROOT_CAUSES.md](../api-patterns/PODCAST_PROGRESS_TRACKING_THREE_ROOT_CAUSES.md)
|
|
146
|
+
|
|
147
|
+
## References
|
|
148
|
+
|
|
149
|
+
- Contributed from: my-other-project, Phase 15 Broadcast Announcements (2026-02-21)
|
|
150
|
+
- Pattern: DRY principle applied to scheduler/controller shared logic
|