@ngxtm/devkit 3.4.0 → 3.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 (344) hide show
  1. package/package.json +2 -1
  2. package/rules/README.md +141 -0
  3. package/rules/dart/best-practices/SKILL.md +23 -0
  4. package/rules/dart/language/SKILL.md +52 -0
  5. package/rules/dart/tooling/SKILL.md +43 -0
  6. package/rules/dotnet/aspnet-core/SKILL.md +92 -0
  7. package/rules/dotnet/aspnet-core/references/REFERENCE.md +335 -0
  8. package/rules/dotnet/best-practices/SKILL.md +101 -0
  9. package/rules/dotnet/best-practices/references/REFERENCE.md +256 -0
  10. package/rules/dotnet/blazor/SKILL.md +146 -0
  11. package/rules/dotnet/blazor/references/REFERENCE.md +392 -0
  12. package/rules/dotnet/language/SKILL.md +82 -0
  13. package/rules/dotnet/language/references/REFERENCE.md +222 -0
  14. package/rules/dotnet/patterns.rule.md +388 -0
  15. package/rules/dotnet/razor-pages/SKILL.md +124 -0
  16. package/rules/dotnet/razor-pages/references/REFERENCE.md +321 -0
  17. package/rules/dotnet/security/SKILL.md +89 -0
  18. package/rules/dotnet/security/references/REFERENCE.md +295 -0
  19. package/rules/dotnet/tooling/SKILL.md +92 -0
  20. package/rules/dotnet/tooling/references/REFERENCE.md +300 -0
  21. package/rules/flutter/auto-route-navigation/SKILL.md +43 -0
  22. package/rules/flutter/auto-route-navigation/references/REFERENCE.md +19 -0
  23. package/rules/flutter/auto-route-navigation/references/router-config.md +62 -0
  24. package/rules/flutter/bloc-state-management/SKILL.md +64 -0
  25. package/rules/flutter/bloc-state-management/references/REFERENCE.md +20 -0
  26. package/rules/flutter/bloc-state-management/references/auth-bloc-example.md +52 -0
  27. package/rules/flutter/bloc-state-management/references/equatable-usage.md +56 -0
  28. package/rules/flutter/bloc-state-management/references/property-based-state.md +68 -0
  29. package/rules/flutter/bloc.rule.md +76 -0
  30. package/rules/flutter/cicd/SKILL.md +48 -0
  31. package/rules/flutter/cicd/references/advanced-workflow.md +66 -0
  32. package/rules/flutter/cicd/references/fastlane.md +139 -0
  33. package/rules/flutter/cicd/references/github-actions.md +59 -0
  34. package/rules/flutter/dependency-injection/SKILL.md +42 -0
  35. package/rules/flutter/dependency-injection/references/REFERENCE.md +15 -0
  36. package/rules/flutter/dependency-injection/references/modules.md +37 -0
  37. package/rules/flutter/error-handling/SKILL.md +32 -0
  38. package/rules/flutter/error-handling/references/REFERENCE.md +19 -0
  39. package/rules/flutter/error-handling/references/error-mapping.md +31 -0
  40. package/rules/flutter/feature-based-clean-architecture/SKILL.md +46 -0
  41. package/rules/flutter/feature-based-clean-architecture/references/REFERENCE.md +14 -0
  42. package/rules/flutter/feature-based-clean-architecture/references/folder-structure.md +36 -0
  43. package/rules/flutter/getx-navigation/SKILL.md +70 -0
  44. package/rules/flutter/getx-navigation/references/app-pages.md +40 -0
  45. package/rules/flutter/getx-navigation/references/middleware-example.md +29 -0
  46. package/rules/flutter/getx-state-management/SKILL.md +76 -0
  47. package/rules/flutter/getx-state-management/references/binding-example.md +32 -0
  48. package/rules/flutter/getx-state-management/references/reactive-vs-simple.md +39 -0
  49. package/rules/flutter/go-router-navigation/SKILL.md +57 -0
  50. package/rules/flutter/idiomatic-flutter/SKILL.md +20 -0
  51. package/rules/flutter/layer-based-clean-architecture/SKILL.md +50 -0
  52. package/rules/flutter/layer-based-clean-architecture/references/REFERENCE.md +60 -0
  53. package/rules/flutter/layer-based-clean-architecture/references/repository-mapping.md +50 -0
  54. package/rules/flutter/localization/SKILL.md +50 -0
  55. package/rules/flutter/localization/references/REFERENCE.md +48 -0
  56. package/rules/flutter/localization/references/sheet-loader.md +33 -0
  57. package/rules/flutter/navigator-v1-navigation/SKILL.md +71 -0
  58. package/rules/flutter/navigator-v1-navigation/references/on-generate-route.md +48 -0
  59. package/rules/flutter/performance/SKILL.md +24 -0
  60. package/rules/flutter/retrofit-networking/SKILL.md +51 -0
  61. package/rules/flutter/retrofit-networking/references/REFERENCE.md +19 -0
  62. package/rules/flutter/retrofit-networking/references/token-refresh.md +40 -0
  63. package/rules/flutter/riverpod-state-management/SKILL.md +53 -0
  64. package/rules/flutter/riverpod-state-management/references/architecture.md +124 -0
  65. package/rules/flutter/riverpod-state-management/references/best-practices.md +89 -0
  66. package/rules/flutter/riverpod-state-management/references/testing.md +73 -0
  67. package/rules/flutter/riverpod.rule.md +78 -0
  68. package/rules/flutter/security/SKILL.md +33 -0
  69. package/rules/flutter/security/references/REFERENCE.md +15 -0
  70. package/rules/flutter/security/references/network-security.md +28 -0
  71. package/rules/flutter/testing/SKILL.md +44 -0
  72. package/rules/flutter/testing/references/REFERENCE.md +21 -0
  73. package/rules/flutter/testing/references/bloc-testing.md +38 -0
  74. package/rules/flutter/testing/references/integration-testing.md +128 -0
  75. package/rules/flutter/testing/references/robot-pattern.md +82 -0
  76. package/rules/flutter/testing/references/unit-testing.md +130 -0
  77. package/rules/flutter/testing/references/widget-testing.md +120 -0
  78. package/rules/flutter/widgets/SKILL.md +37 -0
  79. package/rules/golang/chi-router/SKILL.md +219 -0
  80. package/rules/golang/chi-router/references/REFERENCE.md +13 -0
  81. package/rules/golang/chi-router/references/routing-patterns.md +205 -0
  82. package/rules/golang/cobra-cli/SKILL.md +227 -0
  83. package/rules/golang/cobra-cli/references/REFERENCE.md +13 -0
  84. package/rules/golang/cobra-cli/references/command-patterns.md +224 -0
  85. package/rules/golang/core/SKILL.md +210 -0
  86. package/rules/golang/core/references/REFERENCE.md +14 -0
  87. package/rules/golang/core/references/concurrency-patterns.md +114 -0
  88. package/rules/golang/core/references/error-handling.md +87 -0
  89. package/rules/golang/echo-framework/SKILL.md +215 -0
  90. package/rules/golang/echo-framework/references/REFERENCE.md +14 -0
  91. package/rules/golang/echo-framework/references/middleware-patterns.md +141 -0
  92. package/rules/golang/echo-framework/references/routing-patterns.md +140 -0
  93. package/rules/golang/ent-orm/SKILL.md +239 -0
  94. package/rules/golang/ent-orm/references/REFERENCE.md +13 -0
  95. package/rules/golang/ent-orm/references/schema-patterns.md +255 -0
  96. package/rules/golang/fiber-framework/SKILL.md +196 -0
  97. package/rules/golang/fiber-framework/references/REFERENCE.md +13 -0
  98. package/rules/golang/fiber-framework/references/routing-patterns.md +191 -0
  99. package/rules/golang/gin-framework/SKILL.md +205 -0
  100. package/rules/golang/gin-framework/references/REFERENCE.md +14 -0
  101. package/rules/golang/gin-framework/references/middleware-patterns.md +119 -0
  102. package/rules/golang/gorm-orm/SKILL.md +196 -0
  103. package/rules/golang/gorm-orm/references/REFERENCE.md +14 -0
  104. package/rules/golang/gorm-orm/references/model-definitions.md +167 -0
  105. package/rules/golang/gorm-orm/references/query-patterns.md +161 -0
  106. package/rules/golang/grpc/SKILL.md +231 -0
  107. package/rules/golang/grpc/references/REFERENCE.md +13 -0
  108. package/rules/golang/grpc/references/service-patterns.md +276 -0
  109. package/rules/golang/testify/SKILL.md +239 -0
  110. package/rules/golang/testify/references/REFERENCE.md +13 -0
  111. package/rules/golang/testify/references/assert-patterns.md +170 -0
  112. package/rules/golang/validator/SKILL.md +234 -0
  113. package/rules/golang/validator/references/REFERENCE.md +13 -0
  114. package/rules/golang/validator/references/validation-tags.md +211 -0
  115. package/rules/golang/viper-config/SKILL.md +244 -0
  116. package/rules/golang/viper-config/references/REFERENCE.md +13 -0
  117. package/rules/golang/viper-config/references/config-loading.md +181 -0
  118. package/rules/golang/wire-di/SKILL.md +243 -0
  119. package/rules/golang/wire-di/references/REFERENCE.md +13 -0
  120. package/rules/golang/wire-di/references/provider-patterns.md +193 -0
  121. package/rules/golang/zap-logging/SKILL.md +203 -0
  122. package/rules/golang/zap-logging/references/REFERENCE.md +13 -0
  123. package/rules/golang/zap-logging/references/logger-config.md +165 -0
  124. package/rules/java/build-gradle/SKILL.md +92 -0
  125. package/rules/java/build-gradle/references/REFERENCE.md +14 -0
  126. package/rules/java/build-gradle/references/kotlin-dsl.md +118 -0
  127. package/rules/java/build-gradle/references/task-configuration.md +132 -0
  128. package/rules/java/build-maven/SKILL.md +86 -0
  129. package/rules/java/build-maven/references/REFERENCE.md +14 -0
  130. package/rules/java/build-maven/references/dependency-management.md +111 -0
  131. package/rules/java/build-maven/references/lifecycle-phases.md +114 -0
  132. package/rules/java/graalvm-native/SKILL.md +105 -0
  133. package/rules/java/graalvm-native/references/REFERENCE.md +12 -0
  134. package/rules/java/java-collections-streams/SKILL.md +148 -0
  135. package/rules/java/java-collections-streams/references/REFERENCE.md +15 -0
  136. package/rules/java/java-collections-streams/references/collectors-patterns.md +178 -0
  137. package/rules/java/java-collections-streams/references/stream-pipelines.md +165 -0
  138. package/rules/java/java-concurrency/SKILL.md +187 -0
  139. package/rules/java/java-concurrency/references/REFERENCE.md +17 -0
  140. package/rules/java/java-concurrency/references/completable-future.md +165 -0
  141. package/rules/java/java-concurrency/references/executor-patterns.md +176 -0
  142. package/rules/java/java-concurrency/references/virtual-threads.md +190 -0
  143. package/rules/java/java-core-language/SKILL.md +121 -0
  144. package/rules/java/java-core-language/references/REFERENCE.md +15 -0
  145. package/rules/java/java-core-language/references/jvm-memory-model.md +160 -0
  146. package/rules/java/java-core-language/references/modern-java-features.md +168 -0
  147. package/rules/java/java-project-structure/SKILL.md +195 -0
  148. package/rules/java/java-project-structure/references/REFERENCE.md +15 -0
  149. package/rules/java/java-project-structure/references/maven-project-layout.md +199 -0
  150. package/rules/java/java-project-structure/references/module-system.md +159 -0
  151. package/rules/java/micronaut-core/SKILL.md +99 -0
  152. package/rules/java/micronaut-core/references/REFERENCE.md +12 -0
  153. package/rules/java/micronaut-reactive/SKILL.md +68 -0
  154. package/rules/java/micronaut-reactive/references/REFERENCE.md +12 -0
  155. package/rules/java/quarkus-core/SKILL.md +85 -0
  156. package/rules/java/quarkus-core/references/REFERENCE.md +12 -0
  157. package/rules/java/quarkus-reactive/SKILL.md +67 -0
  158. package/rules/java/quarkus-reactive/references/REFERENCE.md +12 -0
  159. package/rules/java/spring-batch/SKILL.md +102 -0
  160. package/rules/java/spring-batch/references/REFERENCE.md +12 -0
  161. package/rules/java/spring-boot-architecture/SKILL.md +206 -0
  162. package/rules/java/spring-boot-architecture/references/REFERENCE.md +15 -0
  163. package/rules/java/spring-boot-architecture/references/auto-configuration.md +158 -0
  164. package/rules/java/spring-boot-architecture/references/configuration-properties.md +202 -0
  165. package/rules/java/spring-boot-web/SKILL.md +217 -0
  166. package/rules/java/spring-boot-web/references/REFERENCE.md +17 -0
  167. package/rules/java/spring-cloud/SKILL.md +109 -0
  168. package/rules/java/spring-cloud/references/REFERENCE.md +13 -0
  169. package/rules/java/spring-data-jpa/SKILL.md +241 -0
  170. package/rules/java/spring-data-jpa/references/REFERENCE.md +16 -0
  171. package/rules/java/spring-security/SKILL.md +161 -0
  172. package/rules/java/spring-security/references/REFERENCE.md +16 -0
  173. package/rules/java/spring-security/references/jwt-auth-flow.md +213 -0
  174. package/rules/java/testing-junit-mockito/SKILL.md +135 -0
  175. package/rules/java/testing-junit-mockito/references/REFERENCE.md +15 -0
  176. package/rules/java/testing-junit-mockito/references/junit5-patterns.md +159 -0
  177. package/rules/java/testing-junit-mockito/references/mockito-patterns.md +148 -0
  178. package/rules/java/testing-junit-mockito/references/spring-boot-testing.md +152 -0
  179. package/rules/javascript/best-practices/SKILL.md +64 -0
  180. package/rules/javascript/best-practices/references/REFERENCE.md +91 -0
  181. package/rules/javascript/language/SKILL.md +71 -0
  182. package/rules/javascript/language/references/REFERENCE.md +106 -0
  183. package/rules/javascript/tooling/SKILL.md +60 -0
  184. package/rules/javascript/tooling/references/REFERENCE.md +107 -0
  185. package/rules/metadata.json +54 -0
  186. package/rules/nestjs/api-standards/SKILL.md +47 -0
  187. package/rules/nestjs/api-standards/references/pagination-wrapper.md +87 -0
  188. package/rules/nestjs/architecture/SKILL.md +68 -0
  189. package/rules/nestjs/architecture/references/dynamic-module.md +53 -0
  190. package/rules/nestjs/caching/SKILL.md +51 -0
  191. package/rules/nestjs/caching/references/REFERENCE.md +13 -0
  192. package/rules/nestjs/caching/references/cache-patterns.md +183 -0
  193. package/rules/nestjs/configuration/SKILL.md +41 -0
  194. package/rules/nestjs/configuration/references/REFERENCE.md +13 -0
  195. package/rules/nestjs/configuration/references/config-patterns.md +184 -0
  196. package/rules/nestjs/controllers-services/SKILL.md +63 -0
  197. package/rules/nestjs/controllers-services/references/REFERENCE.md +14 -0
  198. package/rules/nestjs/controllers-services/references/controller-patterns.md +119 -0
  199. package/rules/nestjs/controllers-services/references/service-patterns.md +129 -0
  200. package/rules/nestjs/database/SKILL.md +102 -0
  201. package/rules/nestjs/database/references/REFERENCE.md +14 -0
  202. package/rules/nestjs/database/references/typeorm-patterns.md +156 -0
  203. package/rules/nestjs/deployment/SKILL.md +36 -0
  204. package/rules/nestjs/deployment/references/REFERENCE.md +13 -0
  205. package/rules/nestjs/deployment/references/deployment-patterns.md +140 -0
  206. package/rules/nestjs/documentation/SKILL.md +64 -0
  207. package/rules/nestjs/documentation/references/REFERENCE.md +13 -0
  208. package/rules/nestjs/documentation/references/swagger-patterns.md +139 -0
  209. package/rules/nestjs/error-handling/SKILL.md +55 -0
  210. package/rules/nestjs/error-handling/references/REFERENCE.md +13 -0
  211. package/rules/nestjs/error-handling/references/exception-filters.md +152 -0
  212. package/rules/nestjs/file-uploads/SKILL.md +35 -0
  213. package/rules/nestjs/file-uploads/references/REFERENCE.md +13 -0
  214. package/rules/nestjs/file-uploads/references/upload-patterns.md +125 -0
  215. package/rules/nestjs/observability/SKILL.md +39 -0
  216. package/rules/nestjs/observability/references/REFERENCE.md +13 -0
  217. package/rules/nestjs/observability/references/logging-metrics.md +175 -0
  218. package/rules/nestjs/performance/SKILL.md +60 -0
  219. package/rules/nestjs/performance/references/REFERENCE.md +13 -0
  220. package/rules/nestjs/performance/references/performance-patterns.md +107 -0
  221. package/rules/nestjs/real-time/SKILL.md +45 -0
  222. package/rules/nestjs/real-time/references/REFERENCE.md +13 -0
  223. package/rules/nestjs/real-time/references/websocket-patterns.md +121 -0
  224. package/rules/nestjs/scheduling/SKILL.md +39 -0
  225. package/rules/nestjs/scheduling/references/REFERENCE.md +13 -0
  226. package/rules/nestjs/scheduling/references/scheduling-patterns.md +137 -0
  227. package/rules/nestjs/search/SKILL.md +41 -0
  228. package/rules/nestjs/search/references/REFERENCE.md +13 -0
  229. package/rules/nestjs/search/references/search-patterns.md +137 -0
  230. package/rules/nestjs/security/SKILL.md +87 -0
  231. package/rules/nestjs/security/references/REFERENCE.md +14 -0
  232. package/rules/nestjs/security/references/authentication.md +151 -0
  233. package/rules/nestjs/testing/SKILL.md +40 -0
  234. package/rules/nestjs/testing/references/REFERENCE.md +14 -0
  235. package/rules/nestjs/testing/references/unit-testing.md +179 -0
  236. package/rules/nestjs/transport/SKILL.md +45 -0
  237. package/rules/nestjs/transport/references/REFERENCE.md +13 -0
  238. package/rules/nestjs/transport/references/microservices-patterns.md +170 -0
  239. package/rules/nextjs/app-router/SKILL.md +46 -0
  240. package/rules/nextjs/app-router/references/REFERENCE.md +14 -0
  241. package/rules/nextjs/app-router/references/routing-patterns.md +182 -0
  242. package/rules/nextjs/architecture/SKILL.md +44 -0
  243. package/rules/nextjs/architecture/references/fsd-structure.md +77 -0
  244. package/rules/nextjs/authentication/SKILL.md +29 -0
  245. package/rules/nextjs/authentication/references/auth-implementation.md +73 -0
  246. package/rules/nextjs/caching/SKILL.md +66 -0
  247. package/rules/nextjs/caching/references/REFERENCE.md +13 -0
  248. package/rules/nextjs/caching/references/cache-strategies.md +168 -0
  249. package/rules/nextjs/data-access-layer/SKILL.md +33 -0
  250. package/rules/nextjs/data-access-layer/references/patterns.md +66 -0
  251. package/rules/nextjs/data-fetching/SKILL.md +59 -0
  252. package/rules/nextjs/data-fetching/references/REFERENCE.md +13 -0
  253. package/rules/nextjs/data-fetching/references/fetch-patterns.md +160 -0
  254. package/rules/nextjs/internationalization/SKILL.md +105 -0
  255. package/rules/nextjs/internationalization/references/REFERENCE.md +13 -0
  256. package/rules/nextjs/internationalization/references/i18n-patterns.md +180 -0
  257. package/rules/nextjs/optimization/SKILL.md +64 -0
  258. package/rules/nextjs/optimization/references/REFERENCE.md +13 -0
  259. package/rules/nextjs/optimization/references/optimization-patterns.md +190 -0
  260. package/rules/nextjs/rendering/SKILL.md +91 -0
  261. package/rules/nextjs/rendering/references/REFERENCE.md +13 -0
  262. package/rules/nextjs/rendering/references/rendering-modes.md +163 -0
  263. package/rules/nextjs/server-actions/SKILL.md +46 -0
  264. package/rules/nextjs/server-actions/references/REFERENCE.md +13 -0
  265. package/rules/nextjs/server-actions/references/action-patterns.md +188 -0
  266. package/rules/nextjs/server-components/SKILL.md +52 -0
  267. package/rules/nextjs/server-components/references/REFERENCE.md +13 -0
  268. package/rules/nextjs/server-components/references/component-patterns.md +175 -0
  269. package/rules/nextjs/state-management/SKILL.md +73 -0
  270. package/rules/nextjs/state-management/references/REFERENCE.md +13 -0
  271. package/rules/nextjs/state-management/references/state-patterns.md +218 -0
  272. package/rules/nextjs/styling/SKILL.md +31 -0
  273. package/rules/nextjs/styling/references/implementation.md +56 -0
  274. package/rules/react/component-patterns/SKILL.md +66 -0
  275. package/rules/react/component-patterns/references/REFERENCE.md +126 -0
  276. package/rules/react/hooks/SKILL.md +60 -0
  277. package/rules/react/hooks/references/REFERENCE.md +132 -0
  278. package/rules/react/hooks.rule.md +79 -0
  279. package/rules/react/performance/SKILL.md +69 -0
  280. package/rules/react/performance/references/REFERENCE.md +143 -0
  281. package/rules/react/security/SKILL.md +46 -0
  282. package/rules/react/security/references/REFERENCE.md +170 -0
  283. package/rules/react/state-management/SKILL.md +56 -0
  284. package/rules/react/state-management/references/REFERENCE.md +137 -0
  285. package/rules/react/testing/SKILL.md +45 -0
  286. package/rules/react/testing/references/REFERENCE.md +149 -0
  287. package/rules/react/tooling/SKILL.md +39 -0
  288. package/rules/react/typescript/SKILL.md +53 -0
  289. package/rules/rust/actix-web/SKILL.md +160 -0
  290. package/rules/rust/actix-web/references/REFERENCE.md +13 -0
  291. package/rules/rust/actix-web/references/handler-patterns.md +198 -0
  292. package/rules/rust/async-graphql/SKILL.md +228 -0
  293. package/rules/rust/async-graphql/references/REFERENCE.md +13 -0
  294. package/rules/rust/async-graphql/references/schema-patterns.md +215 -0
  295. package/rules/rust/axum/SKILL.md +161 -0
  296. package/rules/rust/axum/references/REFERENCE.md +14 -0
  297. package/rules/rust/axum/references/handler-patterns.md +97 -0
  298. package/rules/rust/bevy/SKILL.md +206 -0
  299. package/rules/rust/bevy/references/REFERENCE.md +13 -0
  300. package/rules/rust/bevy/references/ecs-patterns.md +226 -0
  301. package/rules/rust/clap/SKILL.md +217 -0
  302. package/rules/rust/clap/references/REFERENCE.md +13 -0
  303. package/rules/rust/clap/references/derive-patterns.md +205 -0
  304. package/rules/rust/core/SKILL.md +154 -0
  305. package/rules/rust/core/references/REFERENCE.md +14 -0
  306. package/rules/rust/core/references/error-handling.md +92 -0
  307. package/rules/rust/diesel-orm/SKILL.md +176 -0
  308. package/rules/rust/diesel-orm/references/REFERENCE.md +13 -0
  309. package/rules/rust/diesel-orm/references/schema-patterns.md +206 -0
  310. package/rules/rust/rocket/SKILL.md +182 -0
  311. package/rules/rust/rocket/references/REFERENCE.md +13 -0
  312. package/rules/rust/rocket/references/handler-patterns.md +209 -0
  313. package/rules/rust/sea-orm/SKILL.md +230 -0
  314. package/rules/rust/sea-orm/references/REFERENCE.md +13 -0
  315. package/rules/rust/sea-orm/references/entity-patterns.md +221 -0
  316. package/rules/rust/serde-serialization/SKILL.md +150 -0
  317. package/rules/rust/serde-serialization/references/REFERENCE.md +13 -0
  318. package/rules/rust/serde-serialization/references/serialization-patterns.md +199 -0
  319. package/rules/rust/sqlx-database/SKILL.md +140 -0
  320. package/rules/rust/sqlx-database/references/REFERENCE.md +13 -0
  321. package/rules/rust/sqlx-database/references/query-patterns.md +210 -0
  322. package/rules/rust/tauri/SKILL.md +180 -0
  323. package/rules/rust/tauri/references/REFERENCE.md +13 -0
  324. package/rules/rust/tauri/references/command-patterns.md +209 -0
  325. package/rules/rust/tokio-runtime/SKILL.md +167 -0
  326. package/rules/rust/tokio-runtime/references/REFERENCE.md +14 -0
  327. package/rules/rust/tokio-runtime/references/async-patterns.md +137 -0
  328. package/rules/rust/tokio-runtime/references/synchronization.md +152 -0
  329. package/rules/rust/tonic/SKILL.md +231 -0
  330. package/rules/rust/tonic/references/REFERENCE.md +13 -0
  331. package/rules/rust/tonic/references/service-patterns.md +213 -0
  332. package/rules/rust/tracing/SKILL.md +214 -0
  333. package/rules/rust/tracing/references/REFERENCE.md +13 -0
  334. package/rules/rust/tracing/references/instrumentation.md +187 -0
  335. package/rules/typescript/best-practices/SKILL.md +108 -0
  336. package/rules/typescript/best-practices/references/REFERENCE.md +68 -0
  337. package/rules/typescript/language/SKILL.md +72 -0
  338. package/rules/typescript/language/references/REFERENCE.md +67 -0
  339. package/rules/typescript/patterns.rule.md +85 -0
  340. package/rules/typescript/security/SKILL.md +59 -0
  341. package/rules/typescript/security/references/REFERENCE.md +113 -0
  342. package/rules/typescript/tooling/SKILL.md +52 -0
  343. package/rules/typescript/tooling/references/REFERENCE.md +110 -0
  344. package/skills/learn/SKILL.md +476 -0
@@ -0,0 +1,241 @@
1
+ ---
2
+ name: Spring Data JPA
3
+ description: Entity mapping, repositories, transactions, queries, auditing, and fetching strategies.
4
+ metadata:
5
+ labels: [java, spring-boot, jpa, database, hibernate]
6
+ triggers:
7
+ files: ['**/*Entity.java', '**/*Repository.java', '**/*Jpa*.java']
8
+ keywords: [Entity, Id, Repository, JpaRepository, Transactional, Query, ManyToOne, OneToMany, ManyToMany, JoinColumn]
9
+ ---
10
+
11
+ # Spring Data JPA Standards
12
+
13
+ ## Entity Definition
14
+
15
+ ```java
16
+ @Entity
17
+ @Table(name = "users")
18
+ @Getter @Setter
19
+ @NoArgsConstructor
20
+ public class User {
21
+
22
+ @Id
23
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
24
+ private Long id;
25
+
26
+ @Column(nullable = false, length = 100)
27
+ private String name;
28
+
29
+ @Column(nullable = false, unique = true)
30
+ private String email;
31
+
32
+ @Column(nullable = false)
33
+ private String passwordHash;
34
+
35
+ @Enumerated(EnumType.STRING)
36
+ @Column(nullable = false)
37
+ private UserStatus status = UserStatus.ACTIVE;
38
+
39
+ @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
40
+ private List<Order> orders = new ArrayList<>();
41
+
42
+ @CreatedDate
43
+ @Column(nullable = false, updatable = false)
44
+ private LocalDateTime createdAt;
45
+
46
+ @LastModifiedDate
47
+ private LocalDateTime updatedAt;
48
+
49
+ // Business methods
50
+ public void addOrder(Order order) {
51
+ orders.add(order);
52
+ order.setUser(this);
53
+ }
54
+
55
+ public void removeOrder(Order order) {
56
+ orders.remove(order);
57
+ order.setUser(null);
58
+ }
59
+ }
60
+ ```
61
+
62
+ ## Repository
63
+
64
+ ```java
65
+ public interface UserRepository extends JpaRepository<User, Long> {
66
+
67
+ // Derived query methods
68
+ Optional<User> findByEmail(String email);
69
+
70
+ List<User> findByStatus(UserStatus status);
71
+
72
+ boolean existsByEmail(String email);
73
+
74
+ // JPQL query
75
+ @Query("SELECT u FROM User u WHERE u.status = :status AND u.createdAt > :since")
76
+ List<User> findActiveUsersSince(
77
+ @Param("status") UserStatus status,
78
+ @Param("since") LocalDateTime since
79
+ );
80
+
81
+ // Native query
82
+ @Query(value = "SELECT * FROM users WHERE email LIKE %:domain", nativeQuery = true)
83
+ List<User> findByEmailDomain(@Param("domain") String domain);
84
+
85
+ // Modifying query
86
+ @Modifying
87
+ @Query("UPDATE User u SET u.status = :status WHERE u.id = :id")
88
+ int updateStatus(@Param("id") Long id, @Param("status") UserStatus status);
89
+
90
+ // Projection
91
+ @Query("SELECT u.id as id, u.name as name, u.email as email FROM User u")
92
+ List<UserSummary> findAllSummaries();
93
+
94
+ // Pagination
95
+ Page<User> findByStatus(UserStatus status, Pageable pageable);
96
+
97
+ // Specification (dynamic queries)
98
+ List<User> findAll(Specification<User> spec);
99
+ }
100
+
101
+ // Projection interface
102
+ public interface UserSummary {
103
+ Long getId();
104
+ String getName();
105
+ String getEmail();
106
+ }
107
+ ```
108
+
109
+ ## Transactions
110
+
111
+ ```java
112
+ @Service
113
+ @RequiredArgsConstructor
114
+ public class OrderService {
115
+
116
+ private final OrderRepository orderRepository;
117
+ private final InventoryService inventoryService;
118
+
119
+ @Transactional
120
+ public Order createOrder(CreateOrderRequest request) {
121
+ Order order = new Order();
122
+ // ... setup order
123
+
124
+ for (OrderItem item : request.items()) {
125
+ inventoryService.decreaseStock(item.productId(), item.quantity());
126
+ }
127
+
128
+ return orderRepository.save(order);
129
+ }
130
+
131
+ @Transactional(readOnly = true)
132
+ public Order findById(Long id) {
133
+ return orderRepository.findById(id)
134
+ .orElseThrow(() -> new OrderNotFoundException(id));
135
+ }
136
+
137
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
138
+ public void processPayment(Long orderId) {
139
+ // Runs in new transaction
140
+ }
141
+
142
+ @Transactional(
143
+ isolation = Isolation.SERIALIZABLE,
144
+ timeout = 30,
145
+ rollbackFor = PaymentException.class,
146
+ noRollbackFor = NotificationException.class
147
+ )
148
+ public void processWithOptions(Long orderId) {
149
+ // Custom transaction settings
150
+ }
151
+ }
152
+ ```
153
+
154
+ ## Relationships
155
+
156
+ ```java
157
+ // Many-to-One (owning side)
158
+ @Entity
159
+ public class Order {
160
+ @ManyToOne(fetch = FetchType.LAZY)
161
+ @JoinColumn(name = "user_id", nullable = false)
162
+ private User user;
163
+ }
164
+
165
+ // One-to-Many (inverse side)
166
+ @Entity
167
+ public class User {
168
+ @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
169
+ private List<Order> orders = new ArrayList<>();
170
+ }
171
+
172
+ // Many-to-Many
173
+ @Entity
174
+ public class Student {
175
+ @ManyToMany
176
+ @JoinTable(
177
+ name = "student_courses",
178
+ joinColumns = @JoinColumn(name = "student_id"),
179
+ inverseJoinColumns = @JoinColumn(name = "course_id")
180
+ )
181
+ private Set<Course> courses = new HashSet<>();
182
+ }
183
+
184
+ // One-to-One
185
+ @Entity
186
+ public class User {
187
+ @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
188
+ private UserProfile profile;
189
+ }
190
+ ```
191
+
192
+ ## Auditing
193
+
194
+ ```java
195
+ @Configuration
196
+ @EnableJpaAuditing
197
+ public class JpaConfig {}
198
+
199
+ @MappedSuperclass
200
+ @EntityListeners(AuditingEntityListener.class)
201
+ public abstract class BaseEntity {
202
+
203
+ @CreatedDate
204
+ @Column(nullable = false, updatable = false)
205
+ private LocalDateTime createdAt;
206
+
207
+ @LastModifiedDate
208
+ private LocalDateTime updatedAt;
209
+
210
+ @CreatedBy
211
+ @Column(updatable = false)
212
+ private String createdBy;
213
+
214
+ @LastModifiedBy
215
+ private String updatedBy;
216
+ }
217
+
218
+ @Component
219
+ public class AuditorAwareImpl implements AuditorAware<String> {
220
+ @Override
221
+ public Optional<String> getCurrentAuditor() {
222
+ return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
223
+ .map(Authentication::getName);
224
+ }
225
+ }
226
+ ```
227
+
228
+ ## Best Practices
229
+
230
+ 1. **Use @ManyToOne with LAZY** - avoid N+1 queries
231
+ 2. **Fetch eagerly with JOIN FETCH** when needed
232
+ 3. **Use @Transactional(readOnly = true)** for read operations
233
+ 4. **Avoid @ManyToMany** - use explicit join table entity
234
+ 5. **Use projections** for read-only queries
235
+ 6. **Paginate large result sets**
236
+
237
+ ## References
238
+
239
+ - [Entity Mapping](references/entity-mapping.md) - Inheritance, embeddables, converters
240
+ - [Repository Patterns](references/repository-patterns.md) - Specifications, custom repos
241
+ - [Fetching Strategies](references/fetching-strategies.md) - N+1, EntityGraph, batch
@@ -0,0 +1,16 @@
1
+ # Spring Data JPA References
2
+
3
+ ## References
4
+
5
+ - [**Entity Mapping**](entity-mapping.md) - Inheritance strategies, embeddables, custom converters
6
+ - [**Repository Patterns**](repository-patterns.md) - Specifications, custom implementations
7
+ - [**Fetching Strategies**](fetching-strategies.md) - N+1 problem, EntityGraph, batch fetching
8
+
9
+ ## Quick Checks
10
+
11
+ - [ ] Use LAZY fetch for @ManyToOne and @OneToMany
12
+ - [ ] JOIN FETCH for eager loading in queries
13
+ - [ ] @Transactional(readOnly = true) for reads
14
+ - [ ] Projections for read-only partial data
15
+ - [ ] Paginate large result sets
16
+ - [ ] Avoid open-in-view (disabled by default in Spring Boot 3)
@@ -0,0 +1,161 @@
1
+ ---
2
+ name: Spring Security
3
+ description: Authentication, authorization, JWT, OAuth2, CSRF, CORS, and security filter chain.
4
+ metadata:
5
+ labels: [java, spring-boot, security, authentication, authorization]
6
+ triggers:
7
+ files: ['**/*Security*.java', '**/*Config*.java', '**/*Auth*.java']
8
+ keywords: [SecurityFilterChain, HttpSecurity, Authentication, Authorization, csrf, jwt, OAuth2, UserDetails, PasswordEncoder]
9
+ ---
10
+
11
+ # Spring Security Standards
12
+
13
+ ## Security Configuration (Spring Boot 3+)
14
+
15
+ ```java
16
+ @Configuration
17
+ @EnableWebSecurity
18
+ @EnableMethodSecurity
19
+ public class SecurityConfig {
20
+
21
+ @Bean
22
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
23
+ return http
24
+ .csrf(csrf -> csrf.disable()) // Disable for stateless API
25
+ .cors(cors -> cors.configurationSource(corsConfigurationSource()))
26
+ .sessionManagement(session ->
27
+ session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
28
+ .authorizeHttpRequests(auth -> auth
29
+ .requestMatchers("/api/auth/**").permitAll()
30
+ .requestMatchers("/api/public/**").permitAll()
31
+ .requestMatchers("/actuator/health").permitAll()
32
+ .requestMatchers("/api/admin/**").hasRole("ADMIN")
33
+ .anyRequest().authenticated()
34
+ )
35
+ .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
36
+ .exceptionHandling(ex -> ex
37
+ .authenticationEntryPoint(authEntryPoint)
38
+ .accessDeniedHandler(accessDeniedHandler)
39
+ )
40
+ .build();
41
+ }
42
+
43
+ @Bean
44
+ public PasswordEncoder passwordEncoder() {
45
+ return new BCryptPasswordEncoder();
46
+ }
47
+
48
+ @Bean
49
+ public AuthenticationManager authenticationManager(
50
+ AuthenticationConfiguration config) throws Exception {
51
+ return config.getAuthenticationManager();
52
+ }
53
+ }
54
+ ```
55
+
56
+ ## JWT Authentication Filter
57
+
58
+ ```java
59
+ @Component
60
+ @RequiredArgsConstructor
61
+ public class JwtAuthenticationFilter extends OncePerRequestFilter {
62
+
63
+ private final JwtService jwtService;
64
+ private final UserDetailsService userDetailsService;
65
+
66
+ @Override
67
+ protected void doFilterInternal(
68
+ HttpServletRequest request,
69
+ HttpServletResponse response,
70
+ FilterChain filterChain) throws ServletException, IOException {
71
+
72
+ String authHeader = request.getHeader("Authorization");
73
+
74
+ if (authHeader == null || !authHeader.startsWith("Bearer ")) {
75
+ filterChain.doFilter(request, response);
76
+ return;
77
+ }
78
+
79
+ String jwt = authHeader.substring(7);
80
+ String username = jwtService.extractUsername(jwt);
81
+
82
+ if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
83
+ UserDetails userDetails = userDetailsService.loadUserByUsername(username);
84
+
85
+ if (jwtService.isTokenValid(jwt, userDetails)) {
86
+ UsernamePasswordAuthenticationToken authToken =
87
+ new UsernamePasswordAuthenticationToken(
88
+ userDetails,
89
+ null,
90
+ userDetails.getAuthorities()
91
+ );
92
+ authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
93
+ SecurityContextHolder.getContext().setAuthentication(authToken);
94
+ }
95
+ }
96
+
97
+ filterChain.doFilter(request, response);
98
+ }
99
+ }
100
+ ```
101
+
102
+ ## Method Security
103
+
104
+ ```java
105
+ @Service
106
+ public class UserService {
107
+
108
+ @PreAuthorize("hasRole('ADMIN')")
109
+ public void deleteUser(Long id) { }
110
+
111
+ @PreAuthorize("hasRole('ADMIN') or #id == authentication.principal.id")
112
+ public User updateUser(Long id, UpdateRequest request) { }
113
+
114
+ @PostAuthorize("returnObject.owner == authentication.name")
115
+ public Resource getResource(Long id) { }
116
+
117
+ @PreAuthorize("@securityService.canAccess(#id)")
118
+ public void accessResource(Long id) { }
119
+ }
120
+
121
+ @Component("securityService")
122
+ public class SecurityService {
123
+ public boolean canAccess(Long resourceId) {
124
+ // Custom authorization logic
125
+ return true;
126
+ }
127
+ }
128
+ ```
129
+
130
+ ## CORS Configuration
131
+
132
+ ```java
133
+ @Bean
134
+ public CorsConfigurationSource corsConfigurationSource() {
135
+ CorsConfiguration config = new CorsConfiguration();
136
+ config.setAllowedOrigins(List.of("http://localhost:3000", "https://example.com"));
137
+ config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
138
+ config.setAllowedHeaders(List.of("*"));
139
+ config.setAllowCredentials(true);
140
+ config.setMaxAge(3600L);
141
+
142
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
143
+ source.registerCorsConfiguration("/api/**", config);
144
+ return source;
145
+ }
146
+ ```
147
+
148
+ ## Best Practices
149
+
150
+ 1. **Use BCrypt** for password hashing (strength 10-12)
151
+ 2. **Stateless sessions** for REST APIs with JWT
152
+ 3. **Method security** for fine-grained authorization
153
+ 4. **Validate JWT** on every request
154
+ 5. **Short token expiry** with refresh token pattern
155
+ 6. **Never log sensitive data** (passwords, tokens)
156
+
157
+ ## References
158
+
159
+ - [JWT Auth Flow](references/jwt-auth-flow.md) - Token service, refresh tokens
160
+ - [OAuth2 Resource Server](references/oauth2-resource-server.md) - JWT decoder, claims
161
+ - [Security Filter Chain](references/security-filter-chain.md) - Filter order, custom filters
@@ -0,0 +1,16 @@
1
+ # Spring Security References
2
+
3
+ ## References
4
+
5
+ - [**JWT Auth Flow**](jwt-auth-flow.md) - Token generation, validation, refresh pattern
6
+ - [**OAuth2 Resource Server**](oauth2-resource-server.md) - JWT decoder, extracting claims
7
+ - [**Security Filter Chain**](security-filter-chain.md) - Filter ordering, custom filters
8
+
9
+ ## Quick Checks
10
+
11
+ - [ ] BCrypt password encoder (cost 10-12)
12
+ - [ ] Stateless session for REST APIs
13
+ - [ ] JWT validation on every request
14
+ - [ ] CORS configured for allowed origins only
15
+ - [ ] CSRF disabled only for stateless APIs
16
+ - [ ] Method security for fine-grained authorization
@@ -0,0 +1,213 @@
1
+ # JWT Authentication Flow
2
+
3
+ ## JWT Service
4
+
5
+ ```java
6
+ @Service
7
+ @RequiredArgsConstructor
8
+ public class JwtService {
9
+
10
+ @Value("${jwt.secret}")
11
+ private String secretKey;
12
+
13
+ @Value("${jwt.access-token-expiration}")
14
+ private Duration accessTokenExpiration;
15
+
16
+ @Value("${jwt.refresh-token-expiration}")
17
+ private Duration refreshTokenExpiration;
18
+
19
+ public String generateAccessToken(UserDetails userDetails) {
20
+ return generateToken(userDetails, accessTokenExpiration, Map.of());
21
+ }
22
+
23
+ public String generateRefreshToken(UserDetails userDetails) {
24
+ return generateToken(userDetails, refreshTokenExpiration, Map.of("type", "refresh"));
25
+ }
26
+
27
+ private String generateToken(
28
+ UserDetails userDetails,
29
+ Duration expiration,
30
+ Map<String, Object> extraClaims) {
31
+
32
+ Instant now = Instant.now();
33
+ return Jwts.builder()
34
+ .claims(extraClaims)
35
+ .subject(userDetails.getUsername())
36
+ .issuedAt(Date.from(now))
37
+ .expiration(Date.from(now.plus(expiration)))
38
+ .signWith(getSigningKey())
39
+ .compact();
40
+ }
41
+
42
+ public String extractUsername(String token) {
43
+ return extractClaim(token, Claims::getSubject);
44
+ }
45
+
46
+ public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
47
+ Claims claims = extractAllClaims(token);
48
+ return claimsResolver.apply(claims);
49
+ }
50
+
51
+ private Claims extractAllClaims(String token) {
52
+ return Jwts.parser()
53
+ .verifyWith(getSigningKey())
54
+ .build()
55
+ .parseSignedClaims(token)
56
+ .getPayload();
57
+ }
58
+
59
+ public boolean isTokenValid(String token, UserDetails userDetails) {
60
+ String username = extractUsername(token);
61
+ return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
62
+ }
63
+
64
+ private boolean isTokenExpired(String token) {
65
+ return extractClaim(token, Claims::getExpiration).before(new Date());
66
+ }
67
+
68
+ private SecretKey getSigningKey() {
69
+ byte[] keyBytes = Decoders.BASE64.decode(secretKey);
70
+ return Keys.hmacShaKeyFor(keyBytes);
71
+ }
72
+ }
73
+ ```
74
+
75
+ ## Authentication Controller
76
+
77
+ ```java
78
+ @RestController
79
+ @RequestMapping("/api/auth")
80
+ @RequiredArgsConstructor
81
+ public class AuthController {
82
+
83
+ private final AuthenticationManager authManager;
84
+ private final JwtService jwtService;
85
+ private final UserDetailsService userDetailsService;
86
+ private final RefreshTokenService refreshTokenService;
87
+
88
+ @PostMapping("/login")
89
+ public AuthResponse login(@Valid @RequestBody LoginRequest request) {
90
+ authManager.authenticate(
91
+ new UsernamePasswordAuthenticationToken(
92
+ request.email(),
93
+ request.password()
94
+ )
95
+ );
96
+
97
+ UserDetails userDetails = userDetailsService.loadUserByUsername(request.email());
98
+ String accessToken = jwtService.generateAccessToken(userDetails);
99
+ String refreshToken = jwtService.generateRefreshToken(userDetails);
100
+
101
+ refreshTokenService.save(request.email(), refreshToken);
102
+
103
+ return new AuthResponse(accessToken, refreshToken);
104
+ }
105
+
106
+ @PostMapping("/refresh")
107
+ public AuthResponse refresh(@Valid @RequestBody RefreshRequest request) {
108
+ String refreshToken = request.refreshToken();
109
+
110
+ if (!refreshTokenService.isValid(refreshToken)) {
111
+ throw new InvalidTokenException("Invalid refresh token");
112
+ }
113
+
114
+ String username = jwtService.extractUsername(refreshToken);
115
+ UserDetails userDetails = userDetailsService.loadUserByUsername(username);
116
+
117
+ String newAccessToken = jwtService.generateAccessToken(userDetails);
118
+ String newRefreshToken = jwtService.generateRefreshToken(userDetails);
119
+
120
+ refreshTokenService.revoke(refreshToken);
121
+ refreshTokenService.save(username, newRefreshToken);
122
+
123
+ return new AuthResponse(newAccessToken, newRefreshToken);
124
+ }
125
+
126
+ @PostMapping("/logout")
127
+ public void logout(@RequestHeader("Authorization") String authHeader) {
128
+ if (authHeader != null && authHeader.startsWith("Bearer ")) {
129
+ String token = authHeader.substring(7);
130
+ String username = jwtService.extractUsername(token);
131
+ refreshTokenService.revokeAllForUser(username);
132
+ }
133
+ }
134
+ }
135
+
136
+ public record LoginRequest(
137
+ @NotBlank @Email String email,
138
+ @NotBlank String password
139
+ ) {}
140
+
141
+ public record RefreshRequest(
142
+ @NotBlank String refreshToken
143
+ ) {}
144
+
145
+ public record AuthResponse(
146
+ String accessToken,
147
+ String refreshToken
148
+ ) {}
149
+ ```
150
+
151
+ ## Refresh Token Storage
152
+
153
+ ```java
154
+ @Service
155
+ @RequiredArgsConstructor
156
+ public class RefreshTokenService {
157
+
158
+ private final RefreshTokenRepository repository;
159
+ private final JwtService jwtService;
160
+
161
+ public void save(String username, String token) {
162
+ RefreshToken refreshToken = new RefreshToken();
163
+ refreshToken.setUsername(username);
164
+ refreshToken.setToken(token);
165
+ refreshToken.setExpiresAt(
166
+ jwtService.extractClaim(token, Claims::getExpiration).toInstant()
167
+ );
168
+ repository.save(refreshToken);
169
+ }
170
+
171
+ public boolean isValid(String token) {
172
+ return repository.findByToken(token)
173
+ .map(rt -> rt.getExpiresAt().isAfter(Instant.now()))
174
+ .orElse(false);
175
+ }
176
+
177
+ public void revoke(String token) {
178
+ repository.deleteByToken(token);
179
+ }
180
+
181
+ public void revokeAllForUser(String username) {
182
+ repository.deleteAllByUsername(username);
183
+ }
184
+ }
185
+
186
+ @Entity
187
+ @Table(name = "refresh_tokens")
188
+ public class RefreshToken {
189
+ @Id
190
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
191
+ private Long id;
192
+
193
+ @Column(nullable = false)
194
+ private String username;
195
+
196
+ @Column(nullable = false, unique = true)
197
+ private String token;
198
+
199
+ @Column(nullable = false)
200
+ private Instant expiresAt;
201
+
202
+ // getters, setters
203
+ }
204
+ ```
205
+
206
+ ## Configuration
207
+
208
+ ```yaml
209
+ jwt:
210
+ secret: ${JWT_SECRET} # Base64 encoded, min 256 bits
211
+ access-token-expiration: 15m
212
+ refresh-token-expiration: 7d
213
+ ```