specweave 0.23.18 → 0.24.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 (167) hide show
  1. package/.claude-plugin/marketplace.json +93 -49
  2. package/CLAUDE.md +137 -4
  3. package/dist/src/cli/helpers/ado-area-path-mapper.d.ts +89 -0
  4. package/dist/src/cli/helpers/ado-area-path-mapper.d.ts.map +1 -0
  5. package/dist/src/cli/helpers/ado-area-path-mapper.js +213 -0
  6. package/dist/src/cli/helpers/ado-area-path-mapper.js.map +1 -0
  7. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts +29 -0
  8. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts.map +1 -0
  9. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js +109 -0
  10. package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js.map +1 -0
  11. package/dist/src/cli/helpers/issue-tracker/ado.d.ts +1 -0
  12. package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
  13. package/dist/src/cli/helpers/issue-tracker/ado.js +2 -0
  14. package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
  15. package/dist/src/cli/helpers/smart-filter.d.ts +83 -0
  16. package/dist/src/cli/helpers/smart-filter.d.ts.map +1 -0
  17. package/dist/src/cli/helpers/smart-filter.js +265 -0
  18. package/dist/src/cli/helpers/smart-filter.js.map +1 -0
  19. package/dist/src/core/qa/quality-gate-decider.d.ts +1 -1
  20. package/dist/src/core/qa/quality-gate-decider.js +2 -2
  21. package/dist/src/core/qa/quality-gate-decider.js.map +1 -1
  22. package/dist/src/core/qa/risk-calculator.d.ts +2 -2
  23. package/dist/src/core/qa/risk-calculator.js +2 -2
  24. package/dist/src/core/validators/ac-presence-validator.d.ts +56 -0
  25. package/dist/src/core/validators/ac-presence-validator.d.ts.map +1 -0
  26. package/dist/src/core/validators/ac-presence-validator.js +149 -0
  27. package/dist/src/core/validators/ac-presence-validator.js.map +1 -0
  28. package/dist/src/integrations/ado/area-path-mapper.d.ts +137 -0
  29. package/dist/src/integrations/ado/area-path-mapper.d.ts.map +1 -0
  30. package/dist/src/integrations/ado/area-path-mapper.js +267 -0
  31. package/dist/src/integrations/ado/area-path-mapper.js.map +1 -0
  32. package/dist/src/integrations/jira/filter-processor.d.ts +126 -0
  33. package/dist/src/integrations/jira/filter-processor.d.ts.map +1 -0
  34. package/dist/src/integrations/jira/filter-processor.js +207 -0
  35. package/dist/src/integrations/jira/filter-processor.js.map +1 -0
  36. package/dist/src/integrations/jira/jira-client.d.ts +13 -0
  37. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  38. package/dist/src/integrations/jira/jira-client.js +33 -0
  39. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  40. package/dist/src/utils/ac-embedder.d.ts +63 -0
  41. package/dist/src/utils/ac-embedder.d.ts.map +1 -0
  42. package/dist/src/utils/ac-embedder.js +217 -0
  43. package/dist/src/utils/ac-embedder.js.map +1 -0
  44. package/dist/src/utils/env-manager.d.ts +86 -0
  45. package/dist/src/utils/env-manager.d.ts.map +1 -0
  46. package/dist/src/utils/env-manager.js +188 -0
  47. package/dist/src/utils/env-manager.js.map +1 -0
  48. package/package.json +1 -1
  49. package/plugins/specweave/.claude-plugin/plugin.json +1 -1
  50. package/plugins/specweave/agents/AGENTS-INDEX.md +1 -1
  51. package/plugins/specweave/agents/increment-quality-judge-v2/AGENT.md +9 -9
  52. package/plugins/specweave/commands/specweave-do.md +37 -0
  53. package/plugins/specweave/commands/specweave-done.md +159 -0
  54. package/plugins/specweave/commands/specweave-embed-acs.md +446 -0
  55. package/plugins/specweave/commands/specweave-next.md +148 -3
  56. package/plugins/specweave/commands/specweave-qa.md +2 -2
  57. package/plugins/specweave/hooks/pre-increment-start.sh +168 -0
  58. package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
  59. package/plugins/specweave-ado/.claude-plugin/plugin.json +1 -1
  60. package/plugins/specweave-ado/commands/specweave-ado-import-projects.md +331 -0
  61. package/plugins/specweave-alternatives/.claude-plugin/plugin.json +10 -0
  62. package/plugins/specweave-alternatives/commands/alternatives-analyze.md +336 -0
  63. package/plugins/specweave-alternatives/skills/architecture-alternatives/SKILL.md +651 -0
  64. package/plugins/specweave-alternatives/skills/bmad-method/SKILL.md +420 -0
  65. package/plugins/specweave-alternatives/skills/spec-kit-expert/SKILL.md +487 -0
  66. package/plugins/specweave-backend/commands/api-scaffold.md +80 -0
  67. package/plugins/specweave-backend/commands/crud-generate.md +109 -0
  68. package/plugins/specweave-backend/commands/migration-generate.md +139 -0
  69. package/plugins/specweave-confluent/commands/connector-deploy.md +154 -0
  70. package/plugins/specweave-confluent/commands/ksqldb-query.md +179 -0
  71. package/plugins/specweave-confluent/commands/schema-register.md +123 -0
  72. package/plugins/specweave-core/.claude-plugin/plugin.json +21 -0
  73. package/plugins/specweave-core/commands/architecture-review.md +288 -0
  74. package/plugins/specweave-core/commands/code-review.md +213 -0
  75. package/plugins/specweave-core/commands/refactor-plan.md +249 -0
  76. package/plugins/specweave-core/skills/code-quality/SKILL.md +157 -0
  77. package/plugins/specweave-core/skills/design-patterns/SKILL.md +244 -0
  78. package/plugins/specweave-core/skills/software-architecture/SKILL.md +83 -0
  79. package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +22 -0
  80. package/plugins/specweave-cost-optimizer/commands/cost-analyze.md +360 -0
  81. package/plugins/specweave-cost-optimizer/commands/cost-optimize.md +480 -0
  82. package/plugins/specweave-cost-optimizer/skills/aws-cost-expert/SKILL.md +416 -0
  83. package/plugins/specweave-cost-optimizer/skills/cloud-pricing/SKILL.md +325 -0
  84. package/plugins/specweave-cost-optimizer/skills/cost-optimization/SKILL.md +337 -0
  85. package/plugins/specweave-diagrams/.claude-plugin/plugin.json +1 -1
  86. package/plugins/specweave-diagrams/commands/diagrams-generate.md +168 -0
  87. package/plugins/specweave-docs/.claude-plugin/plugin.json +10 -0
  88. package/plugins/specweave-docs/commands/docs-generate.md +441 -0
  89. package/plugins/specweave-docs/commands/docs-init.md +334 -0
  90. package/plugins/specweave-docs/skills/docusaurus/SKILL.md +581 -0
  91. package/plugins/specweave-docs/skills/spec-driven-brainstorming/SKILL.md +689 -0
  92. package/plugins/specweave-docs/skills/technical-writing/SKILL.md +1039 -0
  93. package/plugins/specweave-docs-preview/.claude-plugin/plugin.json +1 -1
  94. package/plugins/specweave-figma/.claude-plugin/plugin.json +23 -0
  95. package/plugins/specweave-figma/commands/figma-import.md +690 -0
  96. package/plugins/specweave-figma/commands/figma-to-react.md +834 -0
  97. package/plugins/specweave-figma/commands/figma-tokens.md +815 -0
  98. package/plugins/specweave-frontend/.claude-plugin/plugin.json +21 -0
  99. package/plugins/specweave-frontend/agents/frontend-architect/AGENT.md +387 -0
  100. package/plugins/specweave-frontend/agents/frontend-architect/README.md +385 -0
  101. package/plugins/specweave-frontend/agents/frontend-architect/examples.md +590 -0
  102. package/plugins/specweave-frontend/agents/frontend-architect/templates/component-template.tsx +152 -0
  103. package/plugins/specweave-frontend/agents/frontend-architect/templates/hook-template.ts +311 -0
  104. package/plugins/specweave-frontend/agents/frontend-architect/templates/page-template.tsx +228 -0
  105. package/plugins/specweave-frontend/commands/component-generate.md +510 -0
  106. package/plugins/specweave-frontend/commands/design-system-init.md +494 -0
  107. package/plugins/specweave-frontend/commands/frontend-scaffold.md +207 -0
  108. package/plugins/specweave-frontend/commands/nextjs-setup.md +396 -0
  109. package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +278 -0
  110. package/plugins/specweave-frontend/skills/frontend/SKILL.md +420 -0
  111. package/plugins/specweave-frontend/skills/nextjs/SKILL.md +546 -0
  112. package/plugins/specweave-github/.claude-plugin/plugin.json +1 -1
  113. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +194 -0
  114. package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +1 -1
  115. package/plugins/specweave-jira/.claude-plugin/plugin.json +1 -1
  116. package/plugins/specweave-jira/commands/import-projects.js +183 -0
  117. package/plugins/specweave-jira/commands/import-projects.md +97 -0
  118. package/plugins/specweave-jira/commands/import-projects.ts +288 -0
  119. package/plugins/specweave-jira/commands/specweave-jira-import-projects.md +298 -0
  120. package/plugins/specweave-kafka/.claude-plugin/plugin.json +1 -1
  121. package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +1 -1
  122. package/plugins/specweave-kubernetes/commands/cluster-setup.md +262 -0
  123. package/plugins/specweave-kubernetes/commands/deployment-generate.md +242 -0
  124. package/plugins/specweave-kubernetes/commands/helm-scaffold.md +333 -0
  125. package/plugins/specweave-ml/.claude-plugin/plugin.json +1 -1
  126. package/plugins/specweave-mobile/commands/app-scaffold.md +233 -0
  127. package/plugins/specweave-mobile/commands/build-config.md +256 -0
  128. package/plugins/specweave-mobile/commands/screen-generate.md +289 -0
  129. package/plugins/specweave-n8n/.claude-plugin/plugin.json +1 -1
  130. package/plugins/specweave-plugin-dev/.claude-plugin/plugin.json +13 -12
  131. package/plugins/specweave-plugin-dev/commands/plugin-create.md +333 -0
  132. package/plugins/specweave-plugin-dev/commands/plugin-publish.md +339 -0
  133. package/plugins/specweave-plugin-dev/commands/plugin-test.md +293 -0
  134. package/plugins/specweave-plugin-dev/skills/claude-sdk/SKILL.md +162 -0
  135. package/plugins/specweave-plugin-dev/skills/marketplace-publishing/SKILL.md +263 -0
  136. package/plugins/specweave-plugin-dev/skills/plugin-development/SKILL.md +316 -0
  137. package/plugins/specweave-release/.claude-plugin/plugin.json +1 -1
  138. package/plugins/specweave-release/commands/specweave-release-npm.md +110 -0
  139. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +168 -0
  140. package/plugins/specweave-testing/.claude-plugin/plugin.json +21 -0
  141. package/plugins/specweave-testing/agents/qa-engineer/AGENT.md +797 -0
  142. package/plugins/specweave-testing/agents/qa-engineer/README.md +443 -0
  143. package/plugins/specweave-testing/agents/qa-engineer/templates/playwright-e2e-test.ts +470 -0
  144. package/plugins/specweave-testing/agents/qa-engineer/templates/test-data-factory.ts +507 -0
  145. package/plugins/specweave-testing/agents/qa-engineer/templates/vitest-unit-test.ts +400 -0
  146. package/plugins/specweave-testing/agents/qa-engineer/test-strategies.md +726 -0
  147. package/plugins/specweave-testing/commands/e2e-setup.md +1081 -0
  148. package/plugins/specweave-testing/commands/test-coverage.md +979 -0
  149. package/plugins/specweave-testing/commands/test-generate.md +1156 -0
  150. package/plugins/specweave-testing/commands/test-init.md +409 -0
  151. package/plugins/specweave-testing/skills/e2e-playwright/SKILL.md +769 -0
  152. package/plugins/specweave-testing/skills/tdd-expert/SKILL.md +934 -0
  153. package/plugins/specweave-testing/skills/unit-testing-expert/SKILL.md +1011 -0
  154. package/plugins/specweave-tooling/.claude-plugin/plugin.json +22 -0
  155. package/plugins/specweave-tooling/commands/specweave-tooling-skill-create.md +691 -0
  156. package/plugins/specweave-tooling/commands/specweave-tooling-skill-package.md +751 -0
  157. package/plugins/specweave-tooling/commands/specweave-tooling-skill-validate.md +858 -0
  158. package/plugins/specweave-ui/.claude-plugin/plugin.json +10 -0
  159. package/plugins/specweave-ui/commands/ui-automate.md +199 -0
  160. package/plugins/specweave-ui/commands/ui-inspect.md +70 -0
  161. package/plugins/specweave-ui/skills/browser-automation/SKILL.md +314 -0
  162. package/plugins/specweave-ui/skills/ui-testing/SKILL.md +716 -0
  163. package/plugins/specweave-ui/skills/visual-regression/SKILL.md +728 -0
  164. package/plugins/specweave/commands/check-hooks.md +0 -257
  165. package/plugins/specweave/commands/specweave-archive-increments.md +0 -82
  166. package/plugins/specweave-plugin-dev/skills/plugin-expert/SKILL.md +0 -1231
  167. /package/plugins/specweave/{agents/code-reviewer.md → skills/code-reviewer/SKILL.md} +0 -0
@@ -0,0 +1,507 @@
1
+ /**
2
+ * Test Data Factory Template
3
+ *
4
+ * This template demonstrates best practices for creating reusable
5
+ * test data factories using the Factory pattern.
6
+ *
7
+ * Benefits:
8
+ * - Consistent test data generation
9
+ * - Easy to customize with overrides
10
+ * - Reduces test setup boilerplate
11
+ * - Type-safe with TypeScript
12
+ */
13
+
14
+ import { faker } from '@faker-js/faker';
15
+
16
+ // ============================================================================
17
+ // TYPES
18
+ // ============================================================================
19
+
20
+ export interface User {
21
+ id: string;
22
+ email: string;
23
+ username: string;
24
+ firstName: string;
25
+ lastName: string;
26
+ role: 'admin' | 'user' | 'guest';
27
+ isActive: boolean;
28
+ createdAt: Date;
29
+ updatedAt: Date;
30
+ profile?: UserProfile;
31
+ }
32
+
33
+ export interface UserProfile {
34
+ bio: string;
35
+ avatar: string;
36
+ phoneNumber: string;
37
+ address: Address;
38
+ }
39
+
40
+ export interface Address {
41
+ street: string;
42
+ city: string;
43
+ state: string;
44
+ zipCode: string;
45
+ country: string;
46
+ }
47
+
48
+ export interface Product {
49
+ id: string;
50
+ name: string;
51
+ description: string;
52
+ price: number;
53
+ category: string;
54
+ inStock: boolean;
55
+ quantity: number;
56
+ imageUrl: string;
57
+ createdAt: Date;
58
+ }
59
+
60
+ export interface Order {
61
+ id: string;
62
+ userId: string;
63
+ items: OrderItem[];
64
+ subtotal: number;
65
+ tax: number;
66
+ total: number;
67
+ status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled';
68
+ shippingAddress: Address;
69
+ createdAt: Date;
70
+ updatedAt: Date;
71
+ }
72
+
73
+ export interface OrderItem {
74
+ productId: string;
75
+ quantity: number;
76
+ price: number;
77
+ }
78
+
79
+ // ============================================================================
80
+ // FACTORY FUNCTIONS
81
+ // ============================================================================
82
+
83
+ /**
84
+ * User Factory
85
+ *
86
+ * Creates realistic user test data with sensible defaults
87
+ */
88
+ export class UserFactory {
89
+ /**
90
+ * Create a single user
91
+ *
92
+ * @param overrides - Partial user object to override defaults
93
+ * @returns Complete user object
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * const admin = UserFactory.create({ role: 'admin' });
98
+ * const inactiveUser = UserFactory.create({ isActive: false });
99
+ * ```
100
+ */
101
+ static create(overrides: Partial<User> = {}): User {
102
+ const firstName = faker.person.firstName();
103
+ const lastName = faker.person.lastName();
104
+ const email =
105
+ overrides.email || faker.internet.email({ firstName, lastName });
106
+
107
+ return {
108
+ id: faker.string.uuid(),
109
+ email,
110
+ username: faker.internet.userName({ firstName, lastName }),
111
+ firstName,
112
+ lastName,
113
+ role: 'user',
114
+ isActive: true,
115
+ createdAt: faker.date.past(),
116
+ updatedAt: faker.date.recent(),
117
+ ...overrides,
118
+ };
119
+ }
120
+
121
+ /**
122
+ * Create multiple users
123
+ *
124
+ * @param count - Number of users to create
125
+ * @param overrides - Partial user object to override defaults for all users
126
+ * @returns Array of user objects
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * const users = UserFactory.createMany(5);
131
+ * const admins = UserFactory.createMany(3, { role: 'admin' });
132
+ * ```
133
+ */
134
+ static createMany(count: number, overrides: Partial<User> = {}): User[] {
135
+ return Array.from({ length: count }, () => this.create(overrides));
136
+ }
137
+
138
+ /**
139
+ * Create admin user
140
+ *
141
+ * @param overrides - Partial user object to override defaults
142
+ * @returns Admin user object
143
+ */
144
+ static createAdmin(overrides: Partial<User> = {}): User {
145
+ return this.create({
146
+ role: 'admin',
147
+ ...overrides,
148
+ });
149
+ }
150
+
151
+ /**
152
+ * Create user with complete profile
153
+ *
154
+ * @param overrides - Partial user object to override defaults
155
+ * @returns User with profile object
156
+ */
157
+ static createWithProfile(overrides: Partial<User> = {}): User {
158
+ return this.create({
159
+ profile: {
160
+ bio: faker.person.bio(),
161
+ avatar: faker.image.avatar(),
162
+ phoneNumber: faker.phone.number(),
163
+ address: AddressFactory.create(),
164
+ },
165
+ ...overrides,
166
+ });
167
+ }
168
+
169
+ /**
170
+ * Create inactive user
171
+ *
172
+ * @param overrides - Partial user object to override defaults
173
+ * @returns Inactive user object
174
+ */
175
+ static createInactive(overrides: Partial<User> = {}): User {
176
+ return this.create({
177
+ isActive: false,
178
+ ...overrides,
179
+ });
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Address Factory
185
+ *
186
+ * Creates realistic address test data
187
+ */
188
+ export class AddressFactory {
189
+ static create(overrides: Partial<Address> = {}): Address {
190
+ return {
191
+ street: faker.location.streetAddress(),
192
+ city: faker.location.city(),
193
+ state: faker.location.state(),
194
+ zipCode: faker.location.zipCode(),
195
+ country: faker.location.country(),
196
+ ...overrides,
197
+ };
198
+ }
199
+
200
+ static createUS(overrides: Partial<Address> = {}): Address {
201
+ return this.create({
202
+ country: 'United States',
203
+ zipCode: faker.location.zipCode('#####'),
204
+ state: faker.location.state({ abbreviated: true }),
205
+ ...overrides,
206
+ });
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Product Factory
212
+ *
213
+ * Creates realistic product test data
214
+ */
215
+ export class ProductFactory {
216
+ static create(overrides: Partial<Product> = {}): Product {
217
+ return {
218
+ id: faker.string.uuid(),
219
+ name: faker.commerce.productName(),
220
+ description: faker.commerce.productDescription(),
221
+ price: parseFloat(faker.commerce.price()),
222
+ category: faker.commerce.department(),
223
+ inStock: true,
224
+ quantity: faker.number.int({ min: 0, max: 100 }),
225
+ imageUrl: faker.image.url(),
226
+ createdAt: faker.date.past(),
227
+ ...overrides,
228
+ };
229
+ }
230
+
231
+ static createMany(count: number, overrides: Partial<Product> = {}): Product[] {
232
+ return Array.from({ length: count }, () => this.create(overrides));
233
+ }
234
+
235
+ static createOutOfStock(overrides: Partial<Product> = {}): Product {
236
+ return this.create({
237
+ inStock: false,
238
+ quantity: 0,
239
+ ...overrides,
240
+ });
241
+ }
242
+
243
+ static createExpensive(overrides: Partial<Product> = {}): Product {
244
+ return this.create({
245
+ price: faker.number.int({ min: 1000, max: 10000 }),
246
+ ...overrides,
247
+ });
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Order Factory
253
+ *
254
+ * Creates realistic order test data with items
255
+ */
256
+ export class OrderFactory {
257
+ static create(overrides: Partial<Order> = {}): Order {
258
+ const items = overrides.items || [
259
+ {
260
+ productId: faker.string.uuid(),
261
+ quantity: faker.number.int({ min: 1, max: 5 }),
262
+ price: parseFloat(faker.commerce.price()),
263
+ },
264
+ ];
265
+
266
+ const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
267
+ const tax = subtotal * 0.08; // 8% tax
268
+ const total = subtotal + tax;
269
+
270
+ return {
271
+ id: faker.string.uuid(),
272
+ userId: faker.string.uuid(),
273
+ items,
274
+ subtotal,
275
+ tax,
276
+ total,
277
+ status: 'pending',
278
+ shippingAddress: AddressFactory.createUS(),
279
+ createdAt: faker.date.recent(),
280
+ updatedAt: faker.date.recent(),
281
+ ...overrides,
282
+ };
283
+ }
284
+
285
+ static createMany(count: number, overrides: Partial<Order> = {}): Order[] {
286
+ return Array.from({ length: count }, () => this.create(overrides));
287
+ }
288
+
289
+ static createWithItems(items: OrderItem[], overrides: Partial<Order> = {}): Order {
290
+ return this.create({ items, ...overrides });
291
+ }
292
+
293
+ static createShipped(overrides: Partial<Order> = {}): Order {
294
+ return this.create({
295
+ status: 'shipped',
296
+ ...overrides,
297
+ });
298
+ }
299
+
300
+ static createCancelled(overrides: Partial<Order> = {}): Order {
301
+ return this.create({
302
+ status: 'cancelled',
303
+ ...overrides,
304
+ });
305
+ }
306
+ }
307
+
308
+ // ============================================================================
309
+ // BUILDER PATTERN (Advanced)
310
+ // ============================================================================
311
+
312
+ /**
313
+ * User Builder
314
+ *
315
+ * Provides a fluent interface for building complex user objects
316
+ *
317
+ * @example
318
+ * ```ts
319
+ * const user = new UserBuilder()
320
+ * .withEmail('admin@example.com')
321
+ * .withRole('admin')
322
+ * .withProfile()
323
+ * .build();
324
+ * ```
325
+ */
326
+ export class UserBuilder {
327
+ private user: Partial<User> = {};
328
+
329
+ withId(id: string): this {
330
+ this.user.id = id;
331
+ return this;
332
+ }
333
+
334
+ withEmail(email: string): this {
335
+ this.user.email = email;
336
+ return this;
337
+ }
338
+
339
+ withUsername(username: string): this {
340
+ this.user.username = username;
341
+ return this;
342
+ }
343
+
344
+ withName(firstName: string, lastName: string): this {
345
+ this.user.firstName = firstName;
346
+ this.user.lastName = lastName;
347
+ return this;
348
+ }
349
+
350
+ withRole(role: User['role']): this {
351
+ this.user.role = role;
352
+ return this;
353
+ }
354
+
355
+ withProfile(profile?: UserProfile): this {
356
+ this.user.profile = profile || {
357
+ bio: faker.person.bio(),
358
+ avatar: faker.image.avatar(),
359
+ phoneNumber: faker.phone.number(),
360
+ address: AddressFactory.create(),
361
+ };
362
+ return this;
363
+ }
364
+
365
+ inactive(): this {
366
+ this.user.isActive = false;
367
+ return this;
368
+ }
369
+
370
+ active(): this {
371
+ this.user.isActive = true;
372
+ return this;
373
+ }
374
+
375
+ build(): User {
376
+ return UserFactory.create(this.user);
377
+ }
378
+ }
379
+
380
+ // ============================================================================
381
+ // USAGE EXAMPLES
382
+ // ============================================================================
383
+
384
+ /**
385
+ * Example: Simple user creation
386
+ */
387
+ export function exampleSimpleUser() {
388
+ const user = UserFactory.create();
389
+ const admin = UserFactory.createAdmin();
390
+ const users = UserFactory.createMany(5);
391
+
392
+ return { user, admin, users };
393
+ }
394
+
395
+ /**
396
+ * Example: Customized user creation
397
+ */
398
+ export function exampleCustomUser() {
399
+ const user = UserFactory.create({
400
+ email: 'custom@example.com',
401
+ role: 'admin',
402
+ isActive: false,
403
+ });
404
+
405
+ return user;
406
+ }
407
+
408
+ /**
409
+ * Example: Builder pattern
410
+ */
411
+ export function exampleBuilder() {
412
+ const user = new UserBuilder()
413
+ .withEmail('builder@example.com')
414
+ .withName('John', 'Doe')
415
+ .withRole('admin')
416
+ .withProfile()
417
+ .active()
418
+ .build();
419
+
420
+ return user;
421
+ }
422
+
423
+ /**
424
+ * Example: Order with products
425
+ */
426
+ export function exampleOrder() {
427
+ // Create products
428
+ const products = ProductFactory.createMany(3);
429
+
430
+ // Create order items from products
431
+ const items: OrderItem[] = products.map((product) => ({
432
+ productId: product.id,
433
+ quantity: faker.number.int({ min: 1, max: 3 }),
434
+ price: product.price,
435
+ }));
436
+
437
+ // Create order with items
438
+ const order = OrderFactory.createWithItems(items);
439
+
440
+ return { products, order };
441
+ }
442
+
443
+ // ============================================================================
444
+ // TEST USAGE
445
+ // ============================================================================
446
+
447
+ /**
448
+ * Example test using factories
449
+ */
450
+ import { describe, it, expect } from 'vitest';
451
+
452
+ describe('UserService (using factories)', () => {
453
+ it('should create user', () => {
454
+ // ARRANGE
455
+ const userData = UserFactory.create();
456
+
457
+ // ACT
458
+ const result = userService.create(userData);
459
+
460
+ // ASSERT
461
+ expect(result.id).toBeDefined();
462
+ expect(result.email).toBe(userData.email);
463
+ });
464
+
465
+ it('should only allow admins to delete users', () => {
466
+ // ARRANGE
467
+ const admin = UserFactory.createAdmin();
468
+ const regularUser = UserFactory.create();
469
+
470
+ // ACT & ASSERT
471
+ expect(() => userService.deleteUser(regularUser.id, admin)).not.toThrow();
472
+ expect(() => userService.deleteUser(admin.id, regularUser)).toThrow('Unauthorized');
473
+ });
474
+
475
+ it('should calculate order total correctly', () => {
476
+ // ARRANGE
477
+ const order = OrderFactory.create({
478
+ items: [
479
+ { productId: '1', quantity: 2, price: 50 },
480
+ { productId: '2', quantity: 1, price: 30 },
481
+ ],
482
+ });
483
+
484
+ // ACT
485
+ const total = orderService.calculateTotal(order);
486
+
487
+ // ASSERT
488
+ expect(total).toBe(140.4); // (50*2 + 30*1) * 1.08 tax
489
+ });
490
+ });
491
+
492
+ // ============================================================================
493
+ // BEST PRACTICES
494
+ // ============================================================================
495
+
496
+ /*
497
+ ✅ Use realistic data (faker.js)
498
+ ✅ Provide sensible defaults
499
+ ✅ Allow overrides for customization
500
+ ✅ Type-safe with TypeScript
501
+ ✅ Create helper methods (createAdmin, createInactive, etc.)
502
+ ✅ Builder pattern for complex objects
503
+ ✅ Consistent naming (create, createMany, createWith...)
504
+ ✅ Document with JSDoc
505
+ ✅ Export all factories for reuse
506
+ ✅ Keep factories simple and focused
507
+ */