@bradtaylorsf/alpha-loop 1.1.0 → 1.1.2

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.
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Express Router Template
3
+ * Use this template for creating new resource routers
4
+ */
5
+
6
+ import { Router } from 'express';
7
+ import { z } from 'zod';
8
+ import { validateRequest } from '../middleware/validation';
9
+ import { requireAuth } from '../middleware/auth';
10
+ import { AppError } from '../utils/errors';
11
+
12
+ const router = Router();
13
+
14
+ // ============================================================================
15
+ // Validation Schemas
16
+ // ============================================================================
17
+
18
+ const CreateSchema = z.object({
19
+ // Define your fields here
20
+ name: z.string().min(1).max(255),
21
+ description: z.string().optional()
22
+ });
23
+
24
+ const UpdateSchema = CreateSchema.partial();
25
+
26
+ const QuerySchema = z.object({
27
+ page: z.coerce.number().int().min(1).default(1),
28
+ limit: z.coerce.number().int().min(1).max(100).default(20),
29
+ sortBy: z.enum(['createdAt', 'updatedAt', 'name']).default('createdAt'),
30
+ sortOrder: z.enum(['asc', 'desc']).default('desc')
31
+ });
32
+
33
+ // Type inference
34
+ type CreateDto = z.infer<typeof CreateSchema>;
35
+ type UpdateDto = z.infer<typeof UpdateSchema>;
36
+ type QueryDto = z.infer<typeof QuerySchema>;
37
+
38
+ // ============================================================================
39
+ // Routes
40
+ // ============================================================================
41
+
42
+ /**
43
+ * @openapi
44
+ * /api/resources:
45
+ * get:
46
+ * summary: List all resources
47
+ * tags: [Resources]
48
+ * security:
49
+ * - bearerAuth: []
50
+ * parameters:
51
+ * - in: query
52
+ * name: page
53
+ * schema:
54
+ * type: integer
55
+ * minimum: 1
56
+ * - in: query
57
+ * name: limit
58
+ * schema:
59
+ * type: integer
60
+ * minimum: 1
61
+ * maximum: 100
62
+ * responses:
63
+ * 200:
64
+ * description: List of resources
65
+ */
66
+ router.get(
67
+ '/',
68
+ requireAuth,
69
+ validateRequest(QuerySchema),
70
+ async (req, res, next) => {
71
+ try {
72
+ const query = req.body as QueryDto;
73
+ const { page, limit, sortBy, sortOrder } = query;
74
+ const offset = (page - 1) * limit;
75
+
76
+ // TODO: Replace with actual database query
77
+ const resources = [];
78
+ const total = 0;
79
+
80
+ res.json({
81
+ data: resources,
82
+ pagination: {
83
+ page,
84
+ limit,
85
+ total,
86
+ totalPages: Math.ceil(total / limit)
87
+ }
88
+ });
89
+ } catch (err) {
90
+ next(err);
91
+ }
92
+ }
93
+ );
94
+
95
+ /**
96
+ * @openapi
97
+ * /api/resources/{id}:
98
+ * get:
99
+ * summary: Get a single resource
100
+ * tags: [Resources]
101
+ * security:
102
+ * - bearerAuth: []
103
+ * parameters:
104
+ * - in: path
105
+ * name: id
106
+ * required: true
107
+ * schema:
108
+ * type: string
109
+ * responses:
110
+ * 200:
111
+ * description: Resource found
112
+ * 404:
113
+ * description: Resource not found
114
+ */
115
+ router.get('/:id', requireAuth, async (req, res, next) => {
116
+ try {
117
+ const { id } = req.params;
118
+
119
+ // TODO: Replace with actual database query
120
+ const resource = null;
121
+
122
+ if (!resource) {
123
+ throw new AppError('Resource not found', 404, 'RESOURCE_NOT_FOUND');
124
+ }
125
+
126
+ res.json({ data: resource });
127
+ } catch (err) {
128
+ next(err);
129
+ }
130
+ });
131
+
132
+ /**
133
+ * @openapi
134
+ * /api/resources:
135
+ * post:
136
+ * summary: Create a new resource
137
+ * tags: [Resources]
138
+ * security:
139
+ * - bearerAuth: []
140
+ * requestBody:
141
+ * required: true
142
+ * content:
143
+ * application/json:
144
+ * schema:
145
+ * type: object
146
+ * required:
147
+ * - name
148
+ * properties:
149
+ * name:
150
+ * type: string
151
+ * description:
152
+ * type: string
153
+ * responses:
154
+ * 201:
155
+ * description: Resource created
156
+ */
157
+ router.post(
158
+ '/',
159
+ requireAuth,
160
+ validateRequest(CreateSchema),
161
+ async (req, res, next) => {
162
+ try {
163
+ const data = req.body as CreateDto;
164
+ const userId = (req as any).userId;
165
+
166
+ // TODO: Replace with actual database insert
167
+ const resource = {
168
+ id: 'generated-id',
169
+ ...data,
170
+ userId,
171
+ createdAt: new Date().toISOString(),
172
+ updatedAt: new Date().toISOString()
173
+ };
174
+
175
+ res.status(201).json({ data: resource });
176
+ } catch (err) {
177
+ next(err);
178
+ }
179
+ }
180
+ );
181
+
182
+ /**
183
+ * @openapi
184
+ * /api/resources/{id}:
185
+ * put:
186
+ * summary: Update a resource
187
+ * tags: [Resources]
188
+ * security:
189
+ * - bearerAuth: []
190
+ * parameters:
191
+ * - in: path
192
+ * name: id
193
+ * required: true
194
+ * schema:
195
+ * type: string
196
+ * requestBody:
197
+ * required: true
198
+ * content:
199
+ * application/json:
200
+ * schema:
201
+ * type: object
202
+ * properties:
203
+ * name:
204
+ * type: string
205
+ * description:
206
+ * type: string
207
+ * responses:
208
+ * 200:
209
+ * description: Resource updated
210
+ * 404:
211
+ * description: Resource not found
212
+ */
213
+ router.put(
214
+ '/:id',
215
+ requireAuth,
216
+ validateRequest(UpdateSchema),
217
+ async (req, res, next) => {
218
+ try {
219
+ const { id } = req.params;
220
+ const data = req.body as UpdateDto;
221
+ const userId = (req as any).userId;
222
+
223
+ // TODO: Replace with actual database query
224
+ const resource = null;
225
+
226
+ if (!resource) {
227
+ throw new AppError('Resource not found', 404, 'RESOURCE_NOT_FOUND');
228
+ }
229
+
230
+ // Check authorization
231
+ if ((resource as any).userId !== userId) {
232
+ throw new AppError('Forbidden', 403, 'FORBIDDEN');
233
+ }
234
+
235
+ // TODO: Replace with actual database update
236
+ const updated = {
237
+ ...resource,
238
+ ...data,
239
+ updatedAt: new Date().toISOString()
240
+ };
241
+
242
+ res.json({ data: updated });
243
+ } catch (err) {
244
+ next(err);
245
+ }
246
+ }
247
+ );
248
+
249
+ /**
250
+ * @openapi
251
+ * /api/resources/{id}:
252
+ * delete:
253
+ * summary: Delete a resource
254
+ * tags: [Resources]
255
+ * security:
256
+ * - bearerAuth: []
257
+ * parameters:
258
+ * - in: path
259
+ * name: id
260
+ * required: true
261
+ * schema:
262
+ * type: string
263
+ * responses:
264
+ * 204:
265
+ * description: Resource deleted
266
+ * 404:
267
+ * description: Resource not found
268
+ */
269
+ router.delete('/:id', requireAuth, async (req, res, next) => {
270
+ try {
271
+ const { id } = req.params;
272
+ const userId = (req as any).userId;
273
+
274
+ // TODO: Replace with actual database query
275
+ const resource = null;
276
+
277
+ if (!resource) {
278
+ throw new AppError('Resource not found', 404, 'RESOURCE_NOT_FOUND');
279
+ }
280
+
281
+ // Check authorization
282
+ if ((resource as any).userId !== userId) {
283
+ throw new AppError('Forbidden', 403, 'FORBIDDEN');
284
+ }
285
+
286
+ // TODO: Replace with actual database delete
287
+
288
+ res.status(204).send();
289
+ } catch (err) {
290
+ next(err);
291
+ }
292
+ });
293
+
294
+ export default router;
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: docs-sync
3
+ description: Ensure documentation stays in sync with code changes. Trigger when modifying CLI commands, config options, directory structure, or public APIs.
4
+ when-to-use: When adding, removing, or changing CLI commands, config fields, directory layout, or user-facing behavior
5
+ ---
6
+
7
+ # Documentation Sync
8
+
9
+ When making changes that affect user-facing behavior, always update the corresponding documentation.
10
+
11
+ ## What to check
12
+
13
+ ### CLI commands changed?
14
+ - Update `README.md` commands table
15
+ - Update `CLAUDE.md` commands section
16
+ - Update `--help` descriptions in `src/cli.ts`
17
+
18
+ ### Config options changed?
19
+ - Update `README.md` Configuration Reference table
20
+ - Update `README.md` config example block
21
+ - Update `CLAUDE.md` if it references config
22
+ - Update the config template in `src/commands/init.ts`
23
+
24
+ ### Directory structure changed?
25
+ - Update `CLAUDE.md` Directory Structure section
26
+ - Update `README.md` Project Artifacts table
27
+
28
+ ### New skill or agent added?
29
+ - Skill: create `templates/skills/<name>/SKILL.md` with frontmatter
30
+ - Agent: create `templates/agents/<name>.md` with frontmatter
31
+ - Run `alpha-loop sync` to distribute
32
+
33
+ ### Public API or behavior changed?
34
+ - Update relevant README sections
35
+ - Update CLAUDE.md if architectural
36
+
37
+ ## Rules
38
+
39
+ - Documentation updates MUST be in the same commit as the code change
40
+ - Never leave README or CLAUDE.md referencing commands, options, or paths that no longer exist
41
+ - When removing a feature, search docs for all references before committing
42
+ - Keep README under 300 lines, CLAUDE.md under 200 lines