@oriro/orirocli 0.1.11 → 0.3.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/ATTRIBUTION.md +53 -53
- package/LICENSE +21 -21
- package/README.md +10 -9
- package/dist/cli.js +1866 -190
- package/package.json +65 -64
- package/skills/1password/SKILL.md +118 -118
- package/skills/1password/references/cli-examples.md +29 -29
- package/skills/1password/references/get-started.md +21 -21
- package/skills/21stdev/SKILL.md +64 -64
- package/skills/algorithmic-art/LICENSE +21 -21
- package/skills/algorithmic-art/SKILL.md +446 -446
- package/skills/algorithmic-art/templates/generator_template.js +223 -223
- package/skills/algorithmic-art/templates/viewer.html +598 -598
- package/skills/apple-notes/SKILL.md +81 -81
- package/skills/apple-reminders/SKILL.md +122 -122
- package/skills/bear-notes/SKILL.md +111 -111
- package/skills/blogwatcher/SKILL.md +73 -73
- package/skills/blucli/SKILL.md +51 -51
- package/skills/brand-guidelines/LICENSE +21 -21
- package/skills/brand-guidelines/SKILL.md +76 -76
- package/skills/business/biz-analysis/LICENSE +21 -21
- package/skills/business/biz-analysis/SKILL.md +103 -103
- package/skills/business/biz-corporate-strategy/LICENSE +21 -21
- package/skills/business/biz-corporate-strategy/SKILL.md +76 -76
- package/skills/business/biz-customer-success/LICENSE +21 -21
- package/skills/business/biz-customer-success/SKILL.md +55 -55
- package/skills/business/biz-entrepreneurship/LICENSE +21 -21
- package/skills/business/biz-entrepreneurship/SKILL.md +72 -72
- package/skills/business/biz-hr/LICENSE +21 -21
- package/skills/business/biz-hr/SKILL.md +67 -67
- package/skills/business/biz-international/LICENSE +21 -21
- package/skills/business/biz-international/SKILL.md +51 -51
- package/skills/business/biz-leadership/LICENSE +21 -21
- package/skills/business/biz-leadership/SKILL.md +106 -106
- package/skills/business/biz-marketing-strategy/LICENSE +21 -21
- package/skills/business/biz-marketing-strategy/SKILL.md +119 -119
- package/skills/business/biz-negotiation/LICENSE +21 -21
- package/skills/business/biz-negotiation/SKILL.md +152 -152
- package/skills/business/biz-operations/LICENSE +21 -21
- package/skills/business/biz-operations/SKILL.md +74 -74
- package/skills/business/biz-project/LICENSE +21 -21
- package/skills/business/biz-project/SKILL.md +203 -203
- package/skills/business/biz-risk/LICENSE +21 -21
- package/skills/business/biz-risk/SKILL.md +85 -85
- package/skills/business/biz-sales/LICENSE +21 -21
- package/skills/business/biz-sales/SKILL.md +92 -92
- package/skills/business/biz-startup-ops/LICENSE +21 -21
- package/skills/business/biz-startup-ops/SKILL.md +70 -70
- package/skills/business/biz-strategy/LICENSE +21 -21
- package/skills/business/biz-strategy/SKILL.md +233 -233
- package/skills/business/biz-supply-chain-advanced/LICENSE +21 -21
- package/skills/business/biz-supply-chain-advanced/SKILL.md +68 -68
- package/skills/business/fin-chartered-exams/LICENSE +21 -21
- package/skills/business/fin-chartered-exams/SKILL.md +69 -69
- package/skills/camsnap/SKILL.md +49 -49
- package/skills/canvas/SKILL.md +82 -82
- package/skills/canvas-design/LICENSE +21 -21
- package/skills/canvas-design/SKILL.md +140 -140
- package/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -94
- package/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -93
- package/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -93
- package/skills/coding-agent/SKILL.md +146 -146
- package/skills/communication/comm-business-writing/LICENSE +21 -21
- package/skills/communication/comm-business-writing/SKILL.md +67 -67
- package/skills/communication/comm-cross-cultural/LICENSE +21 -21
- package/skills/communication/comm-cross-cultural/SKILL.md +88 -88
- package/skills/communication/comm-journalism/LICENSE +21 -21
- package/skills/communication/comm-journalism/SKILL.md +81 -81
- package/skills/communication/comm-linguistics/LICENSE +21 -21
- package/skills/communication/comm-linguistics/SKILL.md +82 -82
- package/skills/communication/comm-negotiation/LICENSE +21 -21
- package/skills/communication/comm-negotiation/SKILL.md +120 -120
- package/skills/communication/comm-presentations/LICENSE +21 -21
- package/skills/communication/comm-presentations/SKILL.md +93 -93
- package/skills/communication/comm-public-speaking/LICENSE +21 -21
- package/skills/communication/comm-public-speaking/SKILL.md +68 -68
- package/skills/communication/comm-writing/LICENSE +21 -21
- package/skills/communication/comm-writing/SKILL.md +69 -69
- package/skills/craft/ai-engineering/LICENSE +21 -21
- package/skills/craft/ai-engineering/SKILL.md +828 -828
- package/skills/craft/app-builder-guide/LICENSE +21 -21
- package/skills/craft/app-builder-guide/SKILL.md +332 -332
- package/skills/craft/become-an-ai-engineer-26/CONTRIBUTING.md +46 -46
- package/skills/craft/become-an-ai-engineer-26/LICENSE +21 -21
- package/skills/craft/become-an-ai-engineer-26/README.md +270 -270
- package/skills/craft/become-an-ai-engineer-26/SKILL.md +667 -667
- package/skills/craft/become-an-ai-engineer-26/community/BUILDS.md +13 -13
- package/skills/craft/become-an-ai-engineer-26/community/DISCUSSIONS.md +8 -8
- package/skills/craft/become-an-ai-engineer-26/phases/phase-0-mental-models/README.md +14 -14
- package/skills/craft/become-an-ai-engineer-26/phases/phase-0-mental-models/project/TEMPLATE.md +33 -33
- package/skills/craft/become-an-ai-engineer-26/phases/phase-1-first-agent/README.md +25 -25
- package/skills/craft/become-an-ai-engineer-26/phases/phase-1-first-agent/code/raw_loop.py +126 -126
- package/skills/craft/become-an-ai-engineer-26/phases/phase-2-architecture/README.md +17 -17
- package/skills/craft/become-an-ai-engineer-26/phases/phase-3-harness/README.md +17 -17
- package/skills/craft/become-an-ai-engineer-26/phases/phase-4-evals/README.md +21 -21
- package/skills/craft/become-an-ai-engineer-26/phases/phase-4-evals/code/.github/workflows/eval.yml +40 -40
- package/skills/craft/become-an-ai-engineer-26/phases/phase-5-production/README.md +16 -16
- package/skills/craft/become-an-ai-engineer-26/projects/1-mobile-app-slm/README.md +11 -11
- package/skills/craft/become-an-ai-engineer-26/projects/2-self-improving-coder/README.md +11 -11
- package/skills/craft/become-an-ai-engineer-26/projects/3-video-editor-agent/README.md +11 -11
- package/skills/craft/become-an-ai-engineer-26/projects/4-personal-life-os/README.md +12 -12
- package/skills/craft/become-an-ai-engineer-26/projects/5-enterprise-workflow/README.md +12 -12
- package/skills/craft/become-an-ai-engineer-26/references/benchmark-numbers.md +41 -41
- package/skills/craft/become-an-ai-engineer-26/references/mhc-stable-training.md +73 -73
- package/skills/craft/become-an-ai-engineer-26/references/stack-decisions.md +37 -37
- package/skills/craft/become-an-ai-engineer-26/references/yarn-context-extension.md +123 -123
- package/skills/craft/codex-result-handling/LICENSE +21 -21
- package/skills/craft/codex-result-handling/SKILL.md +26 -26
- package/skills/craft/debug-and-build-methodology/LICENSE +21 -21
- package/skills/craft/debug-and-build-methodology/SKILL.md +432 -432
- package/skills/craft/design/LICENSE +21 -21
- package/skills/craft/design/SKILL.md +274 -274
- package/skills/craft/dev/LICENSE +21 -21
- package/skills/craft/dev/SKILL.md +12 -12
- package/skills/craft/dev/release.md +85 -85
- package/skills/craft/dev/roll.md +50 -50
- package/skills/craft/doc-coauthoring/LICENSE +21 -21
- package/skills/craft/doc-coauthoring/SKILL.md +397 -397
- package/skills/craft/focus/LICENSE +21 -21
- package/skills/craft/focus/SKILL.md +432 -432
- package/skills/craft/focus/UPSTREAM_README.md +233 -233
- package/skills/craft/gh/LICENSE +21 -21
- package/skills/craft/gh/SKILL.md +84 -84
- package/skills/craft/gh-skill/LICENSE +21 -21
- package/skills/craft/gh-skill/SKILL.md +121 -121
- package/skills/craft/godmode/LICENSE +21 -21
- package/skills/craft/godmode/SKILL.md +87 -87
- package/skills/craft/godmode/references/android-launch.md +680 -680
- package/skills/craft/godmode/references/data-gcp.md +1038 -1038
- package/skills/craft/godmode/references/expo-eas.md +816 -816
- package/skills/craft/godmode/references/ios-launch.md +734 -734
- package/skills/craft/google-ai-latest/LICENSE +21 -21
- package/skills/craft/google-ai-latest/SKILL.md +682 -682
- package/skills/craft/gpt-5-4-prompting/LICENSE +21 -21
- package/skills/craft/gpt-5-4-prompting/SKILL.md +63 -63
- package/skills/craft/gpt-5-4-prompting/references/codex-prompt-antipatterns.md +101 -101
- package/skills/craft/gpt-5-4-prompting/references/codex-prompt-recipes.md +150 -150
- package/skills/craft/gpt-5-4-prompting/references/prompt-blocks.md +172 -172
- package/skills/craft/grill-me/LICENSE +21 -21
- package/skills/craft/grill-me/SKILL.md +13 -13
- package/skills/craft/idea-to-deploy/LICENSE +21 -21
- package/skills/craft/idea-to-deploy/SKILL.md +292 -292
- package/skills/craft/idea-to-deploy/references/auth-playbook.md +195 -195
- package/skills/craft/idea-to-deploy/references/gcp-deployment.md +268 -268
- package/skills/craft/idea-to-deploy/references/stack-selection.md +117 -117
- package/skills/craft/image-generation-engineer/LICENSE +21 -21
- package/skills/craft/image-generation-engineer/SKILL.md +183 -183
- package/skills/craft/image-generation-engineer/references/architectures.md +260 -260
- package/skills/craft/image-generation-engineer/references/foundations.md +107 -107
- package/skills/craft/image-generation-engineer/references/inference-and-serving.md +253 -253
- package/skills/craft/image-generation-engineer/references/training.md +149 -149
- package/skills/craft/marketing/LICENSE +21 -21
- package/skills/craft/marketing/SKILL.md +1954 -1954
- package/skills/craft/master-architect/LICENSE +21 -21
- package/skills/craft/master-architect/SKILL.md +361 -361
- package/skills/craft/master-architect/references/ai-ml.md +317 -317
- package/skills/craft/master-architect/references/architecture.md +268 -268
- package/skills/craft/master-architect/references/auth-playbook.md +195 -195
- package/skills/craft/master-architect/references/cloud.md +323 -323
- package/skills/craft/master-architect/references/cyber.md +839 -839
- package/skills/craft/master-architect/references/data-eng.md +366 -366
- package/skills/craft/master-architect/references/devops.md +550 -550
- package/skills/craft/master-architect/references/gcp-deployment.md +268 -268
- package/skills/craft/master-architect/references/languages.md +748 -748
- package/skills/craft/master-architect/references/legacy.md +240 -240
- package/skills/craft/master-architect/references/mobile.md +447 -447
- package/skills/craft/master-architect/references/patterns.md +451 -451
- package/skills/craft/master-architect/references/saas-patterns.md +379 -379
- package/skills/craft/master-architect/references/sdlc.md +349 -349
- package/skills/craft/master-architect/references/stack-selection.md +117 -117
- package/skills/craft/oriro-ui-2026/LICENSE +21 -21
- package/skills/craft/oriro-ui-2026/SKILL.md +329 -329
- package/skills/craft/playwright-cli/LICENSE +21 -21
- package/skills/craft/playwright-cli/SKILL.md +393 -393
- package/skills/craft/playwright-cli/references/element-attributes.md +23 -23
- package/skills/craft/playwright-cli/references/playwright-tests.md +39 -39
- package/skills/craft/playwright-cli/references/request-mocking.md +87 -87
- package/skills/craft/playwright-cli/references/running-code.md +240 -240
- package/skills/craft/playwright-cli/references/session-management.md +226 -226
- package/skills/craft/playwright-cli/references/spec-driven-testing.md +312 -312
- package/skills/craft/playwright-cli/references/storage-state.md +275 -275
- package/skills/craft/playwright-cli/references/test-generation.md +134 -134
- package/skills/craft/playwright-cli/references/tracing.md +142 -142
- package/skills/craft/playwright-cli/references/video-recording.md +150 -150
- package/skills/craft/remotion-best-practices/LICENSE +21 -21
- package/skills/craft/remotion-best-practices/SKILL.md +345 -345
- package/skills/craft/remotion-best-practices/rules/3d.md +86 -86
- package/skills/craft/remotion-best-practices/rules/assets/charts-bar-chart.tsx +165 -165
- package/skills/craft/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +89 -89
- package/skills/craft/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +101 -101
- package/skills/craft/remotion-best-practices/rules/audio-visualization.md +195 -195
- package/skills/craft/remotion-best-practices/rules/audio.md +167 -167
- package/skills/craft/remotion-best-practices/rules/calculate-metadata.md +118 -118
- package/skills/craft/remotion-best-practices/rules/compositions.md +132 -132
- package/skills/craft/remotion-best-practices/rules/display-captions.md +176 -176
- package/skills/craft/remotion-best-practices/rules/ffmpeg.md +34 -34
- package/skills/craft/remotion-best-practices/rules/get-audio-duration.md +58 -58
- package/skills/craft/remotion-best-practices/rules/get-video-dimensions.md +68 -68
- package/skills/craft/remotion-best-practices/rules/get-video-duration.md +60 -60
- package/skills/craft/remotion-best-practices/rules/gifs.md +135 -135
- package/skills/craft/remotion-best-practices/rules/google-fonts.md +72 -72
- package/skills/craft/remotion-best-practices/rules/html-in-canvas.md +122 -122
- package/skills/craft/remotion-best-practices/rules/images.md +67 -67
- package/skills/craft/remotion-best-practices/rules/import-srt-captions.md +69 -69
- package/skills/craft/remotion-best-practices/rules/light-leaks.md +73 -73
- package/skills/craft/remotion-best-practices/rules/local-fonts.md +65 -65
- package/skills/craft/remotion-best-practices/rules/lottie.md +67 -67
- package/skills/craft/remotion-best-practices/rules/maplibre.md +441 -441
- package/skills/craft/remotion-best-practices/rules/measuring-dom-nodes.md +34 -34
- package/skills/craft/remotion-best-practices/rules/measuring-text.md +140 -140
- package/skills/craft/remotion-best-practices/rules/parameters.md +109 -109
- package/skills/craft/remotion-best-practices/rules/sequencing.md +144 -144
- package/skills/craft/remotion-best-practices/rules/sfx.md +30 -30
- package/skills/craft/remotion-best-practices/rules/silence-detection.md +73 -73
- package/skills/craft/remotion-best-practices/rules/subtitles.md +36 -36
- package/skills/craft/remotion-best-practices/rules/tailwind.md +11 -11
- package/skills/craft/remotion-best-practices/rules/text-animations.md +20 -20
- package/skills/craft/remotion-best-practices/rules/timing.md +130 -130
- package/skills/craft/remotion-best-practices/rules/transcribe-captions.md +70 -70
- package/skills/craft/remotion-best-practices/rules/transitions.md +193 -193
- package/skills/craft/remotion-best-practices/rules/transparent-videos.md +102 -102
- package/skills/craft/remotion-best-practices/rules/trimming.md +51 -51
- package/skills/craft/remotion-best-practices/rules/videos.md +169 -169
- package/skills/craft/remotion-best-practices/rules/voiceover.md +94 -94
- package/skills/craft/supabase-postgres-best-practices/CHANGELOG.md +25 -25
- package/skills/craft/supabase-postgres-best-practices/LICENSE +21 -21
- package/skills/craft/supabase-postgres-best-practices/SKILL.md +69 -69
- package/skills/craft/supabase-postgres-best-practices/references/_contributing.md +166 -166
- package/skills/craft/supabase-postgres-best-practices/references/_sections.md +47 -47
- package/skills/craft/supabase-postgres-best-practices/references/_template.md +34 -34
- package/skills/craft/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -55
- package/skills/craft/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -49
- package/skills/craft/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -46
- package/skills/craft/supabase-postgres-best-practices/references/conn-limits.md +44 -44
- package/skills/craft/supabase-postgres-best-practices/references/conn-pooling.md +41 -41
- package/skills/craft/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -46
- package/skills/craft/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -54
- package/skills/craft/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -53
- package/skills/craft/supabase-postgres-best-practices/references/data-pagination.md +50 -50
- package/skills/craft/supabase-postgres-best-practices/references/data-upsert.md +50 -50
- package/skills/craft/supabase-postgres-best-practices/references/lock-advisory.md +56 -56
- package/skills/craft/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -68
- package/skills/craft/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -50
- package/skills/craft/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -54
- package/skills/craft/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -45
- package/skills/craft/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -55
- package/skills/craft/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -55
- package/skills/craft/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -44
- package/skills/craft/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -40
- package/skills/craft/supabase-postgres-best-practices/references/query-index-types.md +48 -48
- package/skills/craft/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -43
- package/skills/craft/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -45
- package/skills/craft/supabase-postgres-best-practices/references/schema-constraints.md +80 -80
- package/skills/craft/supabase-postgres-best-practices/references/schema-data-types.md +46 -46
- package/skills/craft/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -59
- package/skills/craft/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -55
- package/skills/craft/supabase-postgres-best-practices/references/schema-partitioning.md +55 -55
- package/skills/craft/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -61
- package/skills/craft/supabase-postgres-best-practices/references/security-privileges.md +54 -54
- package/skills/craft/supabase-postgres-best-practices/references/security-rls-basics.md +50 -50
- package/skills/craft/supabase-postgres-best-practices/references/security-rls-performance.md +63 -63
- package/skills/craft/uipm-banner-design/LICENSE +21 -21
- package/skills/craft/uipm-banner-design/SKILL.md +201 -201
- package/skills/craft/uipm-banner-design/references/banner-sizes-and-styles.md +129 -129
- package/skills/craft/uipm-brand/LICENSE +21 -21
- package/skills/craft/uipm-brand/SKILL.md +104 -104
- package/skills/craft/uipm-brand/references/approval-checklist.md +184 -184
- package/skills/craft/uipm-brand/references/asset-organization.md +167 -167
- package/skills/craft/uipm-brand/references/brand-guideline-template.md +161 -161
- package/skills/craft/uipm-brand/references/color-palette-management.md +203 -203
- package/skills/craft/uipm-brand/references/consistency-checklist.md +105 -105
- package/skills/craft/uipm-brand/references/logo-usage-rules.md +204 -204
- package/skills/craft/uipm-brand/references/messaging-framework.md +91 -91
- package/skills/craft/uipm-brand/references/typography-specifications.md +265 -265
- package/skills/craft/uipm-brand/references/update.md +128 -128
- package/skills/craft/uipm-brand/references/visual-identity.md +109 -109
- package/skills/craft/uipm-brand/references/voice-framework.md +99 -99
- package/skills/craft/uipm-brand/scripts/extract-colors.cjs +333 -333
- package/skills/craft/uipm-brand/scripts/inject-brand-context.cjs +324 -324
- package/skills/craft/uipm-brand/scripts/sync-brand-to-tokens.cjs +269 -269
- package/skills/craft/uipm-brand/scripts/validate-asset.cjs +361 -361
- package/skills/craft/uipm-brand/templates/brand-guidelines-starter.md +280 -280
- package/skills/craft/uipm-design/LICENSE +21 -21
- package/skills/craft/uipm-design/SKILL.md +305 -305
- package/skills/craft/uipm-design/data/cip/deliverables.csv +50 -50
- package/skills/craft/uipm-design/data/cip/industries.csv +20 -20
- package/skills/craft/uipm-design/data/cip/mockup-contexts.csv +20 -20
- package/skills/craft/uipm-design/data/cip/styles.csv +20 -20
- package/skills/craft/uipm-design/data/icon/styles.csv +16 -16
- package/skills/craft/uipm-design/data/logo/colors.csv +56 -56
- package/skills/craft/uipm-design/data/logo/industries.csv +56 -56
- package/skills/craft/uipm-design/data/logo/styles.csv +56 -56
- package/skills/craft/uipm-design/references/banner-sizes-and-styles.md +129 -129
- package/skills/craft/uipm-design/references/cip-deliverable-guide.md +111 -111
- package/skills/craft/uipm-design/references/cip-design.md +121 -121
- package/skills/craft/uipm-design/references/cip-prompt-engineering.md +94 -94
- package/skills/craft/uipm-design/references/cip-style-guide.md +76 -76
- package/skills/craft/uipm-design/references/design-routing.md +226 -226
- package/skills/craft/uipm-design/references/icon-design.md +122 -122
- package/skills/craft/uipm-design/references/logo-color-psychology.md +113 -113
- package/skills/craft/uipm-design/references/logo-design.md +92 -92
- package/skills/craft/uipm-design/references/logo-prompt-engineering.md +176 -176
- package/skills/craft/uipm-design/references/logo-style-guide.md +129 -129
- package/skills/craft/uipm-design/references/slides-copywriting-formulas.md +92 -92
- package/skills/craft/uipm-design/references/slides-create.md +5 -5
- package/skills/craft/uipm-design/references/slides-html-template.md +374 -374
- package/skills/craft/uipm-design/references/slides-layout-patterns.md +155 -155
- package/skills/craft/uipm-design/references/slides-strategies.md +97 -97
- package/skills/craft/uipm-design/references/slides.md +42 -42
- package/skills/craft/uipm-design/references/social-photos-design.md +353 -353
- package/skills/craft/uipm-design/scripts/cip/core.py +215 -215
- package/skills/craft/uipm-design/scripts/cip/generate.py +484 -484
- package/skills/craft/uipm-design/scripts/cip/render-html.py +424 -424
- package/skills/craft/uipm-design/scripts/cip/search.py +127 -127
- package/skills/craft/uipm-design/scripts/icon/generate.py +487 -487
- package/skills/craft/uipm-design/scripts/logo/core.py +175 -175
- package/skills/craft/uipm-design/scripts/logo/generate.py +362 -362
- package/skills/craft/uipm-design/scripts/logo/search.py +114 -114
- package/skills/craft/uipm-design-system/LICENSE +21 -21
- package/skills/craft/uipm-design-system/SKILL.md +255 -255
- package/skills/craft/uipm-design-system/data/slide-backgrounds.csv +11 -11
- package/skills/craft/uipm-design-system/data/slide-charts.csv +26 -26
- package/skills/craft/uipm-design-system/data/slide-color-logic.csv +14 -14
- package/skills/craft/uipm-design-system/data/slide-copy.csv +26 -26
- package/skills/craft/uipm-design-system/data/slide-layout-logic.csv +16 -16
- package/skills/craft/uipm-design-system/data/slide-layouts.csv +26 -26
- package/skills/craft/uipm-design-system/data/slide-strategies.csv +16 -16
- package/skills/craft/uipm-design-system/data/slide-typography.csv +15 -15
- package/skills/craft/uipm-design-system/references/component-specs.md +236 -236
- package/skills/craft/uipm-design-system/references/component-tokens.md +214 -214
- package/skills/craft/uipm-design-system/references/primitive-tokens.md +199 -199
- package/skills/craft/uipm-design-system/references/semantic-tokens.md +215 -215
- package/skills/craft/uipm-design-system/references/states-and-variants.md +243 -243
- package/skills/craft/uipm-design-system/references/tailwind-integration.md +257 -257
- package/skills/craft/uipm-design-system/references/token-architecture.md +226 -226
- package/skills/craft/uipm-design-system/scripts/embed-tokens.cjs +97 -97
- package/skills/craft/uipm-design-system/scripts/fetch-background.py +317 -317
- package/skills/craft/uipm-design-system/scripts/generate-slide.py +753 -753
- package/skills/craft/uipm-design-system/scripts/generate-tokens.cjs +213 -213
- package/skills/craft/uipm-design-system/scripts/html-token-validator.py +327 -327
- package/skills/craft/uipm-design-system/scripts/search-slides.py +218 -218
- package/skills/craft/uipm-design-system/scripts/slide-token-validator.py +35 -35
- package/skills/craft/uipm-design-system/scripts/slide_search_core.py +453 -453
- package/skills/craft/uipm-design-system/scripts/validate-tokens.cjs +254 -254
- package/skills/craft/uipm-design-system/templates/design-tokens-starter.json +143 -143
- package/skills/craft/uipm-slides/LICENSE +21 -21
- package/skills/craft/uipm-slides/SKILL.md +45 -45
- package/skills/craft/uipm-slides/references/copywriting-formulas.md +92 -92
- package/skills/craft/uipm-slides/references/create.md +5 -5
- package/skills/craft/uipm-slides/references/html-template.md +374 -374
- package/skills/craft/uipm-slides/references/layout-patterns.md +155 -155
- package/skills/craft/uipm-slides/references/slide-strategies.md +97 -97
- package/skills/craft/uipm-ui-ux-pro-max/LICENSE +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/SKILL.md +678 -678
- package/skills/craft/uipm-ui-ux-pro-max/data/_sync_all.py +414 -414
- package/skills/craft/uipm-ui-ux-pro-max/data/app-interface.csv +30 -30
- package/skills/craft/uipm-ui-ux-pro-max/data/charts.csv +26 -26
- package/skills/craft/uipm-ui-ux-pro-max/data/colors.csv +161 -161
- package/skills/craft/uipm-ui-ux-pro-max/data/design.csv +1775 -1775
- package/skills/craft/uipm-ui-ux-pro-max/data/draft.csv +1778 -1778
- package/skills/craft/uipm-ui-ux-pro-max/data/google-fonts.csv +1924 -1924
- package/skills/craft/uipm-ui-ux-pro-max/data/icons.csv +105 -105
- package/skills/craft/uipm-ui-ux-pro-max/data/landing.csv +35 -35
- package/skills/craft/uipm-ui-ux-pro-max/data/products.csv +162 -162
- package/skills/craft/uipm-ui-ux-pro-max/data/react-performance.csv +45 -45
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/angular.csv +51 -51
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/astro.csv +54 -54
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/flutter.csv +53 -53
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -56
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -53
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/laravel.csv +51 -51
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/nextjs.csv +53 -53
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -51
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -59
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/react-native.csv +52 -52
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/react.csv +54 -54
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/shadcn.csv +61 -61
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/svelte.csv +54 -54
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/swiftui.csv +51 -51
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/threejs.csv +54 -54
- package/skills/craft/uipm-ui-ux-pro-max/data/stacks/vue.csv +50 -50
- package/skills/craft/uipm-ui-ux-pro-max/data/styles.csv +85 -85
- package/skills/craft/uipm-ui-ux-pro-max/data/typography.csv +74 -74
- package/skills/craft/uipm-ui-ux-pro-max/data/ui-reasoning.csv +162 -162
- package/skills/craft/uipm-ui-ux-pro-max/data/ux-guidelines.csv +99 -99
- package/skills/craft/uipm-ui-ux-pro-max/scripts/core.py +262 -262
- package/skills/craft/uipm-ui-ux-pro-max/scripts/design_system.py +1148 -1148
- package/skills/craft/uipm-ui-ux-pro-max/scripts/search.py +114 -114
- package/skills/craft/uipm-ui-ux-pro-max/templates/base/quick-reference.md +297 -297
- package/skills/craft/uipm-ui-ux-pro-max/templates/base/skill-content.md +375 -375
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/agent.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/augment.json +18 -18
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/claude.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/codebuddy.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/codex.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/continue.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/copilot.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/cursor.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/droid.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/gemini.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/kilocode.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/kiro.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/opencode.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/qoder.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/roocode.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/trae.json +21 -21
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/warp.json +18 -18
- package/skills/craft/uipm-ui-ux-pro-max/templates/platforms/windsurf.json +21 -21
- package/skills/craft/vercel-optimize/AGENTS.md +48 -48
- package/skills/craft/vercel-optimize/CONTRIBUTING.md +41 -41
- package/skills/craft/vercel-optimize/LICENSE +21 -21
- package/skills/craft/vercel-optimize/README.md +91 -91
- package/skills/craft/vercel-optimize/SKILL.md +325 -325
- package/skills/craft/vercel-optimize/lib/auth-route.mjs +23 -23
- package/skills/craft/vercel-optimize/lib/budget-summary.mjs +208 -208
- package/skills/craft/vercel-optimize/lib/citations.mjs +147 -147
- package/skills/craft/vercel-optimize/lib/cost-coverage.mjs +162 -162
- package/skills/craft/vercel-optimize/lib/dedup-recs.mjs +340 -340
- package/skills/craft/vercel-optimize/lib/deep-dive.mjs +371 -371
- package/skills/craft/vercel-optimize/lib/display-labels.mjs +219 -219
- package/skills/craft/vercel-optimize/lib/extract-claims.mjs +640 -640
- package/skills/craft/vercel-optimize/lib/framework-support.mjs +69 -69
- package/skills/craft/vercel-optimize/lib/gates/build-minutes-fanout.mjs +73 -73
- package/skills/craft/vercel-optimize/lib/gates/cold-start.mjs +72 -72
- package/skills/craft/vercel-optimize/lib/gates/contract.mjs +82 -82
- package/skills/craft/vercel-optimize/lib/gates/cwv-poor.mjs +95 -95
- package/skills/craft/vercel-optimize/lib/gates/external-api-slow.mjs +60 -60
- package/skills/craft/vercel-optimize/lib/gates/hard-gates.mjs +70 -70
- package/skills/craft/vercel-optimize/lib/gates/index.mjs +45 -45
- package/skills/craft/vercel-optimize/lib/gates/isr-overrevalidation.mjs +62 -62
- package/skills/craft/vercel-optimize/lib/gates/middleware-heavy.mjs +53 -53
- package/skills/craft/vercel-optimize/lib/gates/observability-events-attribution.mjs +58 -58
- package/skills/craft/vercel-optimize/lib/gates/platform-bot-protection.mjs +123 -123
- package/skills/craft/vercel-optimize/lib/gates/platform-fluid-compute.mjs +94 -94
- package/skills/craft/vercel-optimize/lib/gates/region-misconfig.mjs +71 -71
- package/skills/craft/vercel-optimize/lib/gates/route-errors.mjs +95 -95
- package/skills/craft/vercel-optimize/lib/gates/scanner-driven.mjs +150 -150
- package/skills/craft/vercel-optimize/lib/gates/select-candidates.mjs +137 -137
- package/skills/craft/vercel-optimize/lib/gates/slow-route.mjs +97 -97
- package/skills/craft/vercel-optimize/lib/gates/types.d.ts +38 -38
- package/skills/craft/vercel-optimize/lib/gates/uncached-route.mjs +103 -103
- package/skills/craft/vercel-optimize/lib/gates/usage-spike-triage.mjs +122 -122
- package/skills/craft/vercel-optimize/lib/grade-recommendation.mjs +170 -170
- package/skills/craft/vercel-optimize/lib/impact-label.mjs +128 -128
- package/skills/craft/vercel-optimize/lib/impact-magnitude.mjs +66 -66
- package/skills/craft/vercel-optimize/lib/investigation-brief.mjs +751 -751
- package/skills/craft/vercel-optimize/lib/observation-safety.mjs +217 -217
- package/skills/craft/vercel-optimize/lib/project-facts.mjs +101 -101
- package/skills/craft/vercel-optimize/lib/queries.mjs +333 -333
- package/skills/craft/vercel-optimize/lib/reconcile-candidates.mjs +388 -388
- package/skills/craft/vercel-optimize/lib/render-report.mjs +1065 -1065
- package/skills/craft/vercel-optimize/lib/repo-root.mjs +97 -97
- package/skills/craft/vercel-optimize/lib/route-normalize.mjs +224 -224
- package/skills/craft/vercel-optimize/lib/sanitizers/bot-protection-certainty.mjs +56 -56
- package/skills/craft/vercel-optimize/lib/sanitizers/cache-tag-invalidation-certainty.mjs +33 -33
- package/skills/craft/vercel-optimize/lib/sanitizers/count-correct.mjs +53 -53
- package/skills/craft/vercel-optimize/lib/sanitizers/function-duration-invocations.mjs +32 -32
- package/skills/craft/vercel-optimize/lib/sanitizers/index.mjs +87 -87
- package/skills/craft/vercel-optimize/lib/sanitizers/middleware-conflict.mjs +37 -37
- package/skills/craft/vercel-optimize/lib/sanitizers/missing-citation.mjs +16 -16
- package/skills/craft/vercel-optimize/lib/sanitizers/pre-release.mjs +75 -75
- package/skills/craft/vercel-optimize/lib/sanitizers/rate-limit.mjs +73 -73
- package/skills/craft/vercel-optimize/lib/sanitizers/rendering-mode-mislabel.mjs +42 -42
- package/skills/craft/vercel-optimize/lib/sanitizers/undeclared-dep.mjs +110 -110
- package/skills/craft/vercel-optimize/lib/sanitizers/vercel-directive-strip.mjs +37 -37
- package/skills/craft/vercel-optimize/lib/sanitizers/window-units.mjs +26 -26
- package/skills/craft/vercel-optimize/lib/scanners/cache-components-suspense-dedupe.mjs +114 -114
- package/skills/craft/vercel-optimize/lib/scanners/edge-heavy-import.mjs +102 -102
- package/skills/craft/vercel-optimize/lib/scanners/force-dynamic.mjs +39 -39
- package/skills/craft/vercel-optimize/lib/scanners/headers-in-page.mjs +43 -43
- package/skills/craft/vercel-optimize/lib/scanners/index.mjs +35 -35
- package/skills/craft/vercel-optimize/lib/scanners/large-static-asset.mjs +93 -93
- package/skills/craft/vercel-optimize/lib/scanners/max-age-without-s-maxage.mjs +47 -47
- package/skills/craft/vercel-optimize/lib/scanners/middleware-broad-matcher.mjs +53 -53
- package/skills/craft/vercel-optimize/lib/scanners/missing-cache-headers.mjs +97 -97
- package/skills/craft/vercel-optimize/lib/scanners/prisma-include-tree.mjs +39 -39
- package/skills/craft/vercel-optimize/lib/scanners/region-pin-in-config.mjs +89 -89
- package/skills/craft/vercel-optimize/lib/scanners/source-maps-production.mjs +33 -33
- package/skills/craft/vercel-optimize/lib/scanners/sveltekit-prerender-missing.mjs +47 -47
- package/skills/craft/vercel-optimize/lib/scanners/turbo-force-bypass.mjs +136 -136
- package/skills/craft/vercel-optimize/lib/scanners/unoptimized-image.mjs +127 -127
- package/skills/craft/vercel-optimize/lib/scanners/use-cache-date-stamp.mjs +112 -112
- package/skills/craft/vercel-optimize/lib/support-topics.mjs +365 -365
- package/skills/craft/vercel-optimize/lib/throttle.mjs +280 -280
- package/skills/craft/vercel-optimize/lib/util.mjs +17 -17
- package/skills/craft/vercel-optimize/lib/vercel.mjs +855 -855
- package/skills/craft/vercel-optimize/lib/verify-claim.mjs +1843 -1843
- package/skills/craft/vercel-optimize/lib/workspace-resolver.mjs +552 -552
- package/skills/craft/vercel-optimize/metadata.json +14 -14
- package/skills/craft/vercel-optimize/references/candidates.md +176 -176
- package/skills/craft/vercel-optimize/references/data-collection.md +224 -224
- package/skills/craft/vercel-optimize/references/docs-library.json +683 -683
- package/skills/craft/vercel-optimize/references/doctrine.md +108 -108
- package/skills/craft/vercel-optimize/references/observability-plus.md +109 -109
- package/skills/craft/vercel-optimize/references/playbooks/README.md +57 -57
- package/skills/craft/vercel-optimize/references/playbooks/ai-application.md +32 -32
- package/skills/craft/vercel-optimize/references/playbooks/api-service.md +30 -30
- package/skills/craft/vercel-optimize/references/playbooks/content-site.md +30 -30
- package/skills/craft/vercel-optimize/references/playbooks/ecommerce.md +30 -30
- package/skills/craft/vercel-optimize/references/playbooks/marketing.md +30 -30
- package/skills/craft/vercel-optimize/references/playbooks/saas.md +31 -31
- package/skills/craft/vercel-optimize/references/playbooks/sveltekit.md +75 -75
- package/skills/craft/vercel-optimize/references/recommendations.md +214 -214
- package/skills/craft/vercel-optimize/references/scanner-patterns.md +266 -266
- package/skills/craft/vercel-optimize/references/scoring.md +208 -208
- package/skills/craft/vercel-optimize/references/support-topics/README.md +50 -50
- package/skills/craft/vercel-optimize/references/support-topics/astro-edge-middleware-scope.md +30 -30
- package/skills/craft/vercel-optimize/references/support-topics/astro-output-mode-and-isr.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/auth-preserving-parallelization.md +30 -30
- package/skills/craft/vercel-optimize/references/support-topics/bot-protection-product-guardrails.md +32 -32
- package/skills/craft/vercel-optimize/references/support-topics/build-minutes-monorepo-fanout.md +32 -32
- package/skills/craft/vercel-optimize/references/support-topics/cache-components-static-shell-boundaries.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/cache-components-suspense-dedupe-pitfall.md +32 -32
- package/skills/craft/vercel-optimize/references/support-topics/cdn-cache-auth-safety.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/cold-start-initialization-bundle.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/core-web-vitals-client-bottlenecks.md +33 -33
- package/skills/craft/vercel-optimize/references/support-topics/database-egress-pooling-region.md +32 -32
- package/skills/craft/vercel-optimize/references/support-topics/dynamic-rendering-traps.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/external-api-critical-path-platform.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/external-api-critical-path.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/fast-data-transfer-payloads.md +26 -26
- package/skills/craft/vercel-optimize/references/support-topics/fluid-compute-caveats.md +26 -26
- package/skills/craft/vercel-optimize/references/support-topics/function-duration-io-and-after.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/function-invocation-reduction.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/function-region-misconfiguration-ttfb.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/image-optimization-cost-control.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/isr-revalidation-static-generation.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/middleware-proxy-edge-cost.md +30 -30
- package/skills/craft/vercel-optimize/references/support-topics/next-fetch-revalidate-floor.md +30 -30
- package/skills/craft/vercel-optimize/references/support-topics/next-font-cls-self-hosting.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/next-heavy-ui-lazy-load-boundaries.md +28 -28
- package/skills/craft/vercel-optimize/references/support-topics/next-image-lcp-preload-sizes.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/next-route-handler-get-cache-defaults.md +30 -30
- package/skills/craft/vercel-optimize/references/support-topics/next-script-third-party-strategy.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/nextjs-version-cache-semantics.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/not-found-catchall-request-waste.md +33 -33
- package/skills/craft/vercel-optimize/references/support-topics/nuxt-route-rules-cache-isr.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/observability-events-cost-attribution.md +27 -27
- package/skills/craft/vercel-optimize/references/support-topics/post-response-work-waituntil.md +26 -26
- package/skills/craft/vercel-optimize/references/support-topics/route-error-durable-offload.md +33 -33
- package/skills/craft/vercel-optimize/references/support-topics/route-error-runtime-limits.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/runtime-cache-reusable-data.md +30 -30
- package/skills/craft/vercel-optimize/references/support-topics/sveltekit-isr-prerender-safety.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/sveltekit-split-cold-start-tradeoff.md +30 -30
- package/skills/craft/vercel-optimize/references/support-topics/usage-spike-triage.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/use-cache-date-stamp-isr-write-amplifier.md +31 -31
- package/skills/craft/vercel-optimize/references/support-topics/use-cache-remote-shared-origin-data.md +30 -30
- package/skills/craft/vercel-optimize/references/support-topics/workflow-resumable-stream-routes.md +32 -32
- package/skills/craft/vercel-optimize/references/verification.md +102 -102
- package/skills/craft/vercel-optimize/references/voice.md +76 -76
- package/skills/craft/vercel-optimize/scripts/budget-summary.mjs +58 -58
- package/skills/craft/vercel-optimize/scripts/build-docs.mjs +76 -76
- package/skills/craft/vercel-optimize/scripts/check-citations.mjs +91 -91
- package/skills/craft/vercel-optimize/scripts/check-docs-fresh.mjs +100 -100
- package/skills/craft/vercel-optimize/scripts/collect-signals.mjs +638 -638
- package/skills/craft/vercel-optimize/scripts/collect-sub-agent-outputs.mjs +306 -306
- package/skills/craft/vercel-optimize/scripts/deep-dive.mjs +358 -358
- package/skills/craft/vercel-optimize/scripts/gate-investigations.mjs +178 -178
- package/skills/craft/vercel-optimize/scripts/merge-signals.mjs +203 -203
- package/skills/craft/vercel-optimize/scripts/prepare-investigation-brief.mjs +249 -249
- package/skills/craft/vercel-optimize/scripts/reconcile-candidates.mjs +69 -69
- package/skills/craft/vercel-optimize/scripts/render-report.mjs +462 -462
- package/skills/craft/vercel-optimize/scripts/scan-codebase.mjs +361 -361
- package/skills/craft/vercel-optimize/scripts/verify-and-regen.mjs +379 -379
- package/skills/craft/vercel-optimize/scripts/verify-finding.mjs +21 -21
- package/skills/craft/web-design-guidelines/LICENSE +21 -21
- package/skills/craft/web-design-guidelines/SKILL.md +43 -43
- package/skills/craft/zero-to-live/LICENSE +21 -21
- package/skills/craft/zero-to-live/SKILL.md +422 -422
- package/skills/creative/creative-3d-modeling/LICENSE +21 -21
- package/skills/creative/creative-3d-modeling/SKILL.md +70 -70
- package/skills/creative/creative-architecture/LICENSE +21 -21
- package/skills/creative/creative-architecture/SKILL.md +94 -94
- package/skills/creative/creative-design-principles/LICENSE +21 -21
- package/skills/creative/creative-design-principles/SKILL.md +95 -95
- package/skills/creative/creative-fashion-advanced/LICENSE +21 -21
- package/skills/creative/creative-fashion-advanced/SKILL.md +68 -68
- package/skills/creative/creative-fashion-design/LICENSE +21 -21
- package/skills/creative/creative-fashion-design/SKILL.md +66 -66
- package/skills/creative/creative-game-design/LICENSE +21 -21
- package/skills/creative/creative-game-design/SKILL.md +77 -77
- package/skills/creative/creative-industrial-design/LICENSE +21 -21
- package/skills/creative/creative-industrial-design/SKILL.md +57 -57
- package/skills/creative/creative-interior-design/LICENSE +21 -21
- package/skills/creative/creative-interior-design/SKILL.md +59 -59
- package/skills/creative/creative-music-theory/LICENSE +21 -21
- package/skills/creative/creative-music-theory/SKILL.md +98 -98
- package/skills/creative/creative-photography/LICENSE +21 -21
- package/skills/creative/creative-photography/SKILL.md +87 -87
- package/skills/creative/creative-textile-science/LICENSE +21 -21
- package/skills/creative/creative-textile-science/SKILL.md +67 -67
- package/skills/creative/creative-ux/LICENSE +21 -21
- package/skills/creative/creative-ux/SKILL.md +81 -81
- package/skills/creative/creative-video/LICENSE +21 -21
- package/skills/creative/creative-video/SKILL.md +84 -84
- package/skills/creative/creative-writing-craft/LICENSE +21 -21
- package/skills/creative/creative-writing-craft/SKILL.md +91 -91
- package/skills/diagram-maker/SKILL.md +56 -56
- package/skills/diagram-maker/references/excalidraw-patterns.md +85 -85
- package/skills/diagram-maker/references/svg-template.md +112 -112
- package/skills/discord/SKILL.md +140 -140
- package/skills/education/edu-adult-learning/LICENSE +21 -21
- package/skills/education/edu-adult-learning/SKILL.md +81 -81
- package/skills/education/edu-africa-multilingual/LICENSE +21 -21
- package/skills/education/edu-africa-multilingual/SKILL.md +55 -55
- package/skills/education/edu-arabic/LICENSE +21 -21
- package/skills/education/edu-arabic/SKILL.md +60 -60
- package/skills/education/edu-australia-nz/LICENSE +21 -21
- package/skills/education/edu-australia-nz/SKILL.md +48 -48
- package/skills/education/edu-china-mandarin/LICENSE +21 -21
- package/skills/education/edu-china-mandarin/SKILL.md +58 -58
- package/skills/education/edu-critical-thinking/LICENSE +21 -21
- package/skills/education/edu-critical-thinking/SKILL.md +86 -86
- package/skills/education/edu-curriculum/LICENSE +21 -21
- package/skills/education/edu-curriculum/SKILL.md +87 -87
- package/skills/education/edu-ed-tech/LICENSE +21 -21
- package/skills/education/edu-ed-tech/SKILL.md +73 -73
- package/skills/education/edu-france/LICENSE +21 -21
- package/skills/education/edu-france/SKILL.md +42 -42
- package/skills/education/edu-germany/LICENSE +21 -21
- package/skills/education/edu-germany/SKILL.md +46 -46
- package/skills/education/edu-india-competitive/LICENSE +21 -21
- package/skills/education/edu-india-competitive/SKILL.md +159 -159
- package/skills/education/edu-india-east/LICENSE +21 -21
- package/skills/education/edu-india-east/SKILL.md +60 -60
- package/skills/education/edu-india-hindi/LICENSE +21 -21
- package/skills/education/edu-india-hindi/SKILL.md +107 -107
- package/skills/education/edu-india-south/LICENSE +21 -21
- package/skills/education/edu-india-south/SKILL.md +64 -64
- package/skills/education/edu-india-west/LICENSE +21 -21
- package/skills/education/edu-india-west/SKILL.md +68 -68
- package/skills/education/edu-indonesia-malay/LICENSE +21 -21
- package/skills/education/edu-indonesia-malay/SKILL.md +57 -57
- package/skills/education/edu-international-ib/LICENSE +21 -21
- package/skills/education/edu-international-ib/SKILL.md +61 -61
- package/skills/education/edu-japan/LICENSE +21 -21
- package/skills/education/edu-japan/SKILL.md +48 -48
- package/skills/education/edu-korea/LICENSE +21 -21
- package/skills/education/edu-korea/SKILL.md +48 -48
- package/skills/education/edu-learning-science/LICENSE +21 -21
- package/skills/education/edu-learning-science/SKILL.md +76 -76
- package/skills/education/edu-portuguese-brazil/LICENSE +21 -21
- package/skills/education/edu-portuguese-brazil/SKILL.md +51 -51
- package/skills/education/edu-russia/LICENSE +21 -21
- package/skills/education/edu-russia/SKILL.md +50 -50
- package/skills/education/edu-spain-latam/LICENSE +21 -21
- package/skills/education/edu-spain-latam/SKILL.md +55 -55
- package/skills/education/edu-special/LICENSE +21 -21
- package/skills/education/edu-special/SKILL.md +76 -76
- package/skills/education/edu-thailand/LICENSE +21 -21
- package/skills/education/edu-thailand/SKILL.md +55 -55
- package/skills/education/edu-turkey/LICENSE +21 -21
- package/skills/education/edu-turkey/SKILL.md +58 -58
- package/skills/education/edu-uk-gcse-alevel/LICENSE +21 -21
- package/skills/education/edu-uk-gcse-alevel/SKILL.md +51 -51
- package/skills/education/edu-usa-graduate/LICENSE +21 -21
- package/skills/education/edu-usa-graduate/SKILL.md +57 -57
- package/skills/education/edu-usa-sat-act/LICENSE +21 -21
- package/skills/education/edu-usa-sat-act/SKILL.md +55 -55
- package/skills/education/edu-vietnam/LICENSE +21 -21
- package/skills/education/edu-vietnam/SKILL.md +53 -53
- package/skills/eightctl/SKILL.md +54 -54
- package/skills/engineering/eng-aerospace/LICENSE +21 -21
- package/skills/engineering/eng-aerospace/SKILL.md +117 -117
- package/skills/engineering/eng-chemical/LICENSE +21 -21
- package/skills/engineering/eng-chemical/SKILL.md +63 -63
- package/skills/engineering/eng-civil/LICENSE +21 -21
- package/skills/engineering/eng-civil/SKILL.md +223 -223
- package/skills/engineering/eng-control-systems/LICENSE +21 -21
- package/skills/engineering/eng-control-systems/SKILL.md +158 -158
- package/skills/engineering/eng-cryogenics/LICENSE +21 -21
- package/skills/engineering/eng-cryogenics/SKILL.md +151 -151
- package/skills/engineering/eng-electrical/LICENSE +21 -21
- package/skills/engineering/eng-electrical/SKILL.md +70 -70
- package/skills/engineering/eng-electronics-embedded/LICENSE +21 -21
- package/skills/engineering/eng-electronics-embedded/SKILL.md +89 -89
- package/skills/engineering/eng-environmental/LICENSE +21 -21
- package/skills/engineering/eng-environmental/SKILL.md +66 -66
- package/skills/engineering/eng-manufacturing/LICENSE +21 -21
- package/skills/engineering/eng-manufacturing/SKILL.md +78 -78
- package/skills/engineering/eng-mechanical/LICENSE +21 -21
- package/skills/engineering/eng-mechanical/SKILL.md +66 -66
- package/skills/engineering/eng-project/LICENSE +21 -21
- package/skills/engineering/eng-project/SKILL.md +72 -72
- package/skills/engineering/eng-propulsion/LICENSE +21 -21
- package/skills/engineering/eng-propulsion/SKILL.md +133 -133
- package/skills/engineering/eng-robotics/LICENSE +21 -21
- package/skills/engineering/eng-robotics/SKILL.md +92 -92
- package/skills/engineering/eng-systems/LICENSE +21 -21
- package/skills/engineering/eng-systems/SKILL.md +81 -81
- package/skills/environment/env-biodiversity/LICENSE +21 -21
- package/skills/environment/env-biodiversity/SKILL.md +66 -66
- package/skills/environment/env-circular-economy/LICENSE +21 -21
- package/skills/environment/env-circular-economy/SKILL.md +71 -71
- package/skills/environment/env-climate-action/LICENSE +21 -21
- package/skills/environment/env-climate-action/SKILL.md +55 -55
- package/skills/environment/env-energy/LICENSE +21 -21
- package/skills/environment/env-energy/SKILL.md +83 -83
- package/skills/environment/env-sustainability-biz/LICENSE +21 -21
- package/skills/environment/env-sustainability-biz/SKILL.md +65 -65
- package/skills/environment/env-water/LICENSE +21 -21
- package/skills/environment/env-water/SKILL.md +67 -67
- package/skills/finance/finance-accounting/LICENSE +21 -21
- package/skills/finance/finance-accounting/SKILL.md +239 -239
- package/skills/finance/finance-banking/LICENSE +21 -21
- package/skills/finance/finance-banking/SKILL.md +54 -54
- package/skills/finance/finance-corporate/LICENSE +21 -21
- package/skills/finance/finance-corporate/SKILL.md +105 -105
- package/skills/finance/finance-crypto/LICENSE +21 -21
- package/skills/finance/finance-crypto/SKILL.md +94 -94
- package/skills/finance/finance-debt-management/LICENSE +21 -21
- package/skills/finance/finance-debt-management/SKILL.md +87 -87
- package/skills/finance/finance-insurance/LICENSE +21 -21
- package/skills/finance/finance-insurance/SKILL.md +91 -91
- package/skills/finance/finance-investing/LICENSE +21 -21
- package/skills/finance/finance-investing/SKILL.md +269 -269
- package/skills/finance/finance-options-derivatives/LICENSE +21 -21
- package/skills/finance/finance-options-derivatives/SKILL.md +68 -68
- package/skills/finance/finance-personal/LICENSE +21 -21
- package/skills/finance/finance-personal/SKILL.md +268 -268
- package/skills/finance/finance-real-estate/LICENSE +21 -21
- package/skills/finance/finance-real-estate/SKILL.md +110 -110
- package/skills/finance/finance-startup/LICENSE +21 -21
- package/skills/finance/finance-startup/SKILL.md +253 -253
- package/skills/finance/finance-tax-planning/LICENSE +21 -21
- package/skills/finance/finance-tax-planning/SKILL.md +89 -89
- package/skills/finance/finance-trading/LICENSE +21 -21
- package/skills/finance/finance-trading/SKILL.md +112 -112
- package/skills/gemini/SKILL.md +51 -51
- package/skills/gh-issues/SKILL.md +216 -216
- package/skills/gifgrep/SKILL.md +89 -89
- package/skills/github/SKILL.md +87 -87
- package/skills/gog/SKILL.md +120 -120
- package/skills/goplaces/SKILL.md +56 -56
- package/skills/health/health-aging/LICENSE +21 -21
- package/skills/health/health-aging/SKILL.md +82 -82
- package/skills/health/health-chronic/LICENSE +21 -21
- package/skills/health/health-chronic/SKILL.md +202 -202
- package/skills/health/health-dental/LICENSE +21 -21
- package/skills/health/health-dental/SKILL.md +41 -41
- package/skills/health/health-eye-care/LICENSE +21 -21
- package/skills/health/health-eye-care/SKILL.md +56 -56
- package/skills/health/health-first-aid/LICENSE +21 -21
- package/skills/health/health-first-aid/SKILL.md +201 -201
- package/skills/health/health-fitness/LICENSE +21 -21
- package/skills/health/health-fitness/SKILL.md +111 -111
- package/skills/health/health-general/LICENSE +21 -21
- package/skills/health/health-general/SKILL.md +277 -277
- package/skills/health/health-mens/LICENSE +21 -21
- package/skills/health/health-mens/SKILL.md +53 -53
- package/skills/health/health-mental/LICENSE +21 -21
- package/skills/health/health-mental/SKILL.md +221 -221
- package/skills/health/health-naturopathy-ayurveda/LICENSE +21 -21
- package/skills/health/health-naturopathy-ayurveda/SKILL.md +60 -60
- package/skills/health/health-nutrition/LICENSE +21 -21
- package/skills/health/health-nutrition/SKILL.md +262 -262
- package/skills/health/health-pediatric/LICENSE +21 -21
- package/skills/health/health-pediatric/SKILL.md +94 -94
- package/skills/health/health-pharmacology/LICENSE +21 -21
- package/skills/health/health-pharmacology/SKILL.md +87 -87
- package/skills/health/health-pregnancy/LICENSE +21 -21
- package/skills/health/health-pregnancy/SKILL.md +71 -71
- package/skills/health/health-skin/LICENSE +21 -21
- package/skills/health/health-skin/SKILL.md +71 -71
- package/skills/health/health-sleep/LICENSE +21 -21
- package/skills/health/health-sleep/SKILL.md +81 -81
- package/skills/health/health-womens/LICENSE +21 -21
- package/skills/health/health-womens/SKILL.md +72 -72
- package/skills/health/health-yoga-wellness/LICENSE +21 -21
- package/skills/health/health-yoga-wellness/SKILL.md +58 -58
- package/skills/healthcare-systems/health-sys-global/LICENSE +21 -21
- package/skills/healthcare-systems/health-sys-global/SKILL.md +69 -69
- package/skills/healthcare-systems/health-sys-management/LICENSE +21 -21
- package/skills/healthcare-systems/health-sys-management/SKILL.md +71 -71
- package/skills/healthcare-systems/health-sys-navigation/LICENSE +21 -21
- package/skills/healthcare-systems/health-sys-navigation/SKILL.md +60 -60
- package/skills/healthcare-systems/health-sys-public/LICENSE +21 -21
- package/skills/healthcare-systems/health-sys-public/SKILL.md +71 -71
- package/skills/healthcheck/SKILL.md +109 -109
- package/skills/himalaya/SKILL.md +84 -84
- package/skills/himalaya/references/configuration.md +184 -184
- package/skills/himalaya/references/message-composition.md +199 -199
- package/skills/humanities/humanities-history-world/LICENSE +21 -21
- package/skills/humanities/humanities-history-world/SKILL.md +59 -59
- package/skills/humanities/humanities-indian-classical/LICENSE +21 -21
- package/skills/humanities/humanities-indian-classical/SKILL.md +104 -104
- package/skills/humanities/humanities-philosophy/LICENSE +21 -21
- package/skills/humanities/humanities-philosophy/SKILL.md +105 -105
- package/skills/humanities/humanities-world-religions/LICENSE +21 -21
- package/skills/humanities/humanities-world-religions/SKILL.md +67 -67
- package/skills/impeccable/SKILL.md +185 -185
- package/skills/imsg/SKILL.md +126 -126
- package/skills/industry/industry-construction/LICENSE +21 -21
- package/skills/industry/industry-construction/SKILL.md +81 -81
- package/skills/industry/industry-education-sector/LICENSE +21 -21
- package/skills/industry/industry-education-sector/SKILL.md +49 -49
- package/skills/industry/industry-fashion/LICENSE +21 -21
- package/skills/industry/industry-fashion/SKILL.md +82 -82
- package/skills/industry/industry-food/LICENSE +21 -21
- package/skills/industry/industry-food/SKILL.md +79 -79
- package/skills/industry/industry-government/LICENSE +21 -21
- package/skills/industry/industry-government/SKILL.md +80 -80
- package/skills/industry/industry-hospitality/LICENSE +21 -21
- package/skills/industry/industry-hospitality/SKILL.md +73 -73
- package/skills/industry/industry-insurance-sector/LICENSE +21 -21
- package/skills/industry/industry-insurance-sector/SKILL.md +57 -57
- package/skills/industry/industry-logistics/LICENSE +21 -21
- package/skills/industry/industry-logistics/SKILL.md +80 -80
- package/skills/industry/industry-media/LICENSE +21 -21
- package/skills/industry/industry-media/SKILL.md +66 -66
- package/skills/industry/industry-nonprofit/LICENSE +21 -21
- package/skills/industry/industry-nonprofit/SKILL.md +77 -77
- package/skills/industry/industry-pharma/LICENSE +21 -21
- package/skills/industry/industry-pharma/SKILL.md +69 -69
- package/skills/industry/industry-real-estate/LICENSE +21 -21
- package/skills/industry/industry-real-estate/SKILL.md +61 -61
- package/skills/industry/industry-sports/LICENSE +21 -21
- package/skills/industry/industry-sports/SKILL.md +71 -71
- package/skills/industry/industry-tech-startup/LICENSE +21 -21
- package/skills/industry/industry-tech-startup/SKILL.md +82 -82
- package/skills/internal-comms/LICENSE +21 -21
- package/skills/internal-comms/SKILL.md +38 -38
- package/skills/internal-comms/examples/3p-updates.md +49 -49
- package/skills/internal-comms/examples/company-newsletter.md +76 -76
- package/skills/internal-comms/examples/faq-answers.md +35 -35
- package/skills/internal-comms/examples/general-comms.md +19 -19
- package/skills/legal/legal-business/LICENSE +21 -21
- package/skills/legal/legal-business/SKILL.md +227 -227
- package/skills/legal/legal-consumer/LICENSE +21 -21
- package/skills/legal/legal-consumer/SKILL.md +155 -155
- package/skills/legal/legal-contracts/LICENSE +21 -21
- package/skills/legal/legal-contracts/SKILL.md +268 -268
- package/skills/legal/legal-corporate-governance/LICENSE +21 -21
- package/skills/legal/legal-corporate-governance/SKILL.md +53 -53
- package/skills/legal/legal-employment/LICENSE +21 -21
- package/skills/legal/legal-employment/SKILL.md +291 -291
- package/skills/legal/legal-immigration/LICENSE +21 -21
- package/skills/legal/legal-immigration/SKILL.md +146 -146
- package/skills/legal/legal-international/LICENSE +21 -21
- package/skills/legal/legal-international/SKILL.md +51 -51
- package/skills/legal/legal-ip/LICENSE +21 -21
- package/skills/legal/legal-ip/SKILL.md +264 -264
- package/skills/legal/legal-privacy/LICENSE +21 -21
- package/skills/legal/legal-privacy/SKILL.md +161 -161
- package/skills/legal/legal-real-estate/LICENSE +21 -21
- package/skills/legal/legal-real-estate/SKILL.md +142 -142
- package/skills/legal/legal-startup/LICENSE +21 -21
- package/skills/legal/legal-startup/SKILL.md +182 -182
- package/skills/legal/legal-tax/LICENSE +21 -21
- package/skills/legal/legal-tax/SKILL.md +156 -156
- package/skills/mcp-builder/LICENSE +21 -21
- package/skills/mcp-builder/SKILL.md +257 -257
- package/skills/mcp-builder/reference/evaluation.md +630 -630
- package/skills/mcp-builder/reference/mcp_best_practices.md +269 -269
- package/skills/mcp-builder/reference/node_mcp_server.md +980 -980
- package/skills/mcp-builder/reference/python_mcp_server.md +737 -737
- package/skills/mcp-builder/scripts/connections.py +151 -151
- package/skills/mcp-builder/scripts/evaluation.py +373 -373
- package/skills/mcp-builder/scripts/example_evaluation.xml +22 -22
- package/skills/mcp-builder/scripts/requirements.txt +2 -2
- package/skills/mcporter/SKILL.md +65 -65
- package/skills/meme-maker/SKILL.md +46 -46
- package/skills/meme-maker/references/templates.json +358 -358
- package/skills/meme-maker/scripts/meme.mjs +398 -398
- package/skills/mental-health/mental-health-cbt/LICENSE +21 -21
- package/skills/mental-health/mental-health-cbt/SKILL.md +254 -254
- package/skills/mental-health/psych-addiction/LICENSE +21 -21
- package/skills/mental-health/psych-addiction/SKILL.md +79 -79
- package/skills/mental-health/psych-behavioral-econ/LICENSE +21 -21
- package/skills/mental-health/psych-behavioral-econ/SKILL.md +84 -84
- package/skills/mental-health/psych-child/LICENSE +21 -21
- package/skills/mental-health/psych-child/SKILL.md +84 -84
- package/skills/mental-health/psych-grief/LICENSE +21 -21
- package/skills/mental-health/psych-grief/SKILL.md +85 -85
- package/skills/mental-health/psych-mindfulness/LICENSE +21 -21
- package/skills/mental-health/psych-mindfulness/SKILL.md +71 -71
- package/skills/mental-health/psych-org/LICENSE +21 -21
- package/skills/mental-health/psych-org/SKILL.md +115 -115
- package/skills/mental-health/psych-positive/LICENSE +21 -21
- package/skills/mental-health/psych-positive/SKILL.md +86 -86
- package/skills/mental-health/psych-relationships/LICENSE +21 -21
- package/skills/mental-health/psych-relationships/SKILL.md +100 -100
- package/skills/mental-health/psych-trauma/LICENSE +21 -21
- package/skills/mental-health/psych-trauma/SKILL.md +109 -109
- package/skills/model-usage/SKILL.md +75 -75
- package/skills/model-usage/references/codexbar-cli.md +33 -33
- package/skills/model-usage/scripts/model_usage.py +319 -319
- package/skills/model-usage/scripts/test_model_usage.py +40 -40
- package/skills/nano-pdf/SKILL.md +42 -42
- package/skills/node-connect/SKILL.md +147 -147
- package/skills/node-inspect-debugger/SKILL.md +88 -88
- package/skills/notion/SKILL.md +154 -154
- package/skills/obsidian/SKILL.md +123 -123
- package/skills/openai-whisper/SKILL.md +42 -42
- package/skills/openai-whisper-api/SKILL.md +75 -75
- package/skills/openai-whisper-api/scripts/transcribe.sh +154 -154
- package/skills/openhue/SKILL.md +116 -116
- package/skills/oracle/SKILL.md +130 -130
- package/skills/ordercli/SKILL.md +82 -82
- package/skills/peekaboo/SKILL.md +217 -217
- package/skills/pyproject.toml +10 -10
- package/skills/python-debugpy/SKILL.md +76 -76
- package/skills/sag/SKILL.md +91 -91
- package/skills/science/sci-astronomy/LICENSE +21 -21
- package/skills/science/sci-astronomy/SKILL.md +80 -80
- package/skills/science/sci-biology/LICENSE +21 -21
- package/skills/science/sci-biology/SKILL.md +74 -74
- package/skills/science/sci-chemistry/LICENSE +21 -21
- package/skills/science/sci-chemistry/SKILL.md +89 -89
- package/skills/science/sci-climate/LICENSE +21 -21
- package/skills/science/sci-climate/SKILL.md +72 -72
- package/skills/science/sci-data-analysis/LICENSE +21 -21
- package/skills/science/sci-data-analysis/SKILL.md +87 -87
- package/skills/science/sci-environmental-science/LICENSE +21 -21
- package/skills/science/sci-environmental-science/SKILL.md +69 -69
- package/skills/science/sci-geology/LICENSE +21 -21
- package/skills/science/sci-geology/SKILL.md +56 -56
- package/skills/science/sci-method/LICENSE +21 -21
- package/skills/science/sci-method/SKILL.md +77 -77
- package/skills/science/sci-neuroscience/LICENSE +21 -21
- package/skills/science/sci-neuroscience/SKILL.md +79 -79
- package/skills/science/sci-physics/LICENSE +21 -21
- package/skills/science/sci-physics/SKILL.md +78 -78
- package/skills/science/sci-research-methods/LICENSE +21 -21
- package/skills/science/sci-research-methods/SKILL.md +83 -83
- package/skills/science/sci-statistics/LICENSE +21 -21
- package/skills/science/sci-statistics/SKILL.md +249 -249
- package/skills/session-logs/SKILL.md +155 -155
- package/skills/sherpa-onnx-tts/SKILL.md +113 -113
- package/skills/skill-creator/SKILL.md +81 -81
- package/skills/skill-creator/license.txt +202 -202
- package/skills/skill-creator/scripts/init_skill.py +378 -378
- package/skills/skill-creator/scripts/package_skill.py +144 -144
- package/skills/skill-creator/scripts/quick_validate.py +169 -169
- package/skills/skill-creator/scripts/test_init_skill.py +51 -51
- package/skills/skill-creator/scripts/test_package_skill.py +199 -199
- package/skills/skill-creator/scripts/test_quick_validate.py +116 -116
- package/skills/slack/SKILL.md +82 -82
- package/skills/slack-gif-creator/LICENSE +21 -21
- package/skills/slack-gif-creator/SKILL.md +293 -293
- package/skills/slack-gif-creator/requirements.txt +3 -3
- package/skills/social-sciences/social-anthropology/LICENSE +21 -21
- package/skills/social-sciences/social-anthropology/SKILL.md +62 -62
- package/skills/social-sciences/social-economics/LICENSE +21 -21
- package/skills/social-sciences/social-economics/SKILL.md +88 -88
- package/skills/social-sciences/social-geography/LICENSE +21 -21
- package/skills/social-sciences/social-geography/SKILL.md +61 -61
- package/skills/social-sciences/social-international-dev/LICENSE +21 -21
- package/skills/social-sciences/social-international-dev/SKILL.md +76 -76
- package/skills/social-sciences/social-political-science/LICENSE +21 -21
- package/skills/social-sciences/social-political-science/SKILL.md +70 -70
- package/skills/social-sciences/social-public-policy/LICENSE +21 -21
- package/skills/social-sciences/social-public-policy/SKILL.md +73 -73
- package/skills/social-sciences/social-sociology/LICENSE +21 -21
- package/skills/social-sciences/social-sociology/SKILL.md +78 -78
- package/skills/songsee/SKILL.md +53 -53
- package/skills/sonoscli/SKILL.md +69 -69
- package/skills/spike/SKILL.md +55 -55
- package/skills/spotify-player/SKILL.md +68 -68
- package/skills/summarize/SKILL.md +90 -90
- package/skills/taskflow/SKILL.md +153 -153
- package/skills/taskflow/examples/inbox-triage.lobster +33 -33
- package/skills/taskflow/examples/pr-intake.lobster +32 -32
- package/skills/taskflow-inbox-triage/SKILL.md +123 -123
- package/skills/technical/ai-ethics/LICENSE +21 -21
- package/skills/technical/ai-ethics/SKILL.md +92 -92
- package/skills/technical/ai-product-builder/LICENSE +21 -21
- package/skills/technical/ai-product-builder/SKILL.md +180 -180
- package/skills/technical/analytics-setup/LICENSE +21 -21
- package/skills/technical/analytics-setup/SKILL.md +125 -125
- package/skills/technical/api-builder/LICENSE +21 -21
- package/skills/technical/api-builder/SKILL.md +202 -202
- package/skills/technical/architecture-decisions/LICENSE +21 -21
- package/skills/technical/architecture-decisions/SKILL.md +120 -120
- package/skills/technical/auth-security/LICENSE +21 -21
- package/skills/technical/auth-security/SKILL.md +209 -209
- package/skills/technical/blockchain-web3/LICENSE +21 -21
- package/skills/technical/blockchain-web3/SKILL.md +84 -84
- package/skills/technical/cloud-architecture/LICENSE +21 -21
- package/skills/technical/cloud-architecture/SKILL.md +85 -85
- package/skills/technical/content-platform/LICENSE +21 -21
- package/skills/technical/content-platform/SKILL.md +134 -134
- package/skills/technical/cybersecurity-advanced/LICENSE +21 -21
- package/skills/technical/cybersecurity-advanced/SKILL.md +99 -99
- package/skills/technical/data-engineering/LICENSE +21 -21
- package/skills/technical/data-engineering/SKILL.md +117 -117
- package/skills/technical/database-design/LICENSE +21 -21
- package/skills/technical/database-design/SKILL.md +185 -185
- package/skills/technical/devops-cicd/LICENSE +21 -21
- package/skills/technical/devops-cicd/SKILL.md +181 -181
- package/skills/technical/ecommerce-builder/LICENSE +21 -21
- package/skills/technical/ecommerce-builder/SKILL.md +123 -123
- package/skills/technical/email-marketing/LICENSE +21 -21
- package/skills/technical/email-marketing/SKILL.md +128 -128
- package/skills/technical/fintech-builder/LICENSE +21 -21
- package/skills/technical/fintech-builder/SKILL.md +141 -141
- package/skills/technical/full-stack-web/LICENSE +21 -21
- package/skills/technical/full-stack-web/SKILL.md +173 -173
- package/skills/technical/gdpr-basics/LICENSE +21 -21
- package/skills/technical/gdpr-basics/SKILL.md +145 -145
- package/skills/technical/launch-playbook/LICENSE +21 -21
- package/skills/technical/launch-playbook/SKILL.md +95 -95
- package/skills/technical/marketing-copy/LICENSE +21 -21
- package/skills/technical/marketing-copy/SKILL.md +126 -126
- package/skills/technical/marketplace-builder/LICENSE +21 -21
- package/skills/technical/marketplace-builder/SKILL.md +105 -105
- package/skills/technical/mobile-pwa/LICENSE +21 -21
- package/skills/technical/mobile-pwa/SKILL.md +191 -191
- package/skills/technical/no-code-tools/LICENSE +21 -21
- package/skills/technical/no-code-tools/SKILL.md +80 -80
- package/skills/technical/open-source/LICENSE +21 -21
- package/skills/technical/open-source/SKILL.md +71 -71
- package/skills/technical/performance-optimization/LICENSE +21 -21
- package/skills/technical/performance-optimization/SKILL.md +155 -155
- package/skills/technical/pricing-design/LICENSE +21 -21
- package/skills/technical/pricing-design/SKILL.md +87 -87
- package/skills/technical/product-management/LICENSE +21 -21
- package/skills/technical/product-management/SKILL.md +94 -94
- package/skills/technical/saas-builder/LICENSE +21 -21
- package/skills/technical/saas-builder/SKILL.md +138 -138
- package/skills/technical/scope-estimation/LICENSE +21 -21
- package/skills/technical/scope-estimation/SKILL.md +99 -99
- package/skills/technical/secrets-management/LICENSE +21 -21
- package/skills/technical/secrets-management/SKILL.md +135 -135
- package/skills/technical/seo-technical/LICENSE +21 -21
- package/skills/technical/seo-technical/SKILL.md +136 -136
- package/skills/technical/technical-writing/LICENSE +21 -21
- package/skills/technical/technical-writing/SKILL.md +149 -149
- package/skills/technical/ux-research-tools/LICENSE +21 -21
- package/skills/technical/ux-research-tools/SKILL.md +54 -54
- package/skills/theme-factory/LICENSE +21 -21
- package/skills/theme-factory/SKILL.md +65 -65
- package/skills/theme-factory/themes/arctic-frost.md +19 -19
- package/skills/theme-factory/themes/botanical-garden.md +19 -19
- package/skills/theme-factory/themes/desert-rose.md +19 -19
- package/skills/theme-factory/themes/forest-canopy.md +19 -19
- package/skills/theme-factory/themes/golden-hour.md +19 -19
- package/skills/theme-factory/themes/midnight-galaxy.md +19 -19
- package/skills/theme-factory/themes/modern-minimalist.md +19 -19
- package/skills/theme-factory/themes/ocean-depths.md +19 -19
- package/skills/theme-factory/themes/sunset-boulevard.md +19 -19
- package/skills/theme-factory/themes/tech-innovation.md +19 -19
- package/skills/things-mac/SKILL.md +90 -90
- package/skills/tmux/SKILL.md +95 -95
- package/skills/tmux/scripts/find-sessions.sh +112 -112
- package/skills/tmux/scripts/wait-for-text.sh +83 -83
- package/skills/trades/trades-agriculture/LICENSE +21 -21
- package/skills/trades/trades-agriculture/SKILL.md +80 -80
- package/skills/trades/trades-automotive/LICENSE +21 -21
- package/skills/trades/trades-automotive/SKILL.md +84 -84
- package/skills/trades/trades-carpentry/LICENSE +21 -21
- package/skills/trades/trades-carpentry/SKILL.md +71 -71
- package/skills/trades/trades-cooking-pro/LICENSE +21 -21
- package/skills/trades/trades-cooking-pro/SKILL.md +90 -90
- package/skills/trades/trades-electrical/LICENSE +21 -21
- package/skills/trades/trades-electrical/SKILL.md +146 -146
- package/skills/trades/trades-hvac/LICENSE +21 -21
- package/skills/trades/trades-hvac/SKILL.md +80 -80
- package/skills/trades/trades-landscaping/LICENSE +21 -21
- package/skills/trades/trades-landscaping/SKILL.md +60 -60
- package/skills/trades/trades-metalworking/LICENSE +21 -21
- package/skills/trades/trades-metalworking/SKILL.md +64 -64
- package/skills/trades/trades-painting/LICENSE +21 -21
- package/skills/trades/trades-painting/SKILL.md +70 -70
- package/skills/trades/trades-plumbing/LICENSE +21 -21
- package/skills/trades/trades-plumbing/SKILL.md +160 -160
- package/skills/trades/trades-welding/LICENSE +21 -21
- package/skills/trades/trades-welding/SKILL.md +82 -82
- package/skills/trello/SKILL.md +112 -112
- package/skills/uipm-ui-styling/SKILL.md +328 -328
- package/skills/video-frames/SKILL.md +50 -50
- package/skills/video-frames/scripts/frame.sh +81 -81
- package/skills/voice-call/SKILL.md +49 -49
- package/skills/wacli/SKILL.md +76 -76
- package/skills/weather/SKILL.md +91 -91
- package/skills/web-artifacts-builder/LICENSE +21 -21
- package/skills/web-artifacts-builder/SKILL.md +82 -82
- package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +53 -53
- package/skills/web-artifacts-builder/scripts/init-artifact.sh +322 -322
- package/skills/xurl/SKILL.md +124 -124
- package/skills/graphify/SKILL.md +0 -619
- package/skills/graphify/__init__.py +0 -28
- package/skills/graphify/__main__.py +0 -4582
- package/skills/graphify/affected.py +0 -154
- package/skills/graphify/always_on/agents-md.md +0 -12
- package/skills/graphify/always_on/antigravity-rules.md +0 -14
- package/skills/graphify/always_on/claude-md.md +0 -9
- package/skills/graphify/always_on/gemini-md.md +0 -9
- package/skills/graphify/always_on/kiro-steering.md +0 -5
- package/skills/graphify/always_on/vscode-instructions.md +0 -17
- package/skills/graphify/analyze.py +0 -724
- package/skills/graphify/benchmark.py +0 -155
- package/skills/graphify/build.py +0 -487
- package/skills/graphify/cache.py +0 -417
- package/skills/graphify/callflow_html.py +0 -2020
- package/skills/graphify/cluster.py +0 -272
- package/skills/graphify/command-kilo.md +0 -15
- package/skills/graphify/dedup.py +0 -429
- package/skills/graphify/detect.py +0 -1379
- package/skills/graphify/diagnostics.py +0 -390
- package/skills/graphify/export.py +0 -1408
- package/skills/graphify/extract.py +0 -11570
- package/skills/graphify/global_graph.py +0 -159
- package/skills/graphify/google_workspace.py +0 -223
- package/skills/graphify/hooks.py +0 -457
- package/skills/graphify/ingest.py +0 -331
- package/skills/graphify/llm.py +0 -1896
- package/skills/graphify/manifest.py +0 -4
- package/skills/graphify/mcp_ingest.py +0 -392
- package/skills/graphify/multigraph_compat.py +0 -212
- package/skills/graphify/pg_introspect.py +0 -142
- package/skills/graphify/prs.py +0 -748
- package/skills/graphify/querylog.py +0 -70
- package/skills/graphify/report.py +0 -218
- package/skills/graphify/scip_ingest.py +0 -363
- package/skills/graphify/security.py +0 -336
- package/skills/graphify/semantic_cleanup.py +0 -319
- package/skills/graphify/serve.py +0 -1309
- package/skills/graphify/skill-aider.md +0 -1246
- package/skills/graphify/skill-amp.md +0 -613
- package/skills/graphify/skill-claw.md +0 -616
- package/skills/graphify/skill-codex.md +0 -613
- package/skills/graphify/skill-copilot.md +0 -616
- package/skills/graphify/skill-devin.md +0 -1372
- package/skills/graphify/skill-droid.md +0 -613
- package/skills/graphify/skill-kilo.md +0 -625
- package/skills/graphify/skill-kiro.md +0 -615
- package/skills/graphify/skill-opencode.md +0 -608
- package/skills/graphify/skill-pi.md +0 -615
- package/skills/graphify/skill-trae.md +0 -614
- package/skills/graphify/skill-vscode.md +0 -612
- package/skills/graphify/skill-windows.md +0 -651
- package/skills/graphify/skills/amp/references/add-watch.md +0 -56
- package/skills/graphify/skills/amp/references/exports.md +0 -71
- package/skills/graphify/skills/amp/references/extraction-spec.md +0 -68
- package/skills/graphify/skills/amp/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/amp/references/hooks.md +0 -33
- package/skills/graphify/skills/amp/references/query.md +0 -249
- package/skills/graphify/skills/amp/references/transcribe.md +0 -48
- package/skills/graphify/skills/amp/references/update.md +0 -179
- package/skills/graphify/skills/claude/references/add-watch.md +0 -56
- package/skills/graphify/skills/claude/references/exports.md +0 -71
- package/skills/graphify/skills/claude/references/extraction-spec.md +0 -68
- package/skills/graphify/skills/claude/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/claude/references/hooks.md +0 -33
- package/skills/graphify/skills/claude/references/query.md +0 -103
- package/skills/graphify/skills/claude/references/transcribe.md +0 -48
- package/skills/graphify/skills/claude/references/update.md +0 -179
- package/skills/graphify/skills/claw/references/add-watch.md +0 -56
- package/skills/graphify/skills/claw/references/exports.md +0 -71
- package/skills/graphify/skills/claw/references/extraction-spec.md +0 -29
- package/skills/graphify/skills/claw/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/claw/references/hooks.md +0 -33
- package/skills/graphify/skills/claw/references/query.md +0 -249
- package/skills/graphify/skills/claw/references/transcribe.md +0 -48
- package/skills/graphify/skills/claw/references/update.md +0 -179
- package/skills/graphify/skills/codex/references/add-watch.md +0 -56
- package/skills/graphify/skills/codex/references/exports.md +0 -71
- package/skills/graphify/skills/codex/references/extraction-spec.md +0 -29
- package/skills/graphify/skills/codex/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/codex/references/hooks.md +0 -33
- package/skills/graphify/skills/codex/references/query.md +0 -249
- package/skills/graphify/skills/codex/references/transcribe.md +0 -48
- package/skills/graphify/skills/codex/references/update.md +0 -179
- package/skills/graphify/skills/copilot/references/add-watch.md +0 -56
- package/skills/graphify/skills/copilot/references/exports.md +0 -71
- package/skills/graphify/skills/copilot/references/extraction-spec.md +0 -68
- package/skills/graphify/skills/copilot/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/copilot/references/hooks.md +0 -33
- package/skills/graphify/skills/copilot/references/query.md +0 -249
- package/skills/graphify/skills/copilot/references/transcribe.md +0 -48
- package/skills/graphify/skills/copilot/references/update.md +0 -179
- package/skills/graphify/skills/droid/references/add-watch.md +0 -56
- package/skills/graphify/skills/droid/references/exports.md +0 -71
- package/skills/graphify/skills/droid/references/extraction-spec.md +0 -68
- package/skills/graphify/skills/droid/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/droid/references/hooks.md +0 -33
- package/skills/graphify/skills/droid/references/query.md +0 -249
- package/skills/graphify/skills/droid/references/transcribe.md +0 -48
- package/skills/graphify/skills/droid/references/update.md +0 -179
- package/skills/graphify/skills/kilo/references/add-watch.md +0 -56
- package/skills/graphify/skills/kilo/references/exports.md +0 -71
- package/skills/graphify/skills/kilo/references/extraction-spec.md +0 -68
- package/skills/graphify/skills/kilo/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/kilo/references/hooks.md +0 -33
- package/skills/graphify/skills/kilo/references/query.md +0 -249
- package/skills/graphify/skills/kilo/references/transcribe.md +0 -48
- package/skills/graphify/skills/kilo/references/update.md +0 -179
- package/skills/graphify/skills/kiro/references/add-watch.md +0 -56
- package/skills/graphify/skills/kiro/references/exports.md +0 -71
- package/skills/graphify/skills/kiro/references/extraction-spec.md +0 -29
- package/skills/graphify/skills/kiro/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/kiro/references/hooks.md +0 -33
- package/skills/graphify/skills/kiro/references/query.md +0 -249
- package/skills/graphify/skills/kiro/references/transcribe.md +0 -48
- package/skills/graphify/skills/kiro/references/update.md +0 -179
- package/skills/graphify/skills/opencode/references/add-watch.md +0 -56
- package/skills/graphify/skills/opencode/references/exports.md +0 -71
- package/skills/graphify/skills/opencode/references/extraction-spec.md +0 -68
- package/skills/graphify/skills/opencode/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/opencode/references/hooks.md +0 -33
- package/skills/graphify/skills/opencode/references/query.md +0 -249
- package/skills/graphify/skills/opencode/references/transcribe.md +0 -48
- package/skills/graphify/skills/opencode/references/update.md +0 -179
- package/skills/graphify/skills/pi/references/add-watch.md +0 -56
- package/skills/graphify/skills/pi/references/exports.md +0 -71
- package/skills/graphify/skills/pi/references/extraction-spec.md +0 -29
- package/skills/graphify/skills/pi/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/pi/references/hooks.md +0 -33
- package/skills/graphify/skills/pi/references/query.md +0 -249
- package/skills/graphify/skills/pi/references/transcribe.md +0 -48
- package/skills/graphify/skills/pi/references/update.md +0 -179
- package/skills/graphify/skills/trae/references/add-watch.md +0 -56
- package/skills/graphify/skills/trae/references/exports.md +0 -71
- package/skills/graphify/skills/trae/references/extraction-spec.md +0 -68
- package/skills/graphify/skills/trae/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/trae/references/hooks.md +0 -35
- package/skills/graphify/skills/trae/references/query.md +0 -249
- package/skills/graphify/skills/trae/references/transcribe.md +0 -48
- package/skills/graphify/skills/trae/references/update.md +0 -179
- package/skills/graphify/skills/vscode/references/add-watch.md +0 -56
- package/skills/graphify/skills/vscode/references/exports.md +0 -71
- package/skills/graphify/skills/vscode/references/extraction-spec.md +0 -68
- package/skills/graphify/skills/vscode/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/vscode/references/hooks.md +0 -33
- package/skills/graphify/skills/vscode/references/query.md +0 -249
- package/skills/graphify/skills/vscode/references/transcribe.md +0 -48
- package/skills/graphify/skills/vscode/references/update.md +0 -179
- package/skills/graphify/skills/windows/references/add-watch.md +0 -56
- package/skills/graphify/skills/windows/references/exports.md +0 -71
- package/skills/graphify/skills/windows/references/extraction-spec.md +0 -68
- package/skills/graphify/skills/windows/references/github-and-merge.md +0 -46
- package/skills/graphify/skills/windows/references/hooks.md +0 -33
- package/skills/graphify/skills/windows/references/query.md +0 -249
- package/skills/graphify/skills/windows/references/transcribe.md +0 -48
- package/skills/graphify/skills/windows/references/update.md +0 -179
- package/skills/graphify/symbol_resolution.py +0 -538
- package/skills/graphify/transcribe.py +0 -184
- package/skills/graphify/tree_html.py +0 -582
- package/skills/graphify/validate.py +0 -72
- package/skills/graphify/watch.py +0 -898
- package/skills/graphify/wiki.py +0 -282
|
@@ -1,1038 +1,1038 @@
|
|
|
1
|
-
# Data & GCP Expert Reference — PostgreSQL, Prisma, Cloud SQL, Schedulers
|
|
2
|
-
|
|
3
|
-
## Table of Contents
|
|
4
|
-
|
|
5
|
-
1. [PostgreSQL 15/16 Expert Tier](#1-postgresql-1516-expert-tier)
|
|
6
|
-
2. [Prisma ORM 5.x Deep Reference](#2-prisma-orm-5x-deep-reference)
|
|
7
|
-
3. [Cloud SQL Configuration](#3-cloud-sql-configuration)
|
|
8
|
-
4. [Connection Pooling & Management](#4-connection-pooling--management)
|
|
9
|
-
5. [Zero-Downtime Migrations](#5-zero-downtime-migrations)
|
|
10
|
-
6. [Data Modeling for Fintech](#6-data-modeling-for-fintech)
|
|
11
|
-
7. [Cloud Scheduler — All 61 Jobs](#7-cloud-scheduler--all-61-jobs)
|
|
12
|
-
8. [BigQuery & Analytics](#8-bigquery--analytics)
|
|
13
|
-
9. [Backup, PITR & Disaster Recovery](#9-backup-pitr--disaster-recovery)
|
|
14
|
-
10. [Performance & Monitoring](#10-performance--monitoring)
|
|
15
|
-
11. [Row-Level Security & Multi-Tenancy](#11-row-level-security--multi-tenancy)
|
|
16
|
-
12. [Pub/Sub & Event-Driven Architecture](#12-pubsub--event-driven-architecture)
|
|
17
|
-
13. [GCP Secret Manager Operations](#13-gcp-secret-manager-operations)
|
|
18
|
-
14. [<project> DB Schema Reference](#14-<project>-db-schema-reference)
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## 1. PostgreSQL 15/16 Expert Tier
|
|
23
|
-
|
|
24
|
-
**PostgreSQL 15 highlights relevant to <project>:**
|
|
25
|
-
|
|
26
|
-
- `MERGE` statement (upsert with conditions)
|
|
27
|
-
- `row_pattern_recognition` — for fraud pattern detection in sequences
|
|
28
|
-
- Improved JSON path queries
|
|
29
|
-
- Logical replication improvements for Cloud SQL cross-region replicas
|
|
30
|
-
|
|
31
|
-
**PostgreSQL 16 highlights:**
|
|
32
|
-
|
|
33
|
-
- Parallel query improvements
|
|
34
|
-
- `pg_stat_io` — detailed I/O statistics
|
|
35
|
-
- Logical replication from standbys
|
|
36
|
-
- `to_char()` improvements
|
|
37
|
-
|
|
38
|
-
**Index types and when to use each:**
|
|
39
|
-
| Type | Use case |
|
|
40
|
-
|------|---------|
|
|
41
|
-
| B-tree (default) | Equality, range, sorting — general purpose |
|
|
42
|
-
| GIN | JSONB containment, array operators, full-text search |
|
|
43
|
-
| GiST | Geometric data, full-text, exclusion constraints |
|
|
44
|
-
| BRIN | Very large tables with naturally ordered data (time-series, logs) |
|
|
45
|
-
| Hash | Equality only, faster than B-tree for large equals lookups |
|
|
46
|
-
| Partial | Index only rows matching a WHERE clause (e.g., active records only) |
|
|
47
|
-
|
|
48
|
-
**<project> critical indexes:**
|
|
49
|
-
|
|
50
|
-
```sql
|
|
51
|
-
-- ACH challenges: frequent lookup by userId + status
|
|
52
|
-
CREATE INDEX CONCURRENTLY idx_ach_challenge_user_status
|
|
53
|
-
ON "AchChallenge"("userId", "status", "createdAt" DESC);
|
|
54
|
-
|
|
55
|
-
-- UPI fraud checks: lookup by VPA + time window
|
|
56
|
-
CREATE INDEX CONCURRENTLY idx_upi_fraud_vpa_created
|
|
57
|
-
ON "UpiFraudCheck"("vpa", "createdAt" DESC);
|
|
58
|
-
|
|
59
|
-
-- Unit accounts: lookup by userId
|
|
60
|
-
CREATE INDEX CONCURRENTLY idx_unit_account_user
|
|
61
|
-
ON "UnitAccount"("userId") WHERE "active" = true;
|
|
62
|
-
|
|
63
|
-
-- Guardian devices: lookup by userId
|
|
64
|
-
CREATE INDEX CONCURRENTLY idx_guardian_device_user
|
|
65
|
-
ON "GuardianDevice"("userId", "lastSeen" DESC);
|
|
66
|
-
|
|
67
|
-
-- Threat intelligence: full-text search on threat content
|
|
68
|
-
CREATE INDEX CONCURRENTLY idx_threat_content_fts
|
|
69
|
-
ON "Threat" USING GIN(to_tsvector('english', "content"));
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**EXPLAIN ANALYZE — reading query plans:**
|
|
73
|
-
|
|
74
|
-
```sql
|
|
75
|
-
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
|
|
76
|
-
SELECT * FROM "AchChallenge"
|
|
77
|
-
WHERE "userId" = 'user_id' AND "status" = 'PENDING';
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Key metrics:
|
|
81
|
-
|
|
82
|
-
- `Seq Scan` → needs an index
|
|
83
|
-
- `Index Scan` → good
|
|
84
|
-
- `Bitmap Heap Scan` → good for range queries
|
|
85
|
-
- `rows=X (actual X)` → large discrepancy = stale statistics → `ANALYZE tablename`
|
|
86
|
-
|
|
87
|
-
**VACUUM and autovacuum:**
|
|
88
|
-
Cloud SQL runs autovacuum by default. Monitor bloat:
|
|
89
|
-
|
|
90
|
-
```sql
|
|
91
|
-
SELECT relname, n_dead_tup, n_live_tup,
|
|
92
|
-
round(n_dead_tup::numeric/nullif(n_live_tup,0)*100, 2) as dead_pct
|
|
93
|
-
FROM pg_stat_user_tables
|
|
94
|
-
ORDER BY n_dead_tup DESC;
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
If dead_pct > 10% on hot tables: `VACUUM ANALYZE tablename;`
|
|
98
|
-
|
|
99
|
-
**JSONB operations for <project> threat data:**
|
|
100
|
-
|
|
101
|
-
```sql
|
|
102
|
-
-- Query JSONB field
|
|
103
|
-
SELECT * FROM "ThreatFeed" WHERE "metadata"->>'severity' = 'HIGH';
|
|
104
|
-
|
|
105
|
-
-- Update JSONB field
|
|
106
|
-
UPDATE "ThreatFeed"
|
|
107
|
-
SET "metadata" = "metadata" || '{"reviewed": true}'::jsonb
|
|
108
|
-
WHERE id = 'feed_id';
|
|
109
|
-
|
|
110
|
-
-- JSONB array contains
|
|
111
|
-
SELECT * FROM "ThreatFeed" WHERE "tags" @> '["ransomware"]'::jsonb;
|
|
112
|
-
|
|
113
|
-
-- Index for JSONB containment
|
|
114
|
-
CREATE INDEX CONCURRENTLY idx_threat_metadata_gin
|
|
115
|
-
ON "ThreatFeed" USING GIN("metadata");
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## 2. Prisma ORM 5.x Deep Reference
|
|
121
|
-
|
|
122
|
-
**Prisma 5 key features:**
|
|
123
|
-
|
|
124
|
-
- Faster query engine (Rust-based)
|
|
125
|
-
- `prismaSchemaFolder` for multi-file schemas
|
|
126
|
-
- `jsonProtocol` for edge/Cloudflare Workers
|
|
127
|
-
- `relationJoins` preview feature for JOIN-based queries (vs N+1)
|
|
128
|
-
- Typed SQL (`prisma/sql/` directory for raw SQL with types)
|
|
129
|
-
|
|
130
|
-
**Schema best practices:**
|
|
131
|
-
|
|
132
|
-
```prisma
|
|
133
|
-
// schema.prisma
|
|
134
|
-
generator client {
|
|
135
|
-
provider = "prisma-client-js"
|
|
136
|
-
previewFeatures = ["relationJoins", "typedSql"]
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
datasource db {
|
|
140
|
-
provider = "postgresql"
|
|
141
|
-
url = env("DATABASE_URL")
|
|
142
|
-
directUrl = env("DIRECT_URL") // for migrations (bypasses pgBouncer)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Audit trail mixin pattern
|
|
146
|
-
model AchChallenge {
|
|
147
|
-
id String @id @default(cuid())
|
|
148
|
-
userId String
|
|
149
|
-
status ChallengeStatus @default(PENDING)
|
|
150
|
-
options String[] // ["3", "7", "9"]
|
|
151
|
-
correctOption String
|
|
152
|
-
attempts Int @default(0)
|
|
153
|
-
expiresAt DateTime
|
|
154
|
-
resolvedAt DateTime?
|
|
155
|
-
webhookSent Boolean @default(false)
|
|
156
|
-
createdAt DateTime @default(now())
|
|
157
|
-
updatedAt DateTime @updatedAt
|
|
158
|
-
|
|
159
|
-
user User @relation(fields: [userId], references: [id])
|
|
160
|
-
|
|
161
|
-
@@index([userId, status])
|
|
162
|
-
@@index([expiresAt]) // for cleanup scheduler
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
enum ChallengeStatus {
|
|
166
|
-
PENDING
|
|
167
|
-
APPROVED
|
|
168
|
-
DECLINED
|
|
169
|
-
EXPIRED
|
|
170
|
-
LOCKED
|
|
171
|
-
}
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
**Transaction patterns:**
|
|
175
|
-
|
|
176
|
-
```typescript
|
|
177
|
-
// Interactive transaction (multiple operations, rollback on error)
|
|
178
|
-
const result = await prisma.$transaction(
|
|
179
|
-
async (tx) => {
|
|
180
|
-
const challenge = await tx.achChallenge.update({
|
|
181
|
-
where: { id: challengeId },
|
|
182
|
-
data: { status: "APPROVED", resolvedAt: new Date() },
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
await tx.achAuditLog.create({
|
|
186
|
-
data: { challengeId, action: "APPROVED", userId },
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
return challenge;
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
timeout: 10000, // 10 second timeout
|
|
193
|
-
isolationLevel: Prisma.TransactionIsolationLevel.ReadCommitted,
|
|
194
|
-
},
|
|
195
|
-
);
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
**Batch operations (better performance):**
|
|
199
|
-
|
|
200
|
-
```typescript
|
|
201
|
-
// createMany — single INSERT with multiple rows
|
|
202
|
-
await prisma.threatFeed.createMany({
|
|
203
|
-
data: threats,
|
|
204
|
-
skipDuplicates: true,
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
// updateMany — single UPDATE
|
|
208
|
-
await prisma.achChallenge.updateMany({
|
|
209
|
-
where: { status: "PENDING", expiresAt: { lt: new Date() } },
|
|
210
|
-
data: { status: "EXPIRED" },
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
// deleteMany with limit (safer for large deletes)
|
|
214
|
-
await prisma.$executeRaw`
|
|
215
|
-
DELETE FROM "AchChallenge"
|
|
216
|
-
WHERE id IN (
|
|
217
|
-
SELECT id FROM "AchChallenge"
|
|
218
|
-
WHERE "createdAt" < NOW() - INTERVAL '90 days'
|
|
219
|
-
LIMIT 1000
|
|
220
|
-
)
|
|
221
|
-
`;
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
**Pagination (cursor-based for large datasets):**
|
|
225
|
-
|
|
226
|
-
```typescript
|
|
227
|
-
// First page
|
|
228
|
-
const firstPage = await prisma.achChallenge.findMany({
|
|
229
|
-
take: 20,
|
|
230
|
-
orderBy: { createdAt: "desc" },
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
// Next page (cursor pagination — no offset drift)
|
|
234
|
-
const nextPage = await prisma.achChallenge.findMany({
|
|
235
|
-
take: 20,
|
|
236
|
-
skip: 1, // skip the cursor itself
|
|
237
|
-
cursor: { id: lastId },
|
|
238
|
-
orderBy: { createdAt: "desc" },
|
|
239
|
-
});
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
**Raw SQL with type safety (Prisma 5 typedSql):**
|
|
243
|
-
|
|
244
|
-
```sql
|
|
245
|
-
-- prisma/sql/getActiveChallenges.sql
|
|
246
|
-
SELECT ac.*, u.email FROM "AchChallenge" ac
|
|
247
|
-
JOIN "User" u ON ac."userId" = u.id
|
|
248
|
-
WHERE ac.status = $1 AND ac."expiresAt" > NOW()
|
|
249
|
-
ORDER BY ac."createdAt" DESC
|
|
250
|
-
LIMIT $2;
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
import { getActiveChallenges } from "@prisma/client/sql";
|
|
255
|
-
const challenges = await prisma.$queryRawTyped(getActiveChallenges("PENDING", 50));
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**Connection management in Cloud Run:**
|
|
259
|
-
|
|
260
|
-
```typescript
|
|
261
|
-
// Singleton pattern — critical for Cloud Run (multiple instances)
|
|
262
|
-
import { PrismaClient } from "@prisma/client";
|
|
263
|
-
|
|
264
|
-
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
|
265
|
-
export const prisma =
|
|
266
|
-
globalForPrisma.prisma ??
|
|
267
|
-
new PrismaClient({
|
|
268
|
-
log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"],
|
|
269
|
-
datasources: {
|
|
270
|
-
db: {
|
|
271
|
-
url: process.env.DATABASE_URL,
|
|
272
|
-
},
|
|
273
|
-
},
|
|
274
|
-
});
|
|
275
|
-
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
**Prisma migration commands:**
|
|
279
|
-
|
|
280
|
-
```bash
|
|
281
|
-
# Create migration (development)
|
|
282
|
-
npx prisma migrate dev --name add_unit_account
|
|
283
|
-
|
|
284
|
-
# Apply migrations (production — use in Cloud Build/deployment)
|
|
285
|
-
npx prisma migrate deploy
|
|
286
|
-
|
|
287
|
-
# Reset DB (development only — destroys all data)
|
|
288
|
-
npx prisma migrate reset
|
|
289
|
-
|
|
290
|
-
# Check migration status
|
|
291
|
-
npx prisma migrate status
|
|
292
|
-
|
|
293
|
-
# Generate Prisma client after schema change
|
|
294
|
-
npx prisma generate
|
|
295
|
-
|
|
296
|
-
# Introspect existing DB (for legacy schemas)
|
|
297
|
-
npx prisma db pull
|
|
298
|
-
|
|
299
|
-
# Push schema without migration (for rapid prototyping)
|
|
300
|
-
npx prisma db push
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
**Never run `prisma migrate dev` in production.** Always use `prisma migrate deploy`.
|
|
304
|
-
|
|
305
|
-
---
|
|
306
|
-
|
|
307
|
-
## 3. Cloud SQL Configuration
|
|
308
|
-
|
|
309
|
-
**<project> Cloud SQL:**
|
|
310
|
-
|
|
311
|
-
- Instance: Cloud SQL PostgreSQL 15 (check Console for exact version)
|
|
312
|
-
- Primary: us-central1
|
|
313
|
-
- Read replicas: us-east1, asia-south1
|
|
314
|
-
- GCP project: <gcp-project>
|
|
315
|
-
|
|
316
|
-
**Connection string format:**
|
|
317
|
-
|
|
318
|
-
```
|
|
319
|
-
postgresql://USER:PASSWORD@HOST:5432/DATABASE?sslmode=require
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
**Cloud SQL with Cloud Run — authentication options:**
|
|
323
|
-
|
|
324
|
-
**Option 1: Cloud SQL Auth Proxy (recommended for production):**
|
|
325
|
-
|
|
326
|
-
- Uses IAM authentication, no password needed
|
|
327
|
-
- Socket-based connection: `/cloudsql/PROJECT:REGION:INSTANCE`
|
|
328
|
-
- URL format: `postgresql://user@localhost/db?host=/cloudsql/PROJECT:REGION:INSTANCE`
|
|
329
|
-
|
|
330
|
-
**Option 2: Private IP (Cloud Run VPC Connector):**
|
|
331
|
-
|
|
332
|
-
- Cloud Run → VPC Connector → Cloud SQL private IP
|
|
333
|
-
- Requires VPC connector setup (additional cost)
|
|
334
|
-
|
|
335
|
-
**Option 3: SSL with public IP (current <project> setup):**
|
|
336
|
-
|
|
337
|
-
- `?sslmode=require` in DATABASE_URL
|
|
338
|
-
- Cloud SQL uses SSL certificates for secure connections
|
|
339
|
-
- IP is whitelisted or Cloud SQL Auth Proxy handles auth
|
|
340
|
-
|
|
341
|
-
**Instance settings to check/optimize:**
|
|
342
|
-
|
|
343
|
-
- Max connections: default varies by tier (db-standard-1 = 100, db-standard-2 = 200)
|
|
344
|
-
- Recommended max connections = (RAM in GB × 100) - 10 reserved
|
|
345
|
-
- Storage auto-increase: ON (prevents instance going read-only when disk fills)
|
|
346
|
-
- Maintenance window: choose low-traffic time (e.g., Sunday 3am UTC)
|
|
347
|
-
- High availability: enable for production (standby in same region, failover ~30s)
|
|
348
|
-
|
|
349
|
-
**Viewing current connections:**
|
|
350
|
-
|
|
351
|
-
```sql
|
|
352
|
-
SELECT count(*), state, wait_event_type, wait_event
|
|
353
|
-
FROM pg_stat_activity
|
|
354
|
-
GROUP BY state, wait_event_type, wait_event
|
|
355
|
-
ORDER BY count DESC;
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
**Connection limits by Cloud SQL tier:**
|
|
359
|
-
| Tier | vCPUs | RAM | Max connections |
|
|
360
|
-
|------|-------|-----|-----------------|
|
|
361
|
-
| db-f1-micro | shared | 0.6GB | 25 |
|
|
362
|
-
| db-g1-small | shared | 1.7GB | 100 |
|
|
363
|
-
| db-standard-1 | 1 | 3.75GB | 100 |
|
|
364
|
-
| db-standard-2 | 2 | 7.5GB | 200 |
|
|
365
|
-
| db-standard-4 | 4 | 15GB | 400 |
|
|
366
|
-
|
|
367
|
-
---
|
|
368
|
-
|
|
369
|
-
## 4. Connection Pooling & Management
|
|
370
|
-
|
|
371
|
-
**Problem with Cloud Run + Prisma:**
|
|
372
|
-
Each Cloud Run instance creates a Prisma client with connection pool.
|
|
373
|
-
Cloud Run can spin up many instances → can exhaust PostgreSQL max connections.
|
|
374
|
-
|
|
375
|
-
**Solution 1: PgBouncer (recommended for production at scale):**
|
|
376
|
-
Deploy PgBouncer as a Cloud Run sidecar or separate service.
|
|
377
|
-
|
|
378
|
-
- Transaction pooling: most efficient for API servers
|
|
379
|
-
- One PgBouncer handles 1000s of app connections → 10-50 DB connections
|
|
380
|
-
|
|
381
|
-
**Solution 2: Prisma Data Proxy / Accelerate (managed):**
|
|
382
|
-
Prisma's managed connection pooler.
|
|
383
|
-
|
|
384
|
-
```typescript
|
|
385
|
-
// Install: npm install @prisma/extension-accelerate
|
|
386
|
-
import { withAccelerate } from "@prisma/extension-accelerate";
|
|
387
|
-
const prisma = new PrismaClient().$extends(withAccelerate());
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
**Solution 3: Reduce Prisma pool size (immediate fix for <project>):**
|
|
391
|
-
|
|
392
|
-
```
|
|
393
|
-
DATABASE_URL="postgresql://...?connection_limit=5&pool_timeout=20"
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
- `connection_limit`: max connections per Prisma instance
|
|
397
|
-
- `pool_timeout`: seconds to wait for connection before error
|
|
398
|
-
- With 10 Cloud Run instances × 5 connections = 50 total connections (safe)
|
|
399
|
-
|
|
400
|
-
**Cloud Run recommended settings:**
|
|
401
|
-
|
|
402
|
-
```
|
|
403
|
-
Max instances: 10 (prevents connection exhaustion)
|
|
404
|
-
Min instances: 1 (keeps one warm for fast response)
|
|
405
|
-
Concurrency: 80 (requests per instance)
|
|
406
|
-
connection_limit in DATABASE_URL: 5
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
**Detecting connection exhaustion:**
|
|
410
|
-
|
|
411
|
-
```sql
|
|
412
|
-
SELECT count(*) FROM pg_stat_activity;
|
|
413
|
-
-- If close to max_connections: connection pool is exhausted
|
|
414
|
-
-- Check: SHOW max_connections;
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
**PgBouncer configuration (transaction mode):**
|
|
418
|
-
|
|
419
|
-
```ini
|
|
420
|
-
[databases]
|
|
421
|
-
<project> = host=CLOUD_SQL_HOST port=5432 dbname=<project>
|
|
422
|
-
|
|
423
|
-
[pgbouncer]
|
|
424
|
-
pool_mode = transaction
|
|
425
|
-
max_client_conn = 1000
|
|
426
|
-
default_pool_size = 20
|
|
427
|
-
server_idle_timeout = 600
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
---
|
|
431
|
-
|
|
432
|
-
## 5. Zero-Downtime Migrations
|
|
433
|
-
|
|
434
|
-
**Expand-Contract pattern (for columns that need type changes or renames):**
|
|
435
|
-
|
|
436
|
-
**Phase 1 — Expand (add new, keep old):**
|
|
437
|
-
|
|
438
|
-
```sql
|
|
439
|
-
ALTER TABLE "User" ADD COLUMN "phoneNumberNew" TEXT;
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
**Phase 2 — Migrate data (backfill):**
|
|
443
|
-
|
|
444
|
-
```sql
|
|
445
|
-
UPDATE "User" SET "phoneNumberNew" = "phoneNumber"
|
|
446
|
-
WHERE "phoneNumberNew" IS NULL AND "phoneNumber" IS NOT NULL;
|
|
447
|
-
-- Do in batches to avoid lock:
|
|
448
|
-
-- UPDATE "User" SET "phoneNumberNew" = "phoneNumber"
|
|
449
|
-
-- WHERE id IN (SELECT id FROM "User" WHERE "phoneNumberNew" IS NULL LIMIT 1000)
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
**Phase 3 — Deploy code using new column:**
|
|
453
|
-
Application reads both columns, writes to both.
|
|
454
|
-
|
|
455
|
-
**Phase 4 — Contract (drop old column):**
|
|
456
|
-
|
|
457
|
-
```sql
|
|
458
|
-
ALTER TABLE "User" DROP COLUMN "phoneNumber";
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
**Safe migration operations (no table lock):**
|
|
462
|
-
|
|
463
|
-
- `ADD COLUMN` (without default) ✅
|
|
464
|
-
- `ADD COLUMN ... DEFAULT NULL` ✅
|
|
465
|
-
- `ADD INDEX CONCURRENTLY` ✅
|
|
466
|
-
- `DROP INDEX CONCURRENTLY` ✅
|
|
467
|
-
- `CREATE TABLE` ✅
|
|
468
|
-
- `DROP TABLE` ✅
|
|
469
|
-
- Rename with multiple deployments ✅
|
|
470
|
-
|
|
471
|
-
**Dangerous migration operations (cause table lock):**
|
|
472
|
-
|
|
473
|
-
- `ADD COLUMN ... DEFAULT non-null` on large table ⚠️ (rewrites table)
|
|
474
|
-
- `ALTER COLUMN TYPE` on existing data ⚠️
|
|
475
|
-
- `ADD CONSTRAINT` without `NOT VALID` ⚠️
|
|
476
|
-
- `DROP COLUMN` (but usually fast) ⚠️
|
|
477
|
-
|
|
478
|
-
**Adding NOT NULL column safely:**
|
|
479
|
-
|
|
480
|
-
```sql
|
|
481
|
-
-- Step 1: Add nullable
|
|
482
|
-
ALTER TABLE "AchChallenge" ADD COLUMN "bankCode" TEXT;
|
|
483
|
-
-- Step 2: Backfill
|
|
484
|
-
UPDATE "AchChallenge" SET "bankCode" = 'UNKNOWN' WHERE "bankCode" IS NULL;
|
|
485
|
-
-- Step 3: Add constraint (use NOT VALID to skip scan)
|
|
486
|
-
ALTER TABLE "AchChallenge" ALTER COLUMN "bankCode" SET NOT NULL;
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
**Prisma migration for zero-downtime:**
|
|
490
|
-
Create the migration SQL manually to use CONCURRENTLY:
|
|
491
|
-
|
|
492
|
-
```bash
|
|
493
|
-
npx prisma migrate dev --create-only --name add_bank_code
|
|
494
|
-
# Edit the generated SQL to add CONCURRENTLY
|
|
495
|
-
npx prisma migrate deploy
|
|
496
|
-
```
|
|
497
|
-
|
|
498
|
-
---
|
|
499
|
-
|
|
500
|
-
## 6. Data Modeling for Fintech
|
|
501
|
-
|
|
502
|
-
**Core entities for <project>:**
|
|
503
|
-
|
|
504
|
-
**Users and accounts:**
|
|
505
|
-
|
|
506
|
-
```prisma
|
|
507
|
-
model User {
|
|
508
|
-
id String @id @default(cuid())
|
|
509
|
-
email String @unique
|
|
510
|
-
emailVerified DateTime?
|
|
511
|
-
phone String?
|
|
512
|
-
region String @default("US") // "US" | "IN"
|
|
513
|
-
kycStatus KycStatus @default(PENDING)
|
|
514
|
-
lockoutUntil DateTime?
|
|
515
|
-
failedAttempts Int @default(0)
|
|
516
|
-
createdAt DateTime @default(now())
|
|
517
|
-
updatedAt DateTime @updatedAt
|
|
518
|
-
|
|
519
|
-
achChallenges AchChallenge[]
|
|
520
|
-
unitAccount UnitAccount?
|
|
521
|
-
upiAccounts UpiLinkedAccount[]
|
|
522
|
-
guardianDevices GuardianDevice[]
|
|
523
|
-
|
|
524
|
-
@@index([email])
|
|
525
|
-
@@index([phone])
|
|
526
|
-
}
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
**Immutable audit trail (append-only, never update):**
|
|
530
|
-
|
|
531
|
-
```prisma
|
|
532
|
-
model TransactionAuditLog {
|
|
533
|
-
id String @id @default(cuid())
|
|
534
|
-
userId String
|
|
535
|
-
eventType String // "ACH_APPROVED" | "UPI_BLOCKED" | "GUARDIAN_ALERT"
|
|
536
|
-
entityId String // challengeId, transactionId
|
|
537
|
-
entityType String // "AchChallenge" | "UpiTransaction"
|
|
538
|
-
metadata Json // full snapshot of event data
|
|
539
|
-
ipAddress String?
|
|
540
|
-
userAgent String?
|
|
541
|
-
createdAt DateTime @default(now())
|
|
542
|
-
|
|
543
|
-
@@index([userId, createdAt])
|
|
544
|
-
@@index([entityId])
|
|
545
|
-
// NO updatedAt — this table is append-only
|
|
546
|
-
}
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
**Soft deletes (never hard-delete financial records):**
|
|
550
|
-
|
|
551
|
-
```prisma
|
|
552
|
-
model UnitAccount {
|
|
553
|
-
id String @id @default(cuid())
|
|
554
|
-
userId String @unique
|
|
555
|
-
unitCustomerId String @unique
|
|
556
|
-
unitAccountId String @unique
|
|
557
|
-
routingNumber String
|
|
558
|
-
accountNumber String // encrypted at rest
|
|
559
|
-
nickname String?
|
|
560
|
-
status String @default("ACTIVE")
|
|
561
|
-
active Boolean @default(true)
|
|
562
|
-
deletedAt DateTime? // soft delete
|
|
563
|
-
createdAt DateTime @default(now())
|
|
564
|
-
updatedAt DateTime @updatedAt
|
|
565
|
-
}
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
**Idempotency keys (prevent duplicate transactions):**
|
|
569
|
-
|
|
570
|
-
```prisma
|
|
571
|
-
model IdempotencyKey {
|
|
572
|
-
id String @id @default(cuid())
|
|
573
|
-
key String @unique // UUID from client
|
|
574
|
-
operation String // "ACH_CHALLENGE" | "UPI_PAYMENT"
|
|
575
|
-
response Json? // cached response
|
|
576
|
-
createdAt DateTime @default(now())
|
|
577
|
-
expiresAt DateTime // TTL: 24 hours
|
|
578
|
-
|
|
579
|
-
@@index([key])
|
|
580
|
-
@@index([expiresAt]) // for cleanup
|
|
581
|
-
}
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
**Fraud signal modeling:**
|
|
585
|
-
|
|
586
|
-
```prisma
|
|
587
|
-
model FraudSignal {
|
|
588
|
-
id String @id @default(cuid())
|
|
589
|
-
userId String? // null for anonymous signals
|
|
590
|
-
signalType String // "VELOCITY", "AMOUNT_SPIKE", "GEO_ANOMALY"
|
|
591
|
-
score Float // 0.0-1.0 fraud probability
|
|
592
|
-
features Json // model input features
|
|
593
|
-
decision String // "ALLOW" | "CHALLENGE" | "BLOCK"
|
|
594
|
-
entityId String // transaction/challenge this triggered on
|
|
595
|
-
createdAt DateTime @default(now())
|
|
596
|
-
|
|
597
|
-
@@index([userId, createdAt])
|
|
598
|
-
@@index([signalType, score])
|
|
599
|
-
}
|
|
600
|
-
```
|
|
601
|
-
|
|
602
|
-
---
|
|
603
|
-
|
|
604
|
-
## 7. Cloud Scheduler — All 61 Jobs
|
|
605
|
-
|
|
606
|
-
**<project> scheduler architecture:**
|
|
607
|
-
All 61 jobs hit Cloud Run endpoints secured by `CRON_SECRET` header.
|
|
608
|
-
Pattern: `Authorization: Bearer ${CRON_SECRET}` or `X-Cron-Secret: ${CRON_SECRET}`
|
|
609
|
-
|
|
610
|
-
**Critical scheduler jobs and their timing:**
|
|
611
|
-
| Job | Schedule | Description |
|
|
612
|
-
|-----|----------|-------------|
|
|
613
|
-
| feed-fetch | `*/9 * * * *` | Fetch threat intelligence feeds |
|
|
614
|
-
| offline-settlement | `*/5 * * * *` | Process pending offline UPI settlements |
|
|
615
|
-
| offline-settlement-india | `*/5 * * * *` (IST) | India UPI settlement (IST timezone) |
|
|
616
|
-
| uptime-monitor | `*/5 * * * *` | Health check all 3 regions |
|
|
617
|
-
| shield-evolution-agent | `0 * * * *` | Hourly AI threat model update |
|
|
618
|
-
| news-crawler | `*/30 * * * *` | Financial security news crawl |
|
|
619
|
-
| github-crawler | `0 * * * *` | GitHub security advisory crawl |
|
|
620
|
-
| regulatory-crawler | `*/6 * * * *` | Regulatory update check |
|
|
621
|
-
| daily-digest | `0 6 * * *` | Daily threat digest email (6am UTC) |
|
|
622
|
-
| backup-verify | `0 */6 * * *` | Verify DB backup integrity |
|
|
623
|
-
| sitemap-submit | `0 9 * * 1` | Weekly GSC sitemap submission |
|
|
624
|
-
| feed-discovery | `0 3 * * 0` | Weekly new feed source discovery |
|
|
625
|
-
| ach-challenge-expiry | `*/1 * * * *` | Expire stale ACH challenges (60s TTL) |
|
|
626
|
-
|
|
627
|
-
**ACH challenge expiry job (new — needed for ACH Shield):**
|
|
628
|
-
|
|
629
|
-
```typescript
|
|
630
|
-
// POST /api/cron/expire-ach-challenges
|
|
631
|
-
export async function POST(request: Request) {
|
|
632
|
-
const secret = request.headers.get("x-cron-secret");
|
|
633
|
-
if (secret !== process.env.CRON_SECRET) return new Response("Unauthorized", { status: 401 });
|
|
634
|
-
|
|
635
|
-
const expired = await prisma.achChallenge.updateMany({
|
|
636
|
-
where: {
|
|
637
|
-
status: "PENDING",
|
|
638
|
-
expiresAt: { lt: new Date() },
|
|
639
|
-
},
|
|
640
|
-
data: { status: "EXPIRED" },
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
return Response.json({ expired: expired.count });
|
|
644
|
-
}
|
|
645
|
-
```
|
|
646
|
-
|
|
647
|
-
**Cloud Scheduler job configuration:**
|
|
648
|
-
|
|
649
|
-
```bash
|
|
650
|
-
gcloud scheduler jobs create http expire-ach-challenges \
|
|
651
|
-
--location=us-central1 \
|
|
652
|
-
--schedule="* * * * *" \
|
|
653
|
-
--uri="https://<project>.com/api/cron/expire-ach-challenges" \
|
|
654
|
-
--http-method=POST \
|
|
655
|
-
--headers="X-Cron-Secret=${CRON_SECRET}" \
|
|
656
|
-
--time-zone="UTC" \
|
|
657
|
-
--attempt-deadline="30s" \
|
|
658
|
-
--min-backoff=5s \
|
|
659
|
-
--max-backoff=60s \
|
|
660
|
-
--max-retry-attempts=3
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
**IST timezone for India jobs:**
|
|
664
|
-
`--time-zone="Asia/Kolkata"` — UTC+5:30
|
|
665
|
-
|
|
666
|
-
**Scheduler retry config:**
|
|
667
|
-
|
|
668
|
-
- `max-retry-attempts`: 3 for critical jobs, 0 for idempotent crawlers
|
|
669
|
-
- `attempt-deadline`: set based on expected job duration + buffer
|
|
670
|
-
- Monitor failures: Cloud Console → Cloud Scheduler → job → View logs
|
|
671
|
-
|
|
672
|
-
---
|
|
673
|
-
|
|
674
|
-
## 8. BigQuery & Analytics
|
|
675
|
-
|
|
676
|
-
**When to use BigQuery vs Cloud SQL:**
|
|
677
|
-
|
|
678
|
-
- Cloud SQL: operational data, transactions, real-time queries
|
|
679
|
-
- BigQuery: analytics, aggregations, historical reporting, ML
|
|
680
|
-
|
|
681
|
-
**Streaming inserts from Cloud Run:**
|
|
682
|
-
|
|
683
|
-
```typescript
|
|
684
|
-
import { BigQuery } from "@google-cloud/bigquery";
|
|
685
|
-
const bq = new BigQuery({ projectId: "<gcp-project>" });
|
|
686
|
-
|
|
687
|
-
// Stream fraud signals to BigQuery for analytics
|
|
688
|
-
await bq
|
|
689
|
-
.dataset("<project>_analytics")
|
|
690
|
-
.table("fraud_signals")
|
|
691
|
-
.insert([
|
|
692
|
-
{
|
|
693
|
-
userId: signal.userId,
|
|
694
|
-
signalType: signal.signalType,
|
|
695
|
-
score: signal.score,
|
|
696
|
-
createdAt: signal.createdAt.toISOString(),
|
|
697
|
-
// BigQuery timestamp format: YYYY-MM-DDTHH:MM:SS.fffZ
|
|
698
|
-
},
|
|
699
|
-
]);
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
**BigQuery tables for <project>:**
|
|
703
|
-
|
|
704
|
-
```sql
|
|
705
|
-
-- Fraud signals table
|
|
706
|
-
CREATE TABLE `<project>_analytics.fraud_signals`
|
|
707
|
-
PARTITION BY DATE(created_at)
|
|
708
|
-
OPTIONS (partition_expiration_days = 365)
|
|
709
|
-
AS SELECT ... ;
|
|
710
|
-
|
|
711
|
-
-- Daily aggregates (for dashboard)
|
|
712
|
-
CREATE TABLE `<project>_analytics.daily_metrics`
|
|
713
|
-
PARTITION BY report_date
|
|
714
|
-
AS SELECT
|
|
715
|
-
DATE(created_at) as report_date,
|
|
716
|
-
COUNT(*) as total_challenges,
|
|
717
|
-
COUNTIF(status = 'APPROVED') as approved,
|
|
718
|
-
COUNTIF(status = 'DECLINED') as declined,
|
|
719
|
-
COUNTIF(status = 'EXPIRED') as expired,
|
|
720
|
-
AVG(CASE WHEN resolved_at IS NOT NULL
|
|
721
|
-
THEN TIMESTAMP_DIFF(resolved_at, created_at, SECOND) END) as avg_resolution_seconds
|
|
722
|
-
FROM `<project>_analytics.ach_challenges`
|
|
723
|
-
GROUP BY 1;
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
**Cost optimization:**
|
|
727
|
-
|
|
728
|
-
- Partition all tables by date (partition pruning = pay only for queried partitions)
|
|
729
|
-
- Cluster frequently filtered columns: `CLUSTER BY userId, signalType`
|
|
730
|
-
- Use approximate aggregation: `APPROX_COUNT_DISTINCT()` vs `COUNT(DISTINCT)`
|
|
731
|
-
- Preview query cost before running: check "This query will process X GB"
|
|
732
|
-
|
|
733
|
-
---
|
|
734
|
-
|
|
735
|
-
## 9. Backup, PITR & Disaster Recovery
|
|
736
|
-
|
|
737
|
-
**Cloud SQL automated backups:**
|
|
738
|
-
|
|
739
|
-
- Enabled by default on Cloud SQL
|
|
740
|
-
- Retention: 7 days (default) — increase to 30 days for production
|
|
741
|
-
- Takes ~30 minutes, no performance impact
|
|
742
|
-
- Stored in the same region as the instance
|
|
743
|
-
|
|
744
|
-
**Point-in-Time Recovery (PITR):**
|
|
745
|
-
|
|
746
|
-
- Allows restore to any second within the backup window
|
|
747
|
-
- Requires binary logging enabled (on by default in Cloud SQL)
|
|
748
|
-
- Use case: accidental `DELETE` or data corruption
|
|
749
|
-
- Recovery time: 30-60 minutes for a 10GB database
|
|
750
|
-
|
|
751
|
-
**Enabling extended backup retention:**
|
|
752
|
-
|
|
753
|
-
```bash
|
|
754
|
-
gcloud sql instances patch INSTANCE_NAME \
|
|
755
|
-
--backup-retention-count=30 \
|
|
756
|
-
--enable-bin-log \
|
|
757
|
-
--retained-backups-count=30
|
|
758
|
-
```
|
|
759
|
-
|
|
760
|
-
**Manual backup before risky migrations:**
|
|
761
|
-
|
|
762
|
-
```bash
|
|
763
|
-
gcloud sql backups create \
|
|
764
|
-
--instance=INSTANCE_NAME \
|
|
765
|
-
--description="Pre-migration backup $(date +%Y-%m-%d)"
|
|
766
|
-
```
|
|
767
|
-
|
|
768
|
-
**Cross-region backup (for additional safety):**
|
|
769
|
-
Enable in Cloud SQL instance settings → Backups → Enable cross-region backups
|
|
770
|
-
Copies backups to another region automatically.
|
|
771
|
-
|
|
772
|
-
**Restore procedure:**
|
|
773
|
-
|
|
774
|
-
```bash
|
|
775
|
-
# List available backups
|
|
776
|
-
gcloud sql backups list --instance=INSTANCE_NAME
|
|
777
|
-
|
|
778
|
-
# Restore to a new instance (never restore to production directly)
|
|
779
|
-
gcloud sql instances create RESTORED_INSTANCE \
|
|
780
|
-
--source-instance=INSTANCE_NAME \
|
|
781
|
-
--backup-run-id=BACKUP_ID \
|
|
782
|
-
--region=us-central1
|
|
783
|
-
|
|
784
|
-
# After verification, use Cloud SQL proxy to query restored instance
|
|
785
|
-
```
|
|
786
|
-
|
|
787
|
-
**Recovery time objectives for <project>:**
|
|
788
|
-
|
|
789
|
-
- RTO (Recovery Time Objective): < 1 hour
|
|
790
|
-
- RPO (Recovery Point Objective): < 5 minutes (PITR to last checkpoint)
|
|
791
|
-
- HA (High Availability): 99.95% SLA with Cloud SQL HA enabled
|
|
792
|
-
|
|
793
|
-
---
|
|
794
|
-
|
|
795
|
-
## 10. Performance & Monitoring
|
|
796
|
-
|
|
797
|
-
**Key metrics to monitor (Cloud SQL Insights):**
|
|
798
|
-
|
|
799
|
-
- Query latency: P50, P95, P99
|
|
800
|
-
- Active connections
|
|
801
|
-
- CPU utilization: alert at 70%
|
|
802
|
-
- Memory usage: alert at 85%
|
|
803
|
-
- Disk utilization: alert at 80%
|
|
804
|
-
- Replication lag (for replicas): alert at > 30 seconds
|
|
805
|
-
|
|
806
|
-
**pg_stat_statements (slow query analysis):**
|
|
807
|
-
|
|
808
|
-
```sql
|
|
809
|
-
-- Top 10 slowest queries
|
|
810
|
-
SELECT
|
|
811
|
-
round(total_exec_time::numeric, 2) as total_ms,
|
|
812
|
-
round(mean_exec_time::numeric, 2) as mean_ms,
|
|
813
|
-
calls,
|
|
814
|
-
round((total_exec_time / sum(total_exec_time) OVER ()) * 100, 2) as pct,
|
|
815
|
-
query
|
|
816
|
-
FROM pg_stat_statements
|
|
817
|
-
ORDER BY total_exec_time DESC
|
|
818
|
-
LIMIT 10;
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
**Cloud SQL Query Insights:**
|
|
822
|
-
|
|
823
|
-
- Cloud Console → Cloud SQL → instance → Query insights
|
|
824
|
-
- Shows top queries by CPU, latency, count
|
|
825
|
-
- Execution plan visualization
|
|
826
|
-
- No setup needed — enabled by default
|
|
827
|
-
|
|
828
|
-
**Connection pool monitoring:**
|
|
829
|
-
|
|
830
|
-
```sql
|
|
831
|
-
-- Current connections by state
|
|
832
|
-
SELECT state, count(*)
|
|
833
|
-
FROM pg_stat_activity
|
|
834
|
-
GROUP BY state;
|
|
835
|
-
|
|
836
|
-
-- Long-running queries (> 5 minutes)
|
|
837
|
-
SELECT pid, now() - pg_stat_activity.query_start AS duration, query, state
|
|
838
|
-
FROM pg_stat_activity
|
|
839
|
-
WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes';
|
|
840
|
-
```
|
|
841
|
-
|
|
842
|
-
**Killing a blocking query:**
|
|
843
|
-
|
|
844
|
-
```sql
|
|
845
|
-
SELECT pg_cancel_backend(pid); -- graceful cancel
|
|
846
|
-
SELECT pg_terminate_backend(pid); -- force terminate
|
|
847
|
-
```
|
|
848
|
-
|
|
849
|
-
**Cloud Monitoring alerting policies:**
|
|
850
|
-
|
|
851
|
-
```bash
|
|
852
|
-
# Create alert for high CPU
|
|
853
|
-
gcloud monitoring policies create \
|
|
854
|
-
--notification-channels=CHANNEL_ID \
|
|
855
|
-
--display-name="Cloud SQL CPU > 70%" \
|
|
856
|
-
--condition-threshold-filter='resource.type="cloudsql_database"' \
|
|
857
|
-
--condition-threshold-value=0.7 \
|
|
858
|
-
--condition-threshold-comparison=COMPARISON_GT
|
|
859
|
-
```
|
|
860
|
-
|
|
861
|
-
---
|
|
862
|
-
|
|
863
|
-
## 11. Row-Level Security & Multi-Tenancy
|
|
864
|
-
|
|
865
|
-
**RLS for <project> (isolate user data):**
|
|
866
|
-
|
|
867
|
-
```sql
|
|
868
|
-
-- Enable RLS on sensitive tables
|
|
869
|
-
ALTER TABLE "AchChallenge" ENABLE ROW LEVEL SECURITY;
|
|
870
|
-
|
|
871
|
-
-- Policy: users can only see their own challenges
|
|
872
|
-
CREATE POLICY user_isolation ON "AchChallenge"
|
|
873
|
-
FOR ALL
|
|
874
|
-
USING (current_setting('app.current_user_id') = "userId");
|
|
875
|
-
|
|
876
|
-
-- Set user context at query time (via Prisma middleware)
|
|
877
|
-
SET LOCAL app.current_user_id = 'user_id_here';
|
|
878
|
-
```
|
|
879
|
-
|
|
880
|
-
**Prisma middleware to set user context:**
|
|
881
|
-
|
|
882
|
-
```typescript
|
|
883
|
-
prisma.$use(async (params, next) => {
|
|
884
|
-
if (currentUserId) {
|
|
885
|
-
await prisma.$executeRaw`SET LOCAL app.current_user_id = ${currentUserId}`;
|
|
886
|
-
}
|
|
887
|
-
return next(params);
|
|
888
|
-
});
|
|
889
|
-
```
|
|
890
|
-
|
|
891
|
-
**Note:** RLS adds overhead. For <project>'s current scale, application-level isolation
|
|
892
|
-
(WHERE userId = currentUser.id) is sufficient. Use RLS as defense-in-depth for highly sensitive tables.
|
|
893
|
-
|
|
894
|
-
---
|
|
895
|
-
|
|
896
|
-
## 12. Pub/Sub & Event-Driven Architecture
|
|
897
|
-
|
|
898
|
-
**When to use Pub/Sub vs direct DB writes:**
|
|
899
|
-
|
|
900
|
-
- High-volume events: fraud signals, threat feeds, audit logs → Pub/Sub
|
|
901
|
-
- Real-time webhooks that might fail: ACH notifications → Pub/Sub with retry
|
|
902
|
-
- Cross-service communication: feed-fetch → feed-processor
|
|
903
|
-
|
|
904
|
-
**<project> Pub/Sub topics:**
|
|
905
|
-
|
|
906
|
-
```bash
|
|
907
|
-
# Create topics
|
|
908
|
-
gcloud pubsub topics create threat-feeds-ingestion
|
|
909
|
-
gcloud pubsub topics create ach-webhook-delivery
|
|
910
|
-
gcloud pubsub topics create fraud-signals
|
|
911
|
-
|
|
912
|
-
# Create subscriptions with retry
|
|
913
|
-
gcloud pubsub subscriptions create ach-webhook-processor \
|
|
914
|
-
--topic=ach-webhook-delivery \
|
|
915
|
-
--ack-deadline=60 \
|
|
916
|
-
--min-retry-delay=10s \
|
|
917
|
-
--max-retry-delay=600s \
|
|
918
|
-
--dead-letter-topic=ach-webhook-dlq \
|
|
919
|
-
--max-delivery-attempts=5
|
|
920
|
-
```
|
|
921
|
-
|
|
922
|
-
**Publishing from Next.js:**
|
|
923
|
-
|
|
924
|
-
```typescript
|
|
925
|
-
import { PubSub } from "@google-cloud/pubsub";
|
|
926
|
-
const pubsub = new PubSub({ projectId: "<gcp-project>" });
|
|
927
|
-
|
|
928
|
-
await pubsub.topic("ach-webhook-delivery").publish(
|
|
929
|
-
Buffer.from(
|
|
930
|
-
JSON.stringify({
|
|
931
|
-
challengeId,
|
|
932
|
-
bankWebhookUrl,
|
|
933
|
-
decision: "APPROVED",
|
|
934
|
-
timestamp: new Date().toISOString(),
|
|
935
|
-
}),
|
|
936
|
-
),
|
|
937
|
-
);
|
|
938
|
-
```
|
|
939
|
-
|
|
940
|
-
---
|
|
941
|
-
|
|
942
|
-
## 13. GCP Secret Manager Operations
|
|
943
|
-
|
|
944
|
-
**All <project> secrets:**
|
|
945
|
-
DATABASE_URL, NEXTAUTH_SECRET, RESEND_API_KEY, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, CRON_SECRET, TELEGRAM_BOT_TOKEN, TELEGRAM_CHANNEL_ID, NVD_API_KEY, SHIELD_SIGNING_KEY, TG_MASTER_KEY, ADMIN_EMAIL, FIREBASE_SERVICE_ACCOUNT_KEY, BANK_WEBHOOK_SECRET, UNIT_API_KEY, UNIT_WEBHOOK_SECRET, UNIT_DEPOSIT_PRODUCT_ID
|
|
946
|
-
|
|
947
|
-
**Common operations:**
|
|
948
|
-
|
|
949
|
-
```bash
|
|
950
|
-
# Read a secret
|
|
951
|
-
gcloud secrets versions access latest --secret=SECRET_NAME --project=<gcp-project>
|
|
952
|
-
|
|
953
|
-
# Update a secret (creates new version)
|
|
954
|
-
echo -n "new_value" | gcloud secrets versions add SECRET_NAME --data-file=-
|
|
955
|
-
|
|
956
|
-
# List versions
|
|
957
|
-
gcloud secrets versions list SECRET_NAME
|
|
958
|
-
|
|
959
|
-
# Deploy new secret version to all Cloud Run regions
|
|
960
|
-
# (Cloud Run reads latest version on cold start — use revision deploy to force refresh)
|
|
961
|
-
gcloud run deploy <project> \
|
|
962
|
-
--image LATEST_IMAGE \
|
|
963
|
-
--region us-central1 \
|
|
964
|
-
--update-secrets SECRET_NAME=SECRET_NAME:latest
|
|
965
|
-
```
|
|
966
|
-
|
|
967
|
-
**Adding a new secret:**
|
|
968
|
-
|
|
969
|
-
```bash
|
|
970
|
-
gcloud secrets create NEW_SECRET_NAME \
|
|
971
|
-
--project=<gcp-project> \
|
|
972
|
-
--replication-policy="automatic"
|
|
973
|
-
|
|
974
|
-
echo -n "secret_value" | gcloud secrets versions add NEW_SECRET_NAME --data-file=-
|
|
975
|
-
|
|
976
|
-
# Grant Cloud Run service account access
|
|
977
|
-
gcloud secrets add-iam-policy-binding NEW_SECRET_NAME \
|
|
978
|
-
--member="serviceAccount:<email>" \
|
|
979
|
-
--role="roles/secretmanager.secretAccessor"
|
|
980
|
-
```
|
|
981
|
-
|
|
982
|
-
**Secret rotation pattern:**
|
|
983
|
-
|
|
984
|
-
1. Add new version: `gcloud secrets versions add`
|
|
985
|
-
2. Deploy new Cloud Run revision (picks up new version)
|
|
986
|
-
3. Verify new version works
|
|
987
|
-
4. Disable old version: `gcloud secrets versions disable VERSION_ID --secret=SECRET_NAME`
|
|
988
|
-
|
|
989
|
-
---
|
|
990
|
-
|
|
991
|
-
## 14. <project> DB Schema Reference
|
|
992
|
-
|
|
993
|
-
**Current DB tables (55+):**
|
|
994
|
-
|
|
995
|
-
**Core auth/user:** User, Account, Session, VerificationToken (NextAuth)
|
|
996
|
-
|
|
997
|
-
**ACH Shield:**
|
|
998
|
-
|
|
999
|
-
- AchChallenge (id, userId, status, options[], correctOption, attempts, expiresAt, resolvedAt, webhookSent)
|
|
1000
|
-
- UnitAccount (id, userId, unitCustomerId, unitAccountId, routingNumber, accountNumber, nickname, status, active)
|
|
1001
|
-
|
|
1002
|
-
**UPI Shield:**
|
|
1003
|
-
|
|
1004
|
-
- UpiLinkedAccount (id, userId, vpa, bankName, active, deletedAt)
|
|
1005
|
-
- UpiFraudCheck (id, userId, vpa, amount, decision, score, blockedReason)
|
|
1006
|
-
- UpiTransaction (id, userId, vpa, amount, status, offlineToken, settledAt)
|
|
1007
|
-
|
|
1008
|
-
**Guardian:**
|
|
1009
|
-
|
|
1010
|
-
- GuardianDevice (id, userId, platform, hostname, agentVersion, lastSeen, status)
|
|
1011
|
-
- GuardianHeartbeat (id, deviceId, threats[], metrics{})
|
|
1012
|
-
- GuardianAlert (id, deviceId, alertType, severity, detail, acknowledgedAt)
|
|
1013
|
-
|
|
1014
|
-
**SENTINEL:**
|
|
1015
|
-
|
|
1016
|
-
- ThreatFeed (id, feedId, title, content, severity, tags[], metadata{}, publishedAt)
|
|
1017
|
-
- FeedRegistry (id, name, url, type, active, lastFetchAt, errorCount)
|
|
1018
|
-
- FraudSignal (id, userId, signalType, score, features{}, decision, entityId)
|
|
1019
|
-
|
|
1020
|
-
**Offline UPI:**
|
|
1021
|
-
|
|
1022
|
-
- OfflineToken (id, userId, amount, vpa, encryptedPayload, expiresAt, used)
|
|
1023
|
-
- MeshSettlement (id, tokenId, transportType, settledAt, npciRef)
|
|
1024
|
-
|
|
1025
|
-
**Schema migration for new tables (April 15, 2026 migration):**
|
|
1026
|
-
|
|
1027
|
-
- UnitAccount: created ✅
|
|
1028
|
-
- GuardianDevice: confirmed ✅
|
|
1029
|
-
- UpiLinkedAccount additions: ✅
|
|
1030
|
-
- UpiFraudCheck field additions: ✅
|
|
1031
|
-
|
|
1032
|
-
**Checking migration status:**
|
|
1033
|
-
|
|
1034
|
-
```bash
|
|
1035
|
-
npx prisma migrate status
|
|
1036
|
-
# or
|
|
1037
|
-
gcloud sql databases list --instance=INSTANCE_NAME
|
|
1038
|
-
```
|
|
1
|
+
# Data & GCP Expert Reference — PostgreSQL, Prisma, Cloud SQL, Schedulers
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
1. [PostgreSQL 15/16 Expert Tier](#1-postgresql-1516-expert-tier)
|
|
6
|
+
2. [Prisma ORM 5.x Deep Reference](#2-prisma-orm-5x-deep-reference)
|
|
7
|
+
3. [Cloud SQL Configuration](#3-cloud-sql-configuration)
|
|
8
|
+
4. [Connection Pooling & Management](#4-connection-pooling--management)
|
|
9
|
+
5. [Zero-Downtime Migrations](#5-zero-downtime-migrations)
|
|
10
|
+
6. [Data Modeling for Fintech](#6-data-modeling-for-fintech)
|
|
11
|
+
7. [Cloud Scheduler — All 61 Jobs](#7-cloud-scheduler--all-61-jobs)
|
|
12
|
+
8. [BigQuery & Analytics](#8-bigquery--analytics)
|
|
13
|
+
9. [Backup, PITR & Disaster Recovery](#9-backup-pitr--disaster-recovery)
|
|
14
|
+
10. [Performance & Monitoring](#10-performance--monitoring)
|
|
15
|
+
11. [Row-Level Security & Multi-Tenancy](#11-row-level-security--multi-tenancy)
|
|
16
|
+
12. [Pub/Sub & Event-Driven Architecture](#12-pubsub--event-driven-architecture)
|
|
17
|
+
13. [GCP Secret Manager Operations](#13-gcp-secret-manager-operations)
|
|
18
|
+
14. [<project> DB Schema Reference](#14-<project>-db-schema-reference)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 1. PostgreSQL 15/16 Expert Tier
|
|
23
|
+
|
|
24
|
+
**PostgreSQL 15 highlights relevant to <project>:**
|
|
25
|
+
|
|
26
|
+
- `MERGE` statement (upsert with conditions)
|
|
27
|
+
- `row_pattern_recognition` — for fraud pattern detection in sequences
|
|
28
|
+
- Improved JSON path queries
|
|
29
|
+
- Logical replication improvements for Cloud SQL cross-region replicas
|
|
30
|
+
|
|
31
|
+
**PostgreSQL 16 highlights:**
|
|
32
|
+
|
|
33
|
+
- Parallel query improvements
|
|
34
|
+
- `pg_stat_io` — detailed I/O statistics
|
|
35
|
+
- Logical replication from standbys
|
|
36
|
+
- `to_char()` improvements
|
|
37
|
+
|
|
38
|
+
**Index types and when to use each:**
|
|
39
|
+
| Type | Use case |
|
|
40
|
+
|------|---------|
|
|
41
|
+
| B-tree (default) | Equality, range, sorting — general purpose |
|
|
42
|
+
| GIN | JSONB containment, array operators, full-text search |
|
|
43
|
+
| GiST | Geometric data, full-text, exclusion constraints |
|
|
44
|
+
| BRIN | Very large tables with naturally ordered data (time-series, logs) |
|
|
45
|
+
| Hash | Equality only, faster than B-tree for large equals lookups |
|
|
46
|
+
| Partial | Index only rows matching a WHERE clause (e.g., active records only) |
|
|
47
|
+
|
|
48
|
+
**<project> critical indexes:**
|
|
49
|
+
|
|
50
|
+
```sql
|
|
51
|
+
-- ACH challenges: frequent lookup by userId + status
|
|
52
|
+
CREATE INDEX CONCURRENTLY idx_ach_challenge_user_status
|
|
53
|
+
ON "AchChallenge"("userId", "status", "createdAt" DESC);
|
|
54
|
+
|
|
55
|
+
-- UPI fraud checks: lookup by VPA + time window
|
|
56
|
+
CREATE INDEX CONCURRENTLY idx_upi_fraud_vpa_created
|
|
57
|
+
ON "UpiFraudCheck"("vpa", "createdAt" DESC);
|
|
58
|
+
|
|
59
|
+
-- Unit accounts: lookup by userId
|
|
60
|
+
CREATE INDEX CONCURRENTLY idx_unit_account_user
|
|
61
|
+
ON "UnitAccount"("userId") WHERE "active" = true;
|
|
62
|
+
|
|
63
|
+
-- Guardian devices: lookup by userId
|
|
64
|
+
CREATE INDEX CONCURRENTLY idx_guardian_device_user
|
|
65
|
+
ON "GuardianDevice"("userId", "lastSeen" DESC);
|
|
66
|
+
|
|
67
|
+
-- Threat intelligence: full-text search on threat content
|
|
68
|
+
CREATE INDEX CONCURRENTLY idx_threat_content_fts
|
|
69
|
+
ON "Threat" USING GIN(to_tsvector('english', "content"));
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**EXPLAIN ANALYZE — reading query plans:**
|
|
73
|
+
|
|
74
|
+
```sql
|
|
75
|
+
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
|
|
76
|
+
SELECT * FROM "AchChallenge"
|
|
77
|
+
WHERE "userId" = 'user_id' AND "status" = 'PENDING';
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Key metrics:
|
|
81
|
+
|
|
82
|
+
- `Seq Scan` → needs an index
|
|
83
|
+
- `Index Scan` → good
|
|
84
|
+
- `Bitmap Heap Scan` → good for range queries
|
|
85
|
+
- `rows=X (actual X)` → large discrepancy = stale statistics → `ANALYZE tablename`
|
|
86
|
+
|
|
87
|
+
**VACUUM and autovacuum:**
|
|
88
|
+
Cloud SQL runs autovacuum by default. Monitor bloat:
|
|
89
|
+
|
|
90
|
+
```sql
|
|
91
|
+
SELECT relname, n_dead_tup, n_live_tup,
|
|
92
|
+
round(n_dead_tup::numeric/nullif(n_live_tup,0)*100, 2) as dead_pct
|
|
93
|
+
FROM pg_stat_user_tables
|
|
94
|
+
ORDER BY n_dead_tup DESC;
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If dead_pct > 10% on hot tables: `VACUUM ANALYZE tablename;`
|
|
98
|
+
|
|
99
|
+
**JSONB operations for <project> threat data:**
|
|
100
|
+
|
|
101
|
+
```sql
|
|
102
|
+
-- Query JSONB field
|
|
103
|
+
SELECT * FROM "ThreatFeed" WHERE "metadata"->>'severity' = 'HIGH';
|
|
104
|
+
|
|
105
|
+
-- Update JSONB field
|
|
106
|
+
UPDATE "ThreatFeed"
|
|
107
|
+
SET "metadata" = "metadata" || '{"reviewed": true}'::jsonb
|
|
108
|
+
WHERE id = 'feed_id';
|
|
109
|
+
|
|
110
|
+
-- JSONB array contains
|
|
111
|
+
SELECT * FROM "ThreatFeed" WHERE "tags" @> '["ransomware"]'::jsonb;
|
|
112
|
+
|
|
113
|
+
-- Index for JSONB containment
|
|
114
|
+
CREATE INDEX CONCURRENTLY idx_threat_metadata_gin
|
|
115
|
+
ON "ThreatFeed" USING GIN("metadata");
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 2. Prisma ORM 5.x Deep Reference
|
|
121
|
+
|
|
122
|
+
**Prisma 5 key features:**
|
|
123
|
+
|
|
124
|
+
- Faster query engine (Rust-based)
|
|
125
|
+
- `prismaSchemaFolder` for multi-file schemas
|
|
126
|
+
- `jsonProtocol` for edge/Cloudflare Workers
|
|
127
|
+
- `relationJoins` preview feature for JOIN-based queries (vs N+1)
|
|
128
|
+
- Typed SQL (`prisma/sql/` directory for raw SQL with types)
|
|
129
|
+
|
|
130
|
+
**Schema best practices:**
|
|
131
|
+
|
|
132
|
+
```prisma
|
|
133
|
+
// schema.prisma
|
|
134
|
+
generator client {
|
|
135
|
+
provider = "prisma-client-js"
|
|
136
|
+
previewFeatures = ["relationJoins", "typedSql"]
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
datasource db {
|
|
140
|
+
provider = "postgresql"
|
|
141
|
+
url = env("DATABASE_URL")
|
|
142
|
+
directUrl = env("DIRECT_URL") // for migrations (bypasses pgBouncer)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Audit trail mixin pattern
|
|
146
|
+
model AchChallenge {
|
|
147
|
+
id String @id @default(cuid())
|
|
148
|
+
userId String
|
|
149
|
+
status ChallengeStatus @default(PENDING)
|
|
150
|
+
options String[] // ["3", "7", "9"]
|
|
151
|
+
correctOption String
|
|
152
|
+
attempts Int @default(0)
|
|
153
|
+
expiresAt DateTime
|
|
154
|
+
resolvedAt DateTime?
|
|
155
|
+
webhookSent Boolean @default(false)
|
|
156
|
+
createdAt DateTime @default(now())
|
|
157
|
+
updatedAt DateTime @updatedAt
|
|
158
|
+
|
|
159
|
+
user User @relation(fields: [userId], references: [id])
|
|
160
|
+
|
|
161
|
+
@@index([userId, status])
|
|
162
|
+
@@index([expiresAt]) // for cleanup scheduler
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
enum ChallengeStatus {
|
|
166
|
+
PENDING
|
|
167
|
+
APPROVED
|
|
168
|
+
DECLINED
|
|
169
|
+
EXPIRED
|
|
170
|
+
LOCKED
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Transaction patterns:**
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// Interactive transaction (multiple operations, rollback on error)
|
|
178
|
+
const result = await prisma.$transaction(
|
|
179
|
+
async (tx) => {
|
|
180
|
+
const challenge = await tx.achChallenge.update({
|
|
181
|
+
where: { id: challengeId },
|
|
182
|
+
data: { status: "APPROVED", resolvedAt: new Date() },
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
await tx.achAuditLog.create({
|
|
186
|
+
data: { challengeId, action: "APPROVED", userId },
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
return challenge;
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
timeout: 10000, // 10 second timeout
|
|
193
|
+
isolationLevel: Prisma.TransactionIsolationLevel.ReadCommitted,
|
|
194
|
+
},
|
|
195
|
+
);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Batch operations (better performance):**
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// createMany — single INSERT with multiple rows
|
|
202
|
+
await prisma.threatFeed.createMany({
|
|
203
|
+
data: threats,
|
|
204
|
+
skipDuplicates: true,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// updateMany — single UPDATE
|
|
208
|
+
await prisma.achChallenge.updateMany({
|
|
209
|
+
where: { status: "PENDING", expiresAt: { lt: new Date() } },
|
|
210
|
+
data: { status: "EXPIRED" },
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// deleteMany with limit (safer for large deletes)
|
|
214
|
+
await prisma.$executeRaw`
|
|
215
|
+
DELETE FROM "AchChallenge"
|
|
216
|
+
WHERE id IN (
|
|
217
|
+
SELECT id FROM "AchChallenge"
|
|
218
|
+
WHERE "createdAt" < NOW() - INTERVAL '90 days'
|
|
219
|
+
LIMIT 1000
|
|
220
|
+
)
|
|
221
|
+
`;
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Pagination (cursor-based for large datasets):**
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
// First page
|
|
228
|
+
const firstPage = await prisma.achChallenge.findMany({
|
|
229
|
+
take: 20,
|
|
230
|
+
orderBy: { createdAt: "desc" },
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Next page (cursor pagination — no offset drift)
|
|
234
|
+
const nextPage = await prisma.achChallenge.findMany({
|
|
235
|
+
take: 20,
|
|
236
|
+
skip: 1, // skip the cursor itself
|
|
237
|
+
cursor: { id: lastId },
|
|
238
|
+
orderBy: { createdAt: "desc" },
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Raw SQL with type safety (Prisma 5 typedSql):**
|
|
243
|
+
|
|
244
|
+
```sql
|
|
245
|
+
-- prisma/sql/getActiveChallenges.sql
|
|
246
|
+
SELECT ac.*, u.email FROM "AchChallenge" ac
|
|
247
|
+
JOIN "User" u ON ac."userId" = u.id
|
|
248
|
+
WHERE ac.status = $1 AND ac."expiresAt" > NOW()
|
|
249
|
+
ORDER BY ac."createdAt" DESC
|
|
250
|
+
LIMIT $2;
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
import { getActiveChallenges } from "@prisma/client/sql";
|
|
255
|
+
const challenges = await prisma.$queryRawTyped(getActiveChallenges("PENDING", 50));
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
**Connection management in Cloud Run:**
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// Singleton pattern — critical for Cloud Run (multiple instances)
|
|
262
|
+
import { PrismaClient } from "@prisma/client";
|
|
263
|
+
|
|
264
|
+
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
|
265
|
+
export const prisma =
|
|
266
|
+
globalForPrisma.prisma ??
|
|
267
|
+
new PrismaClient({
|
|
268
|
+
log: process.env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"],
|
|
269
|
+
datasources: {
|
|
270
|
+
db: {
|
|
271
|
+
url: process.env.DATABASE_URL,
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Prisma migration commands:**
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
# Create migration (development)
|
|
282
|
+
npx prisma migrate dev --name add_unit_account
|
|
283
|
+
|
|
284
|
+
# Apply migrations (production — use in Cloud Build/deployment)
|
|
285
|
+
npx prisma migrate deploy
|
|
286
|
+
|
|
287
|
+
# Reset DB (development only — destroys all data)
|
|
288
|
+
npx prisma migrate reset
|
|
289
|
+
|
|
290
|
+
# Check migration status
|
|
291
|
+
npx prisma migrate status
|
|
292
|
+
|
|
293
|
+
# Generate Prisma client after schema change
|
|
294
|
+
npx prisma generate
|
|
295
|
+
|
|
296
|
+
# Introspect existing DB (for legacy schemas)
|
|
297
|
+
npx prisma db pull
|
|
298
|
+
|
|
299
|
+
# Push schema without migration (for rapid prototyping)
|
|
300
|
+
npx prisma db push
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Never run `prisma migrate dev` in production.** Always use `prisma migrate deploy`.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## 3. Cloud SQL Configuration
|
|
308
|
+
|
|
309
|
+
**<project> Cloud SQL:**
|
|
310
|
+
|
|
311
|
+
- Instance: Cloud SQL PostgreSQL 15 (check Console for exact version)
|
|
312
|
+
- Primary: us-central1
|
|
313
|
+
- Read replicas: us-east1, asia-south1
|
|
314
|
+
- GCP project: <gcp-project>
|
|
315
|
+
|
|
316
|
+
**Connection string format:**
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
postgresql://USER:PASSWORD@HOST:5432/DATABASE?sslmode=require
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Cloud SQL with Cloud Run — authentication options:**
|
|
323
|
+
|
|
324
|
+
**Option 1: Cloud SQL Auth Proxy (recommended for production):**
|
|
325
|
+
|
|
326
|
+
- Uses IAM authentication, no password needed
|
|
327
|
+
- Socket-based connection: `/cloudsql/PROJECT:REGION:INSTANCE`
|
|
328
|
+
- URL format: `postgresql://user@localhost/db?host=/cloudsql/PROJECT:REGION:INSTANCE`
|
|
329
|
+
|
|
330
|
+
**Option 2: Private IP (Cloud Run VPC Connector):**
|
|
331
|
+
|
|
332
|
+
- Cloud Run → VPC Connector → Cloud SQL private IP
|
|
333
|
+
- Requires VPC connector setup (additional cost)
|
|
334
|
+
|
|
335
|
+
**Option 3: SSL with public IP (current <project> setup):**
|
|
336
|
+
|
|
337
|
+
- `?sslmode=require` in DATABASE_URL
|
|
338
|
+
- Cloud SQL uses SSL certificates for secure connections
|
|
339
|
+
- IP is whitelisted or Cloud SQL Auth Proxy handles auth
|
|
340
|
+
|
|
341
|
+
**Instance settings to check/optimize:**
|
|
342
|
+
|
|
343
|
+
- Max connections: default varies by tier (db-standard-1 = 100, db-standard-2 = 200)
|
|
344
|
+
- Recommended max connections = (RAM in GB × 100) - 10 reserved
|
|
345
|
+
- Storage auto-increase: ON (prevents instance going read-only when disk fills)
|
|
346
|
+
- Maintenance window: choose low-traffic time (e.g., Sunday 3am UTC)
|
|
347
|
+
- High availability: enable for production (standby in same region, failover ~30s)
|
|
348
|
+
|
|
349
|
+
**Viewing current connections:**
|
|
350
|
+
|
|
351
|
+
```sql
|
|
352
|
+
SELECT count(*), state, wait_event_type, wait_event
|
|
353
|
+
FROM pg_stat_activity
|
|
354
|
+
GROUP BY state, wait_event_type, wait_event
|
|
355
|
+
ORDER BY count DESC;
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**Connection limits by Cloud SQL tier:**
|
|
359
|
+
| Tier | vCPUs | RAM | Max connections |
|
|
360
|
+
|------|-------|-----|-----------------|
|
|
361
|
+
| db-f1-micro | shared | 0.6GB | 25 |
|
|
362
|
+
| db-g1-small | shared | 1.7GB | 100 |
|
|
363
|
+
| db-standard-1 | 1 | 3.75GB | 100 |
|
|
364
|
+
| db-standard-2 | 2 | 7.5GB | 200 |
|
|
365
|
+
| db-standard-4 | 4 | 15GB | 400 |
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## 4. Connection Pooling & Management
|
|
370
|
+
|
|
371
|
+
**Problem with Cloud Run + Prisma:**
|
|
372
|
+
Each Cloud Run instance creates a Prisma client with connection pool.
|
|
373
|
+
Cloud Run can spin up many instances → can exhaust PostgreSQL max connections.
|
|
374
|
+
|
|
375
|
+
**Solution 1: PgBouncer (recommended for production at scale):**
|
|
376
|
+
Deploy PgBouncer as a Cloud Run sidecar or separate service.
|
|
377
|
+
|
|
378
|
+
- Transaction pooling: most efficient for API servers
|
|
379
|
+
- One PgBouncer handles 1000s of app connections → 10-50 DB connections
|
|
380
|
+
|
|
381
|
+
**Solution 2: Prisma Data Proxy / Accelerate (managed):**
|
|
382
|
+
Prisma's managed connection pooler.
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
// Install: npm install @prisma/extension-accelerate
|
|
386
|
+
import { withAccelerate } from "@prisma/extension-accelerate";
|
|
387
|
+
const prisma = new PrismaClient().$extends(withAccelerate());
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**Solution 3: Reduce Prisma pool size (immediate fix for <project>):**
|
|
391
|
+
|
|
392
|
+
```
|
|
393
|
+
DATABASE_URL="postgresql://...?connection_limit=5&pool_timeout=20"
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
- `connection_limit`: max connections per Prisma instance
|
|
397
|
+
- `pool_timeout`: seconds to wait for connection before error
|
|
398
|
+
- With 10 Cloud Run instances × 5 connections = 50 total connections (safe)
|
|
399
|
+
|
|
400
|
+
**Cloud Run recommended settings:**
|
|
401
|
+
|
|
402
|
+
```
|
|
403
|
+
Max instances: 10 (prevents connection exhaustion)
|
|
404
|
+
Min instances: 1 (keeps one warm for fast response)
|
|
405
|
+
Concurrency: 80 (requests per instance)
|
|
406
|
+
connection_limit in DATABASE_URL: 5
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
**Detecting connection exhaustion:**
|
|
410
|
+
|
|
411
|
+
```sql
|
|
412
|
+
SELECT count(*) FROM pg_stat_activity;
|
|
413
|
+
-- If close to max_connections: connection pool is exhausted
|
|
414
|
+
-- Check: SHOW max_connections;
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**PgBouncer configuration (transaction mode):**
|
|
418
|
+
|
|
419
|
+
```ini
|
|
420
|
+
[databases]
|
|
421
|
+
<project> = host=CLOUD_SQL_HOST port=5432 dbname=<project>
|
|
422
|
+
|
|
423
|
+
[pgbouncer]
|
|
424
|
+
pool_mode = transaction
|
|
425
|
+
max_client_conn = 1000
|
|
426
|
+
default_pool_size = 20
|
|
427
|
+
server_idle_timeout = 600
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## 5. Zero-Downtime Migrations
|
|
433
|
+
|
|
434
|
+
**Expand-Contract pattern (for columns that need type changes or renames):**
|
|
435
|
+
|
|
436
|
+
**Phase 1 — Expand (add new, keep old):**
|
|
437
|
+
|
|
438
|
+
```sql
|
|
439
|
+
ALTER TABLE "User" ADD COLUMN "phoneNumberNew" TEXT;
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**Phase 2 — Migrate data (backfill):**
|
|
443
|
+
|
|
444
|
+
```sql
|
|
445
|
+
UPDATE "User" SET "phoneNumberNew" = "phoneNumber"
|
|
446
|
+
WHERE "phoneNumberNew" IS NULL AND "phoneNumber" IS NOT NULL;
|
|
447
|
+
-- Do in batches to avoid lock:
|
|
448
|
+
-- UPDATE "User" SET "phoneNumberNew" = "phoneNumber"
|
|
449
|
+
-- WHERE id IN (SELECT id FROM "User" WHERE "phoneNumberNew" IS NULL LIMIT 1000)
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**Phase 3 — Deploy code using new column:**
|
|
453
|
+
Application reads both columns, writes to both.
|
|
454
|
+
|
|
455
|
+
**Phase 4 — Contract (drop old column):**
|
|
456
|
+
|
|
457
|
+
```sql
|
|
458
|
+
ALTER TABLE "User" DROP COLUMN "phoneNumber";
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
**Safe migration operations (no table lock):**
|
|
462
|
+
|
|
463
|
+
- `ADD COLUMN` (without default) ✅
|
|
464
|
+
- `ADD COLUMN ... DEFAULT NULL` ✅
|
|
465
|
+
- `ADD INDEX CONCURRENTLY` ✅
|
|
466
|
+
- `DROP INDEX CONCURRENTLY` ✅
|
|
467
|
+
- `CREATE TABLE` ✅
|
|
468
|
+
- `DROP TABLE` ✅
|
|
469
|
+
- Rename with multiple deployments ✅
|
|
470
|
+
|
|
471
|
+
**Dangerous migration operations (cause table lock):**
|
|
472
|
+
|
|
473
|
+
- `ADD COLUMN ... DEFAULT non-null` on large table ⚠️ (rewrites table)
|
|
474
|
+
- `ALTER COLUMN TYPE` on existing data ⚠️
|
|
475
|
+
- `ADD CONSTRAINT` without `NOT VALID` ⚠️
|
|
476
|
+
- `DROP COLUMN` (but usually fast) ⚠️
|
|
477
|
+
|
|
478
|
+
**Adding NOT NULL column safely:**
|
|
479
|
+
|
|
480
|
+
```sql
|
|
481
|
+
-- Step 1: Add nullable
|
|
482
|
+
ALTER TABLE "AchChallenge" ADD COLUMN "bankCode" TEXT;
|
|
483
|
+
-- Step 2: Backfill
|
|
484
|
+
UPDATE "AchChallenge" SET "bankCode" = 'UNKNOWN' WHERE "bankCode" IS NULL;
|
|
485
|
+
-- Step 3: Add constraint (use NOT VALID to skip scan)
|
|
486
|
+
ALTER TABLE "AchChallenge" ALTER COLUMN "bankCode" SET NOT NULL;
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
**Prisma migration for zero-downtime:**
|
|
490
|
+
Create the migration SQL manually to use CONCURRENTLY:
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
npx prisma migrate dev --create-only --name add_bank_code
|
|
494
|
+
# Edit the generated SQL to add CONCURRENTLY
|
|
495
|
+
npx prisma migrate deploy
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## 6. Data Modeling for Fintech
|
|
501
|
+
|
|
502
|
+
**Core entities for <project>:**
|
|
503
|
+
|
|
504
|
+
**Users and accounts:**
|
|
505
|
+
|
|
506
|
+
```prisma
|
|
507
|
+
model User {
|
|
508
|
+
id String @id @default(cuid())
|
|
509
|
+
email String @unique
|
|
510
|
+
emailVerified DateTime?
|
|
511
|
+
phone String?
|
|
512
|
+
region String @default("US") // "US" | "IN"
|
|
513
|
+
kycStatus KycStatus @default(PENDING)
|
|
514
|
+
lockoutUntil DateTime?
|
|
515
|
+
failedAttempts Int @default(0)
|
|
516
|
+
createdAt DateTime @default(now())
|
|
517
|
+
updatedAt DateTime @updatedAt
|
|
518
|
+
|
|
519
|
+
achChallenges AchChallenge[]
|
|
520
|
+
unitAccount UnitAccount?
|
|
521
|
+
upiAccounts UpiLinkedAccount[]
|
|
522
|
+
guardianDevices GuardianDevice[]
|
|
523
|
+
|
|
524
|
+
@@index([email])
|
|
525
|
+
@@index([phone])
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
**Immutable audit trail (append-only, never update):**
|
|
530
|
+
|
|
531
|
+
```prisma
|
|
532
|
+
model TransactionAuditLog {
|
|
533
|
+
id String @id @default(cuid())
|
|
534
|
+
userId String
|
|
535
|
+
eventType String // "ACH_APPROVED" | "UPI_BLOCKED" | "GUARDIAN_ALERT"
|
|
536
|
+
entityId String // challengeId, transactionId
|
|
537
|
+
entityType String // "AchChallenge" | "UpiTransaction"
|
|
538
|
+
metadata Json // full snapshot of event data
|
|
539
|
+
ipAddress String?
|
|
540
|
+
userAgent String?
|
|
541
|
+
createdAt DateTime @default(now())
|
|
542
|
+
|
|
543
|
+
@@index([userId, createdAt])
|
|
544
|
+
@@index([entityId])
|
|
545
|
+
// NO updatedAt — this table is append-only
|
|
546
|
+
}
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
**Soft deletes (never hard-delete financial records):**
|
|
550
|
+
|
|
551
|
+
```prisma
|
|
552
|
+
model UnitAccount {
|
|
553
|
+
id String @id @default(cuid())
|
|
554
|
+
userId String @unique
|
|
555
|
+
unitCustomerId String @unique
|
|
556
|
+
unitAccountId String @unique
|
|
557
|
+
routingNumber String
|
|
558
|
+
accountNumber String // encrypted at rest
|
|
559
|
+
nickname String?
|
|
560
|
+
status String @default("ACTIVE")
|
|
561
|
+
active Boolean @default(true)
|
|
562
|
+
deletedAt DateTime? // soft delete
|
|
563
|
+
createdAt DateTime @default(now())
|
|
564
|
+
updatedAt DateTime @updatedAt
|
|
565
|
+
}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
**Idempotency keys (prevent duplicate transactions):**
|
|
569
|
+
|
|
570
|
+
```prisma
|
|
571
|
+
model IdempotencyKey {
|
|
572
|
+
id String @id @default(cuid())
|
|
573
|
+
key String @unique // UUID from client
|
|
574
|
+
operation String // "ACH_CHALLENGE" | "UPI_PAYMENT"
|
|
575
|
+
response Json? // cached response
|
|
576
|
+
createdAt DateTime @default(now())
|
|
577
|
+
expiresAt DateTime // TTL: 24 hours
|
|
578
|
+
|
|
579
|
+
@@index([key])
|
|
580
|
+
@@index([expiresAt]) // for cleanup
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
**Fraud signal modeling:**
|
|
585
|
+
|
|
586
|
+
```prisma
|
|
587
|
+
model FraudSignal {
|
|
588
|
+
id String @id @default(cuid())
|
|
589
|
+
userId String? // null for anonymous signals
|
|
590
|
+
signalType String // "VELOCITY", "AMOUNT_SPIKE", "GEO_ANOMALY"
|
|
591
|
+
score Float // 0.0-1.0 fraud probability
|
|
592
|
+
features Json // model input features
|
|
593
|
+
decision String // "ALLOW" | "CHALLENGE" | "BLOCK"
|
|
594
|
+
entityId String // transaction/challenge this triggered on
|
|
595
|
+
createdAt DateTime @default(now())
|
|
596
|
+
|
|
597
|
+
@@index([userId, createdAt])
|
|
598
|
+
@@index([signalType, score])
|
|
599
|
+
}
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
---
|
|
603
|
+
|
|
604
|
+
## 7. Cloud Scheduler — All 61 Jobs
|
|
605
|
+
|
|
606
|
+
**<project> scheduler architecture:**
|
|
607
|
+
All 61 jobs hit Cloud Run endpoints secured by `CRON_SECRET` header.
|
|
608
|
+
Pattern: `Authorization: Bearer ${CRON_SECRET}` or `X-Cron-Secret: ${CRON_SECRET}`
|
|
609
|
+
|
|
610
|
+
**Critical scheduler jobs and their timing:**
|
|
611
|
+
| Job | Schedule | Description |
|
|
612
|
+
|-----|----------|-------------|
|
|
613
|
+
| feed-fetch | `*/9 * * * *` | Fetch threat intelligence feeds |
|
|
614
|
+
| offline-settlement | `*/5 * * * *` | Process pending offline UPI settlements |
|
|
615
|
+
| offline-settlement-india | `*/5 * * * *` (IST) | India UPI settlement (IST timezone) |
|
|
616
|
+
| uptime-monitor | `*/5 * * * *` | Health check all 3 regions |
|
|
617
|
+
| shield-evolution-agent | `0 * * * *` | Hourly AI threat model update |
|
|
618
|
+
| news-crawler | `*/30 * * * *` | Financial security news crawl |
|
|
619
|
+
| github-crawler | `0 * * * *` | GitHub security advisory crawl |
|
|
620
|
+
| regulatory-crawler | `*/6 * * * *` | Regulatory update check |
|
|
621
|
+
| daily-digest | `0 6 * * *` | Daily threat digest email (6am UTC) |
|
|
622
|
+
| backup-verify | `0 */6 * * *` | Verify DB backup integrity |
|
|
623
|
+
| sitemap-submit | `0 9 * * 1` | Weekly GSC sitemap submission |
|
|
624
|
+
| feed-discovery | `0 3 * * 0` | Weekly new feed source discovery |
|
|
625
|
+
| ach-challenge-expiry | `*/1 * * * *` | Expire stale ACH challenges (60s TTL) |
|
|
626
|
+
|
|
627
|
+
**ACH challenge expiry job (new — needed for ACH Shield):**
|
|
628
|
+
|
|
629
|
+
```typescript
|
|
630
|
+
// POST /api/cron/expire-ach-challenges
|
|
631
|
+
export async function POST(request: Request) {
|
|
632
|
+
const secret = request.headers.get("x-cron-secret");
|
|
633
|
+
if (secret !== process.env.CRON_SECRET) return new Response("Unauthorized", { status: 401 });
|
|
634
|
+
|
|
635
|
+
const expired = await prisma.achChallenge.updateMany({
|
|
636
|
+
where: {
|
|
637
|
+
status: "PENDING",
|
|
638
|
+
expiresAt: { lt: new Date() },
|
|
639
|
+
},
|
|
640
|
+
data: { status: "EXPIRED" },
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
return Response.json({ expired: expired.count });
|
|
644
|
+
}
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
**Cloud Scheduler job configuration:**
|
|
648
|
+
|
|
649
|
+
```bash
|
|
650
|
+
gcloud scheduler jobs create http expire-ach-challenges \
|
|
651
|
+
--location=us-central1 \
|
|
652
|
+
--schedule="* * * * *" \
|
|
653
|
+
--uri="https://<project>.com/api/cron/expire-ach-challenges" \
|
|
654
|
+
--http-method=POST \
|
|
655
|
+
--headers="X-Cron-Secret=${CRON_SECRET}" \
|
|
656
|
+
--time-zone="UTC" \
|
|
657
|
+
--attempt-deadline="30s" \
|
|
658
|
+
--min-backoff=5s \
|
|
659
|
+
--max-backoff=60s \
|
|
660
|
+
--max-retry-attempts=3
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
**IST timezone for India jobs:**
|
|
664
|
+
`--time-zone="Asia/Kolkata"` — UTC+5:30
|
|
665
|
+
|
|
666
|
+
**Scheduler retry config:**
|
|
667
|
+
|
|
668
|
+
- `max-retry-attempts`: 3 for critical jobs, 0 for idempotent crawlers
|
|
669
|
+
- `attempt-deadline`: set based on expected job duration + buffer
|
|
670
|
+
- Monitor failures: Cloud Console → Cloud Scheduler → job → View logs
|
|
671
|
+
|
|
672
|
+
---
|
|
673
|
+
|
|
674
|
+
## 8. BigQuery & Analytics
|
|
675
|
+
|
|
676
|
+
**When to use BigQuery vs Cloud SQL:**
|
|
677
|
+
|
|
678
|
+
- Cloud SQL: operational data, transactions, real-time queries
|
|
679
|
+
- BigQuery: analytics, aggregations, historical reporting, ML
|
|
680
|
+
|
|
681
|
+
**Streaming inserts from Cloud Run:**
|
|
682
|
+
|
|
683
|
+
```typescript
|
|
684
|
+
import { BigQuery } from "@google-cloud/bigquery";
|
|
685
|
+
const bq = new BigQuery({ projectId: "<gcp-project>" });
|
|
686
|
+
|
|
687
|
+
// Stream fraud signals to BigQuery for analytics
|
|
688
|
+
await bq
|
|
689
|
+
.dataset("<project>_analytics")
|
|
690
|
+
.table("fraud_signals")
|
|
691
|
+
.insert([
|
|
692
|
+
{
|
|
693
|
+
userId: signal.userId,
|
|
694
|
+
signalType: signal.signalType,
|
|
695
|
+
score: signal.score,
|
|
696
|
+
createdAt: signal.createdAt.toISOString(),
|
|
697
|
+
// BigQuery timestamp format: YYYY-MM-DDTHH:MM:SS.fffZ
|
|
698
|
+
},
|
|
699
|
+
]);
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
**BigQuery tables for <project>:**
|
|
703
|
+
|
|
704
|
+
```sql
|
|
705
|
+
-- Fraud signals table
|
|
706
|
+
CREATE TABLE `<project>_analytics.fraud_signals`
|
|
707
|
+
PARTITION BY DATE(created_at)
|
|
708
|
+
OPTIONS (partition_expiration_days = 365)
|
|
709
|
+
AS SELECT ... ;
|
|
710
|
+
|
|
711
|
+
-- Daily aggregates (for dashboard)
|
|
712
|
+
CREATE TABLE `<project>_analytics.daily_metrics`
|
|
713
|
+
PARTITION BY report_date
|
|
714
|
+
AS SELECT
|
|
715
|
+
DATE(created_at) as report_date,
|
|
716
|
+
COUNT(*) as total_challenges,
|
|
717
|
+
COUNTIF(status = 'APPROVED') as approved,
|
|
718
|
+
COUNTIF(status = 'DECLINED') as declined,
|
|
719
|
+
COUNTIF(status = 'EXPIRED') as expired,
|
|
720
|
+
AVG(CASE WHEN resolved_at IS NOT NULL
|
|
721
|
+
THEN TIMESTAMP_DIFF(resolved_at, created_at, SECOND) END) as avg_resolution_seconds
|
|
722
|
+
FROM `<project>_analytics.ach_challenges`
|
|
723
|
+
GROUP BY 1;
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
**Cost optimization:**
|
|
727
|
+
|
|
728
|
+
- Partition all tables by date (partition pruning = pay only for queried partitions)
|
|
729
|
+
- Cluster frequently filtered columns: `CLUSTER BY userId, signalType`
|
|
730
|
+
- Use approximate aggregation: `APPROX_COUNT_DISTINCT()` vs `COUNT(DISTINCT)`
|
|
731
|
+
- Preview query cost before running: check "This query will process X GB"
|
|
732
|
+
|
|
733
|
+
---
|
|
734
|
+
|
|
735
|
+
## 9. Backup, PITR & Disaster Recovery
|
|
736
|
+
|
|
737
|
+
**Cloud SQL automated backups:**
|
|
738
|
+
|
|
739
|
+
- Enabled by default on Cloud SQL
|
|
740
|
+
- Retention: 7 days (default) — increase to 30 days for production
|
|
741
|
+
- Takes ~30 minutes, no performance impact
|
|
742
|
+
- Stored in the same region as the instance
|
|
743
|
+
|
|
744
|
+
**Point-in-Time Recovery (PITR):**
|
|
745
|
+
|
|
746
|
+
- Allows restore to any second within the backup window
|
|
747
|
+
- Requires binary logging enabled (on by default in Cloud SQL)
|
|
748
|
+
- Use case: accidental `DELETE` or data corruption
|
|
749
|
+
- Recovery time: 30-60 minutes for a 10GB database
|
|
750
|
+
|
|
751
|
+
**Enabling extended backup retention:**
|
|
752
|
+
|
|
753
|
+
```bash
|
|
754
|
+
gcloud sql instances patch INSTANCE_NAME \
|
|
755
|
+
--backup-retention-count=30 \
|
|
756
|
+
--enable-bin-log \
|
|
757
|
+
--retained-backups-count=30
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
**Manual backup before risky migrations:**
|
|
761
|
+
|
|
762
|
+
```bash
|
|
763
|
+
gcloud sql backups create \
|
|
764
|
+
--instance=INSTANCE_NAME \
|
|
765
|
+
--description="Pre-migration backup $(date +%Y-%m-%d)"
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
**Cross-region backup (for additional safety):**
|
|
769
|
+
Enable in Cloud SQL instance settings → Backups → Enable cross-region backups
|
|
770
|
+
Copies backups to another region automatically.
|
|
771
|
+
|
|
772
|
+
**Restore procedure:**
|
|
773
|
+
|
|
774
|
+
```bash
|
|
775
|
+
# List available backups
|
|
776
|
+
gcloud sql backups list --instance=INSTANCE_NAME
|
|
777
|
+
|
|
778
|
+
# Restore to a new instance (never restore to production directly)
|
|
779
|
+
gcloud sql instances create RESTORED_INSTANCE \
|
|
780
|
+
--source-instance=INSTANCE_NAME \
|
|
781
|
+
--backup-run-id=BACKUP_ID \
|
|
782
|
+
--region=us-central1
|
|
783
|
+
|
|
784
|
+
# After verification, use Cloud SQL proxy to query restored instance
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
**Recovery time objectives for <project>:**
|
|
788
|
+
|
|
789
|
+
- RTO (Recovery Time Objective): < 1 hour
|
|
790
|
+
- RPO (Recovery Point Objective): < 5 minutes (PITR to last checkpoint)
|
|
791
|
+
- HA (High Availability): 99.95% SLA with Cloud SQL HA enabled
|
|
792
|
+
|
|
793
|
+
---
|
|
794
|
+
|
|
795
|
+
## 10. Performance & Monitoring
|
|
796
|
+
|
|
797
|
+
**Key metrics to monitor (Cloud SQL Insights):**
|
|
798
|
+
|
|
799
|
+
- Query latency: P50, P95, P99
|
|
800
|
+
- Active connections
|
|
801
|
+
- CPU utilization: alert at 70%
|
|
802
|
+
- Memory usage: alert at 85%
|
|
803
|
+
- Disk utilization: alert at 80%
|
|
804
|
+
- Replication lag (for replicas): alert at > 30 seconds
|
|
805
|
+
|
|
806
|
+
**pg_stat_statements (slow query analysis):**
|
|
807
|
+
|
|
808
|
+
```sql
|
|
809
|
+
-- Top 10 slowest queries
|
|
810
|
+
SELECT
|
|
811
|
+
round(total_exec_time::numeric, 2) as total_ms,
|
|
812
|
+
round(mean_exec_time::numeric, 2) as mean_ms,
|
|
813
|
+
calls,
|
|
814
|
+
round((total_exec_time / sum(total_exec_time) OVER ()) * 100, 2) as pct,
|
|
815
|
+
query
|
|
816
|
+
FROM pg_stat_statements
|
|
817
|
+
ORDER BY total_exec_time DESC
|
|
818
|
+
LIMIT 10;
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
**Cloud SQL Query Insights:**
|
|
822
|
+
|
|
823
|
+
- Cloud Console → Cloud SQL → instance → Query insights
|
|
824
|
+
- Shows top queries by CPU, latency, count
|
|
825
|
+
- Execution plan visualization
|
|
826
|
+
- No setup needed — enabled by default
|
|
827
|
+
|
|
828
|
+
**Connection pool monitoring:**
|
|
829
|
+
|
|
830
|
+
```sql
|
|
831
|
+
-- Current connections by state
|
|
832
|
+
SELECT state, count(*)
|
|
833
|
+
FROM pg_stat_activity
|
|
834
|
+
GROUP BY state;
|
|
835
|
+
|
|
836
|
+
-- Long-running queries (> 5 minutes)
|
|
837
|
+
SELECT pid, now() - pg_stat_activity.query_start AS duration, query, state
|
|
838
|
+
FROM pg_stat_activity
|
|
839
|
+
WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes';
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
**Killing a blocking query:**
|
|
843
|
+
|
|
844
|
+
```sql
|
|
845
|
+
SELECT pg_cancel_backend(pid); -- graceful cancel
|
|
846
|
+
SELECT pg_terminate_backend(pid); -- force terminate
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
**Cloud Monitoring alerting policies:**
|
|
850
|
+
|
|
851
|
+
```bash
|
|
852
|
+
# Create alert for high CPU
|
|
853
|
+
gcloud monitoring policies create \
|
|
854
|
+
--notification-channels=CHANNEL_ID \
|
|
855
|
+
--display-name="Cloud SQL CPU > 70%" \
|
|
856
|
+
--condition-threshold-filter='resource.type="cloudsql_database"' \
|
|
857
|
+
--condition-threshold-value=0.7 \
|
|
858
|
+
--condition-threshold-comparison=COMPARISON_GT
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
---
|
|
862
|
+
|
|
863
|
+
## 11. Row-Level Security & Multi-Tenancy
|
|
864
|
+
|
|
865
|
+
**RLS for <project> (isolate user data):**
|
|
866
|
+
|
|
867
|
+
```sql
|
|
868
|
+
-- Enable RLS on sensitive tables
|
|
869
|
+
ALTER TABLE "AchChallenge" ENABLE ROW LEVEL SECURITY;
|
|
870
|
+
|
|
871
|
+
-- Policy: users can only see their own challenges
|
|
872
|
+
CREATE POLICY user_isolation ON "AchChallenge"
|
|
873
|
+
FOR ALL
|
|
874
|
+
USING (current_setting('app.current_user_id') = "userId");
|
|
875
|
+
|
|
876
|
+
-- Set user context at query time (via Prisma middleware)
|
|
877
|
+
SET LOCAL app.current_user_id = 'user_id_here';
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
**Prisma middleware to set user context:**
|
|
881
|
+
|
|
882
|
+
```typescript
|
|
883
|
+
prisma.$use(async (params, next) => {
|
|
884
|
+
if (currentUserId) {
|
|
885
|
+
await prisma.$executeRaw`SET LOCAL app.current_user_id = ${currentUserId}`;
|
|
886
|
+
}
|
|
887
|
+
return next(params);
|
|
888
|
+
});
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
**Note:** RLS adds overhead. For <project>'s current scale, application-level isolation
|
|
892
|
+
(WHERE userId = currentUser.id) is sufficient. Use RLS as defense-in-depth for highly sensitive tables.
|
|
893
|
+
|
|
894
|
+
---
|
|
895
|
+
|
|
896
|
+
## 12. Pub/Sub & Event-Driven Architecture
|
|
897
|
+
|
|
898
|
+
**When to use Pub/Sub vs direct DB writes:**
|
|
899
|
+
|
|
900
|
+
- High-volume events: fraud signals, threat feeds, audit logs → Pub/Sub
|
|
901
|
+
- Real-time webhooks that might fail: ACH notifications → Pub/Sub with retry
|
|
902
|
+
- Cross-service communication: feed-fetch → feed-processor
|
|
903
|
+
|
|
904
|
+
**<project> Pub/Sub topics:**
|
|
905
|
+
|
|
906
|
+
```bash
|
|
907
|
+
# Create topics
|
|
908
|
+
gcloud pubsub topics create threat-feeds-ingestion
|
|
909
|
+
gcloud pubsub topics create ach-webhook-delivery
|
|
910
|
+
gcloud pubsub topics create fraud-signals
|
|
911
|
+
|
|
912
|
+
# Create subscriptions with retry
|
|
913
|
+
gcloud pubsub subscriptions create ach-webhook-processor \
|
|
914
|
+
--topic=ach-webhook-delivery \
|
|
915
|
+
--ack-deadline=60 \
|
|
916
|
+
--min-retry-delay=10s \
|
|
917
|
+
--max-retry-delay=600s \
|
|
918
|
+
--dead-letter-topic=ach-webhook-dlq \
|
|
919
|
+
--max-delivery-attempts=5
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
**Publishing from Next.js:**
|
|
923
|
+
|
|
924
|
+
```typescript
|
|
925
|
+
import { PubSub } from "@google-cloud/pubsub";
|
|
926
|
+
const pubsub = new PubSub({ projectId: "<gcp-project>" });
|
|
927
|
+
|
|
928
|
+
await pubsub.topic("ach-webhook-delivery").publish(
|
|
929
|
+
Buffer.from(
|
|
930
|
+
JSON.stringify({
|
|
931
|
+
challengeId,
|
|
932
|
+
bankWebhookUrl,
|
|
933
|
+
decision: "APPROVED",
|
|
934
|
+
timestamp: new Date().toISOString(),
|
|
935
|
+
}),
|
|
936
|
+
),
|
|
937
|
+
);
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
---
|
|
941
|
+
|
|
942
|
+
## 13. GCP Secret Manager Operations
|
|
943
|
+
|
|
944
|
+
**All <project> secrets:**
|
|
945
|
+
DATABASE_URL, NEXTAUTH_SECRET, RESEND_API_KEY, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, CRON_SECRET, TELEGRAM_BOT_TOKEN, TELEGRAM_CHANNEL_ID, NVD_API_KEY, SHIELD_SIGNING_KEY, TG_MASTER_KEY, ADMIN_EMAIL, FIREBASE_SERVICE_ACCOUNT_KEY, BANK_WEBHOOK_SECRET, UNIT_API_KEY, UNIT_WEBHOOK_SECRET, UNIT_DEPOSIT_PRODUCT_ID
|
|
946
|
+
|
|
947
|
+
**Common operations:**
|
|
948
|
+
|
|
949
|
+
```bash
|
|
950
|
+
# Read a secret
|
|
951
|
+
gcloud secrets versions access latest --secret=SECRET_NAME --project=<gcp-project>
|
|
952
|
+
|
|
953
|
+
# Update a secret (creates new version)
|
|
954
|
+
echo -n "new_value" | gcloud secrets versions add SECRET_NAME --data-file=-
|
|
955
|
+
|
|
956
|
+
# List versions
|
|
957
|
+
gcloud secrets versions list SECRET_NAME
|
|
958
|
+
|
|
959
|
+
# Deploy new secret version to all Cloud Run regions
|
|
960
|
+
# (Cloud Run reads latest version on cold start — use revision deploy to force refresh)
|
|
961
|
+
gcloud run deploy <project> \
|
|
962
|
+
--image LATEST_IMAGE \
|
|
963
|
+
--region us-central1 \
|
|
964
|
+
--update-secrets SECRET_NAME=SECRET_NAME:latest
|
|
965
|
+
```
|
|
966
|
+
|
|
967
|
+
**Adding a new secret:**
|
|
968
|
+
|
|
969
|
+
```bash
|
|
970
|
+
gcloud secrets create NEW_SECRET_NAME \
|
|
971
|
+
--project=<gcp-project> \
|
|
972
|
+
--replication-policy="automatic"
|
|
973
|
+
|
|
974
|
+
echo -n "secret_value" | gcloud secrets versions add NEW_SECRET_NAME --data-file=-
|
|
975
|
+
|
|
976
|
+
# Grant Cloud Run service account access
|
|
977
|
+
gcloud secrets add-iam-policy-binding NEW_SECRET_NAME \
|
|
978
|
+
--member="serviceAccount:<email>" \
|
|
979
|
+
--role="roles/secretmanager.secretAccessor"
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
**Secret rotation pattern:**
|
|
983
|
+
|
|
984
|
+
1. Add new version: `gcloud secrets versions add`
|
|
985
|
+
2. Deploy new Cloud Run revision (picks up new version)
|
|
986
|
+
3. Verify new version works
|
|
987
|
+
4. Disable old version: `gcloud secrets versions disable VERSION_ID --secret=SECRET_NAME`
|
|
988
|
+
|
|
989
|
+
---
|
|
990
|
+
|
|
991
|
+
## 14. <project> DB Schema Reference
|
|
992
|
+
|
|
993
|
+
**Current DB tables (55+):**
|
|
994
|
+
|
|
995
|
+
**Core auth/user:** User, Account, Session, VerificationToken (NextAuth)
|
|
996
|
+
|
|
997
|
+
**ACH Shield:**
|
|
998
|
+
|
|
999
|
+
- AchChallenge (id, userId, status, options[], correctOption, attempts, expiresAt, resolvedAt, webhookSent)
|
|
1000
|
+
- UnitAccount (id, userId, unitCustomerId, unitAccountId, routingNumber, accountNumber, nickname, status, active)
|
|
1001
|
+
|
|
1002
|
+
**UPI Shield:**
|
|
1003
|
+
|
|
1004
|
+
- UpiLinkedAccount (id, userId, vpa, bankName, active, deletedAt)
|
|
1005
|
+
- UpiFraudCheck (id, userId, vpa, amount, decision, score, blockedReason)
|
|
1006
|
+
- UpiTransaction (id, userId, vpa, amount, status, offlineToken, settledAt)
|
|
1007
|
+
|
|
1008
|
+
**Guardian:**
|
|
1009
|
+
|
|
1010
|
+
- GuardianDevice (id, userId, platform, hostname, agentVersion, lastSeen, status)
|
|
1011
|
+
- GuardianHeartbeat (id, deviceId, threats[], metrics{})
|
|
1012
|
+
- GuardianAlert (id, deviceId, alertType, severity, detail, acknowledgedAt)
|
|
1013
|
+
|
|
1014
|
+
**SENTINEL:**
|
|
1015
|
+
|
|
1016
|
+
- ThreatFeed (id, feedId, title, content, severity, tags[], metadata{}, publishedAt)
|
|
1017
|
+
- FeedRegistry (id, name, url, type, active, lastFetchAt, errorCount)
|
|
1018
|
+
- FraudSignal (id, userId, signalType, score, features{}, decision, entityId)
|
|
1019
|
+
|
|
1020
|
+
**Offline UPI:**
|
|
1021
|
+
|
|
1022
|
+
- OfflineToken (id, userId, amount, vpa, encryptedPayload, expiresAt, used)
|
|
1023
|
+
- MeshSettlement (id, tokenId, transportType, settledAt, npciRef)
|
|
1024
|
+
|
|
1025
|
+
**Schema migration for new tables (April 15, 2026 migration):**
|
|
1026
|
+
|
|
1027
|
+
- UnitAccount: created ✅
|
|
1028
|
+
- GuardianDevice: confirmed ✅
|
|
1029
|
+
- UpiLinkedAccount additions: ✅
|
|
1030
|
+
- UpiFraudCheck field additions: ✅
|
|
1031
|
+
|
|
1032
|
+
**Checking migration status:**
|
|
1033
|
+
|
|
1034
|
+
```bash
|
|
1035
|
+
npx prisma migrate status
|
|
1036
|
+
# or
|
|
1037
|
+
gcloud sql databases list --instance=INSTANCE_NAME
|
|
1038
|
+
```
|