claudient 0.1.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.
Files changed (283) hide show
  1. package/.claude-plugin/plugin.json +42 -0
  2. package/CONTEXT.md +58 -0
  3. package/README.md +165 -0
  4. package/agents/build-resolvers/de/python-resolver.md +64 -0
  5. package/agents/build-resolvers/de/typescript-resolver.md +65 -0
  6. package/agents/build-resolvers/es/python-resolver.md +64 -0
  7. package/agents/build-resolvers/es/typescript-resolver.md +65 -0
  8. package/agents/build-resolvers/fr/python-resolver.md +64 -0
  9. package/agents/build-resolvers/fr/typescript-resolver.md +65 -0
  10. package/agents/build-resolvers/nl/python-resolver.md +64 -0
  11. package/agents/build-resolvers/nl/typescript-resolver.md +65 -0
  12. package/agents/build-resolvers/python-resolver.md +62 -0
  13. package/agents/build-resolvers/typescript-resolver.md +63 -0
  14. package/agents/core/architect.md +64 -0
  15. package/agents/core/code-reviewer.md +78 -0
  16. package/agents/core/de/architect.md +66 -0
  17. package/agents/core/de/code-reviewer.md +80 -0
  18. package/agents/core/de/planner.md +63 -0
  19. package/agents/core/de/security-reviewer.md +93 -0
  20. package/agents/core/es/architect.md +66 -0
  21. package/agents/core/es/code-reviewer.md +80 -0
  22. package/agents/core/es/planner.md +63 -0
  23. package/agents/core/es/security-reviewer.md +93 -0
  24. package/agents/core/fr/architect.md +66 -0
  25. package/agents/core/fr/code-reviewer.md +80 -0
  26. package/agents/core/fr/planner.md +63 -0
  27. package/agents/core/fr/security-reviewer.md +93 -0
  28. package/agents/core/nl/architect.md +66 -0
  29. package/agents/core/nl/code-reviewer.md +80 -0
  30. package/agents/core/nl/planner.md +63 -0
  31. package/agents/core/nl/security-reviewer.md +93 -0
  32. package/agents/core/planner.md +61 -0
  33. package/agents/core/security-reviewer.md +91 -0
  34. package/guides/agent-orchestration.md +231 -0
  35. package/guides/de/agent-orchestration.md +174 -0
  36. package/guides/de/getting-started.md +164 -0
  37. package/guides/de/hooks-cookbook.md +160 -0
  38. package/guides/de/memory-management.md +153 -0
  39. package/guides/de/security.md +180 -0
  40. package/guides/de/skill-authoring.md +214 -0
  41. package/guides/de/token-optimization.md +156 -0
  42. package/guides/es/agent-orchestration.md +174 -0
  43. package/guides/es/getting-started.md +164 -0
  44. package/guides/es/hooks-cookbook.md +160 -0
  45. package/guides/es/memory-management.md +153 -0
  46. package/guides/es/security.md +180 -0
  47. package/guides/es/skill-authoring.md +214 -0
  48. package/guides/es/token-optimization.md +156 -0
  49. package/guides/fr/agent-orchestration.md +174 -0
  50. package/guides/fr/getting-started.md +164 -0
  51. package/guides/fr/hooks-cookbook.md +227 -0
  52. package/guides/fr/memory-management.md +169 -0
  53. package/guides/fr/security.md +180 -0
  54. package/guides/fr/skill-authoring.md +214 -0
  55. package/guides/fr/token-optimization.md +158 -0
  56. package/guides/getting-started.md +164 -0
  57. package/guides/hooks-cookbook.md +423 -0
  58. package/guides/memory-management.md +192 -0
  59. package/guides/nl/agent-orchestration.md +174 -0
  60. package/guides/nl/getting-started.md +164 -0
  61. package/guides/nl/hooks-cookbook.md +160 -0
  62. package/guides/nl/memory-management.md +153 -0
  63. package/guides/nl/security.md +180 -0
  64. package/guides/nl/skill-authoring.md +214 -0
  65. package/guides/nl/token-optimization.md +156 -0
  66. package/guides/security.md +229 -0
  67. package/guides/skill-authoring.md +226 -0
  68. package/guides/token-optimization.md +169 -0
  69. package/hooks/lifecycle/cost-tracker.md +49 -0
  70. package/hooks/lifecycle/cost-tracker.sh +59 -0
  71. package/hooks/lifecycle/pre-compact-save.md +56 -0
  72. package/hooks/lifecycle/pre-compact-save.sh +37 -0
  73. package/hooks/lifecycle/session-start.md +50 -0
  74. package/hooks/lifecycle/session-start.sh +47 -0
  75. package/hooks/post-tool-use/audit-log.md +53 -0
  76. package/hooks/post-tool-use/audit-log.sh +53 -0
  77. package/hooks/post-tool-use/prettier.md +53 -0
  78. package/hooks/post-tool-use/prettier.sh +49 -0
  79. package/hooks/pre-tool-use/block-dangerous.md +48 -0
  80. package/hooks/pre-tool-use/block-dangerous.sh +76 -0
  81. package/hooks/pre-tool-use/git-push-confirm.md +46 -0
  82. package/hooks/pre-tool-use/git-push-confirm.sh +36 -0
  83. package/mcp/configs/github.json +11 -0
  84. package/mcp/configs/postgres.json +11 -0
  85. package/mcp/de/recommended-servers.md +170 -0
  86. package/mcp/es/recommended-servers.md +170 -0
  87. package/mcp/fr/recommended-servers.md +170 -0
  88. package/mcp/nl/recommended-servers.md +170 -0
  89. package/mcp/recommended-servers.md +168 -0
  90. package/package.json +45 -0
  91. package/prompts/project-starters/de/fastapi-project.md +62 -0
  92. package/prompts/project-starters/de/nextjs-project.md +82 -0
  93. package/prompts/project-starters/es/fastapi-project.md +62 -0
  94. package/prompts/project-starters/es/nextjs-project.md +82 -0
  95. package/prompts/project-starters/fastapi-project.md +60 -0
  96. package/prompts/project-starters/fr/fastapi-project.md +62 -0
  97. package/prompts/project-starters/fr/nextjs-project.md +82 -0
  98. package/prompts/project-starters/nextjs-project.md +80 -0
  99. package/prompts/project-starters/nl/fastapi-project.md +62 -0
  100. package/prompts/project-starters/nl/nextjs-project.md +82 -0
  101. package/prompts/system-prompts/ai-product.md +80 -0
  102. package/prompts/system-prompts/data-pipeline.md +76 -0
  103. package/prompts/system-prompts/de/ai-product.md +82 -0
  104. package/prompts/system-prompts/de/data-pipeline.md +78 -0
  105. package/prompts/system-prompts/de/saas-backend.md +71 -0
  106. package/prompts/system-prompts/es/ai-product.md +82 -0
  107. package/prompts/system-prompts/es/data-pipeline.md +78 -0
  108. package/prompts/system-prompts/es/saas-backend.md +71 -0
  109. package/prompts/system-prompts/fr/ai-product.md +82 -0
  110. package/prompts/system-prompts/fr/data-pipeline.md +78 -0
  111. package/prompts/system-prompts/fr/saas-backend.md +71 -0
  112. package/prompts/system-prompts/nl/ai-product.md +82 -0
  113. package/prompts/system-prompts/nl/data-pipeline.md +78 -0
  114. package/prompts/system-prompts/nl/saas-backend.md +71 -0
  115. package/prompts/system-prompts/saas-backend.md +69 -0
  116. package/prompts/task-specific/changelog.md +81 -0
  117. package/prompts/task-specific/de/changelog.md +83 -0
  118. package/prompts/task-specific/de/debugging.md +78 -0
  119. package/prompts/task-specific/de/pr-description.md +69 -0
  120. package/prompts/task-specific/debugging.md +76 -0
  121. package/prompts/task-specific/es/changelog.md +83 -0
  122. package/prompts/task-specific/es/debugging.md +78 -0
  123. package/prompts/task-specific/es/pr-description.md +69 -0
  124. package/prompts/task-specific/fr/changelog.md +83 -0
  125. package/prompts/task-specific/fr/debugging.md +78 -0
  126. package/prompts/task-specific/fr/pr-description.md +69 -0
  127. package/prompts/task-specific/nl/changelog.md +83 -0
  128. package/prompts/task-specific/nl/debugging.md +78 -0
  129. package/prompts/task-specific/nl/pr-description.md +69 -0
  130. package/prompts/task-specific/pr-description.md +67 -0
  131. package/rules/common/coding-style.md +45 -0
  132. package/rules/common/de/coding-style.md +47 -0
  133. package/rules/common/de/git.md +48 -0
  134. package/rules/common/de/performance.md +40 -0
  135. package/rules/common/de/security.md +45 -0
  136. package/rules/common/de/testing.md +45 -0
  137. package/rules/common/es/coding-style.md +47 -0
  138. package/rules/common/es/git.md +48 -0
  139. package/rules/common/es/performance.md +40 -0
  140. package/rules/common/es/security.md +45 -0
  141. package/rules/common/es/testing.md +45 -0
  142. package/rules/common/fr/coding-style.md +47 -0
  143. package/rules/common/fr/git.md +48 -0
  144. package/rules/common/fr/performance.md +40 -0
  145. package/rules/common/fr/security.md +45 -0
  146. package/rules/common/fr/testing.md +45 -0
  147. package/rules/common/git.md +46 -0
  148. package/rules/common/nl/coding-style.md +47 -0
  149. package/rules/common/nl/git.md +48 -0
  150. package/rules/common/nl/performance.md +40 -0
  151. package/rules/common/nl/security.md +45 -0
  152. package/rules/common/nl/testing.md +45 -0
  153. package/rules/common/performance.md +38 -0
  154. package/rules/common/security.md +43 -0
  155. package/rules/common/testing.md +43 -0
  156. package/rules/language-specific/de/go.md +48 -0
  157. package/rules/language-specific/de/python.md +38 -0
  158. package/rules/language-specific/de/typescript.md +51 -0
  159. package/rules/language-specific/es/go.md +48 -0
  160. package/rules/language-specific/es/python.md +38 -0
  161. package/rules/language-specific/es/typescript.md +51 -0
  162. package/rules/language-specific/fr/go.md +48 -0
  163. package/rules/language-specific/fr/python.md +38 -0
  164. package/rules/language-specific/fr/typescript.md +51 -0
  165. package/rules/language-specific/go.md +46 -0
  166. package/rules/language-specific/nl/go.md +48 -0
  167. package/rules/language-specific/nl/python.md +38 -0
  168. package/rules/language-specific/nl/typescript.md +51 -0
  169. package/rules/language-specific/python.md +36 -0
  170. package/rules/language-specific/typescript.md +49 -0
  171. package/scripts/cli.js +161 -0
  172. package/scripts/link-skills.sh +35 -0
  173. package/scripts/list-skills.sh +34 -0
  174. package/skills/ai-engineering/agent-construction.md +285 -0
  175. package/skills/ai-engineering/claude-api.md +248 -0
  176. package/skills/ai-engineering/de/agent-construction.md +287 -0
  177. package/skills/ai-engineering/de/claude-api.md +250 -0
  178. package/skills/ai-engineering/es/agent-construction.md +287 -0
  179. package/skills/ai-engineering/es/claude-api.md +250 -0
  180. package/skills/ai-engineering/fr/agent-construction.md +287 -0
  181. package/skills/ai-engineering/fr/claude-api.md +250 -0
  182. package/skills/ai-engineering/nl/agent-construction.md +287 -0
  183. package/skills/ai-engineering/nl/claude-api.md +250 -0
  184. package/skills/backend/dotnet/csharp.md +304 -0
  185. package/skills/backend/dotnet/de/csharp.md +306 -0
  186. package/skills/backend/dotnet/es/csharp.md +306 -0
  187. package/skills/backend/dotnet/fr/csharp.md +306 -0
  188. package/skills/backend/dotnet/nl/csharp.md +306 -0
  189. package/skills/backend/go/de/go.md +307 -0
  190. package/skills/backend/go/es/go.md +307 -0
  191. package/skills/backend/go/fr/go.md +307 -0
  192. package/skills/backend/go/go.md +305 -0
  193. package/skills/backend/go/nl/go.md +307 -0
  194. package/skills/backend/nodejs/de/nestjs.md +274 -0
  195. package/skills/backend/nodejs/de/nextjs.md +222 -0
  196. package/skills/backend/nodejs/es/nestjs.md +274 -0
  197. package/skills/backend/nodejs/es/nextjs.md +222 -0
  198. package/skills/backend/nodejs/fr/nestjs.md +274 -0
  199. package/skills/backend/nodejs/fr/nextjs.md +222 -0
  200. package/skills/backend/nodejs/nestjs.md +272 -0
  201. package/skills/backend/nodejs/nextjs.md +220 -0
  202. package/skills/backend/nodejs/nl/nestjs.md +274 -0
  203. package/skills/backend/nodejs/nl/nextjs.md +222 -0
  204. package/skills/backend/python/de/django.md +285 -0
  205. package/skills/backend/python/de/fastapi.md +244 -0
  206. package/skills/backend/python/django.md +283 -0
  207. package/skills/backend/python/es/django.md +285 -0
  208. package/skills/backend/python/es/fastapi.md +244 -0
  209. package/skills/backend/python/fastapi.md +242 -0
  210. package/skills/backend/python/fr/django.md +285 -0
  211. package/skills/backend/python/fr/fastapi.md +244 -0
  212. package/skills/backend/python/nl/django.md +285 -0
  213. package/skills/backend/python/nl/fastapi.md +244 -0
  214. package/skills/data-ml/dbt-data-pipelines.md +155 -0
  215. package/skills/data-ml/de/dbt-data-pipelines.md +157 -0
  216. package/skills/data-ml/de/pandas-polars.md +147 -0
  217. package/skills/data-ml/de/pytorch-tensorflow.md +171 -0
  218. package/skills/data-ml/es/dbt-data-pipelines.md +157 -0
  219. package/skills/data-ml/es/pandas-polars.md +147 -0
  220. package/skills/data-ml/es/pytorch-tensorflow.md +171 -0
  221. package/skills/data-ml/fr/dbt-data-pipelines.md +157 -0
  222. package/skills/data-ml/fr/pandas-polars.md +147 -0
  223. package/skills/data-ml/fr/pytorch-tensorflow.md +171 -0
  224. package/skills/data-ml/nl/dbt-data-pipelines.md +157 -0
  225. package/skills/data-ml/nl/pandas-polars.md +147 -0
  226. package/skills/data-ml/nl/pytorch-tensorflow.md +171 -0
  227. package/skills/data-ml/pandas-polars.md +145 -0
  228. package/skills/data-ml/pytorch-tensorflow.md +169 -0
  229. package/skills/database/de/graphql.md +181 -0
  230. package/skills/database/es/graphql.md +181 -0
  231. package/skills/database/fr/graphql.md +181 -0
  232. package/skills/database/graphql.md +179 -0
  233. package/skills/database/nl/graphql.md +181 -0
  234. package/skills/devops-infra/de/docker.md +133 -0
  235. package/skills/devops-infra/de/github-actions.md +179 -0
  236. package/skills/devops-infra/de/kubernetes.md +129 -0
  237. package/skills/devops-infra/de/terraform.md +130 -0
  238. package/skills/devops-infra/docker.md +131 -0
  239. package/skills/devops-infra/es/docker.md +133 -0
  240. package/skills/devops-infra/es/github-actions.md +179 -0
  241. package/skills/devops-infra/es/kubernetes.md +129 -0
  242. package/skills/devops-infra/es/terraform.md +130 -0
  243. package/skills/devops-infra/fr/docker.md +133 -0
  244. package/skills/devops-infra/fr/github-actions.md +179 -0
  245. package/skills/devops-infra/fr/kubernetes.md +129 -0
  246. package/skills/devops-infra/fr/terraform.md +130 -0
  247. package/skills/devops-infra/github-actions.md +177 -0
  248. package/skills/devops-infra/kubernetes.md +127 -0
  249. package/skills/devops-infra/nl/docker.md +133 -0
  250. package/skills/devops-infra/nl/github-actions.md +179 -0
  251. package/skills/devops-infra/nl/kubernetes.md +129 -0
  252. package/skills/devops-infra/nl/terraform.md +130 -0
  253. package/skills/devops-infra/terraform.md +128 -0
  254. package/skills/finance-payments/de/stripe.md +187 -0
  255. package/skills/finance-payments/es/stripe.md +187 -0
  256. package/skills/finance-payments/fr/stripe.md +187 -0
  257. package/skills/finance-payments/nl/stripe.md +187 -0
  258. package/skills/finance-payments/stripe.md +185 -0
  259. package/workflows/code-review.md +151 -0
  260. package/workflows/de/code-review.md +153 -0
  261. package/workflows/de/debugging-session.md +146 -0
  262. package/workflows/de/feature-development.md +155 -0
  263. package/workflows/de/new-project-bootstrap.md +175 -0
  264. package/workflows/de/refactor-safely.md +150 -0
  265. package/workflows/debugging-session.md +144 -0
  266. package/workflows/es/code-review.md +153 -0
  267. package/workflows/es/debugging-session.md +146 -0
  268. package/workflows/es/feature-development.md +155 -0
  269. package/workflows/es/new-project-bootstrap.md +175 -0
  270. package/workflows/es/refactor-safely.md +150 -0
  271. package/workflows/feature-development.md +153 -0
  272. package/workflows/fr/code-review.md +153 -0
  273. package/workflows/fr/debugging-session.md +146 -0
  274. package/workflows/fr/feature-development.md +155 -0
  275. package/workflows/fr/new-project-bootstrap.md +175 -0
  276. package/workflows/fr/refactor-safely.md +150 -0
  277. package/workflows/new-project-bootstrap.md +173 -0
  278. package/workflows/nl/code-review.md +153 -0
  279. package/workflows/nl/debugging-session.md +146 -0
  280. package/workflows/nl/feature-development.md +155 -0
  281. package/workflows/nl/new-project-bootstrap.md +175 -0
  282. package/workflows/nl/refactor-safely.md +150 -0
  283. package/workflows/refactor-safely.md +148 -0
@@ -0,0 +1,179 @@
1
+ # GraphQL Skill
2
+
3
+ ## When to activate
4
+ - Designing a GraphQL schema (types, queries, mutations, subscriptions)
5
+ - Implementing resolvers in Node.js (Apollo Server, Pothos, GraphQL Yoga)
6
+ - Setting up Prisma with a GraphQL API
7
+ - Writing GraphQL queries and fragments for a frontend client
8
+ - Implementing cursor-based or offset pagination in GraphQL
9
+ - Setting up DataLoader for N+1 query prevention
10
+ - Adding authentication and authorization to a GraphQL API
11
+ - Debugging GraphQL performance or N+1 issues
12
+
13
+ ## When NOT to use
14
+ - REST APIs where GraphQL adds complexity without benefit (simple CRUD, webhooks, file uploads)
15
+ - gRPC or event-driven systems
16
+ - Cases where the client always needs the full response (GraphQL's field selection adds no value)
17
+
18
+ ## Instructions
19
+
20
+ ### Schema design principles
21
+ ```graphql
22
+ # Type names: PascalCase singular nouns
23
+ # Field names: camelCase
24
+ # Enums: SCREAMING_SNAKE_CASE values
25
+
26
+ type Order {
27
+ id: ID!
28
+ status: OrderStatus!
29
+ customer: Customer! # Nested type — always return the object, not just the ID
30
+ items: [OrderItem!]! # Non-null list of non-null items
31
+ totalAmount: Float!
32
+ createdAt: DateTime!
33
+ }
34
+
35
+ enum OrderStatus {
36
+ PENDING
37
+ COMPLETED
38
+ CANCELLED
39
+ }
40
+
41
+ # Queries: return nullable for single item (not found = null), non-null for lists
42
+ type Query {
43
+ order(id: ID!): Order # Nullable — null if not found
44
+ orders(filter: OrderFilter): [Order!]! # Non-null list
45
+ me: User # Nullable — null if not authenticated
46
+ }
47
+
48
+ # Mutations: always return the mutated object plus an errors array
49
+ type Mutation {
50
+ createOrder(input: CreateOrderInput!): CreateOrderPayload!
51
+ }
52
+
53
+ type CreateOrderPayload {
54
+ order: Order # Null if mutation failed
55
+ errors: [UserError!]! # Empty if successful
56
+ }
57
+
58
+ type UserError {
59
+ field: String
60
+ message: String!
61
+ }
62
+ ```
63
+
64
+ ### N+1 prevention with DataLoader
65
+ ```typescript
66
+ import DataLoader from 'dataloader';
67
+
68
+ // Create per-request — never singleton (request data isolation)
69
+ export function createLoaders() {
70
+ return {
71
+ customerLoader: new DataLoader<string, Customer>(async (ids) => {
72
+ const customers = await db.customer.findMany({
73
+ where: { id: { in: [...ids] } }
74
+ });
75
+ // Must return in same order as ids
76
+ const customerMap = new Map(customers.map(c => [c.id, c]));
77
+ return ids.map(id => customerMap.get(id) ?? new Error(`Customer ${id} not found`));
78
+ }),
79
+ };
80
+ }
81
+
82
+ // Resolver — uses loader, not direct DB call
83
+ const resolvers = {
84
+ Order: {
85
+ customer: (order, _, { loaders }) => loaders.customerLoader.load(order.customerId),
86
+ }
87
+ };
88
+ ```
89
+
90
+ ### Cursor-based pagination (preferred over offset)
91
+ ```graphql
92
+ type OrderConnection {
93
+ edges: [OrderEdge!]!
94
+ pageInfo: PageInfo!
95
+ totalCount: Int!
96
+ }
97
+
98
+ type OrderEdge {
99
+ node: Order!
100
+ cursor: String!
101
+ }
102
+
103
+ type PageInfo {
104
+ hasNextPage: Boolean!
105
+ hasPreviousPage: Boolean!
106
+ startCursor: String
107
+ endCursor: String
108
+ }
109
+
110
+ type Query {
111
+ orders(first: Int, after: String, last: Int, before: String): OrderConnection!
112
+ }
113
+ ```
114
+
115
+ ### Authorization pattern
116
+ ```typescript
117
+ // Field-level authorization in resolver
118
+ const resolvers = {
119
+ Query: {
120
+ adminStats: (_, __, { user }) => {
121
+ if (!user || user.role !== 'ADMIN') {
122
+ throw new GraphQLError('Unauthorized', {
123
+ extensions: { code: 'UNAUTHORIZED' }
124
+ });
125
+ }
126
+ return getAdminStats();
127
+ }
128
+ },
129
+ Order: {
130
+ // Object-level: only return sensitive fields to the order's owner
131
+ internalNotes: (order, _, { user }) => {
132
+ if (user?.id !== order.customerId && user?.role !== 'ADMIN') return null;
133
+ return order.internalNotes;
134
+ }
135
+ }
136
+ };
137
+ ```
138
+
139
+ ### Prisma + GraphQL pattern
140
+ ```typescript
141
+ // Resolver using Prisma — avoid over-fetching
142
+ const resolvers = {
143
+ Query: {
144
+ order: async (_, { id }, { prisma, user }) => {
145
+ const order = await prisma.order.findUnique({
146
+ where: { id },
147
+ select: {
148
+ id: true,
149
+ status: true,
150
+ customerId: true,
151
+ totalAmount: true,
152
+ createdAt: true,
153
+ // Do NOT select items here — let the items resolver handle it
154
+ // with DataLoader to avoid N+1
155
+ }
156
+ });
157
+ if (!order) return null;
158
+ if (order.customerId !== user?.id) throw new GraphQLError('Forbidden');
159
+ return order;
160
+ }
161
+ }
162
+ };
163
+ ```
164
+
165
+ ## Example
166
+
167
+ **User:** Design a GraphQL schema and resolvers for a simple e-commerce API — products, orders, and customers. Include pagination, DataLoader for customers, and mutation error handling.
168
+
169
+ **Expected output:**
170
+ - Schema: `Product`, `Order`, `Customer`, `OrderConnection`, `UserError` types
171
+ - `Query.orders` with cursor pagination returning `OrderConnection`
172
+ - `Mutation.createOrder` returning `CreateOrderPayload` with errors array
173
+ - `Order.customer` resolver using DataLoader (not direct DB query)
174
+ - `createLoaders()` function per request, batching customer lookups by ID
175
+ - Auth check: only authenticated users can view their own orders
176
+
177
+ ---
178
+
179
+ > **Work with us:** Claudient is backed by [Uitbreiden](https://uitbreiden.com/) — we build AI products and B2B solutions with developer communities. Building GraphQL APIs or AI-powered data layers? [uitbreiden.com](https://uitbreiden.com/)
@@ -0,0 +1,181 @@
1
+ > 🇳🇱 Dit is de Nederlandse vertaling. [Engelse versie](../graphql.md).
2
+
3
+ # GraphQL Skill
4
+
5
+ ## Wanneer te activeren
6
+ - Een GraphQL-schema ontwerpen (typen, queries, mutaties, subscriptions)
7
+ - Resolvers implementeren in Node.js (Apollo Server, Pothos, GraphQL Yoga)
8
+ - Prisma instellen met een GraphQL API
9
+ - GraphQL-queries en -fragments schrijven voor een frontend-client
10
+ - Cursor-gebaseerde of offset-paginering implementeren in GraphQL
11
+ - DataLoader instellen voor N+1-querypreventie
12
+ - Authenticatie en autorisatie toevoegen aan een GraphQL API
13
+ - GraphQL-prestaties of N+1-problemen debuggen
14
+
15
+ ## Wanneer NIET te gebruiken
16
+ - REST API's waar GraphQL complexiteit toevoegt zonder voordeel (eenvoudige CRUD, webhooks, bestandsuploads)
17
+ - gRPC of event-driven systemen
18
+ - Gevallen waarbij de client altijd de volledige respons nodig heeft (veldkeuze van GraphQL voegt geen waarde toe)
19
+
20
+ ## Instructies
21
+
22
+ ### Schema-ontwerpprincipes
23
+ ```graphql
24
+ # Typenamen: PascalCase enkelvoudige zelfstandige naamwoorden
25
+ # Veldnamen: camelCase
26
+ # Enums: SCREAMING_SNAKE_CASE-waarden
27
+
28
+ type Order {
29
+ id: ID!
30
+ status: OrderStatus!
31
+ customer: Customer! # Genest type — geef altijd het object terug, niet alleen het ID
32
+ items: [OrderItem!]! # Niet-null lijst van niet-null items
33
+ totalAmount: Float!
34
+ createdAt: DateTime!
35
+ }
36
+
37
+ enum OrderStatus {
38
+ PENDING
39
+ COMPLETED
40
+ CANCELLED
41
+ }
42
+
43
+ # Queries: retourneer nullable voor enkelvoudig item (niet gevonden = null), niet-null voor lijsten
44
+ type Query {
45
+ order(id: ID!): Order # Nullable — null als niet gevonden
46
+ orders(filter: OrderFilter): [Order!]! # Niet-null lijst
47
+ me: User # Nullable — null als niet geauthenticeerd
48
+ }
49
+
50
+ # Mutaties: geef altijd het gemuteerde object terug plus een errors-array
51
+ type Mutation {
52
+ createOrder(input: CreateOrderInput!): CreateOrderPayload!
53
+ }
54
+
55
+ type CreateOrderPayload {
56
+ order: Order # Null als mutatie mislukte
57
+ errors: [UserError!]! # Leeg als geslaagd
58
+ }
59
+
60
+ type UserError {
61
+ field: String
62
+ message: String!
63
+ }
64
+ ```
65
+
66
+ ### N+1-preventie met DataLoader
67
+ ```typescript
68
+ import DataLoader from 'dataloader';
69
+
70
+ // Maak per request — nooit singleton (aanvraagdata-isolatie)
71
+ export function createLoaders() {
72
+ return {
73
+ customerLoader: new DataLoader<string, Customer>(async (ids) => {
74
+ const customers = await db.customer.findMany({
75
+ where: { id: { in: [...ids] } }
76
+ });
77
+ // Moet in dezelfde volgorde worden geretourneerd als ids
78
+ const customerMap = new Map(customers.map(c => [c.id, c]));
79
+ return ids.map(id => customerMap.get(id) ?? new Error(`Customer ${id} not found`));
80
+ }),
81
+ };
82
+ }
83
+
84
+ // Resolver — gebruikt loader, geen directe DB-aanroep
85
+ const resolvers = {
86
+ Order: {
87
+ customer: (order, _, { loaders }) => loaders.customerLoader.load(order.customerId),
88
+ }
89
+ };
90
+ ```
91
+
92
+ ### Cursor-gebaseerde paginering (voorkeur boven offset)
93
+ ```graphql
94
+ type OrderConnection {
95
+ edges: [OrderEdge!]!
96
+ pageInfo: PageInfo!
97
+ totalCount: Int!
98
+ }
99
+
100
+ type OrderEdge {
101
+ node: Order!
102
+ cursor: String!
103
+ }
104
+
105
+ type PageInfo {
106
+ hasNextPage: Boolean!
107
+ hasPreviousPage: Boolean!
108
+ startCursor: String
109
+ endCursor: String
110
+ }
111
+
112
+ type Query {
113
+ orders(first: Int, after: String, last: Int, before: String): OrderConnection!
114
+ }
115
+ ```
116
+
117
+ ### Autorisatiepatroon
118
+ ```typescript
119
+ // Veldniveau-autorisatie in resolver
120
+ const resolvers = {
121
+ Query: {
122
+ adminStats: (_, __, { user }) => {
123
+ if (!user || user.role !== 'ADMIN') {
124
+ throw new GraphQLError('Unauthorized', {
125
+ extensions: { code: 'UNAUTHORIZED' }
126
+ });
127
+ }
128
+ return getAdminStats();
129
+ }
130
+ },
131
+ Order: {
132
+ // Objectniveau: geef gevoelige velden alleen terug aan de eigenaar van de bestelling
133
+ internalNotes: (order, _, { user }) => {
134
+ if (user?.id !== order.customerId && user?.role !== 'ADMIN') return null;
135
+ return order.internalNotes;
136
+ }
137
+ }
138
+ };
139
+ ```
140
+
141
+ ### Prisma + GraphQL-patroon
142
+ ```typescript
143
+ // Resolver met Prisma — vermijd over-fetching
144
+ const resolvers = {
145
+ Query: {
146
+ order: async (_, { id }, { prisma, user }) => {
147
+ const order = await prisma.order.findUnique({
148
+ where: { id },
149
+ select: {
150
+ id: true,
151
+ status: true,
152
+ customerId: true,
153
+ totalAmount: true,
154
+ createdAt: true,
155
+ // Selecteer hier GEEN items — laat de items-resolver dit afhandelen
156
+ // met DataLoader om N+1 te vermijden
157
+ }
158
+ });
159
+ if (!order) return null;
160
+ if (order.customerId !== user?.id) throw new GraphQLError('Forbidden');
161
+ return order;
162
+ }
163
+ }
164
+ };
165
+ ```
166
+
167
+ ## Voorbeeld
168
+
169
+ **Gebruiker:** Ontwerp een GraphQL-schema en resolvers voor een eenvoudige e-commerce API — producten, bestellingen en klanten. Inclusief paginering, DataLoader voor klanten en afhandeling van mutatiefouten.
170
+
171
+ **Verwachte output:**
172
+ - Schema: typen `Product`, `Order`, `Customer`, `OrderConnection`, `UserError`
173
+ - `Query.orders` met cursor-paginering die `OrderConnection` retourneert
174
+ - `Mutation.createOrder` die `CreateOrderPayload` retourneert met errors-array
175
+ - `Order.customer`-resolver met DataLoader (geen directe DB-query)
176
+ - `createLoaders()`-functie per aanvraag, klant-lookups batchen op ID
177
+ - Auth-controle: alleen geauthenticeerde gebruikers kunnen hun eigen bestellingen bekijken
178
+
179
+ ---
180
+
181
+ > **Werk met ons:** Claudient wordt ondersteund door [Uitbreiden](https://uitbreiden.com/) — we bouwen AI-producten en B2B-oplossingen met ontwikkelaarsgemeenschappen. GraphQL API's of AI-aangedreven datalaag bouwen? [uitbreiden.com](https://uitbreiden.com/)
@@ -0,0 +1,133 @@
1
+ > 🇩🇪 Dies ist die deutsche Übersetzung. [Englische Version](../docker.md).
2
+
3
+ # Docker Skill
4
+
5
+ ## Wann aktivieren
6
+ - Dockerfiles für die Produktion schreiben oder optimieren
7
+ - Multi-Stage-Builds zur Reduzierung der Image-Größe einrichten
8
+ - Docker Compose-Dateien für die lokale Entwicklung schreiben
9
+ - Container-Startfehler oder Layer-Cache-Probleme debuggen
10
+ - Nicht-Root-Benutzer, Health-Checks und Image-Sicherheit konfigurieren
11
+ - .dockerignore für effiziente Builds einrichten
12
+ - Build-Skripte oder CI/CD Docker-Build-Pipelines schreiben
13
+
14
+ ## Wann NICHT verwenden
15
+ - Kubernetes-Manifeste (Kubernetes Skill verwenden)
16
+ - Buildpacks (Heroku, Cloud Native Buildpacks) — anderes Build-System
17
+ - Virtuelle Maschinen bereitstellen (andere Abstraktionsebene)
18
+ - Nix-basierte reproduzierbare Builds
19
+
20
+ ## Anweisungen
21
+
22
+ ### Produktions-Dockerfile-Struktur
23
+ Für kompilierte Sprachen und Node.js immer Multi-Stage-Builds verwenden:
24
+
25
+ ```dockerfile
26
+ # Stage 1: Build
27
+ FROM node:20-alpine AS builder
28
+ WORKDIR /app
29
+ COPY package*.json ./
30
+ RUN npm ci --only=production
31
+
32
+ # Stage 2: Runtime — minimales Image
33
+ FROM node:20-alpine AS runtime
34
+ RUN addgroup -S appgroup && adduser -S appuser -G appgroup
35
+ WORKDIR /app
36
+ COPY --from=builder /app/node_modules ./node_modules
37
+ COPY . .
38
+ USER appuser
39
+ EXPOSE 8080
40
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
41
+ CMD wget -qO- http://localhost:8080/healthz || exit 1
42
+ CMD ["node", "server.js"]
43
+ ```
44
+
45
+ ### Sicherheitsregeln
46
+ - Niemals als Root in der Produktion ausführen — immer einen Nicht-Root-Benutzer erstellen und zu diesem wechseln
47
+ - Niemals `latest`-Tag verwenden — auf eine spezifische Version oder einen Digest pinnen
48
+ - Alpine oder distroless-Basis-Images gegenüber vollem Debian/Ubuntu bevorzugen
49
+ - Niemals `.env`-Dateien in das Image kopieren — Secrets als Laufzeit-Umgebungsvariablen übergeben
50
+ - Images mit `docker scout` oder Trivy scannen, bevor sie in die Produktion gepusht werden
51
+
52
+ ### Layer-Cache-Optimierung
53
+ Dockerfile-Anweisungen von am wenigsten bis am häufigsten geändert ordnen:
54
+ 1. Basis-Image (ändert sich selten)
55
+ 2. System-Abhängigkeiten (`apt-get`, `apk add`)
56
+ 3. Paketmanager-Dateien (`package.json`, `requirements.txt`)
57
+ 4. Paket-Installation (`npm ci`, `pip install`)
58
+ 5. Anwendungscode (`COPY . .`) — ändert sich am häufigsten, muss zuletzt stehen
59
+
60
+ ### .dockerignore — immer einschließen
61
+ ```
62
+ node_modules/
63
+ .git/
64
+ .env
65
+ .env.*
66
+ *.md
67
+ Dockerfile*
68
+ docker-compose*
69
+ .dockerignore
70
+ coverage/
71
+ .nyc_output/
72
+ __pycache__/
73
+ *.pyc
74
+ .pytest_cache/
75
+ ```
76
+
77
+ ### Docker Compose für die lokale Entwicklung
78
+ ```yaml
79
+ services:
80
+ app:
81
+ build:
82
+ context: .
83
+ target: builder # Build-Stage verwenden, nicht Runtime-Stage lokal
84
+ volumes:
85
+ - .:/app # Hot Reload
86
+ - /app/node_modules # Container node_modules nicht überschreiben
87
+ ports:
88
+ - "8080:8080"
89
+ environment:
90
+ - NODE_ENV=development
91
+ depends_on:
92
+ db:
93
+ condition: service_healthy
94
+
95
+ db:
96
+ image: postgres:16-alpine
97
+ environment:
98
+ POSTGRES_USER: app
99
+ POSTGRES_PASSWORD: dev_password # Nur Dev — niemals Produktion
100
+ POSTGRES_DB: appdb
101
+ ports:
102
+ - "5432:5432"
103
+ healthcheck:
104
+ test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
105
+ interval: 5s
106
+ timeout: 5s
107
+ retries: 5
108
+ volumes:
109
+ - postgres_data:/var/lib/postgresql/data
110
+
111
+ volumes:
112
+ postgres_data:
113
+ ```
114
+
115
+ ### Häufige Build-Fehler
116
+ - `COPY` schlägt lautlos fehl, wenn die Quelle nicht existiert — prüfen, ob `.dockerignore` benötigte Dateien ausschließt
117
+ - Layer-Cache unerwartet invalidiert — prüfen, ob ein `COPY` vor den Install-Schritten geänderte Dateien einbezieht
118
+ - Zugriff verweigert zur Laufzeit — Dateibesitz beim Verwenden von `COPY --from` mit einem Nicht-Root-Benutzer prüfen
119
+
120
+ ## Beispiel
121
+
122
+ **Benutzer:** Ein Produktions-Dockerfile für eine Python FastAPI-App mit Multi-Stage-Build, Nicht-Root-Benutzer und Health-Check schreiben.
123
+
124
+ **Erwartete Ausgabe:**
125
+ - Stage 1 (builder): `python:3.12-slim`, Abhängigkeiten mit `pip install --no-cache-dir` installieren
126
+ - Stage 2 (runtime): `python:3.12-slim`, Nicht-Root-Benutzer, nur Wheels/Deps vom Builder + App-Code kopieren
127
+ - `HEALTHCHECK` trifft `/healthz`-Endpunkt
128
+ - `CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]`
129
+ - `.dockerignore` deckt `__pycache__`, `.env`, `.git`, `*.pyc` ab
130
+
131
+ ---
132
+
133
+ > **Mit uns arbeiten:** Claudient wird von [Uitbreiden](https://uitbreiden.com/) unterstützt — wir bauen KI-Produkte und B2B-Lösungen mit Entwickler-Communities. KI-Workloads containerisieren oder cloud-native Systeme bauen? [uitbreiden.com](https://uitbreiden.com/)
@@ -0,0 +1,179 @@
1
+ > 🇩🇪 Dies ist die deutsche Übersetzung. [Englische Version](../github-actions.md).
2
+
3
+ # GitHub Actions Skill
4
+
5
+ ## Wann aktivieren
6
+ - CI/CD-Pipelines für Tests, Linting, Build und Deployment schreiben
7
+ - Matrix-Builds über mehrere Betriebssysteme oder Sprachversionen einrichten
8
+ - Umgebungsschutzregeln und Deployment-Gates konfigurieren
9
+ - Wiederverwendbare Workflows oder zusammengesetzte Actions schreiben
10
+ - Docker-Build und Push zu einer Container-Registry einrichten
11
+ - OIDC-Authentifizierung bei Cloud-Providern konfigurieren (keine langlebigen Secrets)
12
+ - Fehlschlagende Workflows debuggen oder Workflow-Syntaxfehler verstehen
13
+ - Caching für Abhängigkeiten einrichten (npm, pip, Go-Module)
14
+
15
+ ## Wann NICHT verwenden
16
+ - GitLab CI, CircleCI, Jenkins — andere Pipeline-Systeme
17
+ - Lokale Entwicklungsautomatisierung (Makefile oder Skripte verwenden)
18
+ - Cron-Jobs, die nicht an ein Repository gebunden sind (Cloud-Scheduler verwenden)
19
+
20
+ ## Anweisungen
21
+
22
+ ### Workflow-Dateistruktur
23
+ ```yaml
24
+ name: CI
25
+
26
+ on:
27
+ push:
28
+ branches: [main]
29
+ pull_request:
30
+ branches: [main]
31
+
32
+ # Explizite Berechtigungen — niemals Standard write-all verwenden
33
+ permissions:
34
+ contents: read
35
+ pull-requests: write # Nur wenn benötigt (z.B. Kommentare posten)
36
+
37
+ jobs:
38
+ test:
39
+ runs-on: ubuntu-latest
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+ - name: Set up Node.js
43
+ uses: actions/setup-node@v4
44
+ with:
45
+ node-version: '20'
46
+ cache: 'npm'
47
+ - run: npm ci
48
+ - run: npm test
49
+ ```
50
+
51
+ ### Berechtigungen — immer explizit
52
+ Niemals `permissions: write-all` als Standard verwenden. Immer Mindestberechtigungen deklarieren:
53
+ ```yaml
54
+ permissions:
55
+ contents: read # Repository lesen
56
+ packages: write # In GitHub Container Registry pushen
57
+ id-token: write # OIDC für Cloud-Auth
58
+ pull-requests: write # Kommentare zu PRs
59
+ ```
60
+
61
+ ### Secrets — OIDC über langlebige Anmeldedaten
62
+ OIDC (OpenID Connect) für Cloud-Authentifizierung verwenden — keine gespeicherten Secrets:
63
+
64
+ ```yaml
65
+ # AWS OIDC — kein AWS_ACCESS_KEY_ID erforderlich
66
+ - name: Configure AWS credentials
67
+ uses: aws-actions/configure-aws-credentials@v4
68
+ with:
69
+ role-to-assume: arn:aws:iam::123456789:role/github-actions-role
70
+ aws-region: eu-west-1
71
+
72
+ # GCP OIDC
73
+ - name: Authenticate to GCP
74
+ uses: google-github-actions/auth@v2
75
+ with:
76
+ workload_identity_provider: projects/123/locations/global/workloadIdentityPools/pool/providers/github
77
+ service_account: deploy@project.iam.gserviceaccount.com
78
+ ```
79
+
80
+ ### Abhängigkeits-Caching
81
+ Abhängigkeiten immer cachen, um die Build-Zeit zu verkürzen:
82
+ ```yaml
83
+ # Node.js
84
+ - uses: actions/setup-node@v4
85
+ with:
86
+ node-version: '20'
87
+ cache: 'npm' # Eingebautes Caching — kein manueller Cache-Schritt erforderlich
88
+
89
+ # Python
90
+ - uses: actions/setup-python@v5
91
+ with:
92
+ python-version: '3.12'
93
+ cache: 'pip'
94
+
95
+ # Go
96
+ - uses: actions/setup-go@v5
97
+ with:
98
+ go-version: '1.22'
99
+ cache: true
100
+ ```
101
+
102
+ ### Umgebungs-Gates für Produktions-Deployments
103
+ ```yaml
104
+ jobs:
105
+ deploy-production:
106
+ environment: production # Referenziert GitHub Environment mit Schutzregeln
107
+ needs: [test, build]
108
+ runs-on: ubuntu-latest
109
+ steps:
110
+ - name: Deploy
111
+ run: ./scripts/deploy.sh
112
+ ```
113
+
114
+ Umgebungsschutzregeln in den GitHub-Einstellungen einrichten:
115
+ - Erforderliche Reviewer für Produktions-Deployments
116
+ - Wartezeit zwischen Staging und Produktion
117
+ - Auf spezifische Branches beschränken (nur `main`)
118
+
119
+ ### Matrix-Builds
120
+ ```yaml
121
+ jobs:
122
+ test:
123
+ strategy:
124
+ matrix:
125
+ node-version: [18, 20, 22]
126
+ os: [ubuntu-latest, windows-latest]
127
+ fail-fast: false # Nicht alle bei erstem Fehler abbrechen
128
+ runs-on: ${{ matrix.os }}
129
+ steps:
130
+ - uses: actions/checkout@v4
131
+ - uses: actions/setup-node@v4
132
+ with:
133
+ node-version: ${{ matrix.node-version }}
134
+ ```
135
+
136
+ ### Wiederverwendbare Workflows
137
+ ```yaml
138
+ # .github/workflows/deploy.yml — wiederverwendbar
139
+ on:
140
+ workflow_call:
141
+ inputs:
142
+ environment:
143
+ required: true
144
+ type: string
145
+ secrets:
146
+ deploy-token:
147
+ required: true
148
+
149
+ # Aufrufer
150
+ jobs:
151
+ deploy:
152
+ uses: ./.github/workflows/deploy.yml
153
+ with:
154
+ environment: production
155
+ secrets:
156
+ deploy-token: ${{ secrets.DEPLOY_TOKEN }}
157
+ ```
158
+
159
+ ### Häufige Fehler
160
+ - `actions/checkout@v4` fehlt — immer als erster Schritt
161
+ - Secrets nicht zugänglich in Forks — `pull_request_target` vorsichtig verwenden (Sicherheitsrisiko)
162
+ - Cache nicht getroffen — Schlüssel muss exakt übereinstimmen; `restore-keys` als Fallback verwenden
163
+ - OIDC schlägt fehl — Trust Policy beim Cloud-Provider prüfen, ob das Repository und der Branch erlaubt sind
164
+
165
+ ## Beispiel
166
+
167
+ **Benutzer:** Eine CI/CD-Pipeline für eine Node.js-App schreiben: Tests bei PRs ausführen, Docker-Image beim Merge zu main bauen und pushen, mit einem manuellen Genehmigungsgate in der Produktion deployen.
168
+
169
+ **Erwartete Ausgabe:**
170
+ - `on: push/pull_request`-Trigger
171
+ - `test`-Job: checkout, setup-node mit Cache, `npm ci`, `npm test`
172
+ - `build`-Job (beim Push zu main, benötigt test): Docker-Build + Push zu GHCR mit OIDC
173
+ - `deploy`-Job: `environment: production` (erfordert Genehmigung), ruft Deploy-Skript auf
174
+ - Expliziter `permissions:`-Block — Mindestanforderungen
175
+ - Keine hartcodierten Secrets — OIDC für Registry-Auth
176
+
177
+ ---
178
+
179
+ > **Mit uns arbeiten:** Claudient wird von [Uitbreiden](https://uitbreiden.com/) unterstützt — wir bauen KI-Produkte und B2B-Lösungen mit Entwickler-Communities. CI/CD für KI-Produkte oder Cloud-Deployments aufbauen? [uitbreiden.com](https://uitbreiden.com/)