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.
- package/.claude-plugin/plugin.json +42 -0
- package/CONTEXT.md +58 -0
- package/README.md +165 -0
- package/agents/build-resolvers/de/python-resolver.md +64 -0
- package/agents/build-resolvers/de/typescript-resolver.md +65 -0
- package/agents/build-resolvers/es/python-resolver.md +64 -0
- package/agents/build-resolvers/es/typescript-resolver.md +65 -0
- package/agents/build-resolvers/fr/python-resolver.md +64 -0
- package/agents/build-resolvers/fr/typescript-resolver.md +65 -0
- package/agents/build-resolvers/nl/python-resolver.md +64 -0
- package/agents/build-resolvers/nl/typescript-resolver.md +65 -0
- package/agents/build-resolvers/python-resolver.md +62 -0
- package/agents/build-resolvers/typescript-resolver.md +63 -0
- package/agents/core/architect.md +64 -0
- package/agents/core/code-reviewer.md +78 -0
- package/agents/core/de/architect.md +66 -0
- package/agents/core/de/code-reviewer.md +80 -0
- package/agents/core/de/planner.md +63 -0
- package/agents/core/de/security-reviewer.md +93 -0
- package/agents/core/es/architect.md +66 -0
- package/agents/core/es/code-reviewer.md +80 -0
- package/agents/core/es/planner.md +63 -0
- package/agents/core/es/security-reviewer.md +93 -0
- package/agents/core/fr/architect.md +66 -0
- package/agents/core/fr/code-reviewer.md +80 -0
- package/agents/core/fr/planner.md +63 -0
- package/agents/core/fr/security-reviewer.md +93 -0
- package/agents/core/nl/architect.md +66 -0
- package/agents/core/nl/code-reviewer.md +80 -0
- package/agents/core/nl/planner.md +63 -0
- package/agents/core/nl/security-reviewer.md +93 -0
- package/agents/core/planner.md +61 -0
- package/agents/core/security-reviewer.md +91 -0
- package/guides/agent-orchestration.md +231 -0
- package/guides/de/agent-orchestration.md +174 -0
- package/guides/de/getting-started.md +164 -0
- package/guides/de/hooks-cookbook.md +160 -0
- package/guides/de/memory-management.md +153 -0
- package/guides/de/security.md +180 -0
- package/guides/de/skill-authoring.md +214 -0
- package/guides/de/token-optimization.md +156 -0
- package/guides/es/agent-orchestration.md +174 -0
- package/guides/es/getting-started.md +164 -0
- package/guides/es/hooks-cookbook.md +160 -0
- package/guides/es/memory-management.md +153 -0
- package/guides/es/security.md +180 -0
- package/guides/es/skill-authoring.md +214 -0
- package/guides/es/token-optimization.md +156 -0
- package/guides/fr/agent-orchestration.md +174 -0
- package/guides/fr/getting-started.md +164 -0
- package/guides/fr/hooks-cookbook.md +227 -0
- package/guides/fr/memory-management.md +169 -0
- package/guides/fr/security.md +180 -0
- package/guides/fr/skill-authoring.md +214 -0
- package/guides/fr/token-optimization.md +158 -0
- package/guides/getting-started.md +164 -0
- package/guides/hooks-cookbook.md +423 -0
- package/guides/memory-management.md +192 -0
- package/guides/nl/agent-orchestration.md +174 -0
- package/guides/nl/getting-started.md +164 -0
- package/guides/nl/hooks-cookbook.md +160 -0
- package/guides/nl/memory-management.md +153 -0
- package/guides/nl/security.md +180 -0
- package/guides/nl/skill-authoring.md +214 -0
- package/guides/nl/token-optimization.md +156 -0
- package/guides/security.md +229 -0
- package/guides/skill-authoring.md +226 -0
- package/guides/token-optimization.md +169 -0
- package/hooks/lifecycle/cost-tracker.md +49 -0
- package/hooks/lifecycle/cost-tracker.sh +59 -0
- package/hooks/lifecycle/pre-compact-save.md +56 -0
- package/hooks/lifecycle/pre-compact-save.sh +37 -0
- package/hooks/lifecycle/session-start.md +50 -0
- package/hooks/lifecycle/session-start.sh +47 -0
- package/hooks/post-tool-use/audit-log.md +53 -0
- package/hooks/post-tool-use/audit-log.sh +53 -0
- package/hooks/post-tool-use/prettier.md +53 -0
- package/hooks/post-tool-use/prettier.sh +49 -0
- package/hooks/pre-tool-use/block-dangerous.md +48 -0
- package/hooks/pre-tool-use/block-dangerous.sh +76 -0
- package/hooks/pre-tool-use/git-push-confirm.md +46 -0
- package/hooks/pre-tool-use/git-push-confirm.sh +36 -0
- package/mcp/configs/github.json +11 -0
- package/mcp/configs/postgres.json +11 -0
- package/mcp/de/recommended-servers.md +170 -0
- package/mcp/es/recommended-servers.md +170 -0
- package/mcp/fr/recommended-servers.md +170 -0
- package/mcp/nl/recommended-servers.md +170 -0
- package/mcp/recommended-servers.md +168 -0
- package/package.json +45 -0
- package/prompts/project-starters/de/fastapi-project.md +62 -0
- package/prompts/project-starters/de/nextjs-project.md +82 -0
- package/prompts/project-starters/es/fastapi-project.md +62 -0
- package/prompts/project-starters/es/nextjs-project.md +82 -0
- package/prompts/project-starters/fastapi-project.md +60 -0
- package/prompts/project-starters/fr/fastapi-project.md +62 -0
- package/prompts/project-starters/fr/nextjs-project.md +82 -0
- package/prompts/project-starters/nextjs-project.md +80 -0
- package/prompts/project-starters/nl/fastapi-project.md +62 -0
- package/prompts/project-starters/nl/nextjs-project.md +82 -0
- package/prompts/system-prompts/ai-product.md +80 -0
- package/prompts/system-prompts/data-pipeline.md +76 -0
- package/prompts/system-prompts/de/ai-product.md +82 -0
- package/prompts/system-prompts/de/data-pipeline.md +78 -0
- package/prompts/system-prompts/de/saas-backend.md +71 -0
- package/prompts/system-prompts/es/ai-product.md +82 -0
- package/prompts/system-prompts/es/data-pipeline.md +78 -0
- package/prompts/system-prompts/es/saas-backend.md +71 -0
- package/prompts/system-prompts/fr/ai-product.md +82 -0
- package/prompts/system-prompts/fr/data-pipeline.md +78 -0
- package/prompts/system-prompts/fr/saas-backend.md +71 -0
- package/prompts/system-prompts/nl/ai-product.md +82 -0
- package/prompts/system-prompts/nl/data-pipeline.md +78 -0
- package/prompts/system-prompts/nl/saas-backend.md +71 -0
- package/prompts/system-prompts/saas-backend.md +69 -0
- package/prompts/task-specific/changelog.md +81 -0
- package/prompts/task-specific/de/changelog.md +83 -0
- package/prompts/task-specific/de/debugging.md +78 -0
- package/prompts/task-specific/de/pr-description.md +69 -0
- package/prompts/task-specific/debugging.md +76 -0
- package/prompts/task-specific/es/changelog.md +83 -0
- package/prompts/task-specific/es/debugging.md +78 -0
- package/prompts/task-specific/es/pr-description.md +69 -0
- package/prompts/task-specific/fr/changelog.md +83 -0
- package/prompts/task-specific/fr/debugging.md +78 -0
- package/prompts/task-specific/fr/pr-description.md +69 -0
- package/prompts/task-specific/nl/changelog.md +83 -0
- package/prompts/task-specific/nl/debugging.md +78 -0
- package/prompts/task-specific/nl/pr-description.md +69 -0
- package/prompts/task-specific/pr-description.md +67 -0
- package/rules/common/coding-style.md +45 -0
- package/rules/common/de/coding-style.md +47 -0
- package/rules/common/de/git.md +48 -0
- package/rules/common/de/performance.md +40 -0
- package/rules/common/de/security.md +45 -0
- package/rules/common/de/testing.md +45 -0
- package/rules/common/es/coding-style.md +47 -0
- package/rules/common/es/git.md +48 -0
- package/rules/common/es/performance.md +40 -0
- package/rules/common/es/security.md +45 -0
- package/rules/common/es/testing.md +45 -0
- package/rules/common/fr/coding-style.md +47 -0
- package/rules/common/fr/git.md +48 -0
- package/rules/common/fr/performance.md +40 -0
- package/rules/common/fr/security.md +45 -0
- package/rules/common/fr/testing.md +45 -0
- package/rules/common/git.md +46 -0
- package/rules/common/nl/coding-style.md +47 -0
- package/rules/common/nl/git.md +48 -0
- package/rules/common/nl/performance.md +40 -0
- package/rules/common/nl/security.md +45 -0
- package/rules/common/nl/testing.md +45 -0
- package/rules/common/performance.md +38 -0
- package/rules/common/security.md +43 -0
- package/rules/common/testing.md +43 -0
- package/rules/language-specific/de/go.md +48 -0
- package/rules/language-specific/de/python.md +38 -0
- package/rules/language-specific/de/typescript.md +51 -0
- package/rules/language-specific/es/go.md +48 -0
- package/rules/language-specific/es/python.md +38 -0
- package/rules/language-specific/es/typescript.md +51 -0
- package/rules/language-specific/fr/go.md +48 -0
- package/rules/language-specific/fr/python.md +38 -0
- package/rules/language-specific/fr/typescript.md +51 -0
- package/rules/language-specific/go.md +46 -0
- package/rules/language-specific/nl/go.md +48 -0
- package/rules/language-specific/nl/python.md +38 -0
- package/rules/language-specific/nl/typescript.md +51 -0
- package/rules/language-specific/python.md +36 -0
- package/rules/language-specific/typescript.md +49 -0
- package/scripts/cli.js +161 -0
- package/scripts/link-skills.sh +35 -0
- package/scripts/list-skills.sh +34 -0
- package/skills/ai-engineering/agent-construction.md +285 -0
- package/skills/ai-engineering/claude-api.md +248 -0
- package/skills/ai-engineering/de/agent-construction.md +287 -0
- package/skills/ai-engineering/de/claude-api.md +250 -0
- package/skills/ai-engineering/es/agent-construction.md +287 -0
- package/skills/ai-engineering/es/claude-api.md +250 -0
- package/skills/ai-engineering/fr/agent-construction.md +287 -0
- package/skills/ai-engineering/fr/claude-api.md +250 -0
- package/skills/ai-engineering/nl/agent-construction.md +287 -0
- package/skills/ai-engineering/nl/claude-api.md +250 -0
- package/skills/backend/dotnet/csharp.md +304 -0
- package/skills/backend/dotnet/de/csharp.md +306 -0
- package/skills/backend/dotnet/es/csharp.md +306 -0
- package/skills/backend/dotnet/fr/csharp.md +306 -0
- package/skills/backend/dotnet/nl/csharp.md +306 -0
- package/skills/backend/go/de/go.md +307 -0
- package/skills/backend/go/es/go.md +307 -0
- package/skills/backend/go/fr/go.md +307 -0
- package/skills/backend/go/go.md +305 -0
- package/skills/backend/go/nl/go.md +307 -0
- package/skills/backend/nodejs/de/nestjs.md +274 -0
- package/skills/backend/nodejs/de/nextjs.md +222 -0
- package/skills/backend/nodejs/es/nestjs.md +274 -0
- package/skills/backend/nodejs/es/nextjs.md +222 -0
- package/skills/backend/nodejs/fr/nestjs.md +274 -0
- package/skills/backend/nodejs/fr/nextjs.md +222 -0
- package/skills/backend/nodejs/nestjs.md +272 -0
- package/skills/backend/nodejs/nextjs.md +220 -0
- package/skills/backend/nodejs/nl/nestjs.md +274 -0
- package/skills/backend/nodejs/nl/nextjs.md +222 -0
- package/skills/backend/python/de/django.md +285 -0
- package/skills/backend/python/de/fastapi.md +244 -0
- package/skills/backend/python/django.md +283 -0
- package/skills/backend/python/es/django.md +285 -0
- package/skills/backend/python/es/fastapi.md +244 -0
- package/skills/backend/python/fastapi.md +242 -0
- package/skills/backend/python/fr/django.md +285 -0
- package/skills/backend/python/fr/fastapi.md +244 -0
- package/skills/backend/python/nl/django.md +285 -0
- package/skills/backend/python/nl/fastapi.md +244 -0
- package/skills/data-ml/dbt-data-pipelines.md +155 -0
- package/skills/data-ml/de/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/de/pandas-polars.md +147 -0
- package/skills/data-ml/de/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/es/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/es/pandas-polars.md +147 -0
- package/skills/data-ml/es/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/fr/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/fr/pandas-polars.md +147 -0
- package/skills/data-ml/fr/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/nl/dbt-data-pipelines.md +157 -0
- package/skills/data-ml/nl/pandas-polars.md +147 -0
- package/skills/data-ml/nl/pytorch-tensorflow.md +171 -0
- package/skills/data-ml/pandas-polars.md +145 -0
- package/skills/data-ml/pytorch-tensorflow.md +169 -0
- package/skills/database/de/graphql.md +181 -0
- package/skills/database/es/graphql.md +181 -0
- package/skills/database/fr/graphql.md +181 -0
- package/skills/database/graphql.md +179 -0
- package/skills/database/nl/graphql.md +181 -0
- package/skills/devops-infra/de/docker.md +133 -0
- package/skills/devops-infra/de/github-actions.md +179 -0
- package/skills/devops-infra/de/kubernetes.md +129 -0
- package/skills/devops-infra/de/terraform.md +130 -0
- package/skills/devops-infra/docker.md +131 -0
- package/skills/devops-infra/es/docker.md +133 -0
- package/skills/devops-infra/es/github-actions.md +179 -0
- package/skills/devops-infra/es/kubernetes.md +129 -0
- package/skills/devops-infra/es/terraform.md +130 -0
- package/skills/devops-infra/fr/docker.md +133 -0
- package/skills/devops-infra/fr/github-actions.md +179 -0
- package/skills/devops-infra/fr/kubernetes.md +129 -0
- package/skills/devops-infra/fr/terraform.md +130 -0
- package/skills/devops-infra/github-actions.md +177 -0
- package/skills/devops-infra/kubernetes.md +127 -0
- package/skills/devops-infra/nl/docker.md +133 -0
- package/skills/devops-infra/nl/github-actions.md +179 -0
- package/skills/devops-infra/nl/kubernetes.md +129 -0
- package/skills/devops-infra/nl/terraform.md +130 -0
- package/skills/devops-infra/terraform.md +128 -0
- package/skills/finance-payments/de/stripe.md +187 -0
- package/skills/finance-payments/es/stripe.md +187 -0
- package/skills/finance-payments/fr/stripe.md +187 -0
- package/skills/finance-payments/nl/stripe.md +187 -0
- package/skills/finance-payments/stripe.md +185 -0
- package/workflows/code-review.md +151 -0
- package/workflows/de/code-review.md +153 -0
- package/workflows/de/debugging-session.md +146 -0
- package/workflows/de/feature-development.md +155 -0
- package/workflows/de/new-project-bootstrap.md +175 -0
- package/workflows/de/refactor-safely.md +150 -0
- package/workflows/debugging-session.md +144 -0
- package/workflows/es/code-review.md +153 -0
- package/workflows/es/debugging-session.md +146 -0
- package/workflows/es/feature-development.md +155 -0
- package/workflows/es/new-project-bootstrap.md +175 -0
- package/workflows/es/refactor-safely.md +150 -0
- package/workflows/feature-development.md +153 -0
- package/workflows/fr/code-review.md +153 -0
- package/workflows/fr/debugging-session.md +146 -0
- package/workflows/fr/feature-development.md +155 -0
- package/workflows/fr/new-project-bootstrap.md +175 -0
- package/workflows/fr/refactor-safely.md +150 -0
- package/workflows/new-project-bootstrap.md +173 -0
- package/workflows/nl/code-review.md +153 -0
- package/workflows/nl/debugging-session.md +146 -0
- package/workflows/nl/feature-development.md +155 -0
- package/workflows/nl/new-project-bootstrap.md +175 -0
- package/workflows/nl/refactor-safely.md +150 -0
- package/workflows/refactor-safely.md +148 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
> 🇳🇱 Dit is de Nederlandse vertaling. [Engelse versie](../stripe.md).
|
|
2
|
+
|
|
3
|
+
# Stripe Integratie Skill
|
|
4
|
+
|
|
5
|
+
## Wanneer te activeren
|
|
6
|
+
- Stripe Checkout of Payment Intents implementeren voor eenmalige betalingen
|
|
7
|
+
- Stripe-abonnementen en factureringscycli instellen
|
|
8
|
+
- Stripe-webhooks afhandelen voor betalingsgebeurtenissen
|
|
9
|
+
- Terugbetalingen, geschillen of betalingsannuleringen implementeren
|
|
10
|
+
- Stripe Connect instellen voor marketplace/platform-betalingen
|
|
11
|
+
- Mislukte betalingen, geweigerde kaarten of problemen met webhookbezorging debuggen
|
|
12
|
+
- SCA (Strong Customer Authentication)-compliance implementeren
|
|
13
|
+
|
|
14
|
+
## Wanneer NIET te gebruiken
|
|
15
|
+
- PayPal, Braintree, Adyen, Mollie — andere betalingsproviders met andere SDK's
|
|
16
|
+
- Crypto-betalingen
|
|
17
|
+
- Interne boekhouding of factureringssystemen zonder een betalingsgateway
|
|
18
|
+
- Bankoverschrijving/ACH-only-flows (ander Stripe-product — Payment Elements zijn nog steeds van toepassing, maar flow verschilt)
|
|
19
|
+
|
|
20
|
+
## Instructies
|
|
21
|
+
|
|
22
|
+
### Codeer of log nooit betalingsgegevens
|
|
23
|
+
```typescript
|
|
24
|
+
// Log NOOIT kaartgegevens, volledige payment intent-objecten of klant-PII
|
|
25
|
+
// SLECHT:
|
|
26
|
+
console.log('Payment intent:', paymentIntent); // Kan gevoelige data bevatten
|
|
27
|
+
|
|
28
|
+
// GOED:
|
|
29
|
+
console.log('Payment intent created:', paymentIntent.id, paymentIntent.status);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Payment Intents — aanmaken aan serverzijde
|
|
33
|
+
```typescript
|
|
34
|
+
import Stripe from 'stripe';
|
|
35
|
+
|
|
36
|
+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
|
37
|
+
apiVersion: '2024-12-18.acacia', // Pin altijd de API-versie
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Maak payment intent aan serverzijde — nooit aan clientzijde
|
|
41
|
+
export async function createPaymentIntent(
|
|
42
|
+
amount: number, // Altijd in kleinste valuta-eenheid (centen voor USD)
|
|
43
|
+
currency: string,
|
|
44
|
+
customerId: string,
|
|
45
|
+
metadata: Record<string, string>
|
|
46
|
+
): Promise<{ clientSecret: string; paymentIntentId: string }> {
|
|
47
|
+
const paymentIntent = await stripe.paymentIntents.create({
|
|
48
|
+
amount, // bijv. 2999 = €29,99
|
|
49
|
+
currency, // bijv. 'usd', 'eur'
|
|
50
|
+
customer: customerId,
|
|
51
|
+
automatic_payment_methods: { enabled: true },
|
|
52
|
+
metadata, // Sla hier je interne ID's op
|
|
53
|
+
idempotency_key: `pi_${customerId}_${Date.now()}`, // Voorkom dubbele kosten
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
clientSecret: paymentIntent.client_secret!,
|
|
58
|
+
paymentIntentId: paymentIntent.id,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Webhook-afhandeling — verifieer altijd handtekening
|
|
64
|
+
```typescript
|
|
65
|
+
import { headers } from 'next/headers';
|
|
66
|
+
|
|
67
|
+
export async function POST(request: Request) {
|
|
68
|
+
const body = await request.text(); // Ruwe body — geen geparseerde JSON
|
|
69
|
+
const signature = headers().get('stripe-signature')!;
|
|
70
|
+
|
|
71
|
+
let event: Stripe.Event;
|
|
72
|
+
try {
|
|
73
|
+
event = stripe.webhooks.constructEvent(
|
|
74
|
+
body,
|
|
75
|
+
signature,
|
|
76
|
+
process.env.STRIPE_WEBHOOK_SECRET!
|
|
77
|
+
);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
// Ongeldige handtekening — direct weigeren
|
|
80
|
+
return new Response('Invalid signature', { status: 400 });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Idempotent verwerken — webhooks kunnen meer dan eens worden bezorgd
|
|
84
|
+
switch (event.type) {
|
|
85
|
+
case 'payment_intent.succeeded':
|
|
86
|
+
await handlePaymentSucceeded(event.data.object as Stripe.PaymentIntent);
|
|
87
|
+
break;
|
|
88
|
+
case 'payment_intent.payment_failed':
|
|
89
|
+
await handlePaymentFailed(event.data.object as Stripe.PaymentIntent);
|
|
90
|
+
break;
|
|
91
|
+
case 'customer.subscription.deleted':
|
|
92
|
+
await handleSubscriptionCancelled(event.data.object as Stripe.Subscription);
|
|
93
|
+
break;
|
|
94
|
+
default:
|
|
95
|
+
// Log maar geef geen fout bij onbekende events — Stripe voegt nieuwe events toe in de loop der tijd
|
|
96
|
+
console.log(`Unhandled event type: ${event.type}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return new Response(null, { status: 200 });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Controleer altijd of al verwerkt voordat DB-wijzigingen worden aangebracht
|
|
103
|
+
async function handlePaymentSucceeded(paymentIntent: Stripe.PaymentIntent) {
|
|
104
|
+
const orderId = paymentIntent.metadata.order_id;
|
|
105
|
+
|
|
106
|
+
// Idempotentiecontrole
|
|
107
|
+
const existing = await db.order.findUnique({ where: { id: orderId } });
|
|
108
|
+
if (existing?.status === 'paid') return; // Al verwerkt
|
|
109
|
+
|
|
110
|
+
await db.order.update({
|
|
111
|
+
where: { id: orderId },
|
|
112
|
+
data: { status: 'paid', stripePaymentIntentId: paymentIntent.id }
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Abonnementen
|
|
118
|
+
```typescript
|
|
119
|
+
// Abonnement aanmaken
|
|
120
|
+
const subscription = await stripe.subscriptions.create({
|
|
121
|
+
customer: customerId,
|
|
122
|
+
items: [{ price: priceId }],
|
|
123
|
+
payment_behavior: 'default_incomplete', // Activeer niet totdat betaling bevestigd is
|
|
124
|
+
expand: ['latest_invoice.payment_intent'],
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Sleutel webhook-events voor abonnementen:
|
|
128
|
+
// customer.subscription.created → toegang verlenen
|
|
129
|
+
// customer.subscription.updated → planwijzigingen afhandelen
|
|
130
|
+
// customer.subscription.deleted → toegang intrekken
|
|
131
|
+
// invoice.payment_succeeded → toegangsperiode verlengen
|
|
132
|
+
// invoice.payment_failed → dunning-e-mail sturen, dan opschorten na respijtperiode
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Testmodus-discipline
|
|
136
|
+
```typescript
|
|
137
|
+
// Gebruik testkaartnummers in ontwikkeling:
|
|
138
|
+
// Succes: 4242 4242 4242 4242
|
|
139
|
+
// Geweigerd: 4000 0000 0000 0002
|
|
140
|
+
// Authenticatie vereist: 4000 0025 0000 3155
|
|
141
|
+
// Gebruik test webhook CLI: stripe listen --forward-to localhost:3000/api/webhooks/stripe
|
|
142
|
+
|
|
143
|
+
// Gebruik nooit testsleutels in productie, gebruik nooit live sleutels in ontwikkeling
|
|
144
|
+
const isLiveMode = process.env.STRIPE_SECRET_KEY!.startsWith('sk_live_');
|
|
145
|
+
if (isLiveMode && process.env.NODE_ENV !== 'production') {
|
|
146
|
+
throw new Error('Live Stripe keys must not be used outside production');
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Foutafhandeling
|
|
151
|
+
```typescript
|
|
152
|
+
try {
|
|
153
|
+
const charge = await stripe.charges.create({ ... });
|
|
154
|
+
} catch (err) {
|
|
155
|
+
if (err instanceof Stripe.errors.StripeCardError) {
|
|
156
|
+
// Kaart geweigerd — toon gebruiksvriendelijk bericht
|
|
157
|
+
return { error: err.message, code: err.code };
|
|
158
|
+
}
|
|
159
|
+
if (err instanceof Stripe.errors.StripeRateLimitError) {
|
|
160
|
+
// Opnieuw proberen met exponentieel wachten
|
|
161
|
+
throw err;
|
|
162
|
+
}
|
|
163
|
+
if (err instanceof Stripe.errors.StripeInvalidRequestError) {
|
|
164
|
+
// Slechte API-aanroep — log en herstel de code
|
|
165
|
+
console.error('Invalid Stripe request:', err.message);
|
|
166
|
+
throw err;
|
|
167
|
+
}
|
|
168
|
+
// Andere fouten: StripeAPIError, StripeConnectionError, StripeAuthenticationError
|
|
169
|
+
throw err;
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Voorbeeld
|
|
174
|
+
|
|
175
|
+
**Gebruiker:** Implementeer een checkout-flow voor een SaaS-product: maak aan serverzijde een payment intent aan, handel de webhook bij succes af om het abonnement te activeren en behandel mislukte betalingen.
|
|
176
|
+
|
|
177
|
+
**Verwachte output:**
|
|
178
|
+
- `POST /api/checkout` — maakt PaymentIntent aan, retourneert `clientSecret`
|
|
179
|
+
- `POST /api/webhooks/stripe` — verifieert handtekening, behandelt `payment_intent.succeeded` (idempotente DB-update), `payment_intent.payment_failed` (log + notificeer)
|
|
180
|
+
- Metadata op PaymentIntent: `user_id`, `plan_id`, `order_id`
|
|
181
|
+
- Alle bedragen in centen, valuta expliciet
|
|
182
|
+
- API-versie gepind
|
|
183
|
+
- Geen logging van gevoelige data
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
> **Werk met ons:** Claudient wordt ondersteund door [Uitbreiden](https://uitbreiden.com/) — we bouwen AI-producten en B2B-oplossingen met ontwikkelaarsgemeenschappen. Betalingsflows bouwen of AI-producten monetiseren? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Stripe Integration Skill
|
|
2
|
+
|
|
3
|
+
## When to activate
|
|
4
|
+
- Implementing Stripe Checkout or Payment Intents for one-time payments
|
|
5
|
+
- Setting up Stripe subscriptions and billing cycles
|
|
6
|
+
- Handling Stripe webhooks for payment events
|
|
7
|
+
- Implementing refunds, disputes, or payment cancellations
|
|
8
|
+
- Setting up Stripe Connect for marketplace/platform payments
|
|
9
|
+
- Debugging failed payments, declined cards, or webhook delivery issues
|
|
10
|
+
- Implementing SCA (Strong Customer Authentication) compliance
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
- PayPal, Braintree, Adyen, Mollie — different payment providers with different SDKs
|
|
14
|
+
- Crypto payments
|
|
15
|
+
- Internal accounting or invoicing systems without a payment gateway
|
|
16
|
+
- Bank transfer / ACH-only flows (different Stripe product — Payment Elements still apply, but flow differs)
|
|
17
|
+
|
|
18
|
+
## Instructions
|
|
19
|
+
|
|
20
|
+
### Never hardcode or log payment data
|
|
21
|
+
```typescript
|
|
22
|
+
// NEVER log card details, full payment intent objects, or customer PII
|
|
23
|
+
// BAD:
|
|
24
|
+
console.log('Payment intent:', paymentIntent); // May contain sensitive data
|
|
25
|
+
|
|
26
|
+
// GOOD:
|
|
27
|
+
console.log('Payment intent created:', paymentIntent.id, paymentIntent.status);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Payment Intents — server-side creation
|
|
31
|
+
```typescript
|
|
32
|
+
import Stripe from 'stripe';
|
|
33
|
+
|
|
34
|
+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
|
35
|
+
apiVersion: '2024-12-18.acacia', // Always pin the API version
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Create payment intent server-side — never client-side
|
|
39
|
+
export async function createPaymentIntent(
|
|
40
|
+
amount: number, // Always in smallest currency unit (cents for USD)
|
|
41
|
+
currency: string,
|
|
42
|
+
customerId: string,
|
|
43
|
+
metadata: Record<string, string>
|
|
44
|
+
): Promise<{ clientSecret: string; paymentIntentId: string }> {
|
|
45
|
+
const paymentIntent = await stripe.paymentIntents.create({
|
|
46
|
+
amount, // e.g., 2999 = $29.99
|
|
47
|
+
currency, // e.g., 'usd', 'eur'
|
|
48
|
+
customer: customerId,
|
|
49
|
+
automatic_payment_methods: { enabled: true },
|
|
50
|
+
metadata, // Store your internal IDs here
|
|
51
|
+
idempotency_key: `pi_${customerId}_${Date.now()}`, // Prevent duplicate charges
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
clientSecret: paymentIntent.client_secret!,
|
|
56
|
+
paymentIntentId: paymentIntent.id,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Webhook handling — always verify signature
|
|
62
|
+
```typescript
|
|
63
|
+
import { headers } from 'next/headers';
|
|
64
|
+
|
|
65
|
+
export async function POST(request: Request) {
|
|
66
|
+
const body = await request.text(); // Raw body — not parsed JSON
|
|
67
|
+
const signature = headers().get('stripe-signature')!;
|
|
68
|
+
|
|
69
|
+
let event: Stripe.Event;
|
|
70
|
+
try {
|
|
71
|
+
event = stripe.webhooks.constructEvent(
|
|
72
|
+
body,
|
|
73
|
+
signature,
|
|
74
|
+
process.env.STRIPE_WEBHOOK_SECRET!
|
|
75
|
+
);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
// Invalid signature — reject immediately
|
|
78
|
+
return new Response('Invalid signature', { status: 400 });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Process idempotently — webhooks can be delivered more than once
|
|
82
|
+
switch (event.type) {
|
|
83
|
+
case 'payment_intent.succeeded':
|
|
84
|
+
await handlePaymentSucceeded(event.data.object as Stripe.PaymentIntent);
|
|
85
|
+
break;
|
|
86
|
+
case 'payment_intent.payment_failed':
|
|
87
|
+
await handlePaymentFailed(event.data.object as Stripe.PaymentIntent);
|
|
88
|
+
break;
|
|
89
|
+
case 'customer.subscription.deleted':
|
|
90
|
+
await handleSubscriptionCancelled(event.data.object as Stripe.Subscription);
|
|
91
|
+
break;
|
|
92
|
+
default:
|
|
93
|
+
// Log but don't error on unknown events — Stripe adds new events over time
|
|
94
|
+
console.log(`Unhandled event type: ${event.type}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return new Response(null, { status: 200 });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Always check if already processed before making DB changes
|
|
101
|
+
async function handlePaymentSucceeded(paymentIntent: Stripe.PaymentIntent) {
|
|
102
|
+
const orderId = paymentIntent.metadata.order_id;
|
|
103
|
+
|
|
104
|
+
// Idempotency check
|
|
105
|
+
const existing = await db.order.findUnique({ where: { id: orderId } });
|
|
106
|
+
if (existing?.status === 'paid') return; // Already processed
|
|
107
|
+
|
|
108
|
+
await db.order.update({
|
|
109
|
+
where: { id: orderId },
|
|
110
|
+
data: { status: 'paid', stripePaymentIntentId: paymentIntent.id }
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Subscriptions
|
|
116
|
+
```typescript
|
|
117
|
+
// Create subscription
|
|
118
|
+
const subscription = await stripe.subscriptions.create({
|
|
119
|
+
customer: customerId,
|
|
120
|
+
items: [{ price: priceId }],
|
|
121
|
+
payment_behavior: 'default_incomplete', // Don't activate until payment confirmed
|
|
122
|
+
expand: ['latest_invoice.payment_intent'],
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Key webhook events for subscriptions:
|
|
126
|
+
// customer.subscription.created → provision access
|
|
127
|
+
// customer.subscription.updated → handle plan changes
|
|
128
|
+
// customer.subscription.deleted → revoke access
|
|
129
|
+
// invoice.payment_succeeded → extend access period
|
|
130
|
+
// invoice.payment_failed → send dunning email, then suspend after grace period
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Test mode discipline
|
|
134
|
+
```typescript
|
|
135
|
+
// Use test card numbers in development:
|
|
136
|
+
// Success: 4242 4242 4242 4242
|
|
137
|
+
// Decline: 4000 0000 0000 0002
|
|
138
|
+
// Auth required: 4000 0025 0000 3155
|
|
139
|
+
// Use test webhook CLI: stripe listen --forward-to localhost:3000/api/webhooks/stripe
|
|
140
|
+
|
|
141
|
+
// Never use test keys in production, never use live keys in development
|
|
142
|
+
const isLiveMode = process.env.STRIPE_SECRET_KEY!.startsWith('sk_live_');
|
|
143
|
+
if (isLiveMode && process.env.NODE_ENV !== 'production') {
|
|
144
|
+
throw new Error('Live Stripe keys must not be used outside production');
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Error handling
|
|
149
|
+
```typescript
|
|
150
|
+
try {
|
|
151
|
+
const charge = await stripe.charges.create({ ... });
|
|
152
|
+
} catch (err) {
|
|
153
|
+
if (err instanceof Stripe.errors.StripeCardError) {
|
|
154
|
+
// Card declined — show user-friendly message
|
|
155
|
+
return { error: err.message, code: err.code };
|
|
156
|
+
}
|
|
157
|
+
if (err instanceof Stripe.errors.StripeRateLimitError) {
|
|
158
|
+
// Retry with exponential backoff
|
|
159
|
+
throw err;
|
|
160
|
+
}
|
|
161
|
+
if (err instanceof Stripe.errors.StripeInvalidRequestError) {
|
|
162
|
+
// Bad API call — log and fix the code
|
|
163
|
+
console.error('Invalid Stripe request:', err.message);
|
|
164
|
+
throw err;
|
|
165
|
+
}
|
|
166
|
+
// Other errors: StripeAPIError, StripeConnectionError, StripeAuthenticationError
|
|
167
|
+
throw err;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Example
|
|
172
|
+
|
|
173
|
+
**User:** Implement a checkout flow for a SaaS product: create a payment intent server-side, handle the webhook on success to activate the subscription, and handle failed payments.
|
|
174
|
+
|
|
175
|
+
**Expected output:**
|
|
176
|
+
- `POST /api/checkout` — creates PaymentIntent, returns `clientSecret`
|
|
177
|
+
- `POST /api/webhooks/stripe` — verifies signature, handles `payment_intent.succeeded` (idempotent DB update), `payment_intent.payment_failed` (log + notify)
|
|
178
|
+
- Metadata on PaymentIntent: `user_id`, `plan_id`, `order_id`
|
|
179
|
+
- All amounts in cents, currency explicit
|
|
180
|
+
- API version pinned
|
|
181
|
+
- No logging of sensitive data
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
> **Work with us:** Claudient is backed by [Uitbreiden](https://uitbreiden.com/) — we build AI products and B2B solutions with developer communities. Building payment flows or monetizing AI products? [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Code Review Workflow
|
|
2
|
+
|
|
3
|
+
How to run a structured, automated code review using Claude Code before or alongside human review.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## When to use this workflow
|
|
8
|
+
- Self-reviewing your own changes before pushing
|
|
9
|
+
- Pre-screening a PR before requesting human review
|
|
10
|
+
- Reviewing AI-generated code before accepting it
|
|
11
|
+
- Onboarding review: understanding what changed in an unfamiliar PR
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Step 1 — Prepare context
|
|
16
|
+
|
|
17
|
+
Give Claude everything it needs to review meaningfully.
|
|
18
|
+
|
|
19
|
+
**Prompt Claude:**
|
|
20
|
+
```
|
|
21
|
+
I need you to review the following changes.
|
|
22
|
+
|
|
23
|
+
Project context:
|
|
24
|
+
- Stack: [language, framework, key libraries]
|
|
25
|
+
- Testing approach: [unit/integration, mocking policy]
|
|
26
|
+
- Key conventions: [paste relevant CLAUDE.md sections]
|
|
27
|
+
|
|
28
|
+
Changed files:
|
|
29
|
+
[paste git diff output OR list files and ask Claude to read them]
|
|
30
|
+
|
|
31
|
+
This PR: [one sentence on what it's supposed to do]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Step 2 — Correctness review
|
|
37
|
+
|
|
38
|
+
**Prompt Claude:**
|
|
39
|
+
```
|
|
40
|
+
Review these changes for correctness only.
|
|
41
|
+
|
|
42
|
+
Check:
|
|
43
|
+
1. Does the code do what the PR description says it does?
|
|
44
|
+
2. Are there edge cases not handled? (null inputs, empty collections, concurrent access, large inputs)
|
|
45
|
+
3. Are there off-by-one errors, wrong comparisons, or logic inversions?
|
|
46
|
+
4. Are error paths handled — can this panic, throw, or silently fail?
|
|
47
|
+
5. Are there race conditions if this code runs concurrently?
|
|
48
|
+
|
|
49
|
+
Format: [FILE:LINE] — [issue description] — [suggested fix]
|
|
50
|
+
Only report real issues. Do not nitpick style.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Step 3 — Security review
|
|
56
|
+
|
|
57
|
+
**Prompt Claude:**
|
|
58
|
+
```
|
|
59
|
+
Review these changes for security issues.
|
|
60
|
+
|
|
61
|
+
Check:
|
|
62
|
+
1. Is any user input used in SQL, shell commands, file paths, or HTML without sanitization?
|
|
63
|
+
2. Are there missing authentication or authorization checks?
|
|
64
|
+
3. Are secrets, tokens, or credentials exposed in logs, errors, or responses?
|
|
65
|
+
4. Are there insecure direct object references (IDOR)?
|
|
66
|
+
5. Are there missing rate limits on sensitive endpoints?
|
|
67
|
+
|
|
68
|
+
Severity: CRITICAL / HIGH / MEDIUM / LOW
|
|
69
|
+
Format: [SEVERITY] [FILE:LINE] — [vulnerability] — [fix]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Step 4 — Test coverage check
|
|
75
|
+
|
|
76
|
+
**Prompt Claude:**
|
|
77
|
+
```
|
|
78
|
+
Review the test coverage for these changes.
|
|
79
|
+
|
|
80
|
+
Check:
|
|
81
|
+
1. Is every new function or method covered by at least one test?
|
|
82
|
+
2. Is the happy path tested?
|
|
83
|
+
3. Is at least one error/edge case tested?
|
|
84
|
+
4. Do the tests actually assert meaningful behavior, or just that the function runs?
|
|
85
|
+
5. Are there behaviors changed by this PR that existing tests don't cover?
|
|
86
|
+
|
|
87
|
+
List: [what is tested] and [what is missing]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Step 5 — Maintainability review
|
|
93
|
+
|
|
94
|
+
**Prompt Claude:**
|
|
95
|
+
```
|
|
96
|
+
Review these changes for maintainability.
|
|
97
|
+
|
|
98
|
+
Check:
|
|
99
|
+
1. Will a developer unfamiliar with this code understand it in 6 months?
|
|
100
|
+
2. Are function names and variable names clear and accurate?
|
|
101
|
+
3. Is there duplicated logic that should be extracted?
|
|
102
|
+
4. Are there magic numbers or strings that should be named constants?
|
|
103
|
+
5. Does this introduce unnecessary coupling between modules?
|
|
104
|
+
|
|
105
|
+
Only flag real maintainability issues — not style preferences.
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Step 6 — Consolidate findings
|
|
111
|
+
|
|
112
|
+
**Prompt Claude:**
|
|
113
|
+
```
|
|
114
|
+
Consolidate all findings from the review into a final report.
|
|
115
|
+
|
|
116
|
+
Format:
|
|
117
|
+
## CRITICAL (must fix before merge)
|
|
118
|
+
[list]
|
|
119
|
+
|
|
120
|
+
## HIGH (strongly recommended)
|
|
121
|
+
[list]
|
|
122
|
+
|
|
123
|
+
## SUGGESTED (worth doing)
|
|
124
|
+
[list]
|
|
125
|
+
|
|
126
|
+
## NITPICK (optional)
|
|
127
|
+
[list]
|
|
128
|
+
|
|
129
|
+
## VERDICT
|
|
130
|
+
[ ] Approved — no blockers
|
|
131
|
+
[ ] Approved with suggestions — merge after addressing CRITICAL
|
|
132
|
+
[ ] Changes requested — must address before merge
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Using the Code Reviewer agent
|
|
138
|
+
|
|
139
|
+
For larger PRs, delegate to the Code Reviewer agent rather than running inline:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
Spawn a Code Reviewer agent (Sonnet 4.6) to review [list of files].
|
|
143
|
+
Give it the project context from CLAUDE.md and the PR description.
|
|
144
|
+
Have it return a structured CRITICAL/SUGGESTED/NITPICK report.
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
See `agents/core/code-reviewer.md` for the full agent definition.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
> **Work with us:** Claudient is backed by [Uitbreiden](https://uitbreiden.com/) — we build AI products and B2B solutions with developer communities. [uitbreiden.com](https://uitbreiden.com/)
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
> 🇩🇪 Dies ist die deutsche Übersetzung. [Englische Version](../code-review.md).
|
|
2
|
+
|
|
3
|
+
# Code-Review-Workflow
|
|
4
|
+
|
|
5
|
+
So führt man ein strukturiertes, automatisiertes Code-Review mit Claude Code durch — vor oder parallel zum menschlichen Review.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Wann diesen Workflow verwenden
|
|
10
|
+
- Eigene Änderungen vor dem Pushen selbst überprüfen
|
|
11
|
+
- Einen PR vor dem Anfordern eines menschlichen Reviews vorscreenen
|
|
12
|
+
- KI-generierten Code vor der Annahme überprüfen
|
|
13
|
+
- Onboarding-Review: verstehen, was sich in einem unbekannten PR geändert hat
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Schritt 1 — Kontext vorbereiten
|
|
18
|
+
|
|
19
|
+
Claude alles geben, was für eine sinnvolle Überprüfung benötigt wird.
|
|
20
|
+
|
|
21
|
+
**Claude fragen:**
|
|
22
|
+
```
|
|
23
|
+
I need you to review the following changes.
|
|
24
|
+
|
|
25
|
+
Project context:
|
|
26
|
+
- Stack: [language, framework, key libraries]
|
|
27
|
+
- Testing approach: [unit/integration, mocking policy]
|
|
28
|
+
- Key conventions: [paste relevant CLAUDE.md sections]
|
|
29
|
+
|
|
30
|
+
Changed files:
|
|
31
|
+
[paste git diff output OR list files and ask Claude to read them]
|
|
32
|
+
|
|
33
|
+
This PR: [one sentence on what it's supposed to do]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Schritt 2 — Korrektheitsprüfung
|
|
39
|
+
|
|
40
|
+
**Claude fragen:**
|
|
41
|
+
```
|
|
42
|
+
Review these changes for correctness only.
|
|
43
|
+
|
|
44
|
+
Check:
|
|
45
|
+
1. Does the code do what the PR description says it does?
|
|
46
|
+
2. Are there edge cases not handled? (null inputs, empty collections, concurrent access, large inputs)
|
|
47
|
+
3. Are there off-by-one errors, wrong comparisons, or logic inversions?
|
|
48
|
+
4. Are error paths handled — can this panic, throw, or silently fail?
|
|
49
|
+
5. Are there race conditions if this code runs concurrently?
|
|
50
|
+
|
|
51
|
+
Format: [FILE:LINE] — [issue description] — [suggested fix]
|
|
52
|
+
Only report real issues. Do not nitpick style.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Schritt 3 — Sicherheitsprüfung
|
|
58
|
+
|
|
59
|
+
**Claude fragen:**
|
|
60
|
+
```
|
|
61
|
+
Review these changes for security issues.
|
|
62
|
+
|
|
63
|
+
Check:
|
|
64
|
+
1. Is any user input used in SQL, shell commands, file paths, or HTML without sanitization?
|
|
65
|
+
2. Are there missing authentication or authorization checks?
|
|
66
|
+
3. Are secrets, tokens, or credentials exposed in logs, errors, or responses?
|
|
67
|
+
4. Are there insecure direct object references (IDOR)?
|
|
68
|
+
5. Are there missing rate limits on sensitive endpoints?
|
|
69
|
+
|
|
70
|
+
Severity: CRITICAL / HIGH / MEDIUM / LOW
|
|
71
|
+
Format: [SEVERITY] [FILE:LINE] — [vulnerability] — [fix]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Schritt 4 — Testabdeckungs-Prüfung
|
|
77
|
+
|
|
78
|
+
**Claude fragen:**
|
|
79
|
+
```
|
|
80
|
+
Review the test coverage for these changes.
|
|
81
|
+
|
|
82
|
+
Check:
|
|
83
|
+
1. Is every new function or method covered by at least one test?
|
|
84
|
+
2. Is the happy path tested?
|
|
85
|
+
3. Is at least one error/edge case tested?
|
|
86
|
+
4. Do the tests actually assert meaningful behavior, or just that the function runs?
|
|
87
|
+
5. Are there behaviors changed by this PR that existing tests don't cover?
|
|
88
|
+
|
|
89
|
+
List: [what is tested] and [what is missing]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Schritt 5 — Wartbarkeitsprüfung
|
|
95
|
+
|
|
96
|
+
**Claude fragen:**
|
|
97
|
+
```
|
|
98
|
+
Review these changes for maintainability.
|
|
99
|
+
|
|
100
|
+
Check:
|
|
101
|
+
1. Will a developer unfamiliar with this code understand it in 6 months?
|
|
102
|
+
2. Are function names and variable names clear and accurate?
|
|
103
|
+
3. Is there duplicated logic that should be extracted?
|
|
104
|
+
4. Are there magic numbers or strings that should be named constants?
|
|
105
|
+
5. Does this introduce unnecessary coupling between modules?
|
|
106
|
+
|
|
107
|
+
Only flag real maintainability issues — not style preferences.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Schritt 6 — Befunde konsolidieren
|
|
113
|
+
|
|
114
|
+
**Claude fragen:**
|
|
115
|
+
```
|
|
116
|
+
Consolidate all findings from the review into a final report.
|
|
117
|
+
|
|
118
|
+
Format:
|
|
119
|
+
## CRITICAL (must fix before merge)
|
|
120
|
+
[list]
|
|
121
|
+
|
|
122
|
+
## HIGH (strongly recommended)
|
|
123
|
+
[list]
|
|
124
|
+
|
|
125
|
+
## SUGGESTED (worth doing)
|
|
126
|
+
[list]
|
|
127
|
+
|
|
128
|
+
## NITPICK (optional)
|
|
129
|
+
[list]
|
|
130
|
+
|
|
131
|
+
## VERDICT
|
|
132
|
+
[ ] Approved — no blockers
|
|
133
|
+
[ ] Approved with suggestions — merge after addressing CRITICAL
|
|
134
|
+
[ ] Changes requested — must address before merge
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Den Code Reviewer-Agenten verwenden
|
|
140
|
+
|
|
141
|
+
Für größere PRs den Code Reviewer-Agenten delegieren, anstatt inline zu prüfen:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
Spawn a Code Reviewer agent (Sonnet 4.6) to review [list of files].
|
|
145
|
+
Give it the project context from CLAUDE.md and the PR description.
|
|
146
|
+
Have it return a structured CRITICAL/SUGGESTED/NITPICK report.
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Die vollständige Agentendefinition in `agents/core/code-reviewer.md` finden.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
> **Mit uns arbeiten:** Claudient wird von [Uitbreiden](https://uitbreiden.com/) unterstützt — wir bauen KI-Produkte und B2B-Lösungen mit Entwickler-Communities. [uitbreiden.com](https://uitbreiden.com/)
|