@eventmodelers/cli 0.0.1

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 (220) hide show
  1. package/README.md +175 -0
  2. package/cli.js +676 -0
  3. package/package.json +35 -0
  4. package/shared/build-kit/code-export.mjs +560 -0
  5. package/shared/build-kit/lib/ollama-agent.js +147 -0
  6. package/shared/build-kit/package.json +11 -0
  7. package/shared/build-kit/ralph-ollama.js +39 -0
  8. package/shared/build-kit/realtime-agent.js +18 -0
  9. package/stacks/axon/templates/.claude/skills/build-automation/SKILL.md +407 -0
  10. package/stacks/axon/templates/.claude/skills/build-automation/references/feature-flag-patterns.md +114 -0
  11. package/stacks/axon/templates/.claude/skills/build-automation-workflow/SKILL.md +496 -0
  12. package/stacks/axon/templates/.claude/skills/build-automation-workflow/references/axon-workflow-api.md +279 -0
  13. package/stacks/axon/templates/.claude/skills/build-automation-workflow/references/feature-flag-patterns.md +114 -0
  14. package/stacks/axon/templates/.claude/skills/build-state-change/SKILL.md +396 -0
  15. package/stacks/axon/templates/.claude/skills/build-state-change/references/axon-test-fixture-patterns.md +162 -0
  16. package/stacks/axon/templates/.claude/skills/build-state-change/references/feature-flag-patterns.md +56 -0
  17. package/stacks/axon/templates/.claude/skills/build-state-change/references/rest-api-patterns.md +115 -0
  18. package/stacks/axon/templates/.claude/skills/build-state-view/SKILL.md +282 -0
  19. package/stacks/axon/templates/.claude/skills/connect/SKILL.md +178 -0
  20. package/stacks/axon/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +611 -0
  21. package/stacks/axon/templates/.claude/skills/load-slice/SKILL.md +141 -0
  22. package/stacks/axon/templates/.claude/skills/update-slice-status/SKILL.md +105 -0
  23. package/stacks/axon/templates/build-kit/lib/AGENT.md +47 -0
  24. package/stacks/axon/templates/build-kit/lib/agent.sh +20 -0
  25. package/stacks/axon/templates/build-kit/lib/backend-prompt.md +158 -0
  26. package/stacks/axon/templates/build-kit/lib/prompt.md +126 -0
  27. package/stacks/axon/templates/build-kit/lib/ralph.js +369 -0
  28. package/stacks/axon/templates/build-kit/ralph-claude.js +44 -0
  29. package/stacks/axon/templates/build-kit/ralph.sh +98 -0
  30. package/stacks/axon/templates/root/.env.example +5 -0
  31. package/stacks/axon/templates/root/CLAUDE.md +60 -0
  32. package/stacks/axon/templates/root/README.md +44 -0
  33. package/stacks/axon/templates/root/docker-compose.yml +64 -0
  34. package/stacks/axon/templates/root/mvnw +259 -0
  35. package/stacks/axon/templates/root/mvnw.cmd +149 -0
  36. package/stacks/axon/templates/root/pom.xml +125 -0
  37. package/stacks/axon/templates/root/src/main/java/io/axoniq/quickstart/QuickstartApplication.java +128 -0
  38. package/stacks/axon/templates/root/src/main/java/io/axoniq/quickstart/config/WebConfig.java +155 -0
  39. package/stacks/axon/templates/root/src/main/resources/application.properties +2 -0
  40. package/stacks/axon/templates/root/src/main/resources/static/bg-body.png +0 -0
  41. package/stacks/axon/templates/root/src/main/resources/static/bg-header.png +0 -0
  42. package/stacks/axon/templates/root/src/main/resources/static/index.html +596 -0
  43. package/stacks/cratis-csharp/templates/.claude/skills/_shared/cratis-conventions.md +251 -0
  44. package/stacks/cratis-csharp/templates/.claude/skills/build-automation/SKILL.md +99 -0
  45. package/stacks/cratis-csharp/templates/.claude/skills/build-automation/references/patterns.md +115 -0
  46. package/stacks/cratis-csharp/templates/.claude/skills/build-state-change/SKILL.md +163 -0
  47. package/stacks/cratis-csharp/templates/.claude/skills/build-state-change/references/patterns.md +234 -0
  48. package/stacks/cratis-csharp/templates/.claude/skills/build-state-view/SKILL.md +120 -0
  49. package/stacks/cratis-csharp/templates/.claude/skills/build-state-view/references/patterns.md +166 -0
  50. package/stacks/cratis-csharp/templates/.claude/skills/connect/SKILL.md +169 -0
  51. package/stacks/cratis-csharp/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +609 -0
  52. package/stacks/cratis-csharp/templates/.claude/skills/load-slice/SKILL.md +141 -0
  53. package/stacks/cratis-csharp/templates/.claude/skills/update-slice-status/SKILL.md +105 -0
  54. package/stacks/cratis-csharp/templates/build-kit/lib/AGENT.md +58 -0
  55. package/stacks/cratis-csharp/templates/build-kit/lib/agent.sh +20 -0
  56. package/stacks/cratis-csharp/templates/build-kit/lib/backend-prompt.md +129 -0
  57. package/stacks/cratis-csharp/templates/build-kit/lib/prompt.md +124 -0
  58. package/stacks/cratis-csharp/templates/build-kit/lib/ralph.js +302 -0
  59. package/stacks/cratis-csharp/templates/build-kit/ralph-claude.js +37 -0
  60. package/stacks/cratis-csharp/templates/build-kit/ralph.sh +98 -0
  61. package/stacks/cratis-csharp/templates/root/.frontend/index.css +29 -0
  62. package/stacks/cratis-csharp/templates/root/.frontend/index.html +17 -0
  63. package/stacks/cratis-csharp/templates/root/.frontend/main.tsx +18 -0
  64. package/stacks/cratis-csharp/templates/root/.frontend/tsconfig.json +42 -0
  65. package/stacks/cratis-csharp/templates/root/.frontend/tsconfig.node.json +11 -0
  66. package/stacks/cratis-csharp/templates/root/.frontend/vite.config.ts +56 -0
  67. package/stacks/cratis-csharp/templates/root/App.tsx +23 -0
  68. package/stacks/cratis-csharp/templates/root/CLAUDE.md +62 -0
  69. package/stacks/cratis-csharp/templates/root/CratisApp.csproj +25 -0
  70. package/stacks/cratis-csharp/templates/root/CratisApp.sln +18 -0
  71. package/stacks/cratis-csharp/templates/root/GlobalUsings.cs +3 -0
  72. package/stacks/cratis-csharp/templates/root/Home.tsx +102 -0
  73. package/stacks/cratis-csharp/templates/root/Program.cs +26 -0
  74. package/stacks/cratis-csharp/templates/root/README.md +192 -0
  75. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/AllListings.ts +47 -0
  76. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/Listing.cs +11 -0
  77. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/Listing.ts +12 -0
  78. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/ListingDataTable.tsx +17 -0
  79. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Listing/index.ts +1 -0
  80. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Registration/Register.ts +51 -0
  81. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Registration/RegisterDialog.tsx +18 -0
  82. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Registration/Registration.cs +27 -0
  83. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/Registration/index.ts +1 -0
  84. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/SomeFeature.tsx +22 -0
  85. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/SomeName.cs +3 -0
  86. package/stacks/cratis-csharp/templates/root/SomeModule/SomeFeature/index.ts +1 -0
  87. package/stacks/cratis-csharp/templates/root/appsettings.Development.json +9 -0
  88. package/stacks/cratis-csharp/templates/root/appsettings.json +26 -0
  89. package/stacks/cratis-csharp/templates/root/docker-compose.yml +23 -0
  90. package/stacks/cratis-csharp/templates/root/package.json +33 -0
  91. package/stacks/cratis-csharp/templates/root/tsconfig.json +3 -0
  92. package/stacks/modeling-kit/templates/.claude/settings.local.json +13 -0
  93. package/stacks/modeling-kit/templates/.claude/skills/analyze-existing-model/SKILL.md +215 -0
  94. package/stacks/modeling-kit/templates/.claude/skills/attributes/SKILL.md +176 -0
  95. package/stacks/modeling-kit/templates/.claude/skills/connect/SKILL.md +182 -0
  96. package/stacks/modeling-kit/templates/.claude/skills/discover-storyboard/SKILL.md +383 -0
  97. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-applying-conways-law/SKILL.md +465 -0
  98. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/SKILL.md +587 -0
  99. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-brainstorming-events/references/facilitating-event-modeling-workshops.md +626 -0
  100. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-checking-completeness/SKILL.md +542 -0
  101. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-designing-event-models/SKILL.md +497 -0
  102. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-elaborating-scenarios/SKILL.md +783 -0
  103. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-inputs/SKILL.md +604 -0
  104. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-identifying-outputs/SKILL.md +699 -0
  105. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-integrating-legacy-systems/SKILL.md +674 -0
  106. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/SKILL.md +231 -0
  107. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/domain-patterns.md +150 -0
  108. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/patterns.md +329 -0
  109. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-optimizing-stream-design/references/snapshotting.md +204 -0
  110. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/SKILL.md +352 -0
  111. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-orchestrating-event-modeling/references/project-planning-with-event-modeling.md +341 -0
  112. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-plotting-events/SKILL.md +153 -0
  113. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/SKILL.md +136 -0
  114. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/examples.md +78 -0
  115. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-slicing-event-models/references/patterns.md +85 -0
  116. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-storyboarding-events/SKILL.md +655 -0
  117. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-translating-external-events/SKILL.md +479 -0
  118. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models/SKILL.md +234 -0
  119. package/stacks/modeling-kit/templates/.claude/skills/eventmodeling-validating-event-models-checklist/SKILL.md +353 -0
  120. package/stacks/modeling-kit/templates/.claude/skills/examples/SKILL.md +200 -0
  121. package/stacks/modeling-kit/templates/.claude/skills/handle-comment/SKILL.md +94 -0
  122. package/stacks/modeling-kit/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +441 -0
  123. package/stacks/modeling-kit/templates/.claude/skills/place-element/SKILL.md +290 -0
  124. package/stacks/modeling-kit/templates/.claude/skills/storyboard/SKILL.md +212 -0
  125. package/stacks/modeling-kit/templates/.claude/skills/storyboard-screen/SKILL.md +123 -0
  126. package/stacks/modeling-kit/templates/.claude/skills/timeline/SKILL.md +353 -0
  127. package/stacks/modeling-kit/templates/.claude/skills/update-slice-status/SKILL.md +110 -0
  128. package/stacks/modeling-kit/templates/.claude/skills/wdyt/SKILL.md +134 -0
  129. package/stacks/modeling-kit/templates/kit/lib/agent.sh +20 -0
  130. package/stacks/modeling-kit/templates/kit/lib/ollama-agent.js +147 -0
  131. package/stacks/modeling-kit/templates/kit/lib/ralph.js +286 -0
  132. package/stacks/modeling-kit/templates/kit/package.json +12 -0
  133. package/stacks/modeling-kit/templates/kit/ralph-claude.js +50 -0
  134. package/stacks/modeling-kit/templates/kit/ralph-ollama.js +38 -0
  135. package/stacks/modeling-kit/templates/kit/ralph.sh +61 -0
  136. package/stacks/modeling-kit/templates/kit/realtime-agent.js +18 -0
  137. package/stacks/modeling-kit/templates/root/CLAUDE.md +56 -0
  138. package/stacks/node/templates/.claude/skills/build-automation/SKILL.md +266 -0
  139. package/stacks/node/templates/.claude/skills/build-state-change/SKILL.md +344 -0
  140. package/stacks/node/templates/.claude/skills/build-state-view/SKILL.md +412 -0
  141. package/stacks/node/templates/.claude/skills/connect/SKILL.md +178 -0
  142. package/stacks/node/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +628 -0
  143. package/stacks/node/templates/.claude/skills/load-slice/SKILL.md +143 -0
  144. package/stacks/node/templates/.claude/skills/update-slice-status/SKILL.md +110 -0
  145. package/stacks/node/templates/build-kit/README.md +86 -0
  146. package/stacks/node/templates/build-kit/lib/AGENT.md +47 -0
  147. package/stacks/node/templates/build-kit/lib/agent.sh +20 -0
  148. package/stacks/node/templates/build-kit/lib/backend-prompt.md +152 -0
  149. package/stacks/node/templates/build-kit/lib/prompt.md +122 -0
  150. package/stacks/node/templates/build-kit/lib/ralph.js +369 -0
  151. package/stacks/node/templates/build-kit/ralph-claude.js +44 -0
  152. package/stacks/node/templates/build-kit/ralph.sh +98 -0
  153. package/stacks/node/templates/root/.env.example +15 -0
  154. package/stacks/node/templates/root/CLAUDE.md +60 -0
  155. package/stacks/node/templates/root/docker-compose.yml +15 -0
  156. package/stacks/node/templates/root/flyway.conf +17 -0
  157. package/stacks/node/templates/root/migrations/V1__schema.sql.example +12 -0
  158. package/stacks/node/templates/root/package.json +50 -0
  159. package/stacks/node/templates/root/server.ts +130 -0
  160. package/stacks/node/templates/root/setup-env.sh +53 -0
  161. package/stacks/node/templates/root/src/common/assertions.ts +6 -0
  162. package/stacks/node/templates/root/src/common/db.ts +32 -0
  163. package/stacks/node/templates/root/src/common/loadPostgresEventstore.ts +23 -0
  164. package/stacks/node/templates/root/src/common/parseEndpoint.ts +51 -0
  165. package/stacks/node/templates/root/src/common/processorDlq.ts +28 -0
  166. package/stacks/node/templates/root/src/common/realtimeBroadcast.ts +12 -0
  167. package/stacks/node/templates/root/src/common/replay.ts +16 -0
  168. package/stacks/node/templates/root/src/common/routes.ts +19 -0
  169. package/stacks/node/templates/root/src/common/testHelpers.ts +44 -0
  170. package/stacks/node/templates/root/src/swagger.ts +34 -0
  171. package/stacks/node/templates/root/src/util/assertions.ts +6 -0
  172. package/stacks/node/templates/root/src/util/hash.ts +9 -0
  173. package/stacks/node/templates/root/src/util/sanitize.ts +23 -0
  174. package/stacks/node/templates/root/tsconfig.json +32 -0
  175. package/stacks/node/templates/root/vercel.json +8 -0
  176. package/stacks/supabase/templates/.claude/skills/build-automation/SKILL.md +266 -0
  177. package/stacks/supabase/templates/.claude/skills/build-state-change/SKILL.md +344 -0
  178. package/stacks/supabase/templates/.claude/skills/build-state-view/SKILL.md +390 -0
  179. package/stacks/supabase/templates/.claude/skills/build-webhook/SKILL.md +303 -0
  180. package/stacks/supabase/templates/.claude/skills/connect/SKILL.md +178 -0
  181. package/stacks/supabase/templates/.claude/skills/learn-eventmodelers-api/SKILL.md +628 -0
  182. package/stacks/supabase/templates/.claude/skills/load-slice/SKILL.md +143 -0
  183. package/stacks/supabase/templates/.claude/skills/update-slice-status/SKILL.md +110 -0
  184. package/stacks/supabase/templates/build-kit/README.md +86 -0
  185. package/stacks/supabase/templates/build-kit/lib/AGENT.md +47 -0
  186. package/stacks/supabase/templates/build-kit/lib/agent.sh +20 -0
  187. package/stacks/supabase/templates/build-kit/lib/backend-prompt.md +152 -0
  188. package/stacks/supabase/templates/build-kit/lib/prompt.md +123 -0
  189. package/stacks/supabase/templates/build-kit/lib/ralph.js +369 -0
  190. package/stacks/supabase/templates/build-kit/ralph-claude.js +44 -0
  191. package/stacks/supabase/templates/build-kit/ralph.sh +98 -0
  192. package/stacks/supabase/templates/root/.env.example +22 -0
  193. package/stacks/supabase/templates/root/CLAUDE.md +61 -0
  194. package/stacks/supabase/templates/root/flyway.conf +17 -0
  195. package/stacks/supabase/templates/root/package.json +52 -0
  196. package/stacks/supabase/templates/root/server.ts +177 -0
  197. package/stacks/supabase/templates/root/setup-env.sh +53 -0
  198. package/stacks/supabase/templates/root/src/common/assertions.ts +6 -0
  199. package/stacks/supabase/templates/root/src/common/db.ts +32 -0
  200. package/stacks/supabase/templates/root/src/common/loadPostgresEventstore.ts +23 -0
  201. package/stacks/supabase/templates/root/src/common/parseEndpoint.ts +51 -0
  202. package/stacks/supabase/templates/root/src/common/processorDlq.ts +28 -0
  203. package/stacks/supabase/templates/root/src/common/realtimeBroadcast.ts +19 -0
  204. package/stacks/supabase/templates/root/src/common/replay.ts +16 -0
  205. package/stacks/supabase/templates/root/src/common/routes.ts +23 -0
  206. package/stacks/supabase/templates/root/src/common/testHelpers.ts +54 -0
  207. package/stacks/supabase/templates/root/src/supabase/README.md +141 -0
  208. package/stacks/supabase/templates/root/src/supabase/api.ts +56 -0
  209. package/stacks/supabase/templates/root/src/supabase/requireOrgaAdmin.ts +32 -0
  210. package/stacks/supabase/templates/root/src/supabase/requireSysUser.ts +40 -0
  211. package/stacks/supabase/templates/root/src/supabase/requireUser.ts +72 -0
  212. package/stacks/supabase/templates/root/src/swagger.ts +34 -0
  213. package/stacks/supabase/templates/root/src/util/assertions.ts +6 -0
  214. package/stacks/supabase/templates/root/src/util/hash.ts +9 -0
  215. package/stacks/supabase/templates/root/src/util/sanitize.ts +23 -0
  216. package/stacks/supabase/templates/root/supabase/config.toml +295 -0
  217. package/stacks/supabase/templates/root/supabase/migrations/V1__schema.sql.example +12 -0
  218. package/stacks/supabase/templates/root/supabase/seed.sql +1 -0
  219. package/stacks/supabase/templates/root/tsconfig.json +32 -0
  220. package/stacks/supabase/templates/root/vercel.json +8 -0
@@ -0,0 +1,596 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AxonIQ Gift Card Management</title>
7
+
8
+ <!-- Vuetify CSS -->
9
+ <link href="https://cdn.jsdelivr.net/npm/vuetify@3/dist/vuetify.min.css" rel="stylesheet">
10
+ <!-- Material Design Icons -->
11
+ <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
12
+ <!-- Arimo Font -->
13
+ <link href="https://fonts.googleapis.com/css2?family=Arimo:wght@400;500;600;700;800;900&display=swap" rel="stylesheet">
14
+
15
+ <style>
16
+ :root {
17
+ --v-font-family: 'Arimo', sans-serif;
18
+ }
19
+
20
+ * {
21
+ font-family: 'Arimo', sans-serif !important;
22
+ }
23
+
24
+ body {
25
+ margin: 0;
26
+ padding: 0;
27
+ background-image: url('./bg-body.png');
28
+ background-size: cover;
29
+ background-position: center;
30
+ background-attachment: fixed;
31
+ min-height: 100vh;
32
+ font-family: 'Arimo', sans-serif;
33
+ font-size: 1rem;
34
+ }
35
+
36
+ .v-main, .v-application {
37
+ background: transparent !important;
38
+ }
39
+
40
+ .app-header {
41
+ background-image: url('./bg-header.png') !important;
42
+ background-size: cover !important;
43
+ background-position: center !important;
44
+ background-color: transparent !important;
45
+ position: relative;
46
+ }
47
+
48
+ .app-header .v-toolbar__content {
49
+ background: transparent !important;
50
+ }
51
+
52
+ .header-content {
53
+ position: relative;
54
+ z-index: 1;
55
+ }
56
+
57
+ /* Typography overrides matching SASS config */
58
+ .v-application .text-h1 {
59
+ font-size: 2.25rem !important;
60
+ font-weight: 900 !important;
61
+ line-height: 2.75rem !important;
62
+ text-transform: capitalize !important;
63
+ }
64
+
65
+ .v-application .text-h2 {
66
+ font-size: 1.875rem !important;
67
+ font-weight: 800 !important;
68
+ line-height: 2.25rem !important;
69
+ text-transform: capitalize !important;
70
+ }
71
+
72
+ .v-application .text-h3 {
73
+ font-size: 1.5rem !important;
74
+ font-weight: 700 !important;
75
+ line-height: 2rem !important;
76
+ text-transform: capitalize !important;
77
+ }
78
+
79
+ .v-application .text-h4 {
80
+ font-size: 1.3125rem !important;
81
+ font-weight: 600 !important;
82
+ line-height: 1.6rem !important;
83
+ text-transform: capitalize !important;
84
+ }
85
+
86
+ .v-application .text-h5 {
87
+ font-size: 1.125rem !important;
88
+ font-weight: 600 !important;
89
+ line-height: 1.6rem !important;
90
+ text-transform: capitalize !important;
91
+ }
92
+
93
+ .v-application .text-h6 {
94
+ font-size: 1rem !important;
95
+ font-weight: 600 !important;
96
+ line-height: 1.2rem !important;
97
+ text-transform: capitalize !important;
98
+ }
99
+
100
+ .v-application .text-subtitle-1 {
101
+ font-size: 0.875rem !important;
102
+ font-weight: 400 !important;
103
+ line-height: 1.1rem !important;
104
+ }
105
+
106
+ .v-application .text-subtitle-2 {
107
+ font-size: 0.75rem !important;
108
+ font-weight: 400 !important;
109
+ line-height: 1rem !important;
110
+ }
111
+
112
+ .v-application .text-body-1 {
113
+ font-size: 0.875rem !important;
114
+ font-weight: 400 !important;
115
+ }
116
+
117
+ .v-application .text-body-2 {
118
+ font-size: 0.75rem !important;
119
+ font-weight: 400 !important;
120
+ }
121
+
122
+ .v-application .text-caption {
123
+ font-size: 0.75rem !important;
124
+ font-weight: 400 !important;
125
+ }
126
+
127
+ /* Card styling matching SASS config */
128
+ .v-card {
129
+ border-radius: 12px !important;
130
+ border: 1px solid #D5D7DA !important;
131
+ box-shadow: none !important;
132
+ background: #FFFFFF !important;
133
+ }
134
+
135
+ .v-card-title {
136
+ padding: 16px !important;
137
+ font-size: 18px !important;
138
+ }
139
+
140
+ .v-card-text {
141
+ padding: 16px !important;
142
+ }
143
+
144
+ /* Button styling */
145
+ .v-btn {
146
+ border-radius: 12px !important;
147
+ font-weight: 400 !important;
148
+ letter-spacing: 0 !important;
149
+ text-transform: none !important;
150
+ font-size: 0.875rem !important;
151
+ }
152
+
153
+ .v-btn:hover {
154
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12) !important;
155
+ }
156
+
157
+ .v-btn:active {
158
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.16) !important;
159
+ }
160
+
161
+ /* Text field styling */
162
+ .v-text-field {
163
+ border-radius: 12px !important;
164
+ }
165
+
166
+ .v-text-field .v-field {
167
+ border-radius: 12px !important;
168
+ }
169
+
170
+ .floating-card {
171
+ background: #FFFFFF !important;
172
+ border: 1px solid #D5D7DA !important;
173
+ border-radius: 12px !important;
174
+ box-shadow: none !important;
175
+ }
176
+
177
+ .gift-card-item {
178
+ background: #FFFFFF !important;
179
+ border-radius: 12px !important;
180
+ border: 1px solid #D5D7DA !important;
181
+ box-shadow: none !important;
182
+ transition: all 0.3s ease;
183
+ }
184
+
185
+ .gift-card-item:hover {
186
+ transform: translateY(-2px);
187
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12) !important;
188
+ }
189
+
190
+ /* Custom theme colors */
191
+ .axoniq-primary {
192
+ background-color: #06AED4 !important;
193
+ color: white !important;
194
+ }
195
+
196
+ .axoniq-secondary {
197
+ background-color: #6840c5 !important;
198
+ color: white !important;
199
+ }
200
+
201
+ .status-chip-active {
202
+ background-color: #12B76A !important;
203
+ color: white !important;
204
+ }
205
+
206
+ .status-chip-empty {
207
+ background-color: #B00020 !important;
208
+ color: white !important;
209
+ }
210
+
211
+ .status-chip-tertiary {
212
+ background-color: #15B79E !important;
213
+ color: white !important;
214
+ }
215
+
216
+ /* Progress bar colors */
217
+ .v-progress-linear.success {
218
+ background-color: #12B76A !important;
219
+ }
220
+
221
+ /* Alert styling */
222
+ .v-alert {
223
+ border-radius: 12px !important;
224
+ }
225
+
226
+ /* Chip styling */
227
+ .v-chip {
228
+ border-radius: 6px !important;
229
+ }
230
+
231
+ /* Text field focus colors */
232
+ .v-text-field--focused .v-field__outline {
233
+ color: #06AED4 !important;
234
+ }
235
+
236
+ .v-text-field--focused .v-label {
237
+ color: #06AED4 !important;
238
+ }
239
+
240
+ /* Sidebar background variable support */
241
+ .sidebar-bg {
242
+ background: rgba(242, 246, 250, 0.7) !important;
243
+ }
244
+
245
+ /* Border color variable */
246
+ .border-custom {
247
+ border-color: #e5eaef !important;
248
+ }
249
+
250
+ /* Primary grey text */
251
+ .text-primary-grey {
252
+ color: #717680 !important;
253
+ }
254
+ </style>
255
+ </head>
256
+ <body>
257
+ <div id="app">
258
+ <v-app>
259
+ <!-- Header -->
260
+ <v-app-bar class="app-header" height="120" flat>
261
+ <template v-slot:default>
262
+ <div class="header-content w-100 d-flex align-center justify-center">
263
+ <div class="text-center">
264
+ <h1 class="text-h3 font-weight-bold mb-2">
265
+ <v-icon size="large" class="mr-3">mdi-gift</v-icon>
266
+ Axoniq Platform Quickstart
267
+ </h1>
268
+ <p class="text-h6 opacity-90">Powered by Axon Framework & Server</p>
269
+ </div>
270
+ </div>
271
+ </template>
272
+ </v-app-bar>
273
+
274
+ <v-main>
275
+ <v-container fluid class="pa-6">
276
+ <!-- Alert Messages -->
277
+ <v-alert
278
+ v-if="message"
279
+ :type="message.type === 'success' ? 'success' : 'error'"
280
+ :text="message.text"
281
+ variant="tonal"
282
+ closable
283
+ class="mb-6"
284
+ @click:close="message = null"
285
+ ></v-alert>
286
+
287
+ <v-row>
288
+ <!-- Issue Gift Card Form -->
289
+ <v-col cols="12" md="4">
290
+ <v-card class="floating-card" elevation="0">
291
+ <v-card-title class="text-h5 pb-2">
292
+ <v-icon class="mr-2">mdi-plus-circle</v-icon>
293
+ Issue New Gift Card
294
+ </v-card-title>
295
+ <v-card-text>
296
+ <v-text-field
297
+ v-model="issueAmount"
298
+ label="Amount"
299
+ prefix="$"
300
+ type="number"
301
+ step="0.01"
302
+ min="0.01"
303
+ variant="outlined"
304
+ density="comfortable"
305
+ :rules="[v => !!v && v > 0 || 'Amount must be greater than 0']"
306
+ ></v-text-field>
307
+ </v-card-text>
308
+ <v-card-actions class="px-6 pb-6">
309
+ <v-btn
310
+ @click="issueGiftCard"
311
+ :disabled="!issueAmount || issueAmount <= 0"
312
+ class="axoniq-primary"
313
+ size="large"
314
+ block
315
+ :loading="issuingCard"
316
+ >
317
+ <v-icon class="mr-2">mdi-credit-card-plus</v-icon>
318
+ Issue Gift Card
319
+ </v-btn>
320
+ </v-card-actions>
321
+ </v-card>
322
+ </v-col>
323
+
324
+ <!-- Gift Cards List -->
325
+ <v-col cols="12" md="8">
326
+ <v-card class="floating-card" elevation="0">
327
+ <v-card-title class="text-h5 pb-2">
328
+ <v-icon class="mr-2">mdi-wallet-giftcard</v-icon>
329
+ Gift Cards
330
+ <v-chip class="ml-3" color="primary" size="small">{{ giftCards.length }}</v-chip>
331
+ </v-card-title>
332
+
333
+ <v-card-text v-if="giftCards.length === 0" class="text-center py-8">
334
+ <v-icon size="64" color="grey-lighten-2" class="mb-4">mdi-gift-outline</v-icon>
335
+ <p class="text-h6 text-grey">No gift cards yet!</p>
336
+ <p class="text-body-2 text-grey">Issue your first gift card to get started.</p>
337
+ </v-card-text>
338
+
339
+ <v-card-text v-else class="pa-2">
340
+ <v-row>
341
+ <v-col
342
+ v-for="giftCard in giftCards"
343
+ :key="giftCard.giftCardId"
344
+ cols="12"
345
+ class="pa-2"
346
+ >
347
+ <v-card class="gift-card-item pa-4">
348
+ <v-row align="center">
349
+ <v-col cols="12" sm="6">
350
+ <div class="text-body-2 text-grey mb-1">Gift Card ID</div>
351
+ <div class="text-caption font-mono">{{ giftCard.giftCardId }}</div>
352
+
353
+ <v-row class="mt-3" no-gutters>
354
+ <v-col cols="6">
355
+ <div class="text-body-2 text-grey">Remaining</div>
356
+ <div class="text-h6 font-weight-bold text-success">
357
+ ${{ giftCard.remainingValue.toFixed(2) }}
358
+ </div>
359
+ </v-col>
360
+ <v-col cols="6">
361
+ <div class="text-body-2 text-grey">Initial</div>
362
+ <div class="text-body-1">
363
+ ${{ giftCard.initialValue.toFixed(2) }}
364
+ </div>
365
+ </v-col>
366
+ </v-row>
367
+ </v-col>
368
+
369
+ <v-col cols="12" sm="3" class="text-center">
370
+ <v-chip
371
+ :class="giftCard.remainingValue <= 0 ? 'status-chip-empty' : 'status-chip-active'"
372
+ size="small"
373
+ >
374
+ <v-icon class="mr-1">
375
+ {{ giftCard.remainingValue <= 0 ? 'mdi-close-circle' : 'mdi-check-circle' }}
376
+ </v-icon>
377
+ {{ giftCard.remainingValue <= 0 ? 'EMPTY' : 'ACTIVE' }}
378
+ </v-chip>
379
+
380
+ <v-progress-linear
381
+ :model-value="(giftCard.remainingValue / giftCard.initialValue) * 100"
382
+ color="success"
383
+ class="mt-2"
384
+ height="4"
385
+ ></v-progress-linear>
386
+ </v-col>
387
+
388
+ <v-col cols="12" sm="3" v-if="giftCard.remainingValue > 0">
389
+ <v-text-field
390
+ v-model="redeemAmounts[giftCard.giftCardId]"
391
+ label="Redeem Amount"
392
+ prefix="$"
393
+ type="number"
394
+ step="0.01"
395
+ :max="giftCard.remainingValue"
396
+ min="0.01"
397
+ variant="outlined"
398
+ density="compact"
399
+ hide-details
400
+ ></v-text-field>
401
+
402
+ <v-btn
403
+ @click="redeemGiftCard(giftCard.giftCardId)"
404
+ :disabled="!redeemAmounts[giftCard.giftCardId] ||
405
+ redeemAmounts[giftCard.giftCardId] <= 0 ||
406
+ redeemAmounts[giftCard.giftCardId] > giftCard.remainingValue"
407
+ class="axoniq-secondary mt-2"
408
+ size="small"
409
+ block
410
+ :loading="redeemingCards[giftCard.giftCardId]"
411
+ >
412
+ <v-icon class="mr-1">mdi-cash-minus</v-icon>
413
+ Redeem
414
+ </v-btn>
415
+ </v-col>
416
+ </v-row>
417
+ </v-card>
418
+ </v-col>
419
+ </v-row>
420
+ </v-card-text>
421
+ </v-card>
422
+ </v-col>
423
+ </v-row>
424
+ </v-container>
425
+ </v-main>
426
+ </v-app>
427
+ </div>
428
+
429
+ <!-- Vue 3 -->
430
+ <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
431
+ <!-- Vuetify JS -->
432
+ <script src="https://cdn.jsdelivr.net/npm/vuetify@3/dist/vuetify.min.js"></script>
433
+
434
+ <script>
435
+ const { createApp, ref, reactive, onMounted, onUnmounted } = Vue;
436
+ const { createVuetify } = Vuetify;
437
+
438
+ const vuetify = createVuetify({
439
+ theme: {
440
+ defaultTheme: 'LIGHT_THEME',
441
+ themes: {
442
+ LIGHT_THEME: {
443
+ dark: false,
444
+ colors: {
445
+ background: '#fff',
446
+ surface: '#FFFFFF',
447
+ primary: '#06AED4',
448
+ secondary: '#6840c5',
449
+ tertiary: '#15B79E',
450
+ error: '#B00020',
451
+ info: '#2196F3',
452
+ success: '#12B76A',
453
+ warning: '#FB8C00',
454
+ 'primary-grey': '#717680',
455
+ 'border-color': '#e5eaef',
456
+ }
457
+ }
458
+ }
459
+ }
460
+ });
461
+
462
+ createApp({
463
+ setup() {
464
+ const giftCards = ref([]);
465
+ const issueAmount = ref('');
466
+ const redeemAmounts = reactive({});
467
+ const redeemingCards = reactive({});
468
+ const issuingCard = ref(false);
469
+ const message = ref(null);
470
+ let eventSource = null;
471
+
472
+ const showMessage = (text, type = 'success') => {
473
+ message.value = { text, type };
474
+ setTimeout(() => {
475
+ message.value = null;
476
+ }, 5000);
477
+ };
478
+
479
+ const issueGiftCard = async () => {
480
+ issuingCard.value = true;
481
+ try {
482
+ const response = await fetch('/api/giftcards', {
483
+ method: 'POST',
484
+ headers: {
485
+ 'Content-Type': 'application/json',
486
+ },
487
+ body: JSON.stringify({
488
+ amount: parseFloat(issueAmount.value)
489
+ })
490
+ });
491
+
492
+ if (response.ok) {
493
+ const giftCardId = await response.text();
494
+ showMessage(`Gift card issued successfully! ID: ${giftCardId.substring(0, 8)}...`);
495
+ issueAmount.value = '';
496
+ } else {
497
+ showMessage('Failed to issue gift card', 'error');
498
+ }
499
+ } catch (error) {
500
+ showMessage('Error issuing gift card: ' + error.message, 'error');
501
+ } finally {
502
+ issuingCard.value = false;
503
+ }
504
+ };
505
+
506
+ const redeemGiftCard = async (giftCardId) => {
507
+ redeemingCards[giftCardId] = true;
508
+ try {
509
+ const amount = redeemAmounts[giftCardId];
510
+ const response = await fetch(`/api/giftcards/${giftCardId}/redeem`, {
511
+ method: 'POST',
512
+ headers: {
513
+ 'Content-Type': 'application/json',
514
+ },
515
+ body: JSON.stringify({
516
+ amount: parseFloat(amount)
517
+ })
518
+ });
519
+
520
+ if (response.ok) {
521
+ showMessage(`Successfully redeemed $${amount} from gift card!`);
522
+ redeemAmounts[giftCardId] = '';
523
+ } else {
524
+ const errorText = await response.text();
525
+ showMessage('Failed to redeem: ' + errorText, 'error');
526
+ }
527
+ } catch (error) {
528
+ showMessage('Error redeeming gift card: ' + error.message, 'error');
529
+ } finally {
530
+ redeemingCards[giftCardId] = false;
531
+ }
532
+ };
533
+
534
+ const loadGiftCards = async () => {
535
+ try {
536
+ const response = await fetch('/api/giftcards');
537
+ if (response.ok) {
538
+ giftCards.value = await response.json();
539
+ }
540
+ } catch (error) {
541
+ console.error('Error loading gift cards:', error);
542
+ }
543
+ };
544
+
545
+ const setupEventSource = () => {
546
+ eventSource = new EventSource('/api/giftcards/updates');
547
+
548
+ eventSource.onmessage = (event) => {
549
+ try {
550
+ const data = JSON.parse(event.data);
551
+ if(data.updatedGiftCard) {
552
+ const giftCard = data.updatedGiftCard;
553
+ const existingIndex = giftCards.value.findIndex(gc => gc.giftCardId === giftCard.giftCardId);
554
+
555
+ if (existingIndex >= 0) {
556
+ giftCards.value[existingIndex] = giftCard;
557
+ } else {
558
+ giftCards.value.push(giftCard);
559
+ }
560
+ }
561
+ } catch (error) {
562
+ console.error('Error parsing SSE data:', error);
563
+ }
564
+ };
565
+
566
+ eventSource.onerror = (error) => {
567
+ console.error('SSE connection error:', error);
568
+ };
569
+ };
570
+
571
+ onMounted(() => {
572
+ loadGiftCards();
573
+ setupEventSource();
574
+ });
575
+
576
+ onUnmounted(() => {
577
+ if (eventSource) {
578
+ eventSource.close();
579
+ }
580
+ });
581
+
582
+ return {
583
+ giftCards,
584
+ issueAmount,
585
+ redeemAmounts,
586
+ redeemingCards,
587
+ issuingCard,
588
+ message,
589
+ issueGiftCard,
590
+ redeemGiftCard
591
+ };
592
+ }
593
+ }).use(vuetify).mount('#app');
594
+ </script>
595
+ </body>
596
+ </html>