leedstack 3.1.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 (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +364 -0
  3. package/bin/create-stack.js +277 -0
  4. package/package.json +60 -0
  5. package/tools/templates/backend/go-echo/backend/.env.example +10 -0
  6. package/tools/templates/backend/go-echo/backend/cmd/server/main.go.ejs +57 -0
  7. package/tools/templates/backend/go-echo/backend/go.mod.ejs +10 -0
  8. package/tools/templates/backend/go-echo/backend/internal/handlers/example.go +15 -0
  9. package/tools/templates/backend/go-echo/backend/internal/handlers/health.go +13 -0
  10. package/tools/templates/backend/java-spring/backend/.env.example +10 -0
  11. package/tools/templates/backend/java-spring/backend/pom.xml.ejs +64 -0
  12. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/Application.java.ejs +11 -0
  13. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/config/SecurityConfig.java.ejs +64 -0
  14. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/ExampleController.java +19 -0
  15. package/tools/templates/backend/java-spring/backend/src/main/java/com/app/controller/HealthController.java +15 -0
  16. package/tools/templates/backend/java-spring/backend/src/main/resources/application.yml.ejs +20 -0
  17. package/tools/templates/backend/node-express/backend/.env.example +10 -0
  18. package/tools/templates/backend/node-express/backend/.eslintrc.json +21 -0
  19. package/tools/templates/backend/node-express/backend/.prettierrc +10 -0
  20. package/tools/templates/backend/node-express/backend/Dockerfile +52 -0
  21. package/tools/templates/backend/node-express/backend/README.md +68 -0
  22. package/tools/templates/backend/node-express/backend/package.json.ejs +37 -0
  23. package/tools/templates/backend/node-express/backend/src/index.ts.ejs +75 -0
  24. package/tools/templates/backend/node-express/backend/src/routes/health.ts +54 -0
  25. package/tools/templates/backend/node-express/backend/tsconfig.json +17 -0
  26. package/tools/templates/backend/python-fastapi/backend/.env.example +18 -0
  27. package/tools/templates/backend/python-fastapi/backend/README.md +73 -0
  28. package/tools/templates/backend/python-fastapi/backend/app/__init__.py +1 -0
  29. package/tools/templates/backend/python-fastapi/backend/app/main.py.ejs +68 -0
  30. package/tools/templates/backend/python-fastapi/backend/requirements.txt.ejs +22 -0
  31. package/tools/templates/base/.dockerignore +16 -0
  32. package/tools/templates/base/.env.example +31 -0
  33. package/tools/templates/base/.github/workflows/ci.yml.ejs +124 -0
  34. package/tools/templates/base/.github/workflows/deploy-separate.yml.example +144 -0
  35. package/tools/templates/base/.vscode/extensions.json +17 -0
  36. package/tools/templates/base/.vscode/settings.json +49 -0
  37. package/tools/templates/base/Makefile +98 -0
  38. package/tools/templates/base/README.md.ejs +118 -0
  39. package/tools/templates/base/docker-compose.yml.ejs +49 -0
  40. package/tools/templates/base/package.json.ejs +30 -0
  41. package/tools/templates/base/scripts/split-repos.sh +189 -0
  42. package/tools/templates/db/postgres/backend/java-spring/backend/pom.xml.ejs +81 -0
  43. package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/application.yml.ejs +39 -0
  44. package/tools/templates/db/postgres/backend/java-spring/backend/src/main/resources/db/migration/V1__init.sql +17 -0
  45. package/tools/templates/db/postgres/backend/node-express/backend/.env.example +10 -0
  46. package/tools/templates/db/postgres/backend/node-express/backend/package.json.ejs +32 -0
  47. package/tools/templates/db/postgres/backend/node-express/backend/prisma/schema.prisma.ejs +39 -0
  48. package/tools/templates/frontend/angular/frontend/.env.example +9 -0
  49. package/tools/templates/frontend/angular/frontend/angular.json +66 -0
  50. package/tools/templates/frontend/angular/frontend/package.json.ejs +31 -0
  51. package/tools/templates/frontend/angular/frontend/src/app/app.component.ts +30 -0
  52. package/tools/templates/frontend/angular/frontend/src/app/app.routes.ts +18 -0
  53. package/tools/templates/frontend/angular/frontend/src/app/components/home.component.ts +24 -0
  54. package/tools/templates/frontend/angular/frontend/src/app/services/api.service.ts +48 -0
  55. package/tools/templates/frontend/angular/frontend/src/favicon.ico +1 -0
  56. package/tools/templates/frontend/angular/frontend/src/index.html +13 -0
  57. package/tools/templates/frontend/angular/frontend/src/main.ts +10 -0
  58. package/tools/templates/frontend/angular/frontend/src/styles.css +31 -0
  59. package/tools/templates/frontend/angular/frontend/tsconfig.app.json +9 -0
  60. package/tools/templates/frontend/angular/frontend/tsconfig.json +27 -0
  61. package/tools/templates/frontend/nextjs/frontend/.env.example +9 -0
  62. package/tools/templates/frontend/nextjs/frontend/next.config.js +37 -0
  63. package/tools/templates/frontend/nextjs/frontend/package.json.ejs +25 -0
  64. package/tools/templates/frontend/nextjs/frontend/src/app/globals.css +31 -0
  65. package/tools/templates/frontend/nextjs/frontend/src/app/layout.tsx +36 -0
  66. package/tools/templates/frontend/nextjs/frontend/src/app/page.tsx +19 -0
  67. package/tools/templates/frontend/nextjs/frontend/src/lib/api.ts +45 -0
  68. package/tools/templates/frontend/nextjs/frontend/tsconfig.json +27 -0
  69. package/tools/templates/frontend/react/frontend/.env.example +9 -0
  70. package/tools/templates/frontend/react/frontend/.eslintrc.json +32 -0
  71. package/tools/templates/frontend/react/frontend/.prettierrc +10 -0
  72. package/tools/templates/frontend/react/frontend/Dockerfile +37 -0
  73. package/tools/templates/frontend/react/frontend/README.md +54 -0
  74. package/tools/templates/frontend/react/frontend/index.html +13 -0
  75. package/tools/templates/frontend/react/frontend/nginx.conf +35 -0
  76. package/tools/templates/frontend/react/frontend/package.json.ejs +41 -0
  77. package/tools/templates/frontend/react/frontend/public/vite.svg +4 -0
  78. package/tools/templates/frontend/react/frontend/src/App.css +65 -0
  79. package/tools/templates/frontend/react/frontend/src/App.jsx +41 -0
  80. package/tools/templates/frontend/react/frontend/src/assets/react.svg +7 -0
  81. package/tools/templates/frontend/react/frontend/src/components/ErrorBoundary.jsx +62 -0
  82. package/tools/templates/frontend/react/frontend/src/components/Home.jsx +58 -0
  83. package/tools/templates/frontend/react/frontend/src/components/__tests__/Home.test.jsx +74 -0
  84. package/tools/templates/frontend/react/frontend/src/index.css +31 -0
  85. package/tools/templates/frontend/react/frontend/src/lib/api.js +42 -0
  86. package/tools/templates/frontend/react/frontend/src/lib/env.js +58 -0
  87. package/tools/templates/frontend/react/frontend/src/main.jsx +16 -0
  88. package/tools/templates/frontend/react/frontend/src/setupTests.js +8 -0
  89. package/tools/templates/frontend/react/frontend/vite.config.js +30 -0
  90. package/tools/templates/frontend/react/frontend/vitest.config.js +20 -0
  91. package/tools/templates/frontend/svelte/frontend/.env.example +9 -0
  92. package/tools/templates/frontend/svelte/frontend/package.json.ejs +21 -0
  93. package/tools/templates/frontend/svelte/frontend/src/app.html +12 -0
  94. package/tools/templates/frontend/svelte/frontend/src/lib/api.ts +45 -0
  95. package/tools/templates/frontend/svelte/frontend/src/routes/+layout.svelte +56 -0
  96. package/tools/templates/frontend/svelte/frontend/src/routes/+page.svelte +20 -0
  97. package/tools/templates/frontend/svelte/frontend/static/favicon.png +1 -0
  98. package/tools/templates/frontend/svelte/frontend/svelte.config.js +10 -0
  99. package/tools/templates/frontend/svelte/frontend/vite.config.js +9 -0
  100. package/tools/templates/frontend/vue/frontend/.env.example +9 -0
  101. package/tools/templates/frontend/vue/frontend/index.html +13 -0
  102. package/tools/templates/frontend/vue/frontend/package.json.ejs +20 -0
  103. package/tools/templates/frontend/vue/frontend/src/App.vue +60 -0
  104. package/tools/templates/frontend/vue/frontend/src/lib/api.js +42 -0
  105. package/tools/templates/frontend/vue/frontend/src/main.js +33 -0
  106. package/tools/templates/frontend/vue/frontend/src/views/ApiTest.vue +39 -0
  107. package/tools/templates/frontend/vue/frontend/src/views/Home.vue +30 -0
  108. package/tools/templates/frontend/vue/frontend/vite.config.js +9 -0
  109. package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/controller/AdminController.java +41 -0
  110. package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/entity/User.java +55 -0
  111. package/tools/templates/modules/admin/backend/java-spring/backend/src/main/java/com/app/repository/UserRepository.java +8 -0
  112. package/tools/templates/modules/admin/frontend/svelte/frontend/src/routes/dashboard/+page.svelte +93 -0
  113. package/tools/templates/modules/auth/backend/node-express/backend/src/middleware/auth.ts +42 -0
  114. package/tools/templates/modules/auth/frontend/svelte/frontend/src/hooks.client.ts +3 -0
  115. package/tools/templates/modules/auth/frontend/svelte/frontend/src/lib/auth.ts +104 -0
  116. package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/callback/+page.svelte +18 -0
  117. package/tools/templates/modules/auth/frontend/svelte/frontend/src/routes/login/+page.svelte +12 -0
  118. package/tools/templates/modules/chatbot/backend/node-express/backend/src/index.ts.ejs +69 -0
  119. package/tools/templates/modules/chatbot/backend/node-express/backend/src/routes/chatbot.ts.ejs +37 -0
  120. package/tools/templates/modules/chatbot/backend/node-express/backend/src/services/chatbotService.ts +124 -0
  121. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/main.py.ejs +69 -0
  122. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/routes/chatbot.py +38 -0
  123. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/app/services/chatbot_service.py +123 -0
  124. package/tools/templates/modules/chatbot/backend/python-fastapi/backend/requirements.txt +1 -0
  125. package/tools/templates/modules/chatbot/frontend/react/frontend/src/App.jsx.ejs +74 -0
  126. package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.css +198 -0
  127. package/tools/templates/modules/chatbot/frontend/react/frontend/src/components/Chatbot.jsx +113 -0
  128. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/controller/ContactController.java +29 -0
  129. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/entity/ContactMessage.java +66 -0
  130. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/java/com/app/repository/ContactMessageRepository.java +8 -0
  131. package/tools/templates/modules/contact/backend/java-spring/backend/src/main/resources/db/migration/V2__contact.sql +7 -0
  132. package/tools/templates/modules/contact/frontend/svelte/frontend/src/routes/contact/+page.svelte +80 -0
  133. package/tools/templates/modules/payments/backend/java-spring/backend/src/main/java/com/app/controller/PaymentController.java +69 -0
  134. package/tools/templates/modules/payments/backend/node-express/backend/src/routes/payments.ts +30 -0
  135. package/tools/templates/modules/payments/backend/node-express/backend/src/routes/webhook.ts +36 -0
  136. package/tools/templates/modules/payments/frontend/svelte/frontend/src/lib/payments.ts +28 -0
@@ -0,0 +1,30 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: {
7
+ port: 5173,
8
+ hmr: {
9
+ overlay: true
10
+ }
11
+ },
12
+ build: {
13
+ target: 'esnext',
14
+ minify: 'esbuild',
15
+ cssMinify: true,
16
+ rollupOptions: {
17
+ output: {
18
+ manualChunks: {
19
+ 'react-vendor': ['react', 'react-dom'],
20
+ }
21
+ }
22
+ },
23
+ chunkSizeWarningLimit: 1000,
24
+ sourcemap: false
25
+ },
26
+ optimizeDeps: {
27
+ include: ['react', 'react-dom'],
28
+ force: false
29
+ }
30
+ });
@@ -0,0 +1,20 @@
1
+ import { defineConfig } from 'vitest/config';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ test: {
7
+ globals: true,
8
+ environment: 'jsdom',
9
+ setupFiles: './src/setupTests.js',
10
+ css: true,
11
+ coverage: {
12
+ provider: 'v8',
13
+ reporter: ['text', 'json', 'html'],
14
+ exclude: [
15
+ 'node_modules/',
16
+ 'src/setupTests.js',
17
+ ],
18
+ },
19
+ },
20
+ });
@@ -0,0 +1,9 @@
1
+ PUBLIC_API_BASE=http://localhost:8080
2
+ <% if (modules.auth) { -%>
3
+ PUBLIC_AUTH0_DOMAIN=your-tenant.us.auth0.com
4
+ PUBLIC_AUTH0_CLIENT_ID=your_spa_client_id
5
+ PUBLIC_AUTH0_AUDIENCE=https://api.<%= appSlug %>
6
+ <% } -%>
7
+ <% if (modules.payments) { -%>
8
+ PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
9
+ <% } -%>
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "<%= appSlug %>-frontend",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite dev",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "devDependencies": {
12
+ "@sveltejs/adapter-auto": "^3.0.0",
13
+ "@sveltejs/kit": "^2.0.0",
14
+ "@sveltejs/vite-plugin-svelte": "^4.0.0",
15
+ "svelte": "^5.0.0",
16
+ "vite": "^6.0.0"
17
+ },
18
+ "dependencies": {
19
+ "@auth0/auth0-spa-js": "^2.1.3"
20
+ }
21
+ }
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <link rel="icon" href="%sveltekit.assets%/favicon.png" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ %sveltekit.head%
8
+ </head>
9
+ <body data-sveltekit-preload-data="hover">
10
+ <div style="display: contents">%sveltekit.body%</div>
11
+ </body>
12
+ </html>
@@ -0,0 +1,45 @@
1
+ // API base URL from environment
2
+ const API_BASE = import.meta.env.PUBLIC_API_BASE || 'http://localhost:8080';
3
+
4
+ /**
5
+ * Fetch wrapper that automatically adds API base URL
6
+ * @param endpoint - API endpoint (e.g., '/api/example')
7
+ * @param options - Fetch options
8
+ */
9
+ export async function apiFetch<T = any>(
10
+ endpoint: string,
11
+ options: RequestInit = {}
12
+ ): Promise<T> {
13
+ const url = `${API_BASE}${endpoint}`;
14
+
15
+ const config: RequestInit = {
16
+ ...options,
17
+ headers: {
18
+ 'Content-Type': 'application/json',
19
+ ...options.headers,
20
+ },
21
+ };
22
+
23
+ const response = await fetch(url, config);
24
+
25
+ if (!response.ok) {
26
+ throw new Error(`API Error: ${response.statusText}`);
27
+ }
28
+
29
+ return response.json();
30
+ }
31
+
32
+ /**
33
+ * Example usage in components:
34
+ *
35
+ * import { apiFetch } from '$lib/api';
36
+ *
37
+ * // GET request
38
+ * const data = await apiFetch('/api/example');
39
+ *
40
+ * // POST request
41
+ * const result = await apiFetch('/api/contact', {
42
+ * method: 'POST',
43
+ * body: JSON.stringify({ name: 'John', email: 'john@example.com' })
44
+ * });
45
+ */
@@ -0,0 +1,56 @@
1
+ <script>
2
+ import { page } from '$app/stores';
3
+ </script>
4
+
5
+ <div class="app">
6
+ <nav>
7
+ <a href="/">Home</a>
8
+ <% if (modules.contact) { -%>
9
+ <a href="/contact">Contact</a>
10
+ <% } -%>
11
+ <% if (modules.auth) { -%>
12
+ <a href="/login">Login</a>
13
+ <% } -%>
14
+ <% if (modules.admin) { -%>
15
+ <a href="/dashboard">Dashboard</a>
16
+ <% } -%>
17
+ </nav>
18
+
19
+ <main>
20
+ <slot />
21
+ </main>
22
+ </div>
23
+
24
+ <style>
25
+ .app {
26
+ display: flex;
27
+ flex-direction: column;
28
+ min-height: 100vh;
29
+ }
30
+
31
+ nav {
32
+ display: flex;
33
+ gap: 1rem;
34
+ padding: 1rem;
35
+ background: #f0f0f0;
36
+ }
37
+
38
+ nav a {
39
+ text-decoration: none;
40
+ color: #333;
41
+ }
42
+
43
+ nav a:hover {
44
+ text-decoration: underline;
45
+ }
46
+
47
+ main {
48
+ flex: 1;
49
+ padding: 2rem;
50
+ }
51
+
52
+ :global(body) {
53
+ margin: 0;
54
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
55
+ }
56
+ </style>
@@ -0,0 +1,20 @@
1
+ <h1>Welcome to <%= AppName %></h1>
2
+
3
+ <p>This is a full-stack application built with:</p>
4
+ <ul>
5
+ <li>Frontend: <%= frontend %></li>
6
+ <li>Backend: <%= backend %></li>
7
+ <li>Database: <%= db %></li>
8
+ <% if (modules.auth) { -%>
9
+ <li>Auth: <%= auth %></li>
10
+ <% } -%>
11
+ <% if (modules.payments) { -%>
12
+ <li>Payments: <%= payments %></li>
13
+ <% } -%>
14
+ </ul>
15
+
16
+ <style>
17
+ h1 {
18
+ color: #333;
19
+ }
20
+ </style>
@@ -0,0 +1 @@
1
+ <!-- Placeholder favicon file -->
@@ -0,0 +1,10 @@
1
+ import adapter from '@sveltejs/adapter-auto';
2
+
3
+ /** @type {import('@sveltejs/kit').Config} */
4
+ const config = {
5
+ kit: {
6
+ adapter: adapter()
7
+ }
8
+ };
9
+
10
+ export default config;
@@ -0,0 +1,9 @@
1
+ import { sveltekit } from '@sveltejs/kit/vite';
2
+ import { defineConfig } from 'vite';
3
+
4
+ export default defineConfig({
5
+ plugins: [sveltekit()],
6
+ server: {
7
+ port: 5173
8
+ }
9
+ });
@@ -0,0 +1,9 @@
1
+ VITE_API_BASE=http://localhost:8080
2
+ <% if (modules.auth) { -%>
3
+ VITE_AUTH0_DOMAIN=your-tenant.us.auth0.com
4
+ VITE_AUTH0_CLIENT_ID=your_spa_client_id
5
+ VITE_AUTH0_AUDIENCE=https://api.<%= appSlug %>
6
+ <% } -%>
7
+ <% if (modules.payments) { -%>
8
+ VITE_STRIPE_PUBLISHABLE_KEY=pk_test_xxx
9
+ <% } -%>
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <link rel="icon" href="/favicon.ico">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title><%= AppName %></title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.js"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "<%= appSlug %>-frontend",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "vue": "^3.5.0",
13
+ "vue-router": "^4.4.0",
14
+ "@auth0/auth0-spa-js": "^2.1.3"
15
+ },
16
+ "devDependencies": {
17
+ "@vitejs/plugin-vue": "^5.2.1",
18
+ "vite": "^6.0.0"
19
+ }
20
+ }
@@ -0,0 +1,60 @@
1
+ <template>
2
+ <div id="app">
3
+ <nav>
4
+ <router-link to="/">Home</router-link>
5
+ <% if (modules.contact) { -%>
6
+ <router-link to="/contact">Contact</router-link>
7
+ <% } -%>
8
+ <% if (modules.auth) { -%>
9
+ <router-link to="/login">Login</router-link>
10
+ <% } -%>
11
+ <% if (modules.admin) { -%>
12
+ <router-link to="/dashboard">Dashboard</router-link>
13
+ <% } -%>
14
+ </nav>
15
+ <main>
16
+ <router-view />
17
+ </main>
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ export default {
23
+ name: 'App'
24
+ }
25
+ </script>
26
+
27
+ <style>
28
+ body {
29
+ margin: 0;
30
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
31
+ }
32
+
33
+ #app {
34
+ display: flex;
35
+ flex-direction: column;
36
+ min-height: 100vh;
37
+ }
38
+
39
+ nav {
40
+ display: flex;
41
+ gap: 1rem;
42
+ padding: 1rem;
43
+ background: #f0f0f0;
44
+ }
45
+
46
+ nav a {
47
+ text-decoration: none;
48
+ color: #333;
49
+ }
50
+
51
+ nav a:hover,
52
+ nav a.router-link-active {
53
+ text-decoration: underline;
54
+ }
55
+
56
+ main {
57
+ flex: 1;
58
+ padding: 2rem;
59
+ }
60
+ </style>
@@ -0,0 +1,42 @@
1
+ // API base URL from environment
2
+ const API_BASE = import.meta.env.VITE_API_BASE || 'http://localhost:8080';
3
+
4
+ /**
5
+ * Fetch wrapper that automatically adds API base URL
6
+ * @param {string} endpoint - API endpoint (e.g., '/api/example')
7
+ * @param {RequestInit} options - Fetch options
8
+ */
9
+ export async function apiFetch(endpoint, options = {}) {
10
+ const url = `${API_BASE}${endpoint}`;
11
+
12
+ const config = {
13
+ ...options,
14
+ headers: {
15
+ 'Content-Type': 'application/json',
16
+ ...options.headers,
17
+ },
18
+ };
19
+
20
+ const response = await fetch(url, config);
21
+
22
+ if (!response.ok) {
23
+ throw new Error(`API Error: ${response.statusText}`);
24
+ }
25
+
26
+ return response.json();
27
+ }
28
+
29
+ /**
30
+ * Example usage in components:
31
+ *
32
+ * import { apiFetch } from '@/lib/api';
33
+ *
34
+ * // GET request
35
+ * const data = await apiFetch('/api/example');
36
+ *
37
+ * // POST request
38
+ * const result = await apiFetch('/api/contact', {
39
+ * method: 'POST',
40
+ * body: JSON.stringify({ name: 'John', email: 'john@example.com' })
41
+ * });
42
+ */
@@ -0,0 +1,33 @@
1
+ import { createApp } from 'vue';
2
+ import { createRouter, createWebHistory } from 'vue-router';
3
+ import App from './App.vue';
4
+ import Home from './views/Home.vue';
5
+ <% if (modules.contact) { -%>
6
+ import Contact from './views/Contact.vue';
7
+ <% } -%>
8
+ <% if (modules.admin) { -%>
9
+ import Dashboard from './views/Dashboard.vue';
10
+ <% } -%>
11
+
12
+ const routes = [
13
+ { path: '/', component: Home },
14
+ <% if (modules.contact) { -%>
15
+ { path: '/contact', component: Contact },
16
+ <% } -%>
17
+ <% if (modules.auth) { -%>
18
+ { path: '/login', component: () => import('./views/Login.vue') },
19
+ { path: '/callback', component: () => import('./views/Callback.vue') },
20
+ <% } -%>
21
+ <% if (modules.admin) { -%>
22
+ { path: '/dashboard', component: Dashboard },
23
+ <% } -%>
24
+ ];
25
+
26
+ const router = createRouter({
27
+ history: createWebHistory(),
28
+ routes
29
+ });
30
+
31
+ const app = createApp(App);
32
+ app.use(router);
33
+ app.mount('#app');
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <div style="margin-top: 2rem; padding: 1rem; background: #f5f5f5; border-radius: 8px;">
3
+ <h3>API Connection Test</h3>
4
+ <p v-if="loading">Testing backend connection...</p>
5
+ <p v-if="error" style="color: red;">❌ Error: {{ error }}</p>
6
+ <p v-if="apiMessage" style="color: green;">✅ {{ apiMessage }}</p>
7
+ </div>
8
+ </template>
9
+
10
+ <script>
11
+ import { ref, onMounted } from 'vue';
12
+ import { apiFetch } from '@/lib/api';
13
+
14
+ export default {
15
+ name: 'ApiTest',
16
+ setup() {
17
+ const apiMessage = ref('');
18
+ const loading = ref(true);
19
+ const error = ref('');
20
+
21
+ onMounted(async () => {
22
+ try {
23
+ const data = await apiFetch('/api/example');
24
+ apiMessage.value = data.message;
25
+ } catch (err) {
26
+ error.value = err.message;
27
+ } finally {
28
+ loading.value = false;
29
+ }
30
+ });
31
+
32
+ return {
33
+ apiMessage,
34
+ loading,
35
+ error
36
+ };
37
+ }
38
+ };
39
+ </script>
@@ -0,0 +1,30 @@
1
+ <template>
2
+ <div>
3
+ <h1>Welcome to <%= AppName %></h1>
4
+ <p>This is a full-stack application built with:</p>
5
+ <ul>
6
+ <li>Frontend: <%= frontend %></li>
7
+ <li>Backend: <%= backend %></li>
8
+ <li>Database: <%= db %></li>
9
+ <% if (modules.auth) { -%>
10
+ <li>Auth: <%= auth %></li>
11
+ <% } -%>
12
+ <% if (modules.payments) { -%>
13
+ <li>Payments: <%= payments %></li>
14
+ <% } -%>
15
+ </ul>
16
+
17
+ <ApiTest />
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ import ApiTest from './ApiTest.vue';
23
+
24
+ export default {
25
+ name: 'Home',
26
+ components: {
27
+ ApiTest
28
+ }
29
+ }
30
+ </script>
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vite';
2
+ import vue from '@vitejs/plugin-vue';
3
+
4
+ export default defineConfig({
5
+ plugins: [vue()],
6
+ server: {
7
+ port: 5173
8
+ }
9
+ });
@@ -0,0 +1,41 @@
1
+ package com.app.controller;
2
+
3
+ import com.app.repository.UserRepository;
4
+ <% if (modules.contact) { -%>
5
+ import com.app.repository.ContactMessageRepository;
6
+ <% } -%>
7
+ import org.springframework.beans.factory.annotation.Autowired;
8
+ import org.springframework.http.ResponseEntity;
9
+ import org.springframework.security.access.prepost.PreAuthorize;
10
+ import org.springframework.web.bind.annotation.*;
11
+
12
+ import java.util.Map;
13
+
14
+ @RestController
15
+ @RequestMapping("/api/admin")
16
+ public class AdminController {
17
+
18
+ @Autowired
19
+ private UserRepository userRepository;
20
+
21
+ <% if (modules.contact) { -%>
22
+ @Autowired
23
+ private ContactMessageRepository contactMessageRepository;
24
+
25
+ <% } -%>
26
+ @GetMapping("/stats")
27
+ @PreAuthorize("hasAuthority('SCOPE_admin')")
28
+ public ResponseEntity<?> getStats() {
29
+ long userCount = userRepository.count();
30
+ <% if (modules.contact) { -%>
31
+ long contactCount = contactMessageRepository.count();
32
+
33
+ return ResponseEntity.ok(Map.of(
34
+ "users", userCount,
35
+ "contacts", contactCount
36
+ ));
37
+ <% } else { -%>
38
+ return ResponseEntity.ok(Map.of("users", userCount));
39
+ <% } -%>
40
+ }
41
+ }
@@ -0,0 +1,55 @@
1
+ package com.app.entity;
2
+
3
+ import jakarta.persistence.*;
4
+ import java.time.Instant;
5
+
6
+ @Entity
7
+ @Table(name = "users")
8
+ public class User {
9
+
10
+ @Id
11
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
12
+ private Long id;
13
+
14
+ @Column(unique = true, nullable = false, length = 255)
15
+ private String email;
16
+
17
+ @Column(length = 120)
18
+ private String name;
19
+
20
+ @Column(name = "created_at", nullable = false, updatable = false)
21
+ private Instant createdAt = Instant.now();
22
+
23
+ // Getters and setters
24
+ public Long getId() {
25
+ return id;
26
+ }
27
+
28
+ public void setId(Long id) {
29
+ this.id = id;
30
+ }
31
+
32
+ public String getEmail() {
33
+ return email;
34
+ }
35
+
36
+ public void setEmail(String email) {
37
+ this.email = email;
38
+ }
39
+
40
+ public String getName() {
41
+ return name;
42
+ }
43
+
44
+ public void setName(String name) {
45
+ this.name = name;
46
+ }
47
+
48
+ public Instant getCreatedAt() {
49
+ return createdAt;
50
+ }
51
+
52
+ public void setCreatedAt(Instant createdAt) {
53
+ this.createdAt = createdAt;
54
+ }
55
+ }
@@ -0,0 +1,8 @@
1
+ package com.app.repository;
2
+
3
+ import com.app.entity.User;
4
+ import org.springframework.data.jpa.repository.JpaRepository;
5
+
6
+ public interface UserRepository extends JpaRepository<User, Long> {
7
+ long count();
8
+ }