create-tigra 1.0.7 → 2.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.
- package/LICENSE +21 -21
- package/README.md +80 -87
- package/bin/create-tigra.js +242 -309
- package/package.json +49 -41
- package/template/_claude/QUICK_REFERENCE.md +193 -0
- package/template/_claude/README.md +53 -0
- package/template/_claude/commands/create-client.md +881 -0
- package/template/_claude/commands/create-server.md +383 -0
- package/template/_claude/rules/client/01-project-structure.md +133 -0
- package/template/_claude/rules/client/02-components-and-types.md +146 -0
- package/template/_claude/rules/client/03-data-and-state.md +156 -0
- package/template/_claude/rules/client/04-design-system.md +185 -0
- package/template/_claude/rules/client/05-security.md +55 -0
- package/template/_claude/rules/client/06-ux-checklist.md +81 -0
- package/template/_claude/rules/client/core.md +42 -0
- package/template/_claude/rules/global/core.md +77 -0
- package/template/_claude/rules/server/core.md +50 -0
- package/template/_claude/rules/server/database.md +124 -0
- package/template/_claude/rules/server/project-conventions.md +150 -0
- package/template/_claude/rules/server/response-handling.md +144 -0
- package/template/client/.env.example +5 -0
- package/template/client/README.md +36 -0
- package/template/client/components.json +23 -0
- package/template/client/eslint.config.mjs +18 -0
- package/template/client/next.config.ts +34 -0
- package/template/client/package.json +44 -0
- package/template/client/postcss.config.mjs +7 -0
- package/template/client/src/app/(auth)/layout.tsx +18 -0
- package/template/client/src/app/(auth)/login/page.tsx +13 -0
- package/template/client/src/app/(auth)/register/page.tsx +13 -0
- package/template/client/src/app/(main)/dashboard/page.tsx +22 -0
- package/template/client/src/app/(main)/layout.tsx +11 -0
- package/template/client/src/app/error.tsx +27 -0
- package/template/client/src/app/favicon.ico +0 -0
- package/template/client/src/app/globals.css +145 -0
- package/template/client/src/app/layout.tsx +36 -0
- package/template/client/src/app/loading.tsx +11 -0
- package/template/client/src/app/not-found.tsx +23 -0
- package/template/client/src/app/page.tsx +45 -0
- package/template/client/src/app/providers.tsx +43 -0
- package/template/client/src/components/common/ConfirmDialog.tsx +56 -0
- package/template/client/src/components/common/EmptyState.tsx +31 -0
- package/template/client/src/components/common/LoadingSpinner.tsx +30 -0
- package/template/client/src/components/common/Pagination.tsx +55 -0
- package/template/client/src/components/layout/Footer.tsx +17 -0
- package/template/client/src/components/layout/Header.tsx +173 -0
- package/template/client/src/components/layout/MainLayout.tsx +18 -0
- package/template/client/src/components/ui/alert-dialog.tsx +196 -0
- package/template/client/src/components/ui/badge.tsx +48 -0
- package/template/client/src/components/ui/button.tsx +64 -0
- package/template/client/src/components/ui/card.tsx +92 -0
- package/template/client/src/components/ui/input.tsx +21 -0
- package/template/client/src/components/ui/label.tsx +24 -0
- package/template/client/src/components/ui/select.tsx +190 -0
- package/template/client/src/components/ui/skeleton.tsx +13 -0
- package/template/client/src/components/ui/table.tsx +116 -0
- package/template/client/src/features/auth/components/AuthInitializer.tsx +55 -0
- package/template/client/src/features/auth/components/LoginForm.tsx +107 -0
- package/template/client/src/features/auth/components/RegisterForm.tsx +178 -0
- package/template/client/src/features/auth/hooks/useAuth.ts +84 -0
- package/template/client/src/features/auth/services/auth.service.ts +52 -0
- package/template/client/src/features/auth/store/authSlice.ts +38 -0
- package/template/client/src/features/auth/types/auth.types.ts +32 -0
- package/template/client/src/hooks/useDebounce.ts +14 -0
- package/template/client/src/hooks/useLocalStorage.ts +55 -0
- package/template/client/src/hooks/useMediaQuery.ts +27 -0
- package/template/client/src/lib/api/api.types.ts +34 -0
- package/template/client/src/lib/api/axios.config.ts +98 -0
- package/template/client/src/lib/constants/api-endpoints.ts +18 -0
- package/template/client/src/lib/constants/app.constants.ts +12 -0
- package/template/client/src/lib/constants/routes.ts +9 -0
- package/template/client/src/lib/utils/error.ts +32 -0
- package/template/client/src/lib/utils/format.ts +37 -0
- package/template/client/src/lib/utils/security.ts +34 -0
- package/template/client/src/lib/utils.ts +6 -0
- package/template/client/src/middleware.ts +57 -0
- package/template/client/src/store/hooks.ts +7 -0
- package/template/client/src/store/index.ts +12 -0
- package/template/client/src/types/index.ts +3 -0
- package/template/client/tsconfig.json +34 -0
- package/template/gitignore +34 -0
- package/template/server/.dockerignore +66 -0
- package/template/server/.env.example +96 -69
- package/template/server/.env.production.example +90 -0
- package/template/server/Dockerfile +94 -0
- package/template/server/docker-compose.yml +80 -111
- package/template/server/docs/logging.md +62 -0
- package/template/server/eslint.config.mjs +17 -0
- package/template/server/package.json +68 -81
- package/template/server/phpmyadmin-config.php +26 -0
- package/template/server/postman_collection.json +666 -0
- package/template/server/prisma/schema.prisma +77 -93
- package/template/server/prisma/seed.ts +46 -142
- package/template/server/scripts/flush-redis.ts +41 -0
- package/template/server/src/app.ts +243 -71
- package/template/server/src/config/env.ts +67 -94
- package/template/server/src/libs/auth.ts +88 -0
- package/template/server/src/libs/cleanup.ts +35 -0
- package/template/server/src/libs/cookies.ts +46 -0
- package/template/server/src/libs/logger.ts +33 -60
- package/template/server/src/libs/monitoring.ts +205 -0
- package/template/server/src/libs/password.ts +38 -0
- package/template/server/src/libs/prisma.ts +68 -0
- package/template/server/src/libs/redis.ts +60 -79
- package/template/server/src/libs/requestLogger.ts +66 -0
- package/template/server/src/libs/storage/file-storage.service.ts +211 -0
- package/template/server/src/libs/storage/file-validator.ts +97 -0
- package/template/server/src/libs/storage/filename-sanitizer.ts +71 -0
- package/template/server/src/libs/storage/image-optimizer.service.ts +144 -0
- package/template/server/src/modules/auth/__tests__/auth.service.test.ts +365 -0
- package/template/server/src/modules/auth/auth.controller.ts +90 -141
- package/template/server/src/modules/auth/auth.repo.ts +120 -218
- package/template/server/src/modules/auth/auth.routes.ts +96 -83
- package/template/server/src/modules/auth/auth.schemas.ts +35 -137
- package/template/server/src/modules/auth/auth.service.ts +286 -329
- package/template/server/src/modules/auth/session.repo.ts +110 -0
- package/template/server/src/modules/users/users.controller.ts +120 -0
- package/template/server/src/modules/users/users.repo.ts +77 -0
- package/template/server/src/modules/users/users.routes.ts +89 -0
- package/template/server/src/modules/users/users.schemas.ts +21 -0
- package/template/server/src/modules/users/users.service.ts +169 -0
- package/template/server/src/server.ts +58 -139
- package/template/server/src/shared/errors/AppError.ts +21 -0
- package/template/server/src/shared/errors/errors.ts +43 -0
- package/template/server/src/shared/responses/paginatedResponse.ts +38 -0
- package/template/server/src/shared/responses/successResponse.ts +17 -0
- package/template/server/src/shared/schemas/pagination.schema.ts +12 -0
- package/template/server/src/shared/types/index.ts +26 -0
- package/template/server/src/test/setup.ts +74 -38
- package/template/server/tsconfig.json +27 -89
- package/template/server/uploads/avatars/.gitkeep +1 -0
- package/template/server/vitest.config.ts +43 -98
- package/template/.agent/rules/client/01-project-structure.md +0 -326
- package/template/.agent/rules/client/02-component-patterns.md +0 -249
- package/template/.agent/rules/client/03-typescript-rules.md +0 -226
- package/template/.agent/rules/client/04-state-management.md +0 -474
- package/template/.agent/rules/client/05-api-integration.md +0 -129
- package/template/.agent/rules/client/06-forms-validation.md +0 -129
- package/template/.agent/rules/client/07-common-patterns.md +0 -150
- package/template/.agent/rules/client/08-color-system.md +0 -93
- package/template/.agent/rules/client/09-security-rules.md +0 -97
- package/template/.agent/rules/client/10-testing-strategy.md +0 -370
- package/template/.agent/rules/global/ai-edit-safety.md +0 -38
- package/template/.agent/rules/server/01-db-and-migrations.md +0 -242
- package/template/.agent/rules/server/02-general-rules.md +0 -111
- package/template/.agent/rules/server/03-migrations.md +0 -20
- package/template/.agent/rules/server/04-pagination.md +0 -130
- package/template/.agent/rules/server/05-project-conventions.md +0 -71
- package/template/.agent/rules/server/06-response-handling.md +0 -173
- package/template/.agent/rules/server/07-testing-strategy.md +0 -506
- package/template/.agent/rules/server/08-observability.md +0 -180
- package/template/.agent/rules/server/10-background-jobs-v2.md +0 -185
- package/template/.agent/rules/server/11-rate-limiting-v2.md +0 -210
- package/template/.agent/rules/server/12-performance-optimization.md +0 -567
- package/template/.claude/rules/client-01-project-structure.md +0 -327
- package/template/.claude/rules/client-02-component-patterns.md +0 -250
- package/template/.claude/rules/client-03-typescript-rules.md +0 -227
- package/template/.claude/rules/client-04-state-management.md +0 -475
- package/template/.claude/rules/client-05-api-integration.md +0 -130
- package/template/.claude/rules/client-06-forms-validation.md +0 -130
- package/template/.claude/rules/client-07-common-patterns.md +0 -151
- package/template/.claude/rules/client-08-color-system.md +0 -94
- package/template/.claude/rules/client-09-security-rules.md +0 -98
- package/template/.claude/rules/client-10-testing-strategy.md +0 -371
- package/template/.claude/rules/global-ai-edit-safety.md +0 -39
- package/template/.claude/rules/server-01-db-and-migrations.md +0 -243
- package/template/.claude/rules/server-02-general-rules.md +0 -112
- package/template/.claude/rules/server-03-migrations.md +0 -21
- package/template/.claude/rules/server-04-pagination.md +0 -131
- package/template/.claude/rules/server-05-project-conventions.md +0 -72
- package/template/.claude/rules/server-06-response-handling.md +0 -174
- package/template/.claude/rules/server-07-testing-strategy.md +0 -507
- package/template/.claude/rules/server-08-observability.md +0 -181
- package/template/.claude/rules/server-10-background-jobs-v2.md +0 -186
- package/template/.claude/rules/server-11-rate-limiting-v2.md +0 -211
- package/template/.claude/rules/server-12-performance-optimization.md +0 -568
- package/template/.cursor/rules/client-01-project-structure.mdc +0 -327
- package/template/.cursor/rules/client-02-component-patterns.mdc +0 -250
- package/template/.cursor/rules/client-03-typescript-rules.mdc +0 -227
- package/template/.cursor/rules/client-04-state-management.mdc +0 -475
- package/template/.cursor/rules/client-05-api-integration.mdc +0 -130
- package/template/.cursor/rules/client-06-forms-validation.mdc +0 -130
- package/template/.cursor/rules/client-07-common-patterns.mdc +0 -151
- package/template/.cursor/rules/client-08-color-system.mdc +0 -94
- package/template/.cursor/rules/client-09-security-rules.mdc +0 -98
- package/template/.cursor/rules/client-10-testing-strategy.mdc +0 -371
- package/template/.cursor/rules/global-ai-edit-safety.mdc +0 -39
- package/template/.cursor/rules/server-01-db-and-migrations.mdc +0 -243
- package/template/.cursor/rules/server-02-general-rules.mdc +0 -112
- package/template/.cursor/rules/server-03-migrations.mdc +0 -21
- package/template/.cursor/rules/server-04-pagination.mdc +0 -131
- package/template/.cursor/rules/server-05-project-conventions.mdc +0 -72
- package/template/.cursor/rules/server-06-response-handling.mdc +0 -174
- package/template/.cursor/rules/server-07-testing-strategy.mdc +0 -507
- package/template/.cursor/rules/server-08-observability.mdc +0 -181
- package/template/.cursor/rules/server-09-api-documentation-v2.mdc +0 -169
- package/template/.cursor/rules/server-10-background-jobs-v2.mdc +0 -186
- package/template/.cursor/rules/server-11-rate-limiting-v2.mdc +0 -211
- package/template/.cursor/rules/server-12-performance-optimization.mdc +0 -568
- package/template/CLAUDE.md +0 -207
- package/template/server/.tsc-aliasrc.json +0 -12
- package/template/server/README.md +0 -183
- package/template/server/SECURITY.md +0 -190
- package/template/server/Tigra-API.postman_collection.json +0 -733
- package/template/server/biome.json +0 -42
- package/template/server/scripts/setup-env.js +0 -50
- package/template/server/scripts/wait-for-db.js +0 -60
- package/template/server/src/hooks/request-timing.hook.ts +0 -26
- package/template/server/src/libs/auth/authenticate.middleware.ts +0 -22
- package/template/server/src/libs/auth/rbac.middleware.test.ts +0 -134
- package/template/server/src/libs/auth/rbac.middleware.ts +0 -147
- package/template/server/src/libs/db.ts +0 -76
- package/template/server/src/libs/error-handler.ts +0 -89
- package/template/server/src/libs/queue.ts +0 -79
- package/template/server/src/modules/admin/admin.controller.ts +0 -122
- package/template/server/src/modules/admin/admin.routes.ts +0 -62
- package/template/server/src/modules/admin/admin.schemas.ts +0 -35
- package/template/server/src/modules/admin/admin.service.ts +0 -167
- package/template/server/src/modules/auth/auth.integration.test.ts +0 -150
- package/template/server/src/modules/auth/auth.service.test.ts +0 -119
- package/template/server/src/modules/auth/auth.types.ts +0 -97
- package/template/server/src/modules/resources/resources.controller.ts +0 -218
- package/template/server/src/modules/resources/resources.repo.ts +0 -253
- package/template/server/src/modules/resources/resources.routes.ts +0 -116
- package/template/server/src/modules/resources/resources.schemas.ts +0 -146
- package/template/server/src/modules/resources/resources.service.ts +0 -218
- package/template/server/src/modules/resources/resources.types.ts +0 -73
- package/template/server/src/plugins/rate-limit.plugin.ts +0 -21
- package/template/server/src/plugins/security.plugin.ts +0 -21
- package/template/server/src/routes/health.routes.ts +0 -31
- package/template/server/src/types/fastify.d.ts +0 -36
- package/template/server/src/utils/errors.ts +0 -108
- package/template/server/src/utils/pagination.ts +0 -120
- package/template/server/src/utils/response.ts +0 -110
- package/template/server/src/workers/file.worker.ts +0 -106
- package/template/server/tsconfig.build.json +0 -30
- package/template/server/tsconfig.test.json +0 -22
|
@@ -1,93 +1,77 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
title String
|
|
79
|
-
summary String? @db.Text
|
|
80
|
-
price Float
|
|
81
|
-
status String @default("active")
|
|
82
|
-
createdAt DateTime @default(now()) @map("created_at")
|
|
83
|
-
updatedAt DateTime @updatedAt @map("updated_at")
|
|
84
|
-
|
|
85
|
-
// Relations
|
|
86
|
-
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
|
|
87
|
-
|
|
88
|
-
// Indexes
|
|
89
|
-
@@index([ownerId])
|
|
90
|
-
@@index([status])
|
|
91
|
-
@@index([createdAt])
|
|
92
|
-
@@map("resources")
|
|
93
|
-
}
|
|
1
|
+
generator client {
|
|
2
|
+
provider = "prisma-client-js"
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
datasource db {
|
|
6
|
+
provider = "mysql"
|
|
7
|
+
url = env("DATABASE_URL")
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
enum UserRole {
|
|
11
|
+
USER
|
|
12
|
+
ADMIN
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
model User {
|
|
16
|
+
id String @id @default(uuid())
|
|
17
|
+
email String @unique
|
|
18
|
+
password String
|
|
19
|
+
firstName String
|
|
20
|
+
lastName String
|
|
21
|
+
avatarUrl String? // SEO-friendly path: /uploads/avatars/{userId}/{firstName-lastName}-avatar.webp
|
|
22
|
+
role UserRole @default(USER)
|
|
23
|
+
isActive Boolean @default(true)
|
|
24
|
+
deletedAt DateTime?
|
|
25
|
+
|
|
26
|
+
// Account lockout
|
|
27
|
+
failedLoginAttempts Int @default(0)
|
|
28
|
+
lockedUntil DateTime?
|
|
29
|
+
|
|
30
|
+
createdAt DateTime @default(now())
|
|
31
|
+
updatedAt DateTime @updatedAt
|
|
32
|
+
|
|
33
|
+
refreshTokens RefreshToken[]
|
|
34
|
+
sessions Session[]
|
|
35
|
+
|
|
36
|
+
// Performance indexes for high-traffic scenarios (10K-100K users/day)
|
|
37
|
+
@@index([role]) // For role-based authorization queries
|
|
38
|
+
@@index([isActive]) // For filtering active/inactive users
|
|
39
|
+
@@index([deletedAt]) // For soft delete filtering
|
|
40
|
+
@@index([email, isActive]) // Compound index for login queries
|
|
41
|
+
@@map("users")
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
model RefreshToken {
|
|
45
|
+
id String @id @default(uuid())
|
|
46
|
+
token String @unique @db.VarChar(500)
|
|
47
|
+
userId String
|
|
48
|
+
expiresAt DateTime
|
|
49
|
+
createdAt DateTime @default(now())
|
|
50
|
+
|
|
51
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
52
|
+
|
|
53
|
+
// Performance indexes for token operations and cleanup
|
|
54
|
+
@@index([userId])
|
|
55
|
+
@@index([token])
|
|
56
|
+
@@index([userId, expiresAt]) // Compound index for efficient token cleanup queries
|
|
57
|
+
@@index([expiresAt]) // For expired token cleanup cron jobs
|
|
58
|
+
@@map("refresh_tokens")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
model Session {
|
|
62
|
+
id String @id @default(uuid())
|
|
63
|
+
userId String
|
|
64
|
+
deviceInfo String? @db.VarChar(500) // User agent, device type
|
|
65
|
+
ipAddress String? @db.VarChar(45) // IPv4 or IPv6
|
|
66
|
+
lastActiveAt DateTime @default(now())
|
|
67
|
+
expiresAt DateTime
|
|
68
|
+
createdAt DateTime @default(now())
|
|
69
|
+
|
|
70
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
71
|
+
|
|
72
|
+
// Performance indexes for session queries
|
|
73
|
+
@@index([userId])
|
|
74
|
+
@@index([userId, expiresAt])
|
|
75
|
+
@@index([expiresAt]) // For expired session cleanup
|
|
76
|
+
@@map("sessions")
|
|
77
|
+
}
|
|
@@ -1,142 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return existingAdmin;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Create admin user
|
|
51
|
-
const hashedPassword = await hashPassword(adminPassword);
|
|
52
|
-
|
|
53
|
-
const admin = await prisma.user.create({
|
|
54
|
-
data: {
|
|
55
|
-
email: adminEmail,
|
|
56
|
-
password: hashedPassword,
|
|
57
|
-
role: 'ADMIN',
|
|
58
|
-
emailVerified: true,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
logger.info({ id: admin.id, email: admin.email }, 'Admin user created');
|
|
63
|
-
return admin;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Seed regular user
|
|
68
|
-
*/
|
|
69
|
-
async function seedRegularUser() {
|
|
70
|
-
const userEmail = 'user@example.com';
|
|
71
|
-
const userPassword = 'User123!';
|
|
72
|
-
|
|
73
|
-
// Check if user already exists
|
|
74
|
-
const existingUser = await prisma.user.findUnique({
|
|
75
|
-
where: { email: userEmail },
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
if (existingUser) {
|
|
79
|
-
logger.info({ email: userEmail }, 'Regular user already exists');
|
|
80
|
-
return existingUser;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Create regular user
|
|
84
|
-
const hashedPassword = await hashPassword(userPassword);
|
|
85
|
-
|
|
86
|
-
const user = await prisma.user.create({
|
|
87
|
-
data: {
|
|
88
|
-
email: userEmail,
|
|
89
|
-
password: hashedPassword,
|
|
90
|
-
role: 'USER',
|
|
91
|
-
emailVerified: true,
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
logger.info({ id: user.id, email: user.email }, 'Regular user created');
|
|
96
|
-
return user;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Main seed function
|
|
101
|
-
*/
|
|
102
|
-
async function main() {
|
|
103
|
-
logger.info('Starting database seed...');
|
|
104
|
-
|
|
105
|
-
// Seed admin user
|
|
106
|
-
const admin = await seedAdminUser();
|
|
107
|
-
|
|
108
|
-
// Seed regular user
|
|
109
|
-
const user = await seedRegularUser();
|
|
110
|
-
|
|
111
|
-
// Summary
|
|
112
|
-
console.log('');
|
|
113
|
-
console.log('Database seeded successfully!');
|
|
114
|
-
console.log('');
|
|
115
|
-
console.log('═══════════════════════════════════════════════════════════');
|
|
116
|
-
console.log('LOGIN CREDENTIALS (Save these!)');
|
|
117
|
-
console.log('═══════════════════════════════════════════════════════════');
|
|
118
|
-
console.log('');
|
|
119
|
-
console.log('ADMIN:');
|
|
120
|
-
console.log(' Email: admin@example.com');
|
|
121
|
-
console.log(' Password: Admin123!');
|
|
122
|
-
console.log(' Role: ADMIN');
|
|
123
|
-
console.log('');
|
|
124
|
-
console.log('USER:');
|
|
125
|
-
console.log(' Email: user@example.com');
|
|
126
|
-
console.log(' Password: User123!');
|
|
127
|
-
console.log(' Role: USER');
|
|
128
|
-
console.log('');
|
|
129
|
-
console.log('═══════════════════════════════════════════════════════════');
|
|
130
|
-
console.log('');
|
|
131
|
-
|
|
132
|
-
logger.info('Database seed completed');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
main()
|
|
136
|
-
.catch((e) => {
|
|
137
|
-
logger.error(e, 'Seed failed');
|
|
138
|
-
process.exit(1);
|
|
139
|
-
})
|
|
140
|
-
.finally(async () => {
|
|
141
|
-
await prisma.$disconnect();
|
|
142
|
-
});
|
|
1
|
+
import { PrismaClient } from '@prisma/client';
|
|
2
|
+
import argon2 from 'argon2';
|
|
3
|
+
|
|
4
|
+
const prisma = new PrismaClient();
|
|
5
|
+
|
|
6
|
+
async function main(): Promise<void> {
|
|
7
|
+
const adminPassword = await argon2.hash('Admin123!');
|
|
8
|
+
const userPassword = await argon2.hash('User123!');
|
|
9
|
+
|
|
10
|
+
const admin = await prisma.user.upsert({
|
|
11
|
+
where: { email: 'admin@example.com' },
|
|
12
|
+
update: {},
|
|
13
|
+
create: {
|
|
14
|
+
email: 'admin@example.com',
|
|
15
|
+
password: adminPassword,
|
|
16
|
+
firstName: 'Admin',
|
|
17
|
+
lastName: 'User',
|
|
18
|
+
role: 'ADMIN',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const user = await prisma.user.upsert({
|
|
23
|
+
where: { email: 'user@example.com' },
|
|
24
|
+
update: {},
|
|
25
|
+
create: {
|
|
26
|
+
email: 'user@example.com',
|
|
27
|
+
password: userPassword,
|
|
28
|
+
firstName: 'Test',
|
|
29
|
+
lastName: 'User',
|
|
30
|
+
role: 'USER',
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.log('Seeded users:', { admin: admin.email, user: user.email });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
main()
|
|
39
|
+
.catch((error) => {
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.error('Seed failed:', error);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
})
|
|
44
|
+
.finally(async () => {
|
|
45
|
+
await prisma.$disconnect();
|
|
46
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Redis } from 'ioredis';
|
|
2
|
+
import { config } from 'dotenv';
|
|
3
|
+
|
|
4
|
+
// Load environment variables
|
|
5
|
+
config();
|
|
6
|
+
|
|
7
|
+
const REDIS_URL = process.env.REDIS_URL || 'redis://localhost:6379';
|
|
8
|
+
|
|
9
|
+
async function flushRateLimits(): Promise<void> {
|
|
10
|
+
console.log('Connecting to Redis...');
|
|
11
|
+
const redis = new Redis(REDIS_URL);
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
// Find all rate limit keys (Fastify rate-limit uses 'fastify-rate-limit:' prefix by default)
|
|
15
|
+
const rateLimitKeys = await redis.keys('fastify-rate-limit:*');
|
|
16
|
+
|
|
17
|
+
if (rateLimitKeys.length === 0) {
|
|
18
|
+
console.log('No rate limit keys found. Redis is clean!');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.log(`Found ${rateLimitKeys.length} rate limit keys`);
|
|
23
|
+
|
|
24
|
+
// Delete all rate limit keys
|
|
25
|
+
const result = await redis.del(...rateLimitKeys);
|
|
26
|
+
console.log(`Successfully deleted ${result} rate limit keys`);
|
|
27
|
+
console.log('Rate limits have been reset. You can continue testing!');
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error('Error flushing rate limits:', error);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
} finally {
|
|
32
|
+
await redis.quit();
|
|
33
|
+
console.log('Disconnected from Redis');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Run the script
|
|
38
|
+
flushRateLimits().catch((error) => {
|
|
39
|
+
console.error('Fatal error:', error);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|