@c0x12c/ai-toolkit 1.15.0
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/.claude-plugin/marketplace.json +16 -0
- package/.claude-plugin/plugin.json +12 -0
- package/README.md +439 -0
- package/VERSION +1 -0
- package/agents/design-critic.md +127 -0
- package/agents/idea-killer.md +72 -0
- package/agents/infrastructure-expert.md +49 -0
- package/agents/micronaut-backend-expert.md +45 -0
- package/agents/phase-reviewer.md +150 -0
- package/agents/research-planner.md +70 -0
- package/agents/solution-architect-cto.md +49 -0
- package/agents/sre-architect.md +49 -0
- package/agents/team-coordinator.md +111 -0
- package/bin/cli.js +780 -0
- package/claude-md/00-header.md +39 -0
- package/claude-md/01-core.md +105 -0
- package/claude-md/05-database.md +20 -0
- package/claude-md/11-backend-micronaut.md +19 -0
- package/claude-md/20-frontend-react.md +44 -0
- package/claude-md/25-ux-design.md +56 -0
- package/claude-md/30-infrastructure.md +24 -0
- package/claude-md/30-project-mgmt.md +119 -0
- package/claude-md/40-product.md +39 -0
- package/claude-md/50-ops.md +34 -0
- package/claude-md/60-research.md +27 -0
- package/claude-md/90-footer.md +21 -0
- package/commands/spartan/brainstorm.md +134 -0
- package/commands/spartan/brownfield.md +157 -0
- package/commands/spartan/build.md +435 -0
- package/commands/spartan/careful.md +94 -0
- package/commands/spartan/commit-message.md +112 -0
- package/commands/spartan/content.md +17 -0
- package/commands/spartan/context-save.md +161 -0
- package/commands/spartan/contribute.md +140 -0
- package/commands/spartan/daily.md +42 -0
- package/commands/spartan/debug.md +308 -0
- package/commands/spartan/deep-dive.md +55 -0
- package/commands/spartan/deploy.md +207 -0
- package/commands/spartan/e2e.md +264 -0
- package/commands/spartan/env-setup.md +166 -0
- package/commands/spartan/epic.md +199 -0
- package/commands/spartan/fe-review.md +181 -0
- package/commands/spartan/figma-to-code.md +260 -0
- package/commands/spartan/forensics.md +46 -0
- package/commands/spartan/freeze.md +84 -0
- package/commands/spartan/fundraise.md +53 -0
- package/commands/spartan/gate-review.md +229 -0
- package/commands/spartan/gsd-upgrade.md +376 -0
- package/commands/spartan/guard.md +42 -0
- package/commands/spartan/init-project.md +178 -0
- package/commands/spartan/init-rules.md +298 -0
- package/commands/spartan/interview.md +154 -0
- package/commands/spartan/kickoff.md +73 -0
- package/commands/spartan/kotlin-service.md +109 -0
- package/commands/spartan/lean-canvas.md +222 -0
- package/commands/spartan/lint-rules.md +122 -0
- package/commands/spartan/map-codebase.md +124 -0
- package/commands/spartan/migration.md +82 -0
- package/commands/spartan/next-app.md +317 -0
- package/commands/spartan/next-feature.md +212 -0
- package/commands/spartan/onboard.md +326 -0
- package/commands/spartan/outreach.md +16 -0
- package/commands/spartan/phase.md +142 -0
- package/commands/spartan/pitch.md +18 -0
- package/commands/spartan/plan.md +210 -0
- package/commands/spartan/pr-ready.md +202 -0
- package/commands/spartan/project.md +106 -0
- package/commands/spartan/qa.md +222 -0
- package/commands/spartan/research.md +254 -0
- package/commands/spartan/review.md +132 -0
- package/commands/spartan/scan-rules.md +173 -0
- package/commands/spartan/sessions.md +143 -0
- package/commands/spartan/spec.md +131 -0
- package/commands/spartan/startup.md +257 -0
- package/commands/spartan/team.md +570 -0
- package/commands/spartan/teardown.md +161 -0
- package/commands/spartan/testcontainer.md +97 -0
- package/commands/spartan/tf-cost.md +123 -0
- package/commands/spartan/tf-deploy.md +116 -0
- package/commands/spartan/tf-drift.md +100 -0
- package/commands/spartan/tf-import.md +107 -0
- package/commands/spartan/tf-module.md +121 -0
- package/commands/spartan/tf-plan.md +100 -0
- package/commands/spartan/tf-review.md +106 -0
- package/commands/spartan/tf-scaffold.md +109 -0
- package/commands/spartan/tf-security.md +147 -0
- package/commands/spartan/think.md +221 -0
- package/commands/spartan/unfreeze.md +13 -0
- package/commands/spartan/update.md +134 -0
- package/commands/spartan/ux.md +1233 -0
- package/commands/spartan/validate.md +193 -0
- package/commands/spartan/web-to-prd.md +706 -0
- package/commands/spartan/workstreams.md +109 -0
- package/commands/spartan/write.md +16 -0
- package/commands/spartan.md +386 -0
- package/frameworks/00-framework-comparison-guide.md +317 -0
- package/frameworks/01-lean-canvas.md +196 -0
- package/frameworks/02-design-sprint.md +304 -0
- package/frameworks/03-foundation-sprint.md +337 -0
- package/frameworks/04-business-model-canvas.md +391 -0
- package/frameworks/05-customer-development.md +426 -0
- package/frameworks/06-jobs-to-be-done.md +358 -0
- package/frameworks/07-mom-test.md +392 -0
- package/frameworks/08-value-proposition-canvas.md +488 -0
- package/frameworks/09-javelin-board.md +428 -0
- package/frameworks/10-build-measure-learn.md +467 -0
- package/frameworks/11-mvp-approaches.md +533 -0
- package/frameworks/think-before-build.md +593 -0
- package/lib/assembler.js +197 -0
- package/lib/assembler.test.js +159 -0
- package/lib/detector.js +166 -0
- package/lib/detector.test.js +221 -0
- package/lib/packs.js +16 -0
- package/lib/resolver.js +272 -0
- package/lib/resolver.test.js +298 -0
- package/lib/worktree.sh +104 -0
- package/package.json +50 -0
- package/packs/backend-micronaut.yaml +35 -0
- package/packs/backend-nodejs.yaml +15 -0
- package/packs/backend-python.yaml +15 -0
- package/packs/core.yaml +37 -0
- package/packs/database.yaml +21 -0
- package/packs/frontend-react.yaml +24 -0
- package/packs/infrastructure.yaml +40 -0
- package/packs/ops.yaml +16 -0
- package/packs/packs.compiled.json +371 -0
- package/packs/product.yaml +22 -0
- package/packs/project-mgmt.yaml +24 -0
- package/packs/research.yaml +39 -0
- package/packs/shared-backend.yaml +14 -0
- package/packs/ux-design.yaml +21 -0
- package/rules/backend-micronaut/API_DESIGN.md +313 -0
- package/rules/backend-micronaut/BATCH_PROCESSING.md +92 -0
- package/rules/backend-micronaut/CONTROLLERS.md +388 -0
- package/rules/backend-micronaut/KOTLIN.md +414 -0
- package/rules/backend-micronaut/RETROFIT_PLACEMENT.md +290 -0
- package/rules/backend-micronaut/SERVICES_AND_BEANS.md +325 -0
- package/rules/core/NAMING_CONVENTIONS.md +208 -0
- package/rules/core/SKILL_AUTHORING.md +174 -0
- package/rules/core/TIMEZONE.md +316 -0
- package/rules/database/ORM_AND_REPO.md +289 -0
- package/rules/database/SCHEMA.md +146 -0
- package/rules/database/TRANSACTIONS.md +311 -0
- package/rules/frontend-react/FRONTEND.md +344 -0
- package/rules/infrastructure/MODULES.md +260 -0
- package/rules/infrastructure/NAMING.md +196 -0
- package/rules/infrastructure/PROVIDERS.md +309 -0
- package/rules/infrastructure/SECURITY.md +310 -0
- package/rules/infrastructure/STATE_AND_BACKEND.md +237 -0
- package/rules/infrastructure/STRUCTURE.md +234 -0
- package/rules/infrastructure/VARIABLES.md +285 -0
- package/rules/shared-backend/ARCHITECTURE.md +46 -0
- package/rules/ux-design/DESIGN_PROCESS.md +176 -0
- package/skills/api-endpoint-creator/SKILL.md +455 -0
- package/skills/api-endpoint-creator/error-handling-guide.md +244 -0
- package/skills/api-endpoint-creator/examples.md +522 -0
- package/skills/api-endpoint-creator/testing-patterns.md +302 -0
- package/skills/article-writing/SKILL.md +109 -0
- package/skills/article-writing/examples.md +59 -0
- package/skills/backend-api-design/SKILL.md +84 -0
- package/skills/backend-api-design/code-patterns.md +138 -0
- package/skills/brainstorm/SKILL.md +95 -0
- package/skills/browser-qa/SKILL.md +87 -0
- package/skills/browser-qa/playwright-snippets.md +110 -0
- package/skills/ci-cd-patterns/SKILL.md +108 -0
- package/skills/ci-cd-patterns/workflows.md +149 -0
- package/skills/competitive-teardown/SKILL.md +93 -0
- package/skills/competitive-teardown/example-analysis.md +50 -0
- package/skills/content-engine/SKILL.md +131 -0
- package/skills/content-engine/examples.md +72 -0
- package/skills/database-patterns/SKILL.md +72 -0
- package/skills/database-patterns/code-templates.md +114 -0
- package/skills/database-table-creator/SKILL.md +141 -0
- package/skills/database-table-creator/examples.md +552 -0
- package/skills/database-table-creator/kotlin-templates.md +400 -0
- package/skills/database-table-creator/migration-template.sql +68 -0
- package/skills/database-table-creator/validation-checklist.md +337 -0
- package/skills/deep-research/SKILL.md +80 -0
- package/skills/design-intelligence/SKILL.md +268 -0
- package/skills/design-workflow/SKILL.md +127 -0
- package/skills/design-workflow/checklists.md +45 -0
- package/skills/idea-validation/SKILL.md +129 -0
- package/skills/idea-validation/example-report.md +50 -0
- package/skills/investor-materials/SKILL.md +122 -0
- package/skills/investor-materials/example-outline.md +70 -0
- package/skills/investor-outreach/SKILL.md +112 -0
- package/skills/investor-outreach/examples.md +76 -0
- package/skills/kotlin-best-practices/SKILL.md +58 -0
- package/skills/kotlin-best-practices/code-patterns.md +132 -0
- package/skills/market-research/SKILL.md +99 -0
- package/skills/security-checklist/SKILL.md +65 -0
- package/skills/security-checklist/audit-reference.md +95 -0
- package/skills/service-debugging/SKILL.md +116 -0
- package/skills/service-debugging/common-issues.md +65 -0
- package/skills/startup-pipeline/SKILL.md +152 -0
- package/skills/terraform-best-practices/SKILL.md +244 -0
- package/skills/terraform-module-creator/SKILL.md +284 -0
- package/skills/terraform-review/SKILL.md +222 -0
- package/skills/terraform-security-audit/SKILL.md +280 -0
- package/skills/terraform-service-scaffold/SKILL.md +574 -0
- package/skills/testing-strategies/SKILL.md +116 -0
- package/skills/testing-strategies/examples.md +103 -0
- package/skills/testing-strategies/integration-test-setup.md +71 -0
- package/skills/ui-ux-pro-max/SKILL.md +238 -0
- package/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills/ui-ux-pro-max/python-setup.md +146 -0
- package/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/skills/web-to-prd/SKILL.md +478 -0
- package/templates/build-config.yaml +44 -0
- package/templates/commands-config.yaml +55 -0
- package/templates/competitor-analysis.md +60 -0
- package/templates/content/AGENT_TEMPLATE.md +47 -0
- package/templates/content/COMMAND_TEMPLATE.md +27 -0
- package/templates/content/RULE_TEMPLATE.md +40 -0
- package/templates/content/SKILL_TEMPLATE.md +41 -0
- package/templates/design-config.md +105 -0
- package/templates/design-doc.md +207 -0
- package/templates/epic.md +100 -0
- package/templates/feature-spec.md +181 -0
- package/templates/idea-canvas.md +47 -0
- package/templates/implementation-plan.md +159 -0
- package/templates/prd-template.md +86 -0
- package/templates/preamble.md +89 -0
- package/templates/project-readme.md +35 -0
- package/templates/quality-gates.md +230 -0
- package/templates/spartan-config.yaml +164 -0
- package/templates/user-interview.md +69 -0
- package/templates/validation-checklist.md +108 -0
- package/templates/workflow-backend-micronaut.md +409 -0
- package/templates/workflow-frontend-react.md +233 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: content-engine
|
|
3
|
+
description: Turn one idea into platform-native content for X, LinkedIn, TikTok, YouTube, newsletters. Use when the user wants social posts, threads, scripts, or content calendars.
|
|
4
|
+
allowed_tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- WebSearch
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Content Engine
|
|
11
|
+
|
|
12
|
+
Turn one idea into strong content for each platform. Don't cross-post the same thing.
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
- Writing X posts or threads
|
|
17
|
+
- LinkedIn posts or launch updates
|
|
18
|
+
- Short-form video scripts
|
|
19
|
+
- Turning articles or demos into social content
|
|
20
|
+
- Building a content plan around a launch
|
|
21
|
+
|
|
22
|
+
> See `examples.md` for platform-specific post examples showing the same idea adapted for X, LinkedIn, and newsletter.
|
|
23
|
+
|
|
24
|
+
## First Questions
|
|
25
|
+
|
|
26
|
+
Ask:
|
|
27
|
+
- Source: What are we working from?
|
|
28
|
+
- Audience: Builders, investors, customers, or general?
|
|
29
|
+
- Platform: X, LinkedIn, TikTok, YouTube, newsletter, or all?
|
|
30
|
+
- Goal: Awareness, conversion, recruiting, or engagement?
|
|
31
|
+
|
|
32
|
+
## Setup
|
|
33
|
+
|
|
34
|
+
If the user runs this skill often, store preferences in a `content-config.json`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"defaultPlatforms": ["x", "linkedin"],
|
|
39
|
+
"brandVoice": "direct and technical",
|
|
40
|
+
"audience": "developers and technical founders",
|
|
41
|
+
"avoidWords": ["excited", "thrilled", "game-changer"],
|
|
42
|
+
"hashtagPolicy": "max 2 per post"
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Read this config at the start of every content session. Skip the "First Questions" step for any field that's already configured.
|
|
47
|
+
|
|
48
|
+
## Rules
|
|
49
|
+
|
|
50
|
+
1. Adapt for each platform. Don't copy-paste.
|
|
51
|
+
2. Hooks matter more than summaries.
|
|
52
|
+
3. One clear idea per post.
|
|
53
|
+
4. Use specifics, not slogans.
|
|
54
|
+
5. Keep the ask small and clear.
|
|
55
|
+
|
|
56
|
+
## Platform Tips
|
|
57
|
+
|
|
58
|
+
### X
|
|
59
|
+
- Open fast
|
|
60
|
+
- One idea per tweet
|
|
61
|
+
- Keep links out of the body
|
|
62
|
+
- No hashtag spam
|
|
63
|
+
|
|
64
|
+
### LinkedIn
|
|
65
|
+
- Strong first line
|
|
66
|
+
- Short paragraphs
|
|
67
|
+
- More framing around lessons and results
|
|
68
|
+
|
|
69
|
+
### TikTok / Short Video
|
|
70
|
+
- First 3 seconds must grab attention
|
|
71
|
+
- Script around visuals
|
|
72
|
+
- One demo, one claim, one CTA
|
|
73
|
+
|
|
74
|
+
### YouTube
|
|
75
|
+
- Show the result early
|
|
76
|
+
- Structure by chapters
|
|
77
|
+
- New visual every 20-30 seconds
|
|
78
|
+
|
|
79
|
+
### Newsletter
|
|
80
|
+
- One clear theme
|
|
81
|
+
- Skimmable section titles
|
|
82
|
+
- Opening paragraph does real work
|
|
83
|
+
|
|
84
|
+
## Repurposing Flow
|
|
85
|
+
|
|
86
|
+
1. Start with one anchor piece (article, video, demo)
|
|
87
|
+
2. Pull out 3-7 separate ideas
|
|
88
|
+
3. Write platform-native version of each
|
|
89
|
+
4. Cut overlap between posts
|
|
90
|
+
5. Match CTAs to each platform
|
|
91
|
+
|
|
92
|
+
## Interaction Style
|
|
93
|
+
|
|
94
|
+
**No BS. Honest feedback only.**
|
|
95
|
+
|
|
96
|
+
This is a two-way talk:
|
|
97
|
+
- I ask you questions → you answer
|
|
98
|
+
- You ask me questions → I think hard, give you options, then answer
|
|
99
|
+
|
|
100
|
+
**When I ask you a question, I always:**
|
|
101
|
+
1. Think about it first
|
|
102
|
+
2. Give you 2-3 options with my honest take on each
|
|
103
|
+
3. Tell you which one I'd pick and why
|
|
104
|
+
4. Then ask what you think
|
|
105
|
+
|
|
106
|
+
**When you ask me something:**
|
|
107
|
+
- I give you a straight answer
|
|
108
|
+
- I tell you if a hook is weak or a post won't land
|
|
109
|
+
- I push for platform-native content, not lazy cross-posts
|
|
110
|
+
|
|
111
|
+
**Never:**
|
|
112
|
+
- Ask a question without giving options
|
|
113
|
+
- Write generic hooks like "Here's what I learned..."
|
|
114
|
+
- Say "it depends" without picking a side
|
|
115
|
+
- Skip the "this post won't get engagement because..." feedback
|
|
116
|
+
- Let hype language into social content
|
|
117
|
+
|
|
118
|
+
## Gotchas
|
|
119
|
+
|
|
120
|
+
- **Cross-posting is lazy and it shows.** A LinkedIn post copy-pasted to X looks like spam. Every platform has different norms — adapt the format, length, and hook.
|
|
121
|
+
- **Weak hooks sink good content.** "Here's what I learned about X" is invisible on any feed. Open with tension, a number, or a contrarian take.
|
|
122
|
+
- **Corporate-speak kills engagement.** "We're excited to announce" gets zero engagement. Say what you did, what happened, and why it matters.
|
|
123
|
+
- **Too many CTAs = no action.** Pick one CTA per post. "Like, share, comment, and sign up" is noise. One clear ask.
|
|
124
|
+
- **Hashtag spam on LinkedIn and X is counterproductive.** 1-3 relevant hashtags max. A wall of hashtags signals low-quality content.
|
|
125
|
+
|
|
126
|
+
## Before You Deliver
|
|
127
|
+
|
|
128
|
+
- Each draft fits its platform
|
|
129
|
+
- Hooks are specific, not generic
|
|
130
|
+
- No hype language
|
|
131
|
+
- CTAs match the content and audience
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Content Engine — Platform Examples
|
|
2
|
+
|
|
3
|
+
> Read these examples to understand what platform-native content looks like. Same idea, different format per platform.
|
|
4
|
+
|
|
5
|
+
## Source Idea
|
|
6
|
+
**"We shipped a feature that reduced API response time from 800ms to 120ms by adding a Redis cache layer."**
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## X (Twitter) — Single Post
|
|
11
|
+
> We cut our API response time from 800ms to 120ms.
|
|
12
|
+
>
|
|
13
|
+
> The fix: Redis cache in front of our heaviest query.
|
|
14
|
+
>
|
|
15
|
+
> Took 2 hours to implement. Should've done it 6 months ago.
|
|
16
|
+
|
|
17
|
+
**Why this works:** Specific numbers. Self-deprecating honesty. No hashtags.
|
|
18
|
+
|
|
19
|
+
### Bad Version
|
|
20
|
+
> 🚀 Excited to share that we've optimized our API performance! By leveraging Redis caching, we've achieved significant improvements in response times. #DevOps #Performance #Redis #Optimization
|
|
21
|
+
|
|
22
|
+
**Why this fails:** Emoji rocket, "excited to share", vague ("significant"), hashtag spam.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## X (Twitter) — Thread
|
|
27
|
+
> **1/** Our API was taking 800ms per request. Users were complaining. Here's the 2-hour fix that got us to 120ms.
|
|
28
|
+
>
|
|
29
|
+
> **2/** The problem: our /dashboard endpoint hits 6 tables, joins 3 of them, and runs a GROUP BY. On every. single. request.
|
|
30
|
+
>
|
|
31
|
+
> **3/** The fix: Redis cache with 60-second TTL. Dashboard data doesn't change that often. Users don't need real-time accuracy on a summary screen.
|
|
32
|
+
>
|
|
33
|
+
> **4/** Results after 1 week:
|
|
34
|
+
> - p99 latency: 800ms → 120ms
|
|
35
|
+
> - DB CPU: 78% → 31%
|
|
36
|
+
> - User complaints about "slow dashboard": 0
|
|
37
|
+
>
|
|
38
|
+
> **5/** Should we have done this earlier? Obviously. But we were busy building features nobody used. That's a different thread.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## LinkedIn Post
|
|
43
|
+
> Last week I spent 2 hours on a fix that should've happened 6 months ago.
|
|
44
|
+
>
|
|
45
|
+
> Our API dashboard endpoint was taking 800ms. Users were complaining, but we kept prioritizing new features.
|
|
46
|
+
>
|
|
47
|
+
> The fix was embarrassingly simple: Redis cache with a 60-second TTL.
|
|
48
|
+
>
|
|
49
|
+
> Results:
|
|
50
|
+
> → Response time: 800ms → 120ms
|
|
51
|
+
> → Database CPU: 78% → 31%
|
|
52
|
+
> → User complaints: gone
|
|
53
|
+
>
|
|
54
|
+
> The lesson isn't about Redis. It's about how easy it is to ignore performance problems when you're "too busy building."
|
|
55
|
+
>
|
|
56
|
+
> Sometimes the most impactful work is the boring work.
|
|
57
|
+
|
|
58
|
+
**Why this works:** Personal story, specific numbers, lesson at the end, short paragraphs.
|
|
59
|
+
|
|
60
|
+
### Bad Version
|
|
61
|
+
> 🎉 Thrilled to announce that our engineering team has achieved a remarkable 85% improvement in API performance! This milestone demonstrates our commitment to delivering exceptional user experiences. We leveraged cutting-edge caching technology to optimize our infrastructure. #Engineering #Innovation #TechLeadership
|
|
62
|
+
|
|
63
|
+
**Why this fails:** "Thrilled to announce", "remarkable", "commitment to delivering", hashtags, no specifics.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Newsletter Blurb
|
|
68
|
+
> **This week's win: 2-hour fix, 6x faster API**
|
|
69
|
+
>
|
|
70
|
+
> Our dashboard was slow (800ms). Turned out the endpoint was hitting 6 tables on every request. Added a Redis cache with a 60-second TTL. Now it's 120ms.
|
|
71
|
+
>
|
|
72
|
+
> Lesson: before you build the next feature, check if the last one actually works well.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: database-patterns
|
|
3
|
+
description: Database design patterns including schema design, migrations, soft deletes, and Exposed ORM. Use when creating tables, writing migrations, or implementing repositories.
|
|
4
|
+
allowed_tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Edit
|
|
8
|
+
- Glob
|
|
9
|
+
- Grep
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Database Patterns — Quick Reference
|
|
13
|
+
|
|
14
|
+
## Hard Rules
|
|
15
|
+
|
|
16
|
+
| Rule | Do | Don't |
|
|
17
|
+
|------|------|-------|
|
|
18
|
+
| Data types | TEXT | VARCHAR |
|
|
19
|
+
| Primary keys | UUID | SERIAL, BIGINT |
|
|
20
|
+
| Soft delete | deleted_at TIMESTAMP | DELETE FROM |
|
|
21
|
+
| Foreign keys | App-level validation | REFERENCES, ON DELETE CASCADE |
|
|
22
|
+
| Standard columns | id, created_at, updated_at, deleted_at | Skip any of these |
|
|
23
|
+
|
|
24
|
+
## Migration Template
|
|
25
|
+
|
|
26
|
+
SQL migration with table, trigger, and partial indexes for soft delete.
|
|
27
|
+
|
|
28
|
+
> See code-templates.md for the complete SQL template.
|
|
29
|
+
|
|
30
|
+
## Exposed Table Object
|
|
31
|
+
|
|
32
|
+
Extend `UUIDTable`, use `text()` not `varchar()`, add standard timestamp columns.
|
|
33
|
+
|
|
34
|
+
> See code-templates.md for the complete template.
|
|
35
|
+
|
|
36
|
+
## Entity Data Class
|
|
37
|
+
|
|
38
|
+
Implement `Entity<Instant>`, include all business fields + `createdAt`, `updatedAt`, `deletedAt`.
|
|
39
|
+
|
|
40
|
+
> See code-templates.md for the complete template.
|
|
41
|
+
|
|
42
|
+
## Repository Pattern
|
|
43
|
+
|
|
44
|
+
Interface + `Default*` implementation. Reads on `db.replica`, writes on `db.primary`. Soft delete via `deletedAt` update. `convert()` method maps `ResultRow` to entity.
|
|
45
|
+
|
|
46
|
+
> See code-templates.md for the full interface + implementation code.
|
|
47
|
+
|
|
48
|
+
## When Creating a New Table
|
|
49
|
+
|
|
50
|
+
Full checklist:
|
|
51
|
+
1. SQL migration file (next number in sequence)
|
|
52
|
+
2. Table object in `module-repository/table/`
|
|
53
|
+
3. Entity data class in `module-repository/entity/`
|
|
54
|
+
4. Enum/constants in `module-repository/constant/` (if needed)
|
|
55
|
+
5. Repository interface + implementation
|
|
56
|
+
6. Factory bean for repository
|
|
57
|
+
7. Repository tests
|
|
58
|
+
|
|
59
|
+
## Flyway Rules
|
|
60
|
+
|
|
61
|
+
- NEVER add a migration that fills a gap in deployed sequence
|
|
62
|
+
- NEVER rename an already-deployed migration file
|
|
63
|
+
- Migration numbers must be sequential from the latest
|
|
64
|
+
- Keep migrations simple and focused (one table per migration)
|
|
65
|
+
|
|
66
|
+
## Gotchas
|
|
67
|
+
|
|
68
|
+
- **Only `id` uses `.value` -- everything else is direct.** `row[Table.id].value` gives UUID, but `row[Table.projectId]` already returns UUID. Adding `.value` to non-id columns causes compile errors.
|
|
69
|
+
- **`gen_random_uuid()` vs `uuid_generate_v4()` -- pick one per project.** Mixing them works but confuses code review. Check existing migrations for which one the project uses.
|
|
70
|
+
- **Don't re-declare `createdAt`, `updatedAt`, `deletedAt` if extending SoftDeleteTable.** They're inherited. Declaring them again causes duplicate column errors.
|
|
71
|
+
- **Forgetting `WHERE deleted_at IS NULL` on indexes wastes space.** Every index on a soft-delete table should be partial. Full indexes include dead records nobody queries.
|
|
72
|
+
- **Text columns that hold JSON should still use `text()` in Exposed.** JSONB in Postgres, `text()` in Kotlin, serialize/deserialize in the entity layer.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Database Patterns — Code Templates
|
|
2
|
+
|
|
3
|
+
> This file is referenced by SKILL.md. Read it when writing migrations, table objects, entities, or repositories.
|
|
4
|
+
|
|
5
|
+
## SQL Migration Template
|
|
6
|
+
|
|
7
|
+
```sql
|
|
8
|
+
CREATE TABLE {table_name} (
|
|
9
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
10
|
+
-- business columns here, always TEXT not VARCHAR
|
|
11
|
+
name TEXT NOT NULL,
|
|
12
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
13
|
+
description TEXT,
|
|
14
|
+
-- standard columns (required on ALL tables)
|
|
15
|
+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
16
|
+
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
17
|
+
deleted_at TIMESTAMP
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
-- Updated_at trigger (required)
|
|
21
|
+
CREATE TRIGGER set_{table_name}_updated_at
|
|
22
|
+
BEFORE UPDATE ON {table_name}
|
|
23
|
+
FOR EACH ROW
|
|
24
|
+
EXECUTE FUNCTION update_updated_at_column();
|
|
25
|
+
|
|
26
|
+
-- Indexes (include deleted_at IS NULL for soft delete)
|
|
27
|
+
CREATE INDEX idx_{table_name}_status
|
|
28
|
+
ON {table_name} (status)
|
|
29
|
+
WHERE deleted_at IS NULL;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Exposed Table Object
|
|
33
|
+
|
|
34
|
+
```kotlin
|
|
35
|
+
object EmployeesTable : UUIDTable("employees") {
|
|
36
|
+
val name = text("name")
|
|
37
|
+
val email = text("email")
|
|
38
|
+
val status = text("status").default(EmployeeStatus.ACTIVE.value)
|
|
39
|
+
val description = text("description").nullable()
|
|
40
|
+
val createdAt = timestamp("created_at")
|
|
41
|
+
val updatedAt = timestamp("updated_at").nullable()
|
|
42
|
+
val deletedAt = timestamp("deleted_at").nullable()
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Entity Data Class
|
|
47
|
+
|
|
48
|
+
```kotlin
|
|
49
|
+
data class EmployeeEntity(
|
|
50
|
+
override val id: UUID = UUID.randomUUID(),
|
|
51
|
+
val name: String,
|
|
52
|
+
val email: String,
|
|
53
|
+
val status: String,
|
|
54
|
+
val description: String?,
|
|
55
|
+
override val createdAt: Instant,
|
|
56
|
+
override val updatedAt: Instant?,
|
|
57
|
+
override val deletedAt: Instant?
|
|
58
|
+
) : Entity<Instant>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Repository Pattern
|
|
62
|
+
|
|
63
|
+
```kotlin
|
|
64
|
+
interface EmployeeRepository {
|
|
65
|
+
fun insert(entity: EmployeeEntity): EmployeeEntity
|
|
66
|
+
fun update(id: UUID, name: String?, status: String?): EmployeeEntity?
|
|
67
|
+
fun byId(id: UUID): EmployeeEntity?
|
|
68
|
+
fun byIds(ids: List<UUID>): List<EmployeeEntity>
|
|
69
|
+
fun deleteById(id: UUID): EmployeeEntity?
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
class DefaultEmployeeRepository(
|
|
73
|
+
private val db: DatabaseContext
|
|
74
|
+
) : EmployeeRepository {
|
|
75
|
+
|
|
76
|
+
override fun byId(id: UUID): EmployeeEntity? {
|
|
77
|
+
return transaction(db.replica) {
|
|
78
|
+
EmployeesTable
|
|
79
|
+
.selectAll()
|
|
80
|
+
.where { (EmployeesTable.id eq id) and EmployeesTable.deletedAt.isNull() }
|
|
81
|
+
.singleOrNull()
|
|
82
|
+
?.let { convert(it) }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
override fun deleteById(id: UUID): EmployeeEntity? {
|
|
87
|
+
return transaction(db.primary) {
|
|
88
|
+
EmployeesTable.update(
|
|
89
|
+
where = { (EmployeesTable.id eq id) and EmployeesTable.deletedAt.isNull() }
|
|
90
|
+
) {
|
|
91
|
+
it[deletedAt] = Instant.now()
|
|
92
|
+
it[updatedAt] = Instant.now()
|
|
93
|
+
}
|
|
94
|
+
// Return the soft-deleted entity
|
|
95
|
+
EmployeesTable
|
|
96
|
+
.selectAll()
|
|
97
|
+
.where { EmployeesTable.id eq id }
|
|
98
|
+
.singleOrNull()
|
|
99
|
+
?.let { convert(it) }
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private fun convert(row: ResultRow) = EmployeeEntity(
|
|
104
|
+
id = row[EmployeesTable.id].value,
|
|
105
|
+
name = row[EmployeesTable.name],
|
|
106
|
+
email = row[EmployeesTable.email],
|
|
107
|
+
status = row[EmployeesTable.status],
|
|
108
|
+
description = row[EmployeesTable.description],
|
|
109
|
+
createdAt = row[EmployeesTable.createdAt],
|
|
110
|
+
updatedAt = row[EmployeesTable.updatedAt],
|
|
111
|
+
deletedAt = row[EmployeesTable.deletedAt]
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
```
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: database-table-creator
|
|
3
|
+
description: Creates database table with full Kotlin synchronization (SQL migration → Table → Entity → Repository → Tests). Use when adding new database tables or entities.
|
|
4
|
+
allowed_tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Edit
|
|
8
|
+
- Bash
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Database Table Creator Skill
|
|
14
|
+
|
|
15
|
+
Creates complete database table implementation with SQL migration, Kotlin code, and comprehensive tests.
|
|
16
|
+
|
|
17
|
+
## What This Skill Does
|
|
18
|
+
|
|
19
|
+
Generates:
|
|
20
|
+
1. **SQL Migration** - PostgreSQL table with soft deletes, indexes, triggers
|
|
21
|
+
2. **Kotlin Table Object** - Exposed ORM table definition (extends UUIDTable)
|
|
22
|
+
3. **Entity Data Class** - Kotlin entity implementing Entity<Instant>
|
|
23
|
+
4. **Repository Interface + Implementation** - CRUD operations with soft delete
|
|
24
|
+
5. **Repository Tests** - Comprehensive test coverage (7+ tests)
|
|
25
|
+
6. **Factory Bean** - Dependency injection registration
|
|
26
|
+
|
|
27
|
+
## Critical Rules
|
|
28
|
+
|
|
29
|
+
### Database Design (rules/database/SCHEMA.md)
|
|
30
|
+
|
|
31
|
+
**SQL Requirements**:
|
|
32
|
+
- ❌ NO foreign key constraints (NEVER use REFERENCES or FOREIGN KEY)
|
|
33
|
+
- ✅ Use TEXT for strings (NOT VARCHAR)
|
|
34
|
+
- ✅ Include: id (UUID), created_at, updated_at, deleted_at
|
|
35
|
+
- ✅ ALL indexes MUST have `WHERE deleted_at IS NULL`
|
|
36
|
+
- ✅ Add soft delete index: `WHERE deleted_at IS NOT NULL`
|
|
37
|
+
- ✅ Add update trigger for updated_at
|
|
38
|
+
|
|
39
|
+
**Kotlin Requirements**:
|
|
40
|
+
- ✅ Table MUST extend `UUIDTable` (NOT `Table`)
|
|
41
|
+
- ✅ Entity MUST implement `Entity<Instant>`
|
|
42
|
+
- ✅ ALL queries MUST filter `deletedAt.isNull()`
|
|
43
|
+
- ❌ NO `!!` operators (forbidden by pre-commit hooks)
|
|
44
|
+
- ✅ Soft delete only (set deletedAt, never hard delete)
|
|
45
|
+
|
|
46
|
+
## Workflow
|
|
47
|
+
|
|
48
|
+
### Step 1: Create SQL Migration
|
|
49
|
+
|
|
50
|
+
Location: `database-migration/sql/{number}-{description}.sql`
|
|
51
|
+
|
|
52
|
+
```sql
|
|
53
|
+
-- ============================================================================
|
|
54
|
+
-- Description: [Describe what this migration does]
|
|
55
|
+
-- Table: {table_name}
|
|
56
|
+
-- ============================================================================
|
|
57
|
+
|
|
58
|
+
CREATE TABLE {table_name} (
|
|
59
|
+
-- Primary key (REQUIRED)
|
|
60
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
61
|
+
|
|
62
|
+
-- Business columns
|
|
63
|
+
name TEXT NOT NULL,
|
|
64
|
+
email TEXT,
|
|
65
|
+
status TEXT DEFAULT 'active',
|
|
66
|
+
user_id UUID,
|
|
67
|
+
count INTEGER DEFAULT 0,
|
|
68
|
+
is_active BOOLEAN DEFAULT true,
|
|
69
|
+
metadata JSONB,
|
|
70
|
+
|
|
71
|
+
-- Standard timestamps (REQUIRED)
|
|
72
|
+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
73
|
+
updated_at TIMESTAMP,
|
|
74
|
+
deleted_at TIMESTAMP
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
-- Unique index (allows duplicate soft-deleted records)
|
|
78
|
+
CREATE UNIQUE INDEX idx_{table_name}_email_unique
|
|
79
|
+
ON {table_name}(email) WHERE deleted_at IS NULL;
|
|
80
|
+
|
|
81
|
+
-- Foreign key index (NO FK constraint, just index)
|
|
82
|
+
CREATE INDEX idx_{table_name}_user_id
|
|
83
|
+
ON {table_name}(user_id) WHERE deleted_at IS NULL;
|
|
84
|
+
|
|
85
|
+
-- Soft delete index (REQUIRED)
|
|
86
|
+
CREATE INDEX idx_{table_name}_deleted_at
|
|
87
|
+
ON {table_name}(deleted_at) WHERE deleted_at IS NOT NULL;
|
|
88
|
+
|
|
89
|
+
-- Update trigger (REQUIRED)
|
|
90
|
+
CREATE TRIGGER update_{table_name}_updated_at
|
|
91
|
+
BEFORE UPDATE ON {table_name}
|
|
92
|
+
FOR EACH ROW
|
|
93
|
+
EXECUTE FUNCTION update_updated_at();
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Critical**:
|
|
97
|
+
- Use TEXT not VARCHAR
|
|
98
|
+
- NO REFERENCES or FOREIGN KEY
|
|
99
|
+
- ALL indexes have WHERE clause
|
|
100
|
+
- Soft delete index required
|
|
101
|
+
- Update trigger required
|
|
102
|
+
|
|
103
|
+
### Step 2: Run Migration
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
./gradlew :app:module-repository:flywayMigrate
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Verify success before proceeding.
|
|
110
|
+
|
|
111
|
+
### Steps 3-10: Kotlin Implementation
|
|
112
|
+
|
|
113
|
+
> See `kotlin-templates.md` for all Kotlin code templates (Table, Entity, Repository, Factory Bean, Tests).
|
|
114
|
+
|
|
115
|
+
Follow this order:
|
|
116
|
+
1. **Step 3** — Table object (extends `UUIDTable`, use `text()` not `varchar()`)
|
|
117
|
+
2. **Step 4** — Entity data class (implements `Entity<Instant>`)
|
|
118
|
+
3. **Step 5** — Constants/Enums (if needed)
|
|
119
|
+
4. **Step 6** — Repository interface
|
|
120
|
+
5. **Step 7** — Repository implementation (`db.primary` for writes, `db.replica` for reads, ALWAYS filter `deletedAt.isNull()`)
|
|
121
|
+
6. **Step 8** — Factory bean registration
|
|
122
|
+
7. **Step 9** — Repository tests (minimum 7 tests, must include soft delete verification)
|
|
123
|
+
8. **Step 10** — Run tests: `./gradlew test`
|
|
124
|
+
|
|
125
|
+
## Common Mistakes to Avoid
|
|
126
|
+
|
|
127
|
+
> See `examples.md` for common mistakes and anti-patterns.
|
|
128
|
+
|
|
129
|
+
## Success Criteria
|
|
130
|
+
|
|
131
|
+
✅ SQL migration runs successfully
|
|
132
|
+
✅ Uses TEXT (not VARCHAR)
|
|
133
|
+
✅ NO foreign key constraints
|
|
134
|
+
✅ All indexes have WHERE clause
|
|
135
|
+
✅ Kotlin Table extends UUIDTable
|
|
136
|
+
✅ Entity implements Entity<Instant>
|
|
137
|
+
✅ All queries filter deletedAt.isNull()
|
|
138
|
+
✅ No !! operators
|
|
139
|
+
✅ Soft delete only (no hard delete)
|
|
140
|
+
✅ Factory bean registered
|
|
141
|
+
✅ All 7+ tests pass
|