skillstore-cli 1.0.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 (231) hide show
  1. package/README.md +95 -0
  2. package/data/bundles/devflow-complete.json +19 -0
  3. package/data/free-skills/devflow-agile/manifest.json +19 -0
  4. package/data/free-skills/devflow-agile/plugin/commands/agile/retro.md +23 -0
  5. package/data/free-skills/devflow-agile/plugin/commands/agile/review.md +21 -0
  6. package/data/free-skills/devflow-agile/plugin/commands/agile/sprint.md +30 -0
  7. package/data/free-skills/devflow-agile/plugin/commands/agile/standup.md +20 -0
  8. package/data/free-skills/devflow-agile/plugin/commands/agile.md +35 -0
  9. package/data/free-skills/devflow-agile/plugin/commands/devflow.md +42 -0
  10. package/data/free-skills/devflow-agile/plugin/skills/developer/SKILL.md +93 -0
  11. package/data/free-skills/devflow-agile/plugin/skills/developer/assets/sample-output.md +182 -0
  12. package/data/free-skills/devflow-agile/plugin/skills/developer/references/clean-architecture.md +361 -0
  13. package/data/free-skills/devflow-agile/plugin/skills/developer/references/clean-code-guide.md +207 -0
  14. package/data/free-skills/devflow-agile/plugin/skills/developer/references/debugging-methodology.md +191 -0
  15. package/data/free-skills/devflow-agile/template/agents/agile-coach.md +76 -0
  16. package/data/free-skills/devflow-agile/template/workflows/agile-sprint-workflow.md +81 -0
  17. package/data/free-skills/devflow-bootstrap/manifest.json +8 -0
  18. package/data/free-skills/devflow-bootstrap/plugin/commands/bootstrap/auto.md +31 -0
  19. package/data/free-skills/devflow-bootstrap/plugin/commands/bootstrap.md +38 -0
  20. package/data/free-skills/devflow-bootstrap/plugin/commands/devflow.md +20 -0
  21. package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/SKILL.md +56 -0
  22. package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/assets/sample-output.md +216 -0
  23. package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/references/architecture-decisions.md +254 -0
  24. package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/references/stack-templates.md +400 -0
  25. package/data/free-skills/devflow-bootstrap/template/agents/bootstrap-specialist.md +56 -0
  26. package/data/free-skills/devflow-bootstrap/template/workflows/bootstrap-workflow.md +70 -0
  27. package/data/free-skills/devflow-docs/manifest.json +8 -0
  28. package/data/free-skills/devflow-docs/plugin/commands/devflow.md +20 -0
  29. package/data/free-skills/devflow-docs/plugin/commands/docs/generate.md +17 -0
  30. package/data/free-skills/devflow-docs/plugin/commands/docs/parse.md +19 -0
  31. package/data/free-skills/devflow-docs/plugin/commands/docs.md +26 -0
  32. package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/SKILL.md +59 -0
  33. package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/assets/sample-output.md +114 -0
  34. package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/references/extraction-techniques.md +115 -0
  35. package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/references/ocr-strategies.md +167 -0
  36. package/data/free-skills/devflow-docs/template/agents/docs-specialist.md +35 -0
  37. package/data/free-skills/devflow-docs/template/workflows/docs-workflow.md +70 -0
  38. package/data/free-skills/devflow-postproject/manifest.json +13 -0
  39. package/data/free-skills/devflow-postproject/plugin/commands/devflow.md +34 -0
  40. package/data/free-skills/devflow-postproject/plugin/commands/postproject/handover.md +21 -0
  41. package/data/free-skills/devflow-postproject/plugin/commands/postproject/retro.md +21 -0
  42. package/data/free-skills/devflow-postproject/plugin/commands/postproject/support.md +21 -0
  43. package/data/free-skills/devflow-postproject/plugin/commands/postproject.md +32 -0
  44. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/SKILL.md +70 -0
  45. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/assets/sample-output.md +79 -0
  46. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/references/facilitation-techniques.md +178 -0
  47. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/references/lessons-learned-template.md +118 -0
  48. package/data/free-skills/devflow-postproject/plugin/skills/retrospective/references/retro-techniques.md +100 -0
  49. package/data/free-skills/devflow-postproject/template/agents/transition-manager.md +71 -0
  50. package/data/free-skills/devflow-postproject/template/workflows/transition-workflow.md +72 -0
  51. package/data/free-skills/devflow-presale/manifest.json +15 -0
  52. package/data/free-skills/devflow-presale/plugin/commands/devflow.md +47 -0
  53. package/data/free-skills/devflow-presale/plugin/commands/presale/analyze.md +30 -0
  54. package/data/free-skills/devflow-presale/plugin/commands/presale/estimate.md +30 -0
  55. package/data/free-skills/devflow-presale/plugin/commands/presale/price.md +30 -0
  56. package/data/free-skills/devflow-presale/plugin/commands/presale/propose.md +30 -0
  57. package/data/free-skills/devflow-presale/plugin/commands/presale.md +42 -0
  58. package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/SKILL.md +63 -0
  59. package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/assets/sample-output.md +129 -0
  60. package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/references/extraction-framework.md +140 -0
  61. package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/references/output-template.md +132 -0
  62. package/data/free-skills/devflow-presale/template/agents/presale-lead.md +83 -0
  63. package/data/free-skills/devflow-presale/template/agents/proposal-reviewer.md +63 -0
  64. package/data/free-skills/devflow-presale/template/workflows/presale-workflow.md +70 -0
  65. package/data/registry/categories.json +7 -0
  66. package/data/registry/packages.json +184 -0
  67. package/data/shared/framework/agents/brainstormer.md +74 -0
  68. package/data/shared/framework/agents/code-reviewer.md +87 -0
  69. package/data/shared/framework/agents/debugger.md +84 -0
  70. package/data/shared/framework/agents/docs-manager.md +55 -0
  71. package/data/shared/framework/agents/git-manager.md +59 -0
  72. package/data/shared/framework/agents/planner.md +68 -0
  73. package/data/shared/framework/agents/researcher.md +66 -0
  74. package/data/shared/framework/agents/tester.md +65 -0
  75. package/data/shared/framework/commands/cook/auto.md +27 -0
  76. package/data/shared/framework/commands/cook.md +45 -0
  77. package/data/shared/framework/commands/fix/ci.md +21 -0
  78. package/data/shared/framework/commands/fix/test.md +26 -0
  79. package/data/shared/framework/commands/fix/types.md +29 -0
  80. package/data/shared/framework/commands/fix.md +26 -0
  81. package/data/shared/framework/commands/git/cm.md +37 -0
  82. package/data/shared/framework/commands/git/pr.md +40 -0
  83. package/data/shared/framework/config/CLAUDE.md.template +26 -0
  84. package/data/shared/framework/config/settings.json +41 -0
  85. package/data/shared/framework/config/skillstore.config.json +29 -0
  86. package/data/shared/framework/hooks/discord-notify.sh +85 -0
  87. package/data/shared/framework/hooks/docs-sync.sh +53 -0
  88. package/data/shared/framework/hooks/modularization-hook.js +103 -0
  89. package/data/shared/framework/hooks/notification.js +94 -0
  90. package/data/shared/framework/hooks/quality-gate.js +109 -0
  91. package/data/shared/framework/hooks/scout-block.js +77 -0
  92. package/data/shared/framework/hooks/telegram-notify.sh +77 -0
  93. package/data/shared/framework/protocols/error-recovery.md +80 -0
  94. package/data/shared/framework/protocols/orchestration-protocol.md +112 -0
  95. package/data/shared/framework/quality/review-protocol.md +76 -0
  96. package/data/shared/framework/quality/verification-protocol.md +66 -0
  97. package/data/shared/framework/rules/development-rules.md +75 -0
  98. package/data/shared/framework/skills/backend-development/SKILL.md +77 -0
  99. package/data/shared/framework/skills/backend-development/assets/sample-output.md +175 -0
  100. package/data/shared/framework/skills/backend-development/references/advanced-patterns.md +180 -0
  101. package/data/shared/framework/skills/backend-development/references/api-design-guide.md +160 -0
  102. package/data/shared/framework/skills/backend-development/references/architecture-patterns.md +183 -0
  103. package/data/shared/framework/skills/backend-development/references/observability-resilience.md +155 -0
  104. package/data/shared/framework/skills/backend-development/references/troubleshooting.md +199 -0
  105. package/data/shared/framework/skills/codebase-analysis/SKILL.md +72 -0
  106. package/data/shared/framework/skills/codebase-analysis/assets/sample-output.md +263 -0
  107. package/data/shared/framework/skills/codebase-analysis/references/analysis-techniques.md +241 -0
  108. package/data/shared/framework/skills/codebase-analysis/references/dependency-mapping.md +280 -0
  109. package/data/shared/framework/skills/codebase-analysis/references/tech-debt-assessment.md +208 -0
  110. package/data/shared/framework/skills/databases/SKILL.md +72 -0
  111. package/data/shared/framework/skills/databases/assets/sample-output.md +212 -0
  112. package/data/shared/framework/skills/databases/references/advanced-data-patterns.md +259 -0
  113. package/data/shared/framework/skills/databases/references/query-optimization.md +214 -0
  114. package/data/shared/framework/skills/databases/references/schema-design.md +159 -0
  115. package/data/shared/framework/skills/databases/references/troubleshooting.md +214 -0
  116. package/data/shared/framework/skills/debugging-investigation/SKILL.md +84 -0
  117. package/data/shared/framework/skills/debugging-investigation/assets/sample-output.md +314 -0
  118. package/data/shared/framework/skills/debugging-investigation/references/systematic-debugging.md +197 -0
  119. package/data/shared/framework/skills/debugging-investigation/references/tool-specific-guides.md +202 -0
  120. package/data/shared/framework/skills/debugging-investigation/references/troubleshooting-patterns.md +196 -0
  121. package/data/shared/framework/skills/frontend-development/SKILL.md +67 -0
  122. package/data/shared/framework/skills/frontend-development/assets/sample-output.md +110 -0
  123. package/data/shared/framework/skills/frontend-development/references/component-patterns.md +112 -0
  124. package/data/shared/framework/skills/frontend-development/references/performance-guide.md +169 -0
  125. package/data/shared/framework/skills/frontend-development/references/routing-forms-realtime.md +374 -0
  126. package/data/shared/framework/skills/frontend-development/references/ssr-rsc-patterns.md +284 -0
  127. package/data/shared/framework/skills/frontend-development/references/troubleshooting.md +154 -0
  128. package/data/shared/framework/skills/mobile-development/SKILL.md +67 -0
  129. package/data/shared/framework/skills/mobile-development/assets/sample-output.md +382 -0
  130. package/data/shared/framework/skills/mobile-development/references/mobile-patterns.md +681 -0
  131. package/data/shared/framework/skills/mobile-development/references/mobile-performance.md +524 -0
  132. package/data/shared/framework/skills/mobile-development/references/troubleshooting.md +158 -0
  133. package/data/shared/framework/skills/security-audit/SKILL.md +83 -0
  134. package/data/shared/framework/skills/security-audit/assets/sample-output.md +451 -0
  135. package/data/shared/framework/skills/security-audit/references/owasp-checklist.md +580 -0
  136. package/data/shared/framework/skills/security-audit/references/secure-coding-patterns.md +433 -0
  137. package/data/shared/framework/skills/security-audit/references/vulnerability-remediation.md +331 -0
  138. package/data/shared/framework/skills/ui-generation/SKILL.md +70 -0
  139. package/data/shared/framework/skills/ui-generation/assets/sample-output.md +139 -0
  140. package/data/shared/framework/skills/ui-generation/references/accessibility-responsive.md +127 -0
  141. package/data/shared/framework/skills/ui-generation/references/compound-components.md +252 -0
  142. package/data/shared/framework/skills/ui-generation/references/generation-patterns.md +110 -0
  143. package/data/shared/framework/skills/ui-generation/references/storybook-design-system.md +278 -0
  144. package/data/shared/framework/skills/ui-generation/references/troubleshooting.md +198 -0
  145. package/data/shared/framework/workflows/documentation-management.md +58 -0
  146. package/data/shared/framework/workflows/primary-workflow.md +88 -0
  147. package/dist/commands/activate.d.ts +3 -0
  148. package/dist/commands/activate.d.ts.map +1 -0
  149. package/dist/commands/activate.js +34 -0
  150. package/dist/commands/activate.js.map +1 -0
  151. package/dist/commands/bundle.d.ts +3 -0
  152. package/dist/commands/bundle.d.ts.map +1 -0
  153. package/dist/commands/bundle.js +64 -0
  154. package/dist/commands/bundle.js.map +1 -0
  155. package/dist/commands/install.d.ts +3 -0
  156. package/dist/commands/install.d.ts.map +1 -0
  157. package/dist/commands/install.js +99 -0
  158. package/dist/commands/install.js.map +1 -0
  159. package/dist/commands/list.d.ts +3 -0
  160. package/dist/commands/list.d.ts.map +1 -0
  161. package/dist/commands/list.js +37 -0
  162. package/dist/commands/list.js.map +1 -0
  163. package/dist/commands/search.d.ts +3 -0
  164. package/dist/commands/search.d.ts.map +1 -0
  165. package/dist/commands/search.js +30 -0
  166. package/dist/commands/search.js.map +1 -0
  167. package/dist/commands/status.d.ts +3 -0
  168. package/dist/commands/status.d.ts.map +1 -0
  169. package/dist/commands/status.js +35 -0
  170. package/dist/commands/status.js.map +1 -0
  171. package/dist/commands/update.d.ts +3 -0
  172. package/dist/commands/update.d.ts.map +1 -0
  173. package/dist/commands/update.js +68 -0
  174. package/dist/commands/update.js.map +1 -0
  175. package/dist/download/cache.d.ts +3 -0
  176. package/dist/download/cache.d.ts.map +1 -0
  177. package/dist/download/cache.js +18 -0
  178. package/dist/download/cache.js.map +1 -0
  179. package/dist/download/client.d.ts +2 -0
  180. package/dist/download/client.d.ts.map +1 -0
  181. package/dist/download/client.js +58 -0
  182. package/dist/download/client.js.map +1 -0
  183. package/dist/index.d.ts +3 -0
  184. package/dist/index.d.ts.map +1 -0
  185. package/dist/index.js +23 -0
  186. package/dist/index.js.map +1 -0
  187. package/dist/installer/file-copier.d.ts +6 -0
  188. package/dist/installer/file-copier.d.ts.map +1 -0
  189. package/dist/installer/file-copier.js +32 -0
  190. package/dist/installer/file-copier.js.map +1 -0
  191. package/dist/installer/plugin-installer.d.ts +12 -0
  192. package/dist/installer/plugin-installer.d.ts.map +1 -0
  193. package/dist/installer/plugin-installer.js +33 -0
  194. package/dist/installer/plugin-installer.js.map +1 -0
  195. package/dist/installer/template-installer.d.ts +12 -0
  196. package/dist/installer/template-installer.d.ts.map +1 -0
  197. package/dist/installer/template-installer.js +45 -0
  198. package/dist/installer/template-installer.js.map +1 -0
  199. package/dist/license/crypto.d.ts +16 -0
  200. package/dist/license/crypto.d.ts.map +1 -0
  201. package/dist/license/crypto.js +50 -0
  202. package/dist/license/crypto.js.map +1 -0
  203. package/dist/license/license-store.d.ts +19 -0
  204. package/dist/license/license-store.d.ts.map +1 -0
  205. package/dist/license/license-store.js +99 -0
  206. package/dist/license/license-store.js.map +1 -0
  207. package/dist/license/validator.d.ts +32 -0
  208. package/dist/license/validator.d.ts.map +1 -0
  209. package/dist/license/validator.js +81 -0
  210. package/dist/license/validator.js.map +1 -0
  211. package/dist/registry/loader.d.ts +30 -0
  212. package/dist/registry/loader.d.ts.map +1 -0
  213. package/dist/registry/loader.js +22 -0
  214. package/dist/registry/loader.js.map +1 -0
  215. package/dist/registry/search-engine.d.ts +9 -0
  216. package/dist/registry/search-engine.d.ts.map +1 -0
  217. package/dist/registry/search-engine.js +30 -0
  218. package/dist/registry/search-engine.js.map +1 -0
  219. package/dist/utils/config.d.ts +14 -0
  220. package/dist/utils/config.d.ts.map +1 -0
  221. package/dist/utils/config.js +28 -0
  222. package/dist/utils/config.js.map +1 -0
  223. package/dist/utils/logger.d.ts +9 -0
  224. package/dist/utils/logger.d.ts.map +1 -0
  225. package/dist/utils/logger.js +22 -0
  226. package/dist/utils/logger.js.map +1 -0
  227. package/dist/utils/paths.d.ts +20 -0
  228. package/dist/utils/paths.d.ts.map +1 -0
  229. package/dist/utils/paths.js +79 -0
  230. package/dist/utils/paths.js.map +1 -0
  231. package/package.json +54 -0
@@ -0,0 +1,361 @@
1
+ # Clean Architecture Reference
2
+
3
+ ## SOLID Principles with Real Code Examples
4
+
5
+ ### Single Responsibility Principle (SRP)
6
+
7
+ Every module should have one — and only one — reason to change.
8
+
9
+ **Bad** — One class handles validation, persistence, and notification:
10
+ ```typescript
11
+ class OrderService {
12
+ async createOrder(data: CreateOrderDto) {
13
+ // Validation
14
+ if (!data.items?.length) throw new Error('No items');
15
+ if (data.total < 0) throw new Error('Invalid total');
16
+
17
+ // Persistence
18
+ const order = await this.db.orders.create({ data });
19
+
20
+ // Notification
21
+ await this.mailer.send(order.userEmail, 'Order created', orderTemplate(order));
22
+
23
+ return order;
24
+ }
25
+ }
26
+ ```
27
+
28
+ **Good** — Each concern is a separate class:
29
+ ```typescript
30
+ class OrderValidator {
31
+ validate(data: CreateOrderDto): void {
32
+ if (!data.items?.length) throw new ValidationError('No items');
33
+ if (data.total < 0) throw new ValidationError('Invalid total');
34
+ }
35
+ }
36
+
37
+ class OrderRepository {
38
+ async create(data: CreateOrderDto): Promise<Order> {
39
+ return this.db.orders.create({ data });
40
+ }
41
+ }
42
+
43
+ class OrderNotifier {
44
+ async notifyCreated(order: Order): Promise<void> {
45
+ await this.mailer.send(order.userEmail, 'Order created', orderTemplate(order));
46
+ }
47
+ }
48
+
49
+ class CreateOrderUseCase {
50
+ constructor(
51
+ private validator: OrderValidator,
52
+ private repo: OrderRepository,
53
+ private notifier: OrderNotifier,
54
+ ) {}
55
+
56
+ async execute(data: CreateOrderDto): Promise<Order> {
57
+ this.validator.validate(data);
58
+ const order = await this.repo.create(data);
59
+ await this.notifier.notifyCreated(order);
60
+ return order;
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### Open/Closed Principle (OCP)
66
+
67
+ Open for extension, closed for modification.
68
+
69
+ **Bad** — Adding a new export format requires modifying existing code:
70
+ ```python
71
+ class ReportExporter:
72
+ def export(self, report: Report, format: str) -> bytes:
73
+ if format == "pdf":
74
+ return self._to_pdf(report)
75
+ elif format == "csv":
76
+ return self._to_csv(report)
77
+ # Every new format = another elif
78
+ ```
79
+
80
+ **Good** — New formats are added by creating new classes:
81
+ ```python
82
+ class ReportExporter(Protocol):
83
+ def export(self, report: Report) -> bytes: ...
84
+
85
+ class PdfExporter:
86
+ def export(self, report: Report) -> bytes:
87
+ # PDF generation logic
88
+ ...
89
+
90
+ class CsvExporter:
91
+ def export(self, report: Report) -> bytes:
92
+ # CSV generation logic
93
+ ...
94
+
95
+ # Registry pattern — no modification needed when adding new exporters
96
+ EXPORTERS: dict[str, ReportExporter] = {
97
+ "pdf": PdfExporter(),
98
+ "csv": CsvExporter(),
99
+ }
100
+ ```
101
+
102
+ ### Liskov Substitution Principle (LSP)
103
+
104
+ Subtypes must be substitutable for their base types without breaking behavior.
105
+
106
+ **Bad** — `ReadOnlyRepository` breaks the contract of `Repository`:
107
+ ```typescript
108
+ class Repository<T> {
109
+ async findById(id: string): Promise<T> { /* ... */ }
110
+ async save(entity: T): Promise<void> { /* ... */ }
111
+ }
112
+
113
+ class ReadOnlyRepository<T> extends Repository<T> {
114
+ async save(entity: T): Promise<void> {
115
+ throw new Error('Cannot save to read-only repository'); // BREAKS LSP
116
+ }
117
+ }
118
+ ```
119
+
120
+ **Good** — Separate interfaces for read and write:
121
+ ```typescript
122
+ interface ReadRepository<T> {
123
+ findById(id: string): Promise<T>;
124
+ }
125
+
126
+ interface WriteRepository<T> {
127
+ save(entity: T): Promise<void>;
128
+ }
129
+
130
+ interface Repository<T> extends ReadRepository<T>, WriteRepository<T> {}
131
+ ```
132
+
133
+ ### Interface Segregation Principle (ISP)
134
+
135
+ Clients should not be forced to depend on interfaces they do not use.
136
+
137
+ **Bad** — One fat interface forces all implementations to handle everything:
138
+ ```typescript
139
+ interface Worker {
140
+ writeCode(): void;
141
+ reviewCode(): void;
142
+ attendMeeting(): void;
143
+ manageServer(): void;
144
+ designUI(): void;
145
+ }
146
+ ```
147
+
148
+ **Good** — Focused interfaces that clients opt into:
149
+ ```typescript
150
+ interface Coder { writeCode(): void; }
151
+ interface Reviewer { reviewCode(): void; }
152
+ interface MeetingAttendee { attendMeeting(): void; }
153
+
154
+ class Developer implements Coder, Reviewer, MeetingAttendee {
155
+ writeCode() { /* ... */ }
156
+ reviewCode() { /* ... */ }
157
+ attendMeeting() { /* ... */ }
158
+ }
159
+ ```
160
+
161
+ ## Dependency Inversion: Interface-Based Design
162
+
163
+ ### Dependency Injection Pattern
164
+
165
+ ```typescript
166
+ // 1. Define the port (interface)
167
+ interface PaymentGateway {
168
+ charge(amount: number, currency: string): Promise<PaymentResult>;
169
+ refund(transactionId: string): Promise<RefundResult>;
170
+ }
171
+
172
+ // 2. Implement the adapter
173
+ class StripeGateway implements PaymentGateway {
174
+ async charge(amount: number, currency: string): Promise<PaymentResult> {
175
+ return stripe.paymentIntents.create({ amount, currency });
176
+ }
177
+ async refund(transactionId: string): Promise<RefundResult> {
178
+ return stripe.refunds.create({ payment_intent: transactionId });
179
+ }
180
+ }
181
+
182
+ // 3. Inject via constructor
183
+ class CheckoutService {
184
+ constructor(private gateway: PaymentGateway) {} // depends on interface
185
+
186
+ async checkout(cart: Cart): Promise<Order> {
187
+ const payment = await this.gateway.charge(cart.total, cart.currency);
188
+ // ...
189
+ }
190
+ }
191
+
192
+ // 4. Wire up in composition root (main / DI container)
193
+ const gateway = new StripeGateway();
194
+ const checkoutService = new CheckoutService(gateway);
195
+ ```
196
+
197
+ **Benefits**: Swap StripeGateway for MockGateway in tests. Replace Stripe with another provider without changing CheckoutService.
198
+
199
+ ## Clean Architecture Layers
200
+
201
+ ```
202
+ ┌─────────────────────────────────────────────┐
203
+ │ Frameworks & Drivers │ Express, Prisma, React, AWS SDK
204
+ │ (outermost — depends on everything below) │
205
+ ├─────────────────────────────────────────────┤
206
+ │ Interface Adapters │ Controllers, Presenters, Gateways
207
+ │ (converts data between use cases and │ Repository implementations
208
+ │ external formats) │
209
+ ├─────────────────────────────────────────────┤
210
+ │ Use Cases │ Application-specific business rules
211
+ │ (orchestrates entities, enforces workflow) │ CreateOrder, ProcessPayment
212
+ ├─────────────────────────────────────────────┤
213
+ │ Entities │ Enterprise-wide business rules
214
+ │ (innermost — depends on nothing) │ Order, User, Invoice
215
+ └─────────────────────────────────────────────┘
216
+ ```
217
+
218
+ ### Dependency Rule
219
+ Dependencies always point **inward**. Inner layers never import from outer layers. Outer layers depend on inner layers through interfaces.
220
+
221
+ ### Practical Folder Structure
222
+ ```
223
+ src/
224
+ ├── domain/ # Entities + value objects (no external dependencies)
225
+ │ ├── order.ts
226
+ │ └── user.ts
227
+ ├── application/ # Use cases + port interfaces
228
+ │ ├── ports/
229
+ │ │ ├── order-repository.port.ts
230
+ │ │ └── payment-gateway.port.ts
231
+ │ └── use-cases/
232
+ │ ├── create-order.use-case.ts
233
+ │ └── process-payment.use-case.ts
234
+ ├── infrastructure/ # Adapter implementations
235
+ │ ├── database/
236
+ │ │ └── prisma-order-repository.ts
237
+ │ └── payment/
238
+ │ └── stripe-gateway.ts
239
+ └── presentation/ # Controllers, routes, CLI
240
+ ├── http/
241
+ │ └── order.controller.ts
242
+ └── cli/
243
+ └── seed.command.ts
244
+ ```
245
+
246
+ ## Tech Debt Management
247
+
248
+ ### Identification
249
+
250
+ | Type | Description | Example |
251
+ |------|-------------|---------|
252
+ | **Deliberate** | Conscious shortcut taken with a plan to fix | "Ship without caching, add in next sprint" |
253
+ | **Accidental** | Discovered after the fact | "This module has circular dependencies we didn't notice" |
254
+ | **Bit rot** | Gradual degradation over time | Outdated dependencies, deprecated API usage |
255
+ | **Design debt** | Architecture that no longer fits current needs | Monolith that should be split, wrong database choice |
256
+
257
+ ### Classification Matrix
258
+
259
+ | | Low Effort to Fix | High Effort to Fix |
260
+ |---|---|---|
261
+ | **High Impact** | Fix now (current sprint) | Plan and schedule (next 1-2 sprints) |
262
+ | **Low Impact** | Fix opportunistically (when touching that code) | Track but deprioritize (backlog) |
263
+
264
+ ### Payoff Strategies
265
+ - **Boy Scout Rule**: Leave code cleaner than you found it — small improvements on every PR
266
+ - **Tech debt budget**: Allocate 15-20% of sprint capacity to debt reduction
267
+ - **Quarterly cleanup sprint**: One sprint per quarter focused entirely on tech debt
268
+ - **Debt-driven refactoring**: When a feature is blocked or slowed by debt, fix the debt first
269
+
270
+ ## Refactoring Patterns
271
+
272
+ ### Extract Method
273
+ **When**: A block of code inside a function does a distinct thing (often preceded by a comment).
274
+ ```typescript
275
+ // Before
276
+ function processOrder(order: Order) {
277
+ // validate inventory
278
+ for (const item of order.items) {
279
+ const stock = await getStock(item.productId);
280
+ if (stock < item.quantity) throw new InsufficientStockError(item.productId);
281
+ }
282
+ // ... rest of processing
283
+ }
284
+
285
+ // After
286
+ function processOrder(order: Order) {
287
+ await validateInventory(order.items);
288
+ // ... rest of processing
289
+ }
290
+
291
+ async function validateInventory(items: OrderItem[]) {
292
+ for (const item of items) {
293
+ const stock = await getStock(item.productId);
294
+ if (stock < item.quantity) throw new InsufficientStockError(item.productId);
295
+ }
296
+ }
297
+ ```
298
+
299
+ ### Replace Conditional with Polymorphism
300
+ **When**: A switch/if-else chain selects behavior based on type.
301
+ ```typescript
302
+ // Before
303
+ function calculateShipping(type: string, weight: number): number {
304
+ if (type === 'standard') return weight * 0.5;
305
+ if (type === 'express') return weight * 1.5 + 10;
306
+ if (type === 'overnight') return weight * 3 + 25;
307
+ throw new Error(`Unknown type: ${type}`);
308
+ }
309
+
310
+ // After
311
+ interface ShippingCalculator {
312
+ calculate(weight: number): number;
313
+ }
314
+
315
+ class StandardShipping implements ShippingCalculator {
316
+ calculate(weight: number) { return weight * 0.5; }
317
+ }
318
+ class ExpressShipping implements ShippingCalculator {
319
+ calculate(weight: number) { return weight * 1.5 + 10; }
320
+ }
321
+ class OvernightShipping implements ShippingCalculator {
322
+ calculate(weight: number) { return weight * 3 + 25; }
323
+ }
324
+ ```
325
+
326
+ ### Introduce Parameter Object
327
+ **When**: A function takes 4+ related parameters.
328
+ ```typescript
329
+ // Before
330
+ function searchProducts(query: string, minPrice: number, maxPrice: number,
331
+ category: string, sortBy: string, page: number, limit: number) { /* ... */ }
332
+
333
+ // After
334
+ interface ProductSearchCriteria {
335
+ query: string;
336
+ priceRange: { min: number; max: number };
337
+ category: string;
338
+ sort: { field: string; direction: 'asc' | 'desc' };
339
+ pagination: { page: number; limit: number };
340
+ }
341
+
342
+ function searchProducts(criteria: ProductSearchCriteria) { /* ... */ }
343
+ ```
344
+
345
+ ## Code Review from Developer Perspective
346
+
347
+ ### What to Look For (Priority Order)
348
+
349
+ 1. **Correctness**: Does it do what the ticket says? Are edge cases handled?
350
+ 2. **Security**: SQL injection, XSS, auth bypass, secrets in code?
351
+ 3. **Performance**: N+1 queries, unbounded loops, missing indexes, memory leaks?
352
+ 4. **Maintainability**: Can the next developer understand this in 6 months?
353
+ 5. **Test coverage**: Are the important paths tested? Are tests meaningful (not just line coverage)?
354
+ 6. **Style**: Consistent with codebase conventions? (Lowest priority — automate with linters)
355
+
356
+ ### How to Give Constructive Feedback
357
+ - **Be specific**: "This query runs N+1 for each order item" not "This is slow"
358
+ - **Suggest alternatives**: "Consider using `Promise.all()` here to parallelize" not just "Fix this"
359
+ - **Distinguish must-fix from nice-to-have**: Use labels like `[blocking]` vs `[nit]` vs `[suggestion]`
360
+ - **Ask questions instead of commanding**: "Would it be simpler to extract this into a helper?" vs "Extract this"
361
+ - **Praise good code**: "Nice use of the builder pattern here" — positive feedback reinforces good practices
@@ -0,0 +1,207 @@
1
+ # Clean Code Guide
2
+
3
+ ## SOLID Principles with Practical Examples
4
+
5
+ ### Single Responsibility Principle (SRP)
6
+ A class or function should have **one reason to change**.
7
+
8
+ **Bad:**
9
+ ```typescript
10
+ class UserService {
11
+ createUser(data: CreateUserDto) { /* creates user in DB */ }
12
+ sendWelcomeEmail(user: User) { /* sends email */ }
13
+ generateReport(users: User[]) { /* creates CSV report */ }
14
+ }
15
+ ```
16
+
17
+ **Good:**
18
+ ```typescript
19
+ class UserService {
20
+ createUser(data: CreateUserDto): User { /* creates user in DB */ }
21
+ }
22
+ class EmailService {
23
+ sendWelcomeEmail(user: User) { /* sends email */ }
24
+ }
25
+ class UserReportService {
26
+ generateReport(users: User[]): Buffer { /* creates CSV report */ }
27
+ }
28
+ ```
29
+
30
+ ### Open/Closed Principle (OCP)
31
+ Open for extension, closed for modification. Use abstractions to add behavior.
32
+
33
+ **Bad** — Adding a new payment method requires modifying existing code:
34
+ ```typescript
35
+ function processPayment(method: string, amount: number) {
36
+ if (method === 'stripe') { /* stripe logic */ }
37
+ else if (method === 'paypal') { /* paypal logic */ }
38
+ // Every new method = another else-if
39
+ }
40
+ ```
41
+
42
+ **Good** — New payment methods are added without touching existing code:
43
+ ```typescript
44
+ interface PaymentProcessor {
45
+ process(amount: number): PaymentResult;
46
+ }
47
+ class StripeProcessor implements PaymentProcessor { /* ... */ }
48
+ class PaypalProcessor implements PaymentProcessor { /* ... */ }
49
+ // Adding BankTransferProcessor requires zero changes to existing code
50
+ ```
51
+
52
+ ### Dependency Inversion Principle (DIP)
53
+ Depend on abstractions, not concretions. High-level modules should not depend on low-level modules.
54
+
55
+ **Bad:**
56
+ ```typescript
57
+ class OrderService {
58
+ private db = new PostgresDatabase(); // tightly coupled to Postgres
59
+ private mailer = new SendGridMailer(); // tightly coupled to SendGrid
60
+ }
61
+ ```
62
+
63
+ **Good:**
64
+ ```typescript
65
+ class OrderService {
66
+ constructor(
67
+ private db: DatabasePort, // depends on interface
68
+ private mailer: MailerPort, // depends on interface
69
+ ) {}
70
+ }
71
+ ```
72
+
73
+ ## DRY, KISS, YAGNI Application
74
+
75
+ | Principle | Meaning | Practical Rule |
76
+ |-----------|---------|---------------|
77
+ | **DRY** | Don't Repeat Yourself | If you copy-paste code a **third time**, extract it. Twice is OK — premature abstraction is worse than duplication |
78
+ | **KISS** | Keep It Simple | Choose the simplest solution that works. A 10-line if/else is often better than a design pattern nobody understands |
79
+ | **YAGNI** | You Aren't Gonna Need It | Do not build features, abstractions, or infrastructure "just in case." Build what the current ticket requires |
80
+
81
+ ### DRY Anti-Pattern: Wrong Abstraction
82
+ Sharing code between two callers that happen to look similar today but have different reasons to change leads to **coupling that hurts more than the duplication**. When in doubt, duplicate for now and extract later when the pattern is clear.
83
+
84
+ ## Function Design
85
+
86
+ ### Rules
87
+ | Rule | Guideline |
88
+ |------|-----------|
89
+ | Length | Aim for under 20 lines. Hard limit at 50 lines — extract subfunctions beyond that |
90
+ | Parameters | 3 or fewer. If more, group into an options object / DTO |
91
+ | Single abstraction level | A function should not mix high-level orchestration with low-level implementation details |
92
+ | Return early | Validate inputs at the top, return/throw early. Avoid deep nesting |
93
+ | Side effects | Minimize. If a function has side effects, make them obvious from the name (`saveUser`, not `getUser` that also saves) |
94
+
95
+ ### Example: Return Early Pattern
96
+ **Bad** — Deeply nested:
97
+ ```typescript
98
+ function processOrder(order: Order) {
99
+ if (order) {
100
+ if (order.items.length > 0) {
101
+ if (order.payment) {
102
+ // actual logic buried 3 levels deep
103
+ }
104
+ }
105
+ }
106
+ }
107
+ ```
108
+
109
+ **Good** — Guard clauses:
110
+ ```typescript
111
+ function processOrder(order: Order) {
112
+ if (!order) throw new InvalidOrderError('Order is required');
113
+ if (order.items.length === 0) throw new InvalidOrderError('Order has no items');
114
+ if (!order.payment) throw new InvalidOrderError('Payment info missing');
115
+
116
+ // actual logic at top level, easy to read
117
+ }
118
+ ```
119
+
120
+ ## Error Handling Patterns
121
+
122
+ ### Rules
123
+ 1. **Never swallow exceptions** — `catch (e) {}` is a bug waiting to happen
124
+ 2. **Catch at the right level** — catch where you can actually handle or translate the error
125
+ 3. **Use custom error classes** for business errors (not generic Error/Exception)
126
+ 4. **Include context** — error messages should help debugging without looking at code
127
+
128
+ ### Error Handling Strategy
129
+ | Layer | Approach |
130
+ |-------|---------|
131
+ | Controller/Route | Catch and translate to HTTP status + user-friendly message |
132
+ | Service | Throw domain-specific errors (`InsufficientBalanceError`, `UserNotFoundError`) |
133
+ | Repository/DB | Translate database errors to domain errors (constraint violation → `DuplicateEmailError`) |
134
+ | External API | Wrap and translate third-party errors, add retry for transient failures |
135
+
136
+ ### Example
137
+ ```typescript
138
+ // BAD
139
+ try {
140
+ await paymentGateway.charge(amount);
141
+ } catch (e) {
142
+ console.log('error'); // No context, swallowed
143
+ }
144
+
145
+ // GOOD
146
+ try {
147
+ await paymentGateway.charge(amount);
148
+ } catch (error) {
149
+ logger.error('Payment charge failed', {
150
+ orderId: order.id,
151
+ amount,
152
+ gateway: 'stripe',
153
+ error: error.message,
154
+ });
155
+ throw new PaymentFailedError(order.id, error);
156
+ }
157
+ ```
158
+
159
+ ## Logging Best Practices
160
+
161
+ | Rule | Guideline |
162
+ |------|-----------|
163
+ | **Log context, not noise** | Include: requestId, userId, orderId. Skip: "entering function X" |
164
+ | **Structured logging** | Use JSON format with consistent fields, not free-text strings |
165
+ | **Log levels matter** | ERROR: needs attention. WARN: unusual but handled. INFO: business events. DEBUG: development only |
166
+ | **Never log secrets** | Passwords, tokens, full credit card numbers, PII must never appear in logs |
167
+ | **Log at boundaries** | Log incoming requests, outgoing API calls, and state transitions — not every line |
168
+
169
+ ## Code Documentation Standards
170
+
171
+ ### When to Comment
172
+ - **Why**, not what — the code shows what, comments explain why
173
+ - **Business rules** — "Discount applies only to orders over $50 per client contract section 3.2"
174
+ - **Workarounds** — "Using setTimeout because library X has a race condition (see issue #234)"
175
+ - **Public APIs** — JSDoc/docstring for every public function with params and return value
176
+
177
+ ### When NOT to Comment
178
+ - `// increment counter` → `counter++` — the code is self-explanatory
179
+ - `// TODO: fix this later` without a ticket number — create a ticket or fix it now
180
+ - Commented-out code — delete it, git remembers
181
+
182
+ ## Common Refactoring Techniques
183
+
184
+ | Technique | When to Use | How |
185
+ |-----------|-------------|-----|
186
+ | Extract Function | Block of code with a comment explaining what it does | Move the block to a named function — the name replaces the comment |
187
+ | Introduce Parameter Object | Function with 4+ parameters | Group related params into a DTO/interface |
188
+ | Replace Conditional with Polymorphism | Long if/else or switch on type | Create subclasses or strategy pattern implementations |
189
+ | Decompose Conditional | Complex boolean expression | Extract to a named function: `isEligibleForDiscount()` |
190
+ | Replace Magic Number | `if (status === 3)` | Define a constant or enum: `if (status === OrderStatus.SHIPPED)` |
191
+ | Move to Caller/Callee | Responsibility in the wrong place | Move logic to where the data lives |
192
+
193
+ ## Code Complexity Management
194
+
195
+ ### Cyclomatic Complexity Targets
196
+ | Complexity | Assessment | Action |
197
+ |-----------|-----------|--------|
198
+ | 1–5 | Simple, easy to test | No action needed |
199
+ | 6–10 | Moderate, still manageable | Monitor, refactor if adding more branches |
200
+ | 11–20 | High, hard to test thoroughly | Refactor: extract functions, simplify conditions |
201
+ | 21+ | Very high, error-prone | Must refactor before adding any new logic |
202
+
203
+ ### Reducing Complexity
204
+ 1. **Extract early returns** — handle errors/edge cases upfront, reduce nesting
205
+ 2. **Use lookup tables** instead of switch/case for data mapping
206
+ 3. **Split decision from action** — one function decides, another executes
207
+ 4. **Limit function scope** — if a function handles 3 concerns, split into 3 functions