@mytechtoday/augment-extensions 1.4.0 → 1.5.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 (307) hide show
  1. package/augment-extensions/coding-standards/c/CHANGELOG.md +55 -0
  2. package/augment-extensions/coding-standards/c/LICENSE +22 -0
  3. package/augment-extensions/coding-standards/c/README.md +167 -0
  4. package/augment-extensions/coding-standards/c/config/defaults.json +26 -0
  5. package/augment-extensions/coding-standards/c/config/examples/embedded.yaml +25 -0
  6. package/augment-extensions/coding-standards/c/config/examples/systems.json +31 -0
  7. package/augment-extensions/coding-standards/c/config/schema.json +244 -0
  8. package/augment-extensions/coding-standards/c/docs/API.md +613 -0
  9. package/augment-extensions/coding-standards/c/docs/CONFIGURATION.md +259 -0
  10. package/augment-extensions/coding-standards/c/docs/USER_GUIDE.md +567 -0
  11. package/augment-extensions/coding-standards/c/examples/drivers/Makefile +33 -0
  12. package/augment-extensions/coding-standards/c/examples/drivers/README.md +192 -0
  13. package/augment-extensions/coding-standards/c/examples/drivers/dma-example.c +224 -0
  14. package/augment-extensions/coding-standards/c/examples/drivers/example.dts +64 -0
  15. package/augment-extensions/coding-standards/c/examples/drivers/platform-driver.c +174 -0
  16. package/augment-extensions/coding-standards/c/examples/embedded/README.md +167 -0
  17. package/augment-extensions/coding-standards/c/examples/embedded/gpio-control.c +172 -0
  18. package/augment-extensions/coding-standards/c/examples/embedded/timer-isr.c +198 -0
  19. package/augment-extensions/coding-standards/c/examples/embedded/uart-communication.c +212 -0
  20. package/augment-extensions/coding-standards/c/examples/kernel/Makefile +82 -0
  21. package/augment-extensions/coding-standards/c/examples/kernel/README.md +168 -0
  22. package/augment-extensions/coding-standards/c/examples/kernel/char-device.c +198 -0
  23. package/augment-extensions/coding-standards/c/examples/kernel/proc-file.c +131 -0
  24. package/augment-extensions/coding-standards/c/examples/kernel/simple-module.c +111 -0
  25. package/augment-extensions/coding-standards/c/examples/legacy/Makefile +62 -0
  26. package/augment-extensions/coding-standards/c/examples/legacy/README.md +255 -0
  27. package/augment-extensions/coding-standards/c/examples/legacy/c89-to-c11-migration.c +268 -0
  28. package/augment-extensions/coding-standards/c/examples/legacy/compatibility-layer.c +239 -0
  29. package/augment-extensions/coding-standards/c/examples/networking/Makefile +35 -0
  30. package/augment-extensions/coding-standards/c/examples/networking/README.md +207 -0
  31. package/augment-extensions/coding-standards/c/examples/networking/protocol-parser.c +270 -0
  32. package/augment-extensions/coding-standards/c/examples/networking/tcp-server.c +197 -0
  33. package/augment-extensions/coding-standards/c/examples/networking/udp-multicast.c +220 -0
  34. package/augment-extensions/coding-standards/c/examples/realtime/Makefile +53 -0
  35. package/augment-extensions/coding-standards/c/examples/realtime/README.md +199 -0
  36. package/augment-extensions/coding-standards/c/examples/realtime/deadline-monitoring.c +260 -0
  37. package/augment-extensions/coding-standards/c/examples/realtime/priority-scheduling.c +258 -0
  38. package/augment-extensions/coding-standards/c/examples/systems/Makefile +34 -0
  39. package/augment-extensions/coding-standards/c/examples/systems/README.md +123 -0
  40. package/augment-extensions/coding-standards/c/examples/systems/ipc-pipes.c +181 -0
  41. package/augment-extensions/coding-standards/c/examples/systems/process-management.c +153 -0
  42. package/augment-extensions/coding-standards/c/examples/systems/signal-handling.c +162 -0
  43. package/augment-extensions/coding-standards/c/module.json +149 -0
  44. package/augment-extensions/coding-standards/c/rules/categories/drivers.md +635 -0
  45. package/augment-extensions/coding-standards/c/rules/categories/embedded.md +510 -0
  46. package/augment-extensions/coding-standards/c/rules/categories/kernel.md +653 -0
  47. package/augment-extensions/coding-standards/c/rules/categories/legacy.md +526 -0
  48. package/augment-extensions/coding-standards/c/rules/categories/networking.md +735 -0
  49. package/augment-extensions/coding-standards/c/rules/categories/realtime.md +631 -0
  50. package/augment-extensions/coding-standards/c/rules/categories/systems.md +586 -0
  51. package/augment-extensions/coding-standards/c/rules/universal/const-correctness.md +275 -0
  52. package/augment-extensions/coding-standards/c/rules/universal/documentation.md +251 -0
  53. package/augment-extensions/coding-standards/c/rules/universal/error-handling.md +250 -0
  54. package/augment-extensions/coding-standards/c/rules/universal/header-guards.md +254 -0
  55. package/augment-extensions/coding-standards/c/rules/universal/memory-safety.md +233 -0
  56. package/augment-extensions/coding-standards/c/rules/universal/naming.md +146 -0
  57. package/augment-extensions/coding-standards/c/src/conflict-detector.ts +461 -0
  58. package/augment-extensions/coding-standards/c/src/prompt-generator.ts +307 -0
  59. package/augment-extensions/coding-standards/c/src/rule-evaluator.ts +307 -0
  60. package/augment-extensions/coding-standards/c/src/rule-override.ts +427 -0
  61. package/augment-extensions/coding-standards/c/src/template-engine.ts +217 -0
  62. package/augment-extensions/coding-standards/c/templates/prompts/drivers.txt +191 -0
  63. package/augment-extensions/coding-standards/c/templates/prompts/embedded.txt +164 -0
  64. package/augment-extensions/coding-standards/c/templates/prompts/kernel.txt +175 -0
  65. package/augment-extensions/coding-standards/c/templates/prompts/legacy.txt +280 -0
  66. package/augment-extensions/coding-standards/c/templates/prompts/networking.txt +259 -0
  67. package/augment-extensions/coding-standards/c/templates/prompts/realtime.txt +219 -0
  68. package/augment-extensions/coding-standards/c/templates/prompts/systems.txt +147 -0
  69. package/augment-extensions/coding-standards/c/tests/integration/category-specific.test.ts +356 -0
  70. package/augment-extensions/coding-standards/c/tests/integration/end-to-end-workflow.test.ts +377 -0
  71. package/augment-extensions/coding-standards/c/tests/performance/benchmarks.test.ts +407 -0
  72. package/augment-extensions/coding-standards/c/tests/unit/config-manager.test.ts +345 -0
  73. package/augment-extensions/coding-standards/c/tests/unit/conflict-detector.test.ts +294 -0
  74. package/augment-extensions/coding-standards/c/tests/unit/prompt-generator.test.ts +174 -0
  75. package/augment-extensions/coding-standards/c/tests/unit/registry.test.ts +313 -0
  76. package/augment-extensions/coding-standards/c/tests/unit/rule-evaluator.test.ts +318 -0
  77. package/augment-extensions/coding-standards/c/tests/unit/rule-override.test.ts +326 -0
  78. package/augment-extensions/coding-standards/c/tests/unit/template-engine.test.ts +314 -0
  79. package/augment-extensions/coding-standards/go/CHARACTER-COUNT-REPORT.md +135 -0
  80. package/augment-extensions/coding-standards/go/PHASE1-COMPLETION.md +146 -0
  81. package/augment-extensions/coding-standards/go/PHASE4-COMPLETION.md +184 -0
  82. package/augment-extensions/coding-standards/go/README.md +200 -0
  83. package/augment-extensions/coding-standards/go/VALIDATION-CHECKLIST.md +154 -0
  84. package/augment-extensions/coding-standards/go/config/examples/example-cli.json +15 -0
  85. package/augment-extensions/coding-standards/go/config/examples/example-microservices.json +21 -0
  86. package/augment-extensions/coding-standards/go/config/examples/example-multi-category.yaml +24 -0
  87. package/augment-extensions/coding-standards/go/config/examples/example-web.json +15 -0
  88. package/augment-extensions/coding-standards/go/config/schema.json +110 -0
  89. package/augment-extensions/coding-standards/go/docs/CATEGORIES.md +221 -0
  90. package/augment-extensions/coding-standards/go/docs/CONFIGURATION.md +198 -0
  91. package/augment-extensions/coding-standards/go/docs/TROUBLESHOOTING.md +285 -0
  92. package/augment-extensions/coding-standards/go/examples/cli/cobra-app.go +287 -0
  93. package/augment-extensions/coding-standards/go/examples/cloud-native-app.go +217 -0
  94. package/augment-extensions/coding-standards/go/examples/devops-tool.go +250 -0
  95. package/augment-extensions/coding-standards/go/examples/distributed-system.go +247 -0
  96. package/augment-extensions/coding-standards/go/examples/microservices/grpc-service.go +253 -0
  97. package/augment-extensions/coding-standards/go/examples/rest-api.go +270 -0
  98. package/augment-extensions/coding-standards/go/examples/web/http-server.go +224 -0
  99. package/augment-extensions/coding-standards/go/module.json +139 -0
  100. package/augment-extensions/coding-standards/go/rules/categories/api-development/api-versioning.md +149 -0
  101. package/augment-extensions/coding-standards/go/rules/categories/api-development/rate-limiting.md +209 -0
  102. package/augment-extensions/coding-standards/go/rules/categories/api-development/rest-api-design.md +183 -0
  103. package/augment-extensions/coding-standards/go/rules/categories/cloud-native/cloud-config.md +193 -0
  104. package/augment-extensions/coding-standards/go/rules/categories/cloud-native/health-checks.md +231 -0
  105. package/augment-extensions/coding-standards/go/rules/categories/cloud-native/kubernetes.md +180 -0
  106. package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/automation.md +179 -0
  107. package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/ci-cd-integration.md +147 -0
  108. package/augment-extensions/coding-standards/go/rules/categories/devops-tooling/infrastructure-as-code.md +231 -0
  109. package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/caching.md +150 -0
  110. package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/consensus.md +187 -0
  111. package/augment-extensions/coding-standards/go/rules/categories/distributed-systems/event-sourcing.md +246 -0
  112. package/augment-extensions/coding-standards/go/rules/cli/command-parsing.md +264 -0
  113. package/augment-extensions/coding-standards/go/rules/cli/configuration.md +268 -0
  114. package/augment-extensions/coding-standards/go/rules/cli/cross-platform.md +324 -0
  115. package/augment-extensions/coding-standards/go/rules/microservices/distributed-tracing.md +253 -0
  116. package/augment-extensions/coding-standards/go/rules/microservices/grpc.md +257 -0
  117. package/augment-extensions/coding-standards/go/rules/microservices/metrics.md +278 -0
  118. package/augment-extensions/coding-standards/go/rules/microservices/service-discovery.md +249 -0
  119. package/augment-extensions/coding-standards/go/rules/universal/code-organization.md +221 -0
  120. package/augment-extensions/coding-standards/go/rules/universal/documentation.md +269 -0
  121. package/augment-extensions/coding-standards/go/rules/universal/performance.md +323 -0
  122. package/augment-extensions/coding-standards/go/rules/universal/testing.md +162 -0
  123. package/augment-extensions/coding-standards/go/rules/web/graceful-shutdown.md +249 -0
  124. package/augment-extensions/coding-standards/go/rules/web/http-handlers.md +164 -0
  125. package/augment-extensions/coding-standards/go/rules/web/middleware.md +234 -0
  126. package/augment-extensions/coding-standards/go/rules/web/routing.md +251 -0
  127. package/augment-extensions/coding-standards/go/templates/prompts/api.md +160 -0
  128. package/augment-extensions/coding-standards/go/templates/prompts/cli.md +225 -0
  129. package/augment-extensions/coding-standards/go/templates/prompts/cloud-native.md +121 -0
  130. package/augment-extensions/coding-standards/go/templates/prompts/devops.md +146 -0
  131. package/augment-extensions/coding-standards/go/templates/prompts/distributed.md +133 -0
  132. package/augment-extensions/coding-standards/go/templates/prompts/microservices.md +225 -0
  133. package/augment-extensions/coding-standards/go/templates/prompts/web.md +181 -0
  134. package/augment-extensions/coding-standards/go/tests/integration/module-integration.test.ts +164 -0
  135. package/augment-extensions/coding-standards/go/tests/unit/category-selection.test.ts +147 -0
  136. package/augment-extensions/coding-standards/go/tests/unit/module-structure.test.ts +154 -0
  137. package/augment-extensions/coding-standards/go/tests/validate-character-count.ps1 +13 -0
  138. package/augment-extensions/coding-standards/go/tests/validate-examples.ps1 +148 -0
  139. package/augment-extensions/coding-standards/go/tests/validate-examples.sh +135 -0
  140. package/cli/dist/analysis/ast-parser.d.ts +47 -0
  141. package/cli/dist/analysis/ast-parser.d.ts.map +1 -0
  142. package/cli/dist/analysis/ast-parser.js +161 -0
  143. package/cli/dist/analysis/ast-parser.js.map +1 -0
  144. package/cli/dist/analysis/complexity-analyzer.d.ts +27 -0
  145. package/cli/dist/analysis/complexity-analyzer.d.ts.map +1 -0
  146. package/cli/dist/analysis/complexity-analyzer.js +189 -0
  147. package/cli/dist/analysis/complexity-analyzer.js.map +1 -0
  148. package/cli/dist/analysis/dependency-analyzer.d.ts +23 -0
  149. package/cli/dist/analysis/dependency-analyzer.d.ts.map +1 -0
  150. package/cli/dist/analysis/dependency-analyzer.js +237 -0
  151. package/cli/dist/analysis/dependency-analyzer.js.map +1 -0
  152. package/cli/dist/analysis/index.d.ts +9 -0
  153. package/cli/dist/analysis/index.d.ts.map +1 -0
  154. package/cli/dist/analysis/index.js +25 -0
  155. package/cli/dist/analysis/index.js.map +1 -0
  156. package/cli/dist/analysis/security-scanner.d.ts +11 -0
  157. package/cli/dist/analysis/security-scanner.d.ts.map +1 -0
  158. package/cli/dist/analysis/security-scanner.js +294 -0
  159. package/cli/dist/analysis/security-scanner.js.map +1 -0
  160. package/cli/dist/analysis/types.d.ts +151 -0
  161. package/cli/dist/analysis/types.d.ts.map +1 -0
  162. package/cli/dist/analysis/types.js +6 -0
  163. package/cli/dist/analysis/types.js.map +1 -0
  164. package/cli/dist/cli.js +24 -0
  165. package/cli/dist/cli.js.map +1 -1
  166. package/cli/dist/commands/code-analysis.d.ts +11 -0
  167. package/cli/dist/commands/code-analysis.d.ts.map +1 -0
  168. package/cli/dist/commands/code-analysis.js +412 -0
  169. package/cli/dist/commands/code-analysis.js.map +1 -0
  170. package/modules.md +99 -3
  171. package/package.json +14 -2
  172. package/cli/dist/commands/agent.d.ts +0 -37
  173. package/cli/dist/commands/agent.d.ts.map +0 -1
  174. package/cli/dist/commands/agent.js +0 -222
  175. package/cli/dist/commands/agent.js.map +0 -1
  176. package/cli/dist/commands/beads.d.ts +0 -64
  177. package/cli/dist/commands/beads.d.ts.map +0 -1
  178. package/cli/dist/commands/beads.js +0 -377
  179. package/cli/dist/commands/beads.js.map +0 -1
  180. package/cli/dist/commands/change.d.ts +0 -54
  181. package/cli/dist/commands/change.d.ts.map +0 -1
  182. package/cli/dist/commands/change.js +0 -243
  183. package/cli/dist/commands/change.js.map +0 -1
  184. package/cli/dist/commands/clean.d.ts +0 -15
  185. package/cli/dist/commands/clean.d.ts.map +0 -1
  186. package/cli/dist/commands/clean.js +0 -63
  187. package/cli/dist/commands/clean.js.map +0 -1
  188. package/cli/dist/commands/clone.d.ts +0 -15
  189. package/cli/dist/commands/clone.d.ts.map +0 -1
  190. package/cli/dist/commands/clone.js +0 -49
  191. package/cli/dist/commands/clone.js.map +0 -1
  192. package/cli/dist/commands/config.d.ts +0 -33
  193. package/cli/dist/commands/config.d.ts.map +0 -1
  194. package/cli/dist/commands/config.js +0 -166
  195. package/cli/dist/commands/config.js.map +0 -1
  196. package/cli/dist/commands/context.d.ts +0 -38
  197. package/cli/dist/commands/context.d.ts.map +0 -1
  198. package/cli/dist/commands/context.js +0 -205
  199. package/cli/dist/commands/context.js.map +0 -1
  200. package/cli/dist/commands/create.d.ts +0 -18
  201. package/cli/dist/commands/create.d.ts.map +0 -1
  202. package/cli/dist/commands/create.js +0 -178
  203. package/cli/dist/commands/create.js.map +0 -1
  204. package/cli/dist/commands/diff.d.ts +0 -19
  205. package/cli/dist/commands/diff.d.ts.map +0 -1
  206. package/cli/dist/commands/diff.js +0 -104
  207. package/cli/dist/commands/diff.js.map +0 -1
  208. package/cli/dist/commands/doctor.d.ts +0 -14
  209. package/cli/dist/commands/doctor.d.ts.map +0 -1
  210. package/cli/dist/commands/doctor.js +0 -62
  211. package/cli/dist/commands/doctor.js.map +0 -1
  212. package/cli/dist/commands/export.d.ts +0 -28
  213. package/cli/dist/commands/export.d.ts.map +0 -1
  214. package/cli/dist/commands/export.js +0 -135
  215. package/cli/dist/commands/export.js.map +0 -1
  216. package/cli/dist/commands/import.d.ts +0 -23
  217. package/cli/dist/commands/import.d.ts.map +0 -1
  218. package/cli/dist/commands/import.js +0 -118
  219. package/cli/dist/commands/import.js.map +0 -1
  220. package/cli/dist/commands/prompt.d.ts +0 -45
  221. package/cli/dist/commands/prompt.d.ts.map +0 -1
  222. package/cli/dist/commands/prompt.js +0 -223
  223. package/cli/dist/commands/prompt.js.map +0 -1
  224. package/cli/dist/commands/spec.d.ts +0 -57
  225. package/cli/dist/commands/spec.d.ts.map +0 -1
  226. package/cli/dist/commands/spec.js +0 -279
  227. package/cli/dist/commands/spec.js.map +0 -1
  228. package/cli/dist/commands/stats.d.ts +0 -18
  229. package/cli/dist/commands/stats.d.ts.map +0 -1
  230. package/cli/dist/commands/stats.js +0 -85
  231. package/cli/dist/commands/stats.js.map +0 -1
  232. package/cli/dist/commands/task.d.ts +0 -65
  233. package/cli/dist/commands/task.d.ts.map +0 -1
  234. package/cli/dist/commands/task.js +0 -282
  235. package/cli/dist/commands/task.js.map +0 -1
  236. package/cli/dist/commands/template.d.ts +0 -17
  237. package/cli/dist/commands/template.d.ts.map +0 -1
  238. package/cli/dist/commands/template.js +0 -55
  239. package/cli/dist/commands/template.js.map +0 -1
  240. package/cli/dist/utils/agent-config.d.ts +0 -129
  241. package/cli/dist/utils/agent-config.d.ts.map +0 -1
  242. package/cli/dist/utils/agent-config.js +0 -297
  243. package/cli/dist/utils/agent-config.js.map +0 -1
  244. package/cli/dist/utils/beads-graph.d.ts +0 -17
  245. package/cli/dist/utils/beads-graph.d.ts.map +0 -1
  246. package/cli/dist/utils/beads-graph.js +0 -150
  247. package/cli/dist/utils/beads-graph.js.map +0 -1
  248. package/cli/dist/utils/beads-integration.d.ts +0 -112
  249. package/cli/dist/utils/beads-integration.d.ts.map +0 -1
  250. package/cli/dist/utils/beads-integration.js +0 -312
  251. package/cli/dist/utils/beads-integration.js.map +0 -1
  252. package/cli/dist/utils/beads-reporter.d.ts +0 -17
  253. package/cli/dist/utils/beads-reporter.d.ts.map +0 -1
  254. package/cli/dist/utils/beads-reporter.js +0 -160
  255. package/cli/dist/utils/beads-reporter.js.map +0 -1
  256. package/cli/dist/utils/cache-manager.d.ts +0 -55
  257. package/cli/dist/utils/cache-manager.d.ts.map +0 -1
  258. package/cli/dist/utils/cache-manager.js +0 -150
  259. package/cli/dist/utils/cache-manager.js.map +0 -1
  260. package/cli/dist/utils/change-manager.d.ts +0 -70
  261. package/cli/dist/utils/change-manager.d.ts.map +0 -1
  262. package/cli/dist/utils/change-manager.js +0 -412
  263. package/cli/dist/utils/change-manager.js.map +0 -1
  264. package/cli/dist/utils/config-manager-enhanced.d.ts +0 -66
  265. package/cli/dist/utils/config-manager-enhanced.d.ts.map +0 -1
  266. package/cli/dist/utils/config-manager-enhanced.js +0 -77
  267. package/cli/dist/utils/config-manager-enhanced.js.map +0 -1
  268. package/cli/dist/utils/context-manager.d.ts +0 -96
  269. package/cli/dist/utils/context-manager.d.ts.map +0 -1
  270. package/cli/dist/utils/context-manager.js +0 -258
  271. package/cli/dist/utils/context-manager.js.map +0 -1
  272. package/cli/dist/utils/diff-engine.d.ts +0 -78
  273. package/cli/dist/utils/diff-engine.d.ts.map +0 -1
  274. package/cli/dist/utils/diff-engine.js +0 -233
  275. package/cli/dist/utils/diff-engine.js.map +0 -1
  276. package/cli/dist/utils/export-system.d.ts +0 -101
  277. package/cli/dist/utils/export-system.d.ts.map +0 -1
  278. package/cli/dist/utils/export-system.js +0 -289
  279. package/cli/dist/utils/export-system.js.map +0 -1
  280. package/cli/dist/utils/health-checker.d.ts +0 -66
  281. package/cli/dist/utils/health-checker.d.ts.map +0 -1
  282. package/cli/dist/utils/health-checker.js +0 -285
  283. package/cli/dist/utils/health-checker.js.map +0 -1
  284. package/cli/dist/utils/import-system.d.ts +0 -74
  285. package/cli/dist/utils/import-system.d.ts.map +0 -1
  286. package/cli/dist/utils/import-system.js +0 -317
  287. package/cli/dist/utils/import-system.js.map +0 -1
  288. package/cli/dist/utils/module-cloner.d.ts +0 -40
  289. package/cli/dist/utils/module-cloner.d.ts.map +0 -1
  290. package/cli/dist/utils/module-cloner.js +0 -136
  291. package/cli/dist/utils/module-cloner.js.map +0 -1
  292. package/cli/dist/utils/prompt-manager.d.ts +0 -90
  293. package/cli/dist/utils/prompt-manager.d.ts.map +0 -1
  294. package/cli/dist/utils/prompt-manager.js +0 -302
  295. package/cli/dist/utils/prompt-manager.js.map +0 -1
  296. package/cli/dist/utils/spec-manager.d.ts +0 -65
  297. package/cli/dist/utils/spec-manager.d.ts.map +0 -1
  298. package/cli/dist/utils/spec-manager.js +0 -329
  299. package/cli/dist/utils/spec-manager.js.map +0 -1
  300. package/cli/dist/utils/stats-collector.d.ts +0 -74
  301. package/cli/dist/utils/stats-collector.d.ts.map +0 -1
  302. package/cli/dist/utils/stats-collector.js +0 -164
  303. package/cli/dist/utils/stats-collector.js.map +0 -1
  304. package/cli/dist/utils/template-engine.d.ts +0 -47
  305. package/cli/dist/utils/template-engine.d.ts.map +0 -1
  306. package/cli/dist/utils/template-engine.js +0 -204
  307. package/cli/dist/utils/template-engine.js.map +0 -1
@@ -0,0 +1,253 @@
1
+ // Package main demonstrates a production-ready gRPC microservice
2
+ package main
3
+
4
+ import (
5
+ "context"
6
+ "errors"
7
+ "fmt"
8
+ "log"
9
+ "log/slog"
10
+ "net"
11
+ "os"
12
+ "os/signal"
13
+ "syscall"
14
+ "time"
15
+
16
+ "google.golang.org/grpc"
17
+ "google.golang.org/grpc/codes"
18
+ "google.golang.org/grpc/status"
19
+ )
20
+
21
+ // User represents a user in the system
22
+ type User struct {
23
+ ID int64
24
+ Name string
25
+ Email string
26
+ CreatedAt time.Time
27
+ }
28
+
29
+ var ErrNotFound = errors.New("user not found")
30
+
31
+ // UserRepository handles user data operations
32
+ type UserRepository struct {
33
+ users map[int64]*User
34
+ }
35
+
36
+ func NewUserRepository() *UserRepository {
37
+ return &UserRepository{
38
+ users: make(map[int64]*User),
39
+ }
40
+ }
41
+
42
+ func (r *UserRepository) GetUser(ctx context.Context, id int64) (*User, error) {
43
+ user, ok := r.users[id]
44
+ if !ok {
45
+ return nil, ErrNotFound
46
+ }
47
+ return user, nil
48
+ }
49
+
50
+ func (r *UserRepository) CreateUser(ctx context.Context, name, email string) (*User, error) {
51
+ id := int64(len(r.users) + 1)
52
+ user := &User{
53
+ ID: id,
54
+ Name: name,
55
+ Email: email,
56
+ CreatedAt: time.Now(),
57
+ }
58
+ r.users[id] = user
59
+ return user, nil
60
+ }
61
+
62
+ // UserServiceServer implements the gRPC UserService
63
+ type UserServiceServer struct {
64
+ repo *UserRepository
65
+ logger *slog.Logger
66
+ }
67
+
68
+ func NewUserServiceServer(logger *slog.Logger) *UserServiceServer {
69
+ return &UserServiceServer{
70
+ repo: NewUserRepository(),
71
+ logger: logger,
72
+ }
73
+ }
74
+
75
+ // GetUser retrieves a user by ID
76
+ func (s *UserServiceServer) GetUser(ctx context.Context, req *GetUserRequest) (*GetUserResponse, error) {
77
+ if req.Id <= 0 {
78
+ return nil, status.Error(codes.InvalidArgument, "user ID must be positive")
79
+ }
80
+
81
+ user, err := s.repo.GetUser(ctx, req.Id)
82
+ if err != nil {
83
+ if errors.Is(err, ErrNotFound) {
84
+ return nil, status.Error(codes.NotFound, "user not found")
85
+ }
86
+ s.logger.Error("failed to get user", "error", err)
87
+ return nil, status.Error(codes.Internal, "internal error")
88
+ }
89
+
90
+ return &GetUserResponse{
91
+ User: &UserProto{
92
+ Id: user.ID,
93
+ Name: user.Name,
94
+ Email: user.Email,
95
+ CreatedAt: user.CreatedAt.Unix(),
96
+ },
97
+ }, nil
98
+ }
99
+
100
+ // CreateUser creates a new user
101
+ func (s *UserServiceServer) CreateUser(ctx context.Context, req *CreateUserRequest) (*CreateUserResponse, error) {
102
+ if req.Name == "" {
103
+ return nil, status.Error(codes.InvalidArgument, "name is required")
104
+ }
105
+ if req.Email == "" {
106
+ return nil, status.Error(codes.InvalidArgument, "email is required")
107
+ }
108
+
109
+ user, err := s.repo.CreateUser(ctx, req.Name, req.Email)
110
+ if err != nil {
111
+ s.logger.Error("failed to create user", "error", err)
112
+ return nil, status.Error(codes.Internal, "internal error")
113
+ }
114
+
115
+ s.logger.Info("user created", "id", user.ID, "name", user.Name)
116
+
117
+ return &CreateUserResponse{
118
+ User: &UserProto{
119
+ Id: user.ID,
120
+ Name: user.Name,
121
+ Email: user.Email,
122
+ CreatedAt: user.CreatedAt.Unix(),
123
+ },
124
+ }, nil
125
+ }
126
+
127
+ // Logging interceptor
128
+ func loggingUnaryInterceptor(logger *slog.Logger) grpc.UnaryServerInterceptor {
129
+ return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
130
+ start := time.Now()
131
+
132
+ resp, err := handler(ctx, req)
133
+
134
+ logger.Info("gRPC call",
135
+ "method", info.FullMethod,
136
+ "duration_ms", time.Since(start).Milliseconds(),
137
+ "error", err,
138
+ )
139
+
140
+ return resp, err
141
+ }
142
+ }
143
+
144
+ // Recovery interceptor
145
+ func recoveryUnaryInterceptor(logger *slog.Logger) grpc.UnaryServerInterceptor {
146
+ return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
147
+ defer func() {
148
+ if r := recover(); r != nil {
149
+ logger.Error("panic recovered", "panic", r, "method", info.FullMethod)
150
+ err = status.Error(codes.Internal, "internal error")
151
+ }
152
+ }()
153
+ return handler(ctx, req)
154
+ }
155
+ }
156
+
157
+ // Server manages the gRPC server lifecycle
158
+ type Server struct {
159
+ grpcServer *grpc.Server
160
+ listener net.Listener
161
+ logger *slog.Logger
162
+ }
163
+
164
+ func NewServer(port int, logger *slog.Logger) (*Server, error) {
165
+ listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
166
+ if err != nil {
167
+ return nil, err
168
+ }
169
+
170
+ grpcServer := grpc.NewServer(
171
+ grpc.ChainUnaryInterceptor(
172
+ recoveryUnaryInterceptor(logger),
173
+ loggingUnaryInterceptor(logger),
174
+ ),
175
+ )
176
+
177
+ // Register service
178
+ userService := NewUserServiceServer(logger)
179
+ RegisterUserServiceServer(grpcServer, userService)
180
+
181
+ return &Server{
182
+ grpcServer: grpcServer,
183
+ listener: listener,
184
+ logger: logger,
185
+ }, nil
186
+ }
187
+
188
+ func (s *Server) Start() error {
189
+ s.logger.Info("gRPC server starting", "addr", s.listener.Addr())
190
+ return s.grpcServer.Serve(s.listener)
191
+ }
192
+
193
+ func (s *Server) Stop() {
194
+ s.logger.Info("gRPC server stopping")
195
+ s.grpcServer.GracefulStop()
196
+ }
197
+
198
+ func main() {
199
+ logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
200
+
201
+ srv, err := NewServer(50051, logger)
202
+ if err != nil {
203
+ log.Fatal(err)
204
+ }
205
+
206
+ // Start server in goroutine
207
+ go func() {
208
+ if err := srv.Start(); err != nil {
209
+ logger.Error("server failed", "error", err)
210
+ os.Exit(1)
211
+ }
212
+ }()
213
+
214
+ // Wait for interrupt signal
215
+ quit := make(chan os.Signal, 1)
216
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
217
+ <-quit
218
+
219
+ logger.Info("shutdown signal received")
220
+ srv.Stop()
221
+ logger.Info("server stopped")
222
+ }
223
+
224
+ // Proto message definitions (normally generated from .proto files)
225
+ type GetUserRequest struct {
226
+ Id int64
227
+ }
228
+
229
+ type GetUserResponse struct {
230
+ User *UserProto
231
+ }
232
+
233
+ type CreateUserRequest struct {
234
+ Name string
235
+ Email string
236
+ }
237
+
238
+ type CreateUserResponse struct {
239
+ User *UserProto
240
+ }
241
+
242
+ type UserProto struct {
243
+ Id int64
244
+ Name string
245
+ Email string
246
+ CreatedAt int64
247
+ }
248
+
249
+ // Service registration (normally generated)
250
+ func RegisterUserServiceServer(s *grpc.Server, srv *UserServiceServer) {
251
+ // Registration logic would be generated by protoc
252
+ }
253
+
@@ -0,0 +1,270 @@
1
+ // Package main demonstrates a REST API in Go with versioning, rate limiting,
2
+ // pagination, and proper error handling.
3
+ package main
4
+
5
+ import (
6
+ "context"
7
+ "encoding/json"
8
+ "fmt"
9
+ "log"
10
+ "net/http"
11
+ "strconv"
12
+ "time"
13
+
14
+ "github.com/gorilla/mux"
15
+ "golang.org/x/time/rate"
16
+ )
17
+
18
+ // User represents a user entity
19
+ type User struct {
20
+ ID string `json:"id"`
21
+ FirstName string `json:"first_name"`
22
+ LastName string `json:"last_name"`
23
+ Email string `json:"email"`
24
+ CreatedAt time.Time `json:"created_at"`
25
+ }
26
+
27
+ // ErrorResponse represents an API error
28
+ type ErrorResponse struct {
29
+ Error string `json:"error"`
30
+ Message string `json:"message"`
31
+ Code string `json:"code,omitempty"`
32
+ }
33
+
34
+ // PaginatedResponse represents a paginated API response
35
+ type PaginatedResponse struct {
36
+ Data interface{} `json:"data"`
37
+ Page int `json:"page"`
38
+ PageSize int `json:"page_size"`
39
+ TotalItems int `json:"total_items"`
40
+ TotalPages int `json:"total_pages"`
41
+ }
42
+
43
+ // RateLimiter manages rate limiting
44
+ type RateLimiter struct {
45
+ limiters map[string]*rate.Limiter
46
+ rate rate.Limit
47
+ burst int
48
+ }
49
+
50
+ // NewRateLimiter creates a new rate limiter
51
+ func NewRateLimiter(r rate.Limit, b int) *RateLimiter {
52
+ return &RateLimiter{
53
+ limiters: make(map[string]*rate.Limiter),
54
+ rate: r,
55
+ burst: b,
56
+ }
57
+ }
58
+
59
+ // GetLimiter returns a limiter for the given key
60
+ func (rl *RateLimiter) GetLimiter(key string) *rate.Limiter {
61
+ limiter, exists := rl.limiters[key]
62
+ if !exists {
63
+ limiter = rate.NewLimiter(rl.rate, rl.burst)
64
+ rl.limiters[key] = limiter
65
+ }
66
+ return limiter
67
+ }
68
+
69
+ // API represents the REST API server
70
+ type API struct {
71
+ router *mux.Router
72
+ rateLimiter *RateLimiter
73
+ users map[string]*User // In-memory store for demo
74
+ }
75
+
76
+ // NewAPI creates a new API instance
77
+ func NewAPI() *API {
78
+ api := &API{
79
+ router: mux.NewRouter(),
80
+ rateLimiter: NewRateLimiter(rate.Limit(10), 20),
81
+ users: make(map[string]*User),
82
+ }
83
+
84
+ api.setupRoutes()
85
+ return api
86
+ }
87
+
88
+ // setupRoutes configures API routes
89
+ func (api *API) setupRoutes() {
90
+ // Apply middleware
91
+ api.router.Use(api.rateLimitMiddleware)
92
+ api.router.Use(api.loggingMiddleware)
93
+
94
+ // V1 routes
95
+ v1 := api.router.PathPrefix("/api/v1").Subrouter()
96
+ v1.HandleFunc("/users", api.listUsersV1).Methods("GET")
97
+ v1.HandleFunc("/users", api.createUserV1).Methods("POST")
98
+ v1.HandleFunc("/users/{id}", api.getUserV1).Methods("GET")
99
+ v1.HandleFunc("/users/{id}", api.updateUserV1).Methods("PUT")
100
+ v1.HandleFunc("/users/{id}", api.deleteUserV1).Methods("DELETE")
101
+ }
102
+
103
+ // rateLimitMiddleware implements rate limiting
104
+ func (api *API) rateLimitMiddleware(next http.Handler) http.Handler {
105
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
106
+ key := r.RemoteAddr
107
+ limiter := api.rateLimiter.GetLimiter(key)
108
+
109
+ if !limiter.Allow() {
110
+ w.Header().Set("X-RateLimit-Limit", fmt.Sprintf("%d", api.rateLimiter.burst))
111
+ w.Header().Set("X-RateLimit-Remaining", "0")
112
+ w.Header().Set("Retry-After", "60")
113
+
114
+ api.writeError(w, http.StatusTooManyRequests, "Rate limit exceeded")
115
+ return
116
+ }
117
+
118
+ w.Header().Set("X-RateLimit-Limit", fmt.Sprintf("%d", api.rateLimiter.burst))
119
+ next.ServeHTTP(w, r)
120
+ })
121
+ }
122
+
123
+ // loggingMiddleware logs requests
124
+ func (api *API) loggingMiddleware(next http.Handler) http.Handler {
125
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
126
+ start := time.Now()
127
+ log.Printf("%s %s", r.Method, r.URL.Path)
128
+ next.ServeHTTP(w, r)
129
+ log.Printf("Completed in %v", time.Since(start))
130
+ })
131
+ }
132
+
133
+ // listUsersV1 handles GET /api/v1/users
134
+ func (api *API) listUsersV1(w http.ResponseWriter, r *http.Request) {
135
+ page, _ := strconv.Atoi(r.URL.Query().Get("page"))
136
+ if page < 1 {
137
+ page = 1
138
+ }
139
+
140
+ pageSize, _ := strconv.Atoi(r.URL.Query().Get("page_size"))
141
+ if pageSize < 1 || pageSize > 100 {
142
+ pageSize = 20
143
+ }
144
+
145
+ // Convert map to slice
146
+ users := make([]*User, 0, len(api.users))
147
+ for _, user := range api.users {
148
+ users = append(users, user)
149
+ }
150
+
151
+ // Simple pagination
152
+ start := (page - 1) * pageSize
153
+ end := start + pageSize
154
+ if start > len(users) {
155
+ start = len(users)
156
+ }
157
+ if end > len(users) {
158
+ end = len(users)
159
+ }
160
+
161
+ response := PaginatedResponse{
162
+ Data: users[start:end],
163
+ Page: page,
164
+ PageSize: pageSize,
165
+ TotalItems: len(users),
166
+ TotalPages: (len(users) + pageSize - 1) / pageSize,
167
+ }
168
+
169
+ api.writeJSON(w, http.StatusOK, response)
170
+ }
171
+
172
+ // createUserV1 handles POST /api/v1/users
173
+ func (api *API) createUserV1(w http.ResponseWriter, r *http.Request) {
174
+ var user User
175
+ if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
176
+ api.writeError(w, http.StatusBadRequest, "Invalid request body")
177
+ return
178
+ }
179
+
180
+ user.ID = fmt.Sprintf("user-%d", len(api.users)+1)
181
+ user.CreatedAt = time.Now()
182
+
183
+ api.users[user.ID] = &user
184
+
185
+ api.writeJSON(w, http.StatusCreated, user)
186
+ }
187
+
188
+ // getUserV1 handles GET /api/v1/users/{id}
189
+ func (api *API) getUserV1(w http.ResponseWriter, r *http.Request) {
190
+ vars := mux.Vars(r)
191
+ id := vars["id"]
192
+
193
+ user, exists := api.users[id]
194
+ if !exists {
195
+ api.writeError(w, http.StatusNotFound, "User not found")
196
+ return
197
+ }
198
+
199
+ api.writeJSON(w, http.StatusOK, user)
200
+ }
201
+
202
+ // updateUserV1 handles PUT /api/v1/users/{id}
203
+ func (api *API) updateUserV1(w http.ResponseWriter, r *http.Request) {
204
+ vars := mux.Vars(r)
205
+ id := vars["id"]
206
+
207
+ if _, exists := api.users[id]; !exists {
208
+ api.writeError(w, http.StatusNotFound, "User not found")
209
+ return
210
+ }
211
+
212
+ var user User
213
+ if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
214
+ api.writeError(w, http.StatusBadRequest, "Invalid request body")
215
+ return
216
+ }
217
+
218
+ user.ID = id
219
+ api.users[id] = &user
220
+
221
+ api.writeJSON(w, http.StatusOK, user)
222
+ }
223
+
224
+ // deleteUserV1 handles DELETE /api/v1/users/{id}
225
+ func (api *API) deleteUserV1(w http.ResponseWriter, r *http.Request) {
226
+ vars := mux.Vars(r)
227
+ id := vars["id"]
228
+
229
+ if _, exists := api.users[id]; !exists {
230
+ api.writeError(w, http.StatusNotFound, "User not found")
231
+ return
232
+ }
233
+
234
+ delete(api.users, id)
235
+ w.WriteHeader(http.StatusNoContent)
236
+ }
237
+
238
+ // writeJSON writes a JSON response
239
+ func (api *API) writeJSON(w http.ResponseWriter, status int, data interface{}) {
240
+ w.Header().Set("Content-Type", "application/json")
241
+ w.WriteHeader(status)
242
+ json.NewEncoder(w).Encode(data)
243
+ }
244
+
245
+ // writeError writes an error response
246
+ func (api *API) writeError(w http.ResponseWriter, status int, message string) {
247
+ response := ErrorResponse{
248
+ Error: http.StatusText(status),
249
+ Message: message,
250
+ }
251
+ api.writeJSON(w, status, response)
252
+ }
253
+
254
+ func main() {
255
+ api := NewAPI()
256
+
257
+ server := &http.Server{
258
+ Addr: ":8080",
259
+ Handler: api.router,
260
+ ReadTimeout: 15 * time.Second,
261
+ WriteTimeout: 15 * time.Second,
262
+ IdleTimeout: 60 * time.Second,
263
+ }
264
+
265
+ log.Println("Starting REST API server on :8080")
266
+ if err := server.ListenAndServe(); err != nil {
267
+ log.Fatalf("Server failed: %v", err)
268
+ }
269
+ }
270
+