@codihaus/claude-skills 1.0.0 → 1.3.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/knowledge/domains/_index.md +105 -0
- package/knowledge/domains/ecommerce/_index.md +499 -0
- package/knowledge/domains/saas/_index.md +371 -0
- package/knowledge/stacks/_index.md +101 -0
- package/knowledge/stacks/directus/_index.md +349 -0
- package/knowledge/stacks/nextjs/_index.md +654 -0
- package/knowledge/stacks/nuxt/_index.md +469 -0
- package/package.json +3 -1
- package/project-scripts/graph.py +330 -0
- package/skills/_registry.md +61 -0
- package/skills/dev-coding/SKILL.md +16 -5
- package/skills/dev-coding-backend/SKILL.md +116 -251
- package/skills/dev-coding-frontend/SKILL.md +134 -388
- package/skills/dev-review/SKILL.md +13 -2
- package/skills/dev-scout/SKILL.md +180 -2
- package/skills/dev-scout/references/stack-patterns.md +371 -0
- package/skills/dev-specs/SKILL.md +74 -2
- package/src/commands/init.js +89 -12
- package/src/utils/project-setup.js +444 -0
- package/src/utils/skills.js +87 -1
- /package/{skills/dev-coding-frontend/references/nextjs.md → knowledge/stacks/nextjs/references/performance.md} +0 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# Directus
|
|
2
|
+
|
|
3
|
+
> Headless CMS and Backend-as-a-Service with auto-generated REST & GraphQL APIs
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
**What it is:**
|
|
8
|
+
- Headless CMS that wraps any SQL database
|
|
9
|
+
- Auto-generates REST and GraphQL APIs for collections
|
|
10
|
+
- Built-in auth, permissions, file storage, webhooks, flows
|
|
11
|
+
|
|
12
|
+
**When to use:**
|
|
13
|
+
- Content-driven applications
|
|
14
|
+
- Admin panels / dashboards
|
|
15
|
+
- APIs without writing backend code
|
|
16
|
+
- Projects needing flexible content modeling
|
|
17
|
+
|
|
18
|
+
**Key concepts:**
|
|
19
|
+
- **Collections** = Database tables (managed via Directus Admin)
|
|
20
|
+
- **Items** = Rows in collections
|
|
21
|
+
- **Fields** = Columns with types and validation
|
|
22
|
+
- **Roles & Permissions** = Granular access control
|
|
23
|
+
- **Flows** = Automation (triggers → operations)
|
|
24
|
+
- **Extensions** = Custom endpoints, hooks, interfaces
|
|
25
|
+
|
|
26
|
+
## Best Practices
|
|
27
|
+
|
|
28
|
+
### Data Modeling
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
DO:
|
|
32
|
+
✓ Use Directus Admin to create/modify collections
|
|
33
|
+
✓ Define relationships in Directus (M2O, O2M, M2M, M2A)
|
|
34
|
+
✓ Use system fields: id (uuid), status, sort, created/updated timestamps
|
|
35
|
+
✓ Set field validation in Directus (not just frontend)
|
|
36
|
+
|
|
37
|
+
DON'T:
|
|
38
|
+
✗ Modify database directly (bypasses Directus cache)
|
|
39
|
+
✗ Create tables via migrations (use Directus schema)
|
|
40
|
+
✗ Hardcode IDs (use relations)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### API Access
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
DO:
|
|
47
|
+
✓ Use @directus/sdk for type-safe access
|
|
48
|
+
✓ Use REST for simple CRUD, GraphQL for complex queries
|
|
49
|
+
✓ Filter at API level, not in frontend
|
|
50
|
+
✓ Use fields parameter to limit response size
|
|
51
|
+
|
|
52
|
+
DON'T:
|
|
53
|
+
✗ Fetch all fields when you need few
|
|
54
|
+
✗ Filter large datasets client-side
|
|
55
|
+
✗ Bypass Directus API for direct DB access
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Authentication
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
DO:
|
|
62
|
+
✓ Use Directus auth endpoints (/auth/login, /auth/refresh)
|
|
63
|
+
✓ Store access_token, refresh with refresh_token
|
|
64
|
+
✓ Use static tokens for server-to-server
|
|
65
|
+
✓ Set appropriate token expiry
|
|
66
|
+
|
|
67
|
+
DON'T:
|
|
68
|
+
✗ Build custom auth (use Directus)
|
|
69
|
+
✗ Store tokens in localStorage (use httpOnly cookies)
|
|
70
|
+
✗ Share admin tokens with frontend
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Permissions
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
DO:
|
|
77
|
+
✓ Create roles for each user type
|
|
78
|
+
✓ Use field-level permissions (hide sensitive data)
|
|
79
|
+
✓ Use custom permissions with $CURRENT_USER
|
|
80
|
+
✓ Test permissions with role preview
|
|
81
|
+
|
|
82
|
+
DON'T:
|
|
83
|
+
✗ Give Public role more than needed
|
|
84
|
+
✗ Use Admin role for regular users
|
|
85
|
+
✗ Forget to set permissions on new collections
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Flows (Automation)
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
DO:
|
|
92
|
+
✓ Use Flows for: email notifications, data validation, sync
|
|
93
|
+
✓ Use "Filter" trigger for conditional automation
|
|
94
|
+
✓ Chain operations for complex workflows
|
|
95
|
+
✓ Log flow runs for debugging
|
|
96
|
+
|
|
97
|
+
DON'T:
|
|
98
|
+
✗ Put business logic only in frontend
|
|
99
|
+
✗ Create circular flow triggers
|
|
100
|
+
✗ Use flows for heavy computation (use extensions)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Anti-Patterns
|
|
104
|
+
|
|
105
|
+
| Anti-Pattern | Problem | Better Approach |
|
|
106
|
+
|--------------|---------|-----------------|
|
|
107
|
+
| Direct DB writes | Bypasses cache, permissions | Use Directus SDK/API |
|
|
108
|
+
| Fetching all items | Memory issues, slow | Use pagination, filters |
|
|
109
|
+
| Frontend-only validation | Data integrity issues | Set validation in Directus fields |
|
|
110
|
+
| Hardcoded collection names | Breaks if renamed | Use constants/config |
|
|
111
|
+
| Admin token in frontend | Security risk | Use user auth or server proxy |
|
|
112
|
+
| Ignoring relations | Redundant data, sync issues | Use proper M2O/O2M/M2M |
|
|
113
|
+
|
|
114
|
+
## For /dev-specs
|
|
115
|
+
|
|
116
|
+
### API Design
|
|
117
|
+
|
|
118
|
+
When specifying Directus features:
|
|
119
|
+
|
|
120
|
+
```markdown
|
|
121
|
+
## Data Model (Directus Collections)
|
|
122
|
+
|
|
123
|
+
### Collection: products
|
|
124
|
+
| Field | Type | Notes |
|
|
125
|
+
|-------|------|-------|
|
|
126
|
+
| id | uuid | PK (auto) |
|
|
127
|
+
| status | status | draft/published/archived |
|
|
128
|
+
| name | string | Required |
|
|
129
|
+
| price | decimal | Required |
|
|
130
|
+
| category | m2o:categories | Relation |
|
|
131
|
+
| images | files | M2M to directus_files |
|
|
132
|
+
|
|
133
|
+
### Permissions
|
|
134
|
+
| Role | Create | Read | Update | Delete |
|
|
135
|
+
|------|--------|------|--------|--------|
|
|
136
|
+
| Public | ✗ | status=published | ✗ | ✗ |
|
|
137
|
+
| Customer | ✗ | ✓ | own items | ✗ |
|
|
138
|
+
| Admin | ✓ | ✓ | ✓ | ✓ |
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Don't Specify
|
|
142
|
+
|
|
143
|
+
- Custom REST endpoints (use Directus API)
|
|
144
|
+
- Database migrations (use Directus schema)
|
|
145
|
+
- Auth endpoints (use Directus auth)
|
|
146
|
+
|
|
147
|
+
### Do Specify
|
|
148
|
+
|
|
149
|
+
- Collection structure and relations
|
|
150
|
+
- Permission rules per role
|
|
151
|
+
- Flows for automation
|
|
152
|
+
- Custom extensions if needed
|
|
153
|
+
|
|
154
|
+
## For /dev-coding
|
|
155
|
+
|
|
156
|
+
### SDK Setup (TypeScript)
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// lib/directus.ts
|
|
160
|
+
import { createDirectus, rest, authentication } from '@directus/sdk';
|
|
161
|
+
|
|
162
|
+
type Schema = {
|
|
163
|
+
products: Product[];
|
|
164
|
+
categories: Category[];
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const directus = createDirectus<Schema>(process.env.DIRECTUS_URL!)
|
|
168
|
+
.with(rest())
|
|
169
|
+
.with(authentication());
|
|
170
|
+
|
|
171
|
+
export default directus;
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### CRUD Operations
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { readItems, readItem, createItem, updateItem, deleteItem } from '@directus/sdk';
|
|
178
|
+
|
|
179
|
+
// Read with filters
|
|
180
|
+
const products = await directus.request(
|
|
181
|
+
readItems('products', {
|
|
182
|
+
filter: { status: { _eq: 'published' } },
|
|
183
|
+
fields: ['id', 'name', 'price', { category: ['name'] }],
|
|
184
|
+
limit: 10,
|
|
185
|
+
})
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// Create
|
|
189
|
+
const newProduct = await directus.request(
|
|
190
|
+
createItem('products', {
|
|
191
|
+
name: 'New Product',
|
|
192
|
+
price: 99.99,
|
|
193
|
+
category: 'category-uuid',
|
|
194
|
+
})
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// Update
|
|
198
|
+
await directus.request(
|
|
199
|
+
updateItem('products', 'product-uuid', { price: 89.99 })
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
// Delete
|
|
203
|
+
await directus.request(deleteItem('products', 'product-uuid'));
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Authentication
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
// Login
|
|
210
|
+
const auth = await directus.login(email, password);
|
|
211
|
+
// Returns: { access_token, refresh_token, expires }
|
|
212
|
+
|
|
213
|
+
// Refresh
|
|
214
|
+
await directus.refresh();
|
|
215
|
+
|
|
216
|
+
// Logout
|
|
217
|
+
await directus.logout();
|
|
218
|
+
|
|
219
|
+
// Get current user
|
|
220
|
+
import { readMe } from '@directus/sdk';
|
|
221
|
+
const me = await directus.request(readMe());
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### File Uploads
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import { uploadFiles } from '@directus/sdk';
|
|
228
|
+
|
|
229
|
+
const formData = new FormData();
|
|
230
|
+
formData.append('file', fileBlob);
|
|
231
|
+
|
|
232
|
+
const uploaded = await directus.request(uploadFiles(formData));
|
|
233
|
+
// Returns: { id, filename_download, ... }
|
|
234
|
+
|
|
235
|
+
// Get file URL
|
|
236
|
+
const url = `${DIRECTUS_URL}/assets/${uploaded.id}`;
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Realtime (WebSockets)
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { createDirectus, realtime } from '@directus/sdk';
|
|
243
|
+
|
|
244
|
+
const client = createDirectus<Schema>(DIRECTUS_URL).with(realtime());
|
|
245
|
+
|
|
246
|
+
client.onWebSocket('message', (data) => {
|
|
247
|
+
if (data.type === 'subscription') {
|
|
248
|
+
console.log('Update:', data.data);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
await client.subscribe('products', {
|
|
253
|
+
query: { fields: ['id', 'name', 'price'] },
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## For /dev-review
|
|
258
|
+
|
|
259
|
+
### Security Checklist
|
|
260
|
+
|
|
261
|
+
- [ ] No admin tokens exposed to frontend
|
|
262
|
+
- [ ] Public role has minimal permissions
|
|
263
|
+
- [ ] Sensitive fields have field-level permissions
|
|
264
|
+
- [ ] File access restricted appropriately
|
|
265
|
+
- [ ] CORS configured correctly
|
|
266
|
+
- [ ] Rate limiting enabled
|
|
267
|
+
|
|
268
|
+
### Performance Checklist
|
|
269
|
+
|
|
270
|
+
- [ ] Using `fields` parameter (not fetching all)
|
|
271
|
+
- [ ] Using `filter` at API level
|
|
272
|
+
- [ ] Pagination for large collections
|
|
273
|
+
- [ ] Caching strategy for static content
|
|
274
|
+
- [ ] No N+1 queries (use nested fields)
|
|
275
|
+
|
|
276
|
+
### Data Integrity Checklist
|
|
277
|
+
|
|
278
|
+
- [ ] Required fields marked in Directus
|
|
279
|
+
- [ ] Field validation set (regex, min/max)
|
|
280
|
+
- [ ] Relationships properly defined
|
|
281
|
+
- [ ] Status workflow configured
|
|
282
|
+
- [ ] Soft delete vs hard delete decided
|
|
283
|
+
|
|
284
|
+
### Common Mistakes
|
|
285
|
+
|
|
286
|
+
| Mistake | Impact | Fix |
|
|
287
|
+
|---------|--------|-----|
|
|
288
|
+
| `fields: ['*']` | Over-fetching | List needed fields |
|
|
289
|
+
| No pagination | Memory issues | Add `limit` + `offset` |
|
|
290
|
+
| Direct DB queries | Cache inconsistency | Use SDK |
|
|
291
|
+
| Frontend auth storage | Security risk | Use httpOnly cookies |
|
|
292
|
+
| Missing error handling | Poor UX | Catch SDK errors |
|
|
293
|
+
|
|
294
|
+
## Integration
|
|
295
|
+
|
|
296
|
+
### With Nuxt.js
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// composables/useDirectus.ts
|
|
300
|
+
export const useDirectus = () => {
|
|
301
|
+
const config = useRuntimeConfig();
|
|
302
|
+
return createDirectus<Schema>(config.public.directusUrl)
|
|
303
|
+
.with(rest())
|
|
304
|
+
.with(authentication());
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
// Usage in component
|
|
308
|
+
const directus = useDirectus();
|
|
309
|
+
const { data } = await useAsyncData('products', () =>
|
|
310
|
+
directus.request(readItems('products'))
|
|
311
|
+
);
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### With Next.js
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
// lib/directus.ts (server-side)
|
|
318
|
+
const directus = createDirectus<Schema>(process.env.DIRECTUS_URL!)
|
|
319
|
+
.with(rest())
|
|
320
|
+
.with(staticToken(process.env.DIRECTUS_TOKEN!));
|
|
321
|
+
|
|
322
|
+
// app/products/page.tsx (Server Component)
|
|
323
|
+
export default async function ProductsPage() {
|
|
324
|
+
const products = await directus.request(readItems('products'));
|
|
325
|
+
return <ProductList products={products} />;
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Resources
|
|
330
|
+
|
|
331
|
+
### Official Docs
|
|
332
|
+
- Docs: https://docs.directus.io
|
|
333
|
+
- SDK: https://docs.directus.io/reference/sdk/
|
|
334
|
+
|
|
335
|
+
### Context7 Queries
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
Query: "Directus SDK TypeScript setup"
|
|
339
|
+
Query: "Directus permissions best practices"
|
|
340
|
+
Query: "Directus flows automation"
|
|
341
|
+
Query: "Directus file uploads"
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### MCP Tools
|
|
345
|
+
|
|
346
|
+
If `directus` MCP available:
|
|
347
|
+
- Can query collections directly
|
|
348
|
+
- Can check permissions
|
|
349
|
+
- Can test API endpoints
|