openwork-agent 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +436 -0
  3. package/package.json +78 -0
  4. package/src/core/TechDetector.js +351 -0
  5. package/src/generators/ProjectGenerator.js +1241 -0
  6. package/src/generators/ProjectGeneratorExtensions.js +14 -0
  7. package/src/generators/TemplateMethods.js +402 -0
  8. package/src/generators/index.js +5 -0
  9. package/src/index.js +152 -0
  10. package/src/main.js +8 -0
  11. package/src/templates/common/README.md.hbs +358 -0
  12. package/src/templates/docker/index.js +518 -0
  13. package/src/templates/docker.js +58 -0
  14. package/src/templates/go/basic/api/routes/user.go.hbs +138 -0
  15. package/src/templates/go/basic/config/config.go.hbs +54 -0
  16. package/src/templates/go/basic/go.mod.hbs +8 -0
  17. package/src/templates/go/basic/main.go.hbs +70 -0
  18. package/src/templates/go/basic/models/user.go.hbs +69 -0
  19. package/src/templates/go/basic/services/user_service.go.hbs +173 -0
  20. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/controller/UserController.java.hbs +91 -0
  21. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/dto/ApiResponse.java.hbs +40 -0
  22. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/model/User.java.hbs +102 -0
  23. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/repository/UserRepository.java.hbs +20 -0
  24. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/service/UserService.java.hbs +65 -0
  25. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/{{pascalCase projectName}}Application.java.hbs +16 -0
  26. package/src/templates/node/basic/src/config/database.ts.hbs +18 -0
  27. package/src/templates/node/basic/src/controllers/UserController.ts.hbs +98 -0
  28. package/src/templates/node/basic/src/index.ts.hbs +45 -0
  29. package/src/templates/node/basic/src/middleware/errorHandler.ts.hbs +33 -0
  30. package/src/templates/node/basic/src/routes/index.ts.hbs +42 -0
  31. package/src/templates/node/basic/src/types/index.ts.hbs +18 -0
  32. package/src/templates/python/basic/config/database.py.hbs +36 -0
  33. package/src/templates/python/basic/main.py.hbs +58 -0
  34. package/src/templates/python/basic/middleware/error_handler.py.hbs +41 -0
  35. package/src/templates/python/basic/models/user.py.hbs +40 -0
  36. package/src/templates/python/basic/routes/__init__.py.hbs +12 -0
  37. package/src/templates/python/basic/routes/users.py.hbs +64 -0
  38. package/src/templates/rust/basic/Cargo.toml.hbs +39 -0
  39. package/src/templates/rust/basic/src/config/database.rs.hbs +27 -0
  40. package/src/templates/rust/basic/src/handlers/user.rs.hbs +130 -0
  41. package/src/templates/rust/basic/src/handlers/user_routes.rs.hbs +15 -0
  42. package/src/templates/rust/basic/src/main.rs.hbs +53 -0
  43. package/src/templates/rust/basic/src/models/mod.rs.hbs +79 -0
  44. package/src/templates/rust/basic/src/schema.rs.hbs +10 -0
  45. package/src/utils/FileManager.js +186 -0
  46. package/src/utils/Templates.js +231 -0
@@ -0,0 +1,518 @@
1
+ // Docker template generation methods
2
+ const generateDockerTemplates = {
3
+ node: function(config) {
4
+ return `# Stage 1: Build
5
+ FROM node:18-alpine AS builder
6
+
7
+ WORKDIR /app
8
+
9
+ # Copy package files
10
+ COPY package*.json ./
11
+
12
+ # Install dependencies
13
+ RUN npm ci --only=production
14
+
15
+ # Copy source code
16
+ COPY . .
17
+
18
+ # Build the application
19
+ ${config.framework === 'typescript' || config.framework === 'nestjs' ? 'RUN npm run build' : ''}
20
+
21
+ # Stage 2: Production
22
+ FROM node:18-alpine AS production
23
+
24
+ WORKDIR /app
25
+
26
+ # Copy built application and dependencies
27
+ ${config.framework === 'typescript' || config.framework === 'nestjs' ? 'COPY --from=builder /app/dist ./dist' : 'COPY --from=builder /app/src ./src'}
28
+ COPY --from=builder /app/node_modules ./node_modules
29
+ COPY --from=builder /app/package*.json ./
30
+
31
+ # Create non-root user
32
+ RUN addgroup -g 1001 -S nodejs
33
+ RUN adduser -S nextjs -u 1001
34
+
35
+ USER nextjs
36
+
37
+ EXPOSE 3000
38
+
39
+ ENV NODE_ENV=production
40
+ ENV PORT=3000
41
+
42
+ CMD ["npm", "start"]`;
43
+ },
44
+
45
+ python: function(config) {
46
+ return `FROM python:3.11-slim
47
+
48
+ WORKDIR /app
49
+
50
+ # Install system dependencies
51
+ RUN apt-get update && apt-get install -y \\
52
+ gcc \\
53
+ && rm -rf /var/lib/apt/lists/*
54
+
55
+ # Copy requirements and install Python dependencies
56
+ COPY requirements.txt .
57
+ RUN pip install --no-cache-dir -r requirements.txt
58
+
59
+ # Copy application code
60
+ COPY . .
61
+
62
+ # Create non-root user
63
+ RUN useradd --create-home --shell /bin/bash app \\
64
+ && chown -R app:app /app
65
+ USER app
66
+
67
+ EXPOSE 8000
68
+
69
+ ENV PYTHONPATH=/app
70
+ ENV PYTHONUNBUFFERED=1
71
+
72
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]`;
73
+ },
74
+
75
+ java: function(config) {
76
+ return `FROM maven:3.9-openjdk-17 AS builder
77
+
78
+ WORKDIR /app
79
+
80
+ # Copy pom.xml and download dependencies
81
+ COPY pom.xml .
82
+ RUN mvn dependency:go-offline
83
+
84
+ # Copy source code
85
+ COPY src ./src
86
+
87
+ # Build the application
88
+ RUN mvn clean package -DskipTests
89
+
90
+ # Production stage
91
+ FROM openjdk:17-jre-slim
92
+
93
+ WORKDIR /app
94
+
95
+ # Copy the built JAR file
96
+ COPY --from=builder /app/target/*.jar app.jar
97
+
98
+ # Create non-root user
99
+ RUN groupadd -r spring && useradd -r -g spring spring
100
+ USER spring
101
+
102
+ EXPOSE 8080
103
+
104
+ ENV JAVA_OPTS="-Xmx512m -Xms256m"
105
+
106
+ CMD ["java", "-jar", "app.jar"]`;
107
+ },
108
+
109
+ go: function(config) {
110
+ return `FROM golang:1.21-alpine AS builder
111
+
112
+ WORKDIR /app
113
+
114
+ # Copy go mod files
115
+ COPY go.mod go.sum ./
116
+
117
+ # Download dependencies
118
+ RUN go mod download
119
+
120
+ # Copy source code
121
+ COPY . .
122
+
123
+ # Build the application
124
+ RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
125
+
126
+ # Production stage
127
+ FROM alpine:latest
128
+
129
+ RUN apk --no-cache add ca-certificates tzdata
130
+
131
+ WORKDIR /root/
132
+
133
+ # Copy the binary from builder stage
134
+ COPY --from=builder /app/main .
135
+
136
+ # Expose port
137
+ EXPOSE 8080
138
+
139
+ CMD ["./main"]`;
140
+ },
141
+
142
+ rust: function(config) {
143
+ return `FROM rust:1.70 as builder
144
+
145
+ WORKDIR /app
146
+
147
+ # Copy Cargo files
148
+ COPY Cargo.toml Cargo.lock ./
149
+
150
+ # Create dummy main.rs to cache dependencies
151
+ RUN mkdir src && echo "fn main() {}" > src/main.rs
152
+ RUN cargo build --release && rm -rf src
153
+
154
+ # Copy source code
155
+ COPY src ./src
156
+
157
+ # Build the application
158
+ RUN touch src/main.rs && cargo build --release
159
+
160
+ # Production stage
161
+ FROM debian:bookworm-slim
162
+
163
+ # Install runtime dependencies
164
+ RUN apt-get update && apt-get install -y \\
165
+ ca-certificates \\
166
+ && rm -rf /var/lib/apt/lists/*
167
+
168
+ WORKDIR /app
169
+
170
+ # Copy the binary from builder stage
171
+ COPY --from=builder /app/target/release/${config.projectName} .
172
+
173
+ # Create non-root user
174
+ RUN useradd -r -s /bin/false rustuser
175
+ USER rustuser
176
+
177
+ EXPOSE 8080
178
+
179
+ CMD ["./${config.projectName}"]`;
180
+ },
181
+
182
+ php: function(config) {
183
+ return `FROM php:8.2-fpm-alpine
184
+
185
+ # Install system dependencies
186
+ RUN apk add --no-cache \\
187
+ git \\
188
+ curl \\
189
+ libpng-dev \\
190
+ oniguruma-dev \\
191
+ libxml2-dev \\
192
+ zip \\
193
+ unzip \\
194
+ && docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
195
+
196
+ # Get latest Composer
197
+ COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
198
+
199
+ # Set working directory
200
+ WORKDIR /var/www
201
+
202
+ # Copy application files
203
+ COPY . .
204
+
205
+ # Install PHP dependencies
206
+ RUN composer install --no-interaction --no-plugins --no-scripts --prefer-dist
207
+
208
+ # Set permissions
209
+ RUN chown -R www-data:www-data /var/www
210
+ RUN chmod -R 755 /var/www/storage
211
+
212
+ EXPOSE 9000
213
+
214
+ CMD ["php-fpm"]`;
215
+ }
216
+ };
217
+
218
+ // Docker Compose generation
219
+ function generateDockerCompose(config) {
220
+ const services = {
221
+ api: {
222
+ build: {
223
+ context: '.',
224
+ dockerfile: 'Dockerfile'
225
+ },
226
+ ports: ['3000:3000'],
227
+ environment: [
228
+ 'NODE_ENV=production'
229
+ ],
230
+ depends_on: config.database ? [config.database] : undefined,
231
+ restart: 'unless-stopped'
232
+ }
233
+ };
234
+
235
+ // Add database service if selected
236
+ if (config.database) {
237
+ const dbServices = {
238
+ mongodb: {
239
+ image: 'mongo:7.0',
240
+ ports: ['27017:27017'],
241
+ environment: [
242
+ 'MONGO_INITDB_ROOT_USERNAME=admin',
243
+ 'MONGO_INITDB_ROOT_PASSWORD=password',
244
+ `MONGO_INITDB_DATABASE=${config.projectName}`
245
+ ],
246
+ volumes: ['mongodb_data:/data/db'],
247
+ restart: 'unless-stopped'
248
+ },
249
+ postgresql: {
250
+ image: 'postgres:15',
251
+ ports: ['5432:5432'],
252
+ environment: [
253
+ 'POSTGRES_DB=postgres',
254
+ 'POSTGRES_USER=postgres',
255
+ 'POSTGRES_PASSWORD=password'
256
+ ],
257
+ volumes: ['postgres_data:/var/lib/postgresql/data'],
258
+ restart: 'unless-stopped'
259
+ },
260
+ mysql: {
261
+ image: 'mysql:8.0',
262
+ ports: ['3306:3306'],
263
+ environment: [
264
+ `MYSQL_DATABASE=${config.projectName}`,
265
+ 'MYSQL_ROOT_PASSWORD=password',
266
+ 'MYSQL_USER=user',
267
+ 'MYSQL_PASSWORD=password'
268
+ ],
269
+ volumes: ['mysql_data:/var/lib/mysql'],
270
+ restart: 'unless-stopped'
271
+ },
272
+ redis: {
273
+ image: 'redis:7.0-alpine',
274
+ ports: ['6379:6379'],
275
+ volumes: ['redis_data:/data'],
276
+ restart: 'unless-stopped'
277
+ }
278
+ };
279
+
280
+ if (dbServices[config.database]) {
281
+ services[config.database] = dbServices[config.database];
282
+ }
283
+ }
284
+
285
+ const dockerCompose = {
286
+ version: '3.8',
287
+ services,
288
+ volumes: {}
289
+ };
290
+
291
+ // Add volume definitions
292
+ if (config.database && ['mongodb', 'postgresql', 'mysql', 'redis'].includes(config.database)) {
293
+ dockerCompose.volumes[`${config.database}_data`] = {};
294
+ }
295
+
296
+ return `version: '3.8'
297
+
298
+ services:
299
+ ${Object.entries(services).map(([name, service]) => {
300
+ let serviceYaml = ` ${name}:\n`;
301
+
302
+ if (service.build) {
303
+ serviceYaml += ` build:\n`;
304
+ Object.entries(service.build).forEach(([key, value]) => {
305
+ serviceYaml += ` ${key}: ${typeof value === 'string' ? value : ''}\n`;
306
+ });
307
+ }
308
+
309
+ if (service.image) {
310
+ serviceYaml += ` image: ${service.image}\n`;
311
+ }
312
+
313
+ if (service.ports) {
314
+ serviceYaml += ` ports:\n`;
315
+ service.ports.forEach(port => {
316
+ serviceYaml += ` - "${port}"\n`;
317
+ });
318
+ }
319
+
320
+ if (service.environment) {
321
+ serviceYaml += ` environment:\n`;
322
+ service.environment.forEach(env => {
323
+ serviceYaml += ` - ${env}\n`;
324
+ });
325
+ }
326
+
327
+ if (service.depends_on) {
328
+ serviceYaml += ` depends_on:\n`;
329
+ service.depends_on.forEach(dep => {
330
+ serviceYaml += ` - ${dep}\n`;
331
+ });
332
+ }
333
+
334
+ if (service.volumes) {
335
+ serviceYaml += ` volumes:\n`;
336
+ service.volumes.forEach(vol => {
337
+ serviceYaml += ` - ${vol}\n`;
338
+ });
339
+ }
340
+
341
+ if (service.restart) {
342
+ serviceYaml += ` restart: ${service.restart}\n`;
343
+ }
344
+
345
+ return serviceYaml;
346
+ }).join('')}
347
+ ${Object.keys(dockerCompose.volumes).length > 0 ? `
348
+ volumes:
349
+ ${Object.keys(dockerCompose.volumes).map(vol => ` ${vol}:`).join('\n')}` : ''}`;
350
+ }
351
+
352
+ // Dockerignore generation
353
+ function generateDockerignore(config) {
354
+ const commonIgnore = `
355
+ # Dependencies
356
+ node_modules/
357
+ __pycache__/
358
+ target/
359
+ build/
360
+ dist/
361
+ vendor/
362
+
363
+ # Environment variables
364
+ .env
365
+ .env.local
366
+ .env.*.local
367
+
368
+ # Logs
369
+ logs
370
+ *.log
371
+ npm-debug.log*
372
+ yarn-debug.log*
373
+ yarn-error.log*
374
+
375
+ # Runtime data
376
+ pids
377
+ *.pid
378
+ *.seed
379
+ *.pid.lock
380
+
381
+ # Coverage directory used by tools like istanbul
382
+ coverage/
383
+ *.lcov
384
+
385
+ # IDE files
386
+ .vscode/
387
+ .idea/
388
+ *.swp
389
+ *.swo
390
+
391
+ # OS files
392
+ .DS_Store
393
+ Thumbs.db
394
+
395
+ # Git
396
+ .git
397
+ .gitignore
398
+
399
+ # Documentation
400
+ README.md
401
+ docs/
402
+
403
+ # Test files
404
+ test/
405
+ tests/
406
+ *.test.js
407
+ *.spec.js
408
+ `;
409
+
410
+ return commonIgnore;
411
+ }
412
+
413
+ // CI/CD templates
414
+ function generateGitHubActions(config) {
415
+ return `name: CI/CD Pipeline
416
+
417
+ on:
418
+ push:
419
+ branches: [ main, develop ]
420
+ pull_request:
421
+ branches: [ main ]
422
+
423
+ jobs:
424
+ test:
425
+ runs-on: ubuntu-latest
426
+
427
+ services:
428
+ ${config.database ? `${config.database}:
429
+ image: ${getDatabaseImage(config.database)}
430
+ ports:
431
+ - ${getDatabasePort(config.database)}:${getDatabasePort(config.database)}
432
+ env:
433
+ ${getDatabaseEnv(config.database)}` : ''}
434
+
435
+ steps:
436
+ - uses: actions/checkout@v3
437
+
438
+ - name: Setup Node.js
439
+ uses: actions/setup-node@v3
440
+ with:
441
+ node-version: '18'
442
+ cache: 'npm'
443
+
444
+ - name: Install dependencies
445
+ run: npm ci
446
+
447
+ - name: Run tests
448
+ run: npm test
449
+ env:
450
+ ${config.database ? getTestEnv(config) : ''}
451
+
452
+ - name: Build application
453
+ run: npm run build
454
+
455
+ deploy:
456
+ needs: test
457
+ runs-on: ubuntu-latest
458
+ if: github.ref == 'refs/heads/main'
459
+
460
+ steps:
461
+ - uses: actions/checkout@v3
462
+
463
+ - name: Deploy to production
464
+ run: |
465
+ echo "Deploy to production"
466
+ # Add your deployment commands here
467
+ `;
468
+ }
469
+
470
+ function getDatabaseImage(database) {
471
+ const images = {
472
+ mongodb: 'mongo:7.0',
473
+ postgresql: 'postgres:15',
474
+ mysql: 'mysql:8.0',
475
+ redis: 'redis:7.0'
476
+ };
477
+ return images[database] || '';
478
+ }
479
+
480
+ function getDatabasePort(database) {
481
+ const ports = {
482
+ mongodb: '27017',
483
+ postgresql: '5432',
484
+ mysql: '3306',
485
+ redis: '6379'
486
+ };
487
+ return ports[database] || '';
488
+ }
489
+
490
+ function getDatabaseEnv(database) {
491
+ const envs = {
492
+ mongodb: 'MONGO_INITDB_ROOT_USERNAME: admin\n MONGO_INITDB_ROOT_PASSWORD: password',
493
+ postgresql: 'POSTGRES_PASSWORD: password\n POSTGRES_USER: postgres',
494
+ mysql: 'MYSQL_ROOT_PASSWORD: password\n MYSQL_DATABASE: test'
495
+ };
496
+ return envs[database] || '';
497
+ }
498
+
499
+ function getTestEnv(config) {
500
+ const envs = {
501
+ mongodb: `MONGODB_URI: mongodb://admin:password@localhost:${getDatabasePort(config.database)}/test`,
502
+ postgresql: `DATABASE_URL: postgresql://postgres:password@localhost:${getDatabasePort(config.database)}/test`,
503
+ mysql: `DATABASE_URL: mysql://root:password@localhost:${getDatabasePort(config.database)}/test`
504
+ };
505
+ return envs[config.database] || '';
506
+ }
507
+
508
+ module.exports = {
509
+ generateDockerfileNode: generateDockerTemplates.node,
510
+ generateDockerfilePython: generateDockerTemplates.python,
511
+ generateDockerfileJava: generateDockerTemplates.java,
512
+ generateDockerfileGo: generateDockerTemplates.go,
513
+ generateDockerfileRust: generateDockerTemplates.rust,
514
+ generateDockerfilePhp: generateDockerTemplates.php,
515
+ generateDockerCompose,
516
+ generateDockerignore,
517
+ generateGitHubActions
518
+ };
@@ -0,0 +1,58 @@
1
+ module.exports = {
2
+ generateDockerfileNode(config) {
3
+ return `FROM node:18-alpine
4
+
5
+ WORKDIR /app
6
+
7
+ COPY package*.json ./
8
+ RUN npm ci --only=production
9
+
10
+ COPY . .
11
+ RUN npm run build
12
+
13
+ EXPOSE 3000
14
+
15
+ CMD ["npm", "start"]`;
16
+ },
17
+
18
+ generateDockerCompose(config) {
19
+ const dbServices = {
20
+ mongodb: `
21
+ mongodb:
22
+ image: mongo:7.0
23
+ ports:
24
+ - "27017:27017"
25
+ volumes:
26
+ - mongodb_data:/data/db`,
27
+ postgresql: `
28
+ postgres:
29
+ image: postgres:15
30
+ ports:
31
+ - "5432:5432"
32
+ environment:
33
+ POSTGRES_DB: ${config.projectName}
34
+ POSTGRES_USER: postgres
35
+ POSTGRES_PASSWORD: password
36
+ volumes:
37
+ - postgres_data:/var/lib/postgresql/data`
38
+ };
39
+
40
+ const dbService = config.database ? dbServices[config.database] : '';
41
+
42
+ return `version: '3.8'
43
+
44
+ services:
45
+ api:
46
+ build: .
47
+ ports:
48
+ - "3000:3000"
49
+ depends_on:
50
+ ${config.database ? ` - ${config.database}` : ''}
51
+ environment:
52
+ - DATABASE_URL=${config.database ? `${config.database}://localhost:27017/${config.projectName}` : ''}
53
+ ${dbService}
54
+
55
+ volumes:
56
+ ${config.database ? ` ${config.database}_data:` : ''}`;
57
+ }
58
+ };
@@ -0,0 +1,138 @@
1
+ package routes
2
+
3
+ import (
4
+ "net/http"
5
+ "strconv"
6
+
7
+ "{{projectName}}/models"
8
+ "{{projectName}}/services"
9
+
10
+ "github.com/gin-gonic/gin"
11
+ )
12
+
13
+ func SetupRoutes(rg *gin.RouterGroup) {
14
+ userService := services.NewUserService()
15
+
16
+ users := rg.Group("/users")
17
+ {
18
+ users.GET("", GetUsers(userService))
19
+ users.GET("/:id", GetUser(userService))
20
+ users.POST("", CreateUser(userService))
21
+ users.PUT("/:id", UpdateUser(userService))
22
+ users.DELETE("/:id", DeleteUser(userService))
23
+ }
24
+ }
25
+
26
+ func GetUsers(userService *services.UserService) gin.HandlerFunc {
27
+ return func(c *gin.Context) {
28
+ users, err := userService.GetAllUsers()
29
+ if err != nil {
30
+ c.JSON(http.StatusInternalServerError, gin.H{
31
+ "success": false,
32
+ "error": gin.H{"message": "Failed to fetch users"},
33
+ })
34
+ return
35
+ }
36
+
37
+ c.JSON(http.StatusOK, gin.H{
38
+ "success": true,
39
+ "data": users,
40
+ })
41
+ }
42
+ }
43
+
44
+ func GetUser(userService *services.UserService) gin.HandlerFunc {
45
+ return func(c *gin.Context) {
46
+ id := c.Param("id")
47
+
48
+ user, err := userService.GetUserByID(id)
49
+ if err != nil {
50
+ c.JSON(http.StatusNotFound, gin.H{
51
+ "success": false,
52
+ "error": gin.H{"message": "User not found"},
53
+ })
54
+ return
55
+ }
56
+
57
+ c.JSON(http.StatusOK, gin.H{
58
+ "success": true,
59
+ "data": user,
60
+ })
61
+ }
62
+ }
63
+
64
+ func CreateUser(userService *services.UserService) gin.HandlerFunc {
65
+ return func(c *gin.Context) {
66
+ var user models.User
67
+ if err := c.ShouldBindJSON(&user); err != nil {
68
+ c.JSON(http.StatusBadRequest, gin.H{
69
+ "success": false,
70
+ "error": gin.H{"message": "Invalid request body"},
71
+ })
72
+ return
73
+ }
74
+
75
+ createdUser, err := userService.CreateUser(&user)
76
+ if err != nil {
77
+ c.JSON(http.StatusInternalServerError, gin.H{
78
+ "success": false,
79
+ "error": gin.H{"message": "Failed to create user"},
80
+ })
81
+ return
82
+ }
83
+
84
+ c.JSON(http.StatusCreated, gin.H{
85
+ "success": true,
86
+ "data": createdUser,
87
+ })
88
+ }
89
+ }
90
+
91
+ func UpdateUser(userService *services.UserService) gin.HandlerFunc {
92
+ return func(c *gin.Context) {
93
+ id := c.Param("id")
94
+
95
+ var user models.User
96
+ if err := c.ShouldBindJSON(&user); err != nil {
97
+ c.JSON(http.StatusBadRequest, gin.H{
98
+ "success": false,
99
+ "error": gin.H{"message": "Invalid request body"},
100
+ })
101
+ return
102
+ }
103
+
104
+ updatedUser, err := userService.UpdateUser(id, &user)
105
+ if err != nil {
106
+ c.JSON(http.StatusNotFound, gin.H{
107
+ "success": false,
108
+ "error": gin.H{"message": "User not found"},
109
+ })
110
+ return
111
+ }
112
+
113
+ c.JSON(http.StatusOK, gin.H{
114
+ "success": true,
115
+ "data": updatedUser,
116
+ })
117
+ }
118
+ }
119
+
120
+ func DeleteUser(userService *services.UserService) gin.HandlerFunc {
121
+ return func(c *gin.Context) {
122
+ id := c.Param("id")
123
+
124
+ err := userService.DeleteUser(id)
125
+ if err != nil {
126
+ c.JSON(http.StatusNotFound, gin.H{
127
+ "success": false,
128
+ "error": gin.H{"message": "User not found"},
129
+ })
130
+ return
131
+ }
132
+
133
+ c.JSON(http.StatusOK, gin.H{
134
+ "success": true,
135
+ "message": "User deleted successfully",
136
+ })
137
+ }
138
+ }