create-blitzpack 0.1.0 → 0.1.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 (259) hide show
  1. package/dist/index.js +35 -77
  2. package/package.json +5 -6
  3. package/template/.dockerignore +0 -59
  4. package/template/.github/workflows/ci.yml +0 -157
  5. package/template/.husky/pre-commit +0 -1
  6. package/template/.husky/pre-push +0 -1
  7. package/template/.lintstagedrc.cjs +0 -4
  8. package/template/.nvmrc +0 -1
  9. package/template/.prettierrc +0 -9
  10. package/template/.vscode/settings.json +0 -13
  11. package/template/CLAUDE.md +0 -175
  12. package/template/CONTRIBUTING.md +0 -32
  13. package/template/Dockerfile +0 -90
  14. package/template/GETTING_STARTED.md +0 -35
  15. package/template/LICENSE +0 -21
  16. package/template/README.md +0 -116
  17. package/template/apps/api/.dockerignore +0 -51
  18. package/template/apps/api/.env.local.example +0 -62
  19. package/template/apps/api/emails/account-deleted-email.tsx +0 -69
  20. package/template/apps/api/emails/components/email-layout.tsx +0 -154
  21. package/template/apps/api/emails/config.ts +0 -22
  22. package/template/apps/api/emails/password-changed-email.tsx +0 -88
  23. package/template/apps/api/emails/password-reset-email.tsx +0 -86
  24. package/template/apps/api/emails/verification-email.tsx +0 -85
  25. package/template/apps/api/emails/welcome-email.tsx +0 -70
  26. package/template/apps/api/package.json +0 -84
  27. package/template/apps/api/prisma/migrations/20251012111439_init/migration.sql +0 -13
  28. package/template/apps/api/prisma/migrations/20251018162629_add_better_auth_fields/migration.sql +0 -67
  29. package/template/apps/api/prisma/migrations/20251019142208_add_user_role_enum/migration.sql +0 -5
  30. package/template/apps/api/prisma/migrations/20251019182151_user_auth/migration.sql +0 -7
  31. package/template/apps/api/prisma/migrations/20251019211416_faster_session_lookup/migration.sql +0 -2
  32. package/template/apps/api/prisma/migrations/20251119124337_add_upload_model/migration.sql +0 -26
  33. package/template/apps/api/prisma/migrations/20251120071241_add_scope_to_account/migration.sql +0 -2
  34. package/template/apps/api/prisma/migrations/20251120072608_add_oauth_token_expiration_fields/migration.sql +0 -10
  35. package/template/apps/api/prisma/migrations/20251120144705_add_audit_logs/migration.sql +0 -29
  36. package/template/apps/api/prisma/migrations/20251127123614_remove_impersonated_by/migration.sql +0 -8
  37. package/template/apps/api/prisma/migrations/20251127125630_remove_audit_logs/migration.sql +0 -11
  38. package/template/apps/api/prisma/migrations/migration_lock.toml +0 -3
  39. package/template/apps/api/prisma/schema.prisma +0 -116
  40. package/template/apps/api/prisma/seed.ts +0 -159
  41. package/template/apps/api/prisma.config.ts +0 -14
  42. package/template/apps/api/src/app.ts +0 -377
  43. package/template/apps/api/src/common/logger.service.ts +0 -227
  44. package/template/apps/api/src/config/env.ts +0 -60
  45. package/template/apps/api/src/config/rate-limit.ts +0 -29
  46. package/template/apps/api/src/hooks/auth.ts +0 -122
  47. package/template/apps/api/src/plugins/auth.ts +0 -198
  48. package/template/apps/api/src/plugins/database.ts +0 -45
  49. package/template/apps/api/src/plugins/logger.ts +0 -33
  50. package/template/apps/api/src/plugins/multipart.ts +0 -16
  51. package/template/apps/api/src/plugins/scalar.ts +0 -20
  52. package/template/apps/api/src/plugins/schedule.ts +0 -52
  53. package/template/apps/api/src/plugins/services.ts +0 -66
  54. package/template/apps/api/src/plugins/swagger.ts +0 -56
  55. package/template/apps/api/src/routes/accounts.ts +0 -91
  56. package/template/apps/api/src/routes/admin-sessions.ts +0 -92
  57. package/template/apps/api/src/routes/metrics.ts +0 -71
  58. package/template/apps/api/src/routes/password.ts +0 -46
  59. package/template/apps/api/src/routes/sessions.ts +0 -53
  60. package/template/apps/api/src/routes/stats.ts +0 -38
  61. package/template/apps/api/src/routes/uploads-serve.ts +0 -27
  62. package/template/apps/api/src/routes/uploads.ts +0 -154
  63. package/template/apps/api/src/routes/users.ts +0 -114
  64. package/template/apps/api/src/routes/verification.ts +0 -90
  65. package/template/apps/api/src/server.ts +0 -34
  66. package/template/apps/api/src/services/accounts.service.ts +0 -125
  67. package/template/apps/api/src/services/authorization.service.ts +0 -162
  68. package/template/apps/api/src/services/email.service.ts +0 -170
  69. package/template/apps/api/src/services/file-storage.service.ts +0 -267
  70. package/template/apps/api/src/services/metrics.service.ts +0 -175
  71. package/template/apps/api/src/services/password.service.ts +0 -56
  72. package/template/apps/api/src/services/sessions.service.spec.ts +0 -134
  73. package/template/apps/api/src/services/sessions.service.ts +0 -276
  74. package/template/apps/api/src/services/stats.service.ts +0 -273
  75. package/template/apps/api/src/services/uploads.service.ts +0 -163
  76. package/template/apps/api/src/services/users.service.spec.ts +0 -249
  77. package/template/apps/api/src/services/users.service.ts +0 -198
  78. package/template/apps/api/src/utils/file-validation.ts +0 -108
  79. package/template/apps/api/start.sh +0 -33
  80. package/template/apps/api/test/helpers/fastify-app.ts +0 -24
  81. package/template/apps/api/test/helpers/mock-authorization.ts +0 -16
  82. package/template/apps/api/test/helpers/mock-logger.ts +0 -28
  83. package/template/apps/api/test/helpers/mock-prisma.ts +0 -30
  84. package/template/apps/api/test/helpers/test-db.ts +0 -125
  85. package/template/apps/api/test/integration/auth-flow.integration.spec.ts +0 -449
  86. package/template/apps/api/test/integration/password.integration.spec.ts +0 -427
  87. package/template/apps/api/test/integration/rate-limit.integration.spec.ts +0 -51
  88. package/template/apps/api/test/integration/sessions.integration.spec.ts +0 -445
  89. package/template/apps/api/test/integration/users.integration.spec.ts +0 -211
  90. package/template/apps/api/test/setup.ts +0 -31
  91. package/template/apps/api/tsconfig.json +0 -26
  92. package/template/apps/api/vitest.config.ts +0 -35
  93. package/template/apps/web/.env.local.example +0 -11
  94. package/template/apps/web/components.json +0 -24
  95. package/template/apps/web/next.config.ts +0 -22
  96. package/template/apps/web/package.json +0 -56
  97. package/template/apps/web/postcss.config.js +0 -5
  98. package/template/apps/web/public/apple-icon.png +0 -0
  99. package/template/apps/web/public/icon.png +0 -0
  100. package/template/apps/web/public/robots.txt +0 -3
  101. package/template/apps/web/src/app/(admin)/admin/layout.tsx +0 -222
  102. package/template/apps/web/src/app/(admin)/admin/page.tsx +0 -157
  103. package/template/apps/web/src/app/(admin)/admin/sessions/page.tsx +0 -18
  104. package/template/apps/web/src/app/(admin)/admin/users/page.tsx +0 -20
  105. package/template/apps/web/src/app/(auth)/forgot-password/page.tsx +0 -177
  106. package/template/apps/web/src/app/(auth)/login/page.tsx +0 -159
  107. package/template/apps/web/src/app/(auth)/reset-password/page.tsx +0 -245
  108. package/template/apps/web/src/app/(auth)/signup/page.tsx +0 -153
  109. package/template/apps/web/src/app/dashboard/change-password/page.tsx +0 -255
  110. package/template/apps/web/src/app/dashboard/page.tsx +0 -296
  111. package/template/apps/web/src/app/error.tsx +0 -32
  112. package/template/apps/web/src/app/examples/file-upload/page.tsx +0 -200
  113. package/template/apps/web/src/app/favicon.ico +0 -0
  114. package/template/apps/web/src/app/global-error.tsx +0 -96
  115. package/template/apps/web/src/app/globals.css +0 -22
  116. package/template/apps/web/src/app/icon.png +0 -0
  117. package/template/apps/web/src/app/layout.tsx +0 -34
  118. package/template/apps/web/src/app/not-found.tsx +0 -28
  119. package/template/apps/web/src/app/page.tsx +0 -192
  120. package/template/apps/web/src/components/admin/activity-feed.tsx +0 -101
  121. package/template/apps/web/src/components/admin/charts/auth-breakdown-chart.tsx +0 -114
  122. package/template/apps/web/src/components/admin/charts/chart-tooltip.tsx +0 -124
  123. package/template/apps/web/src/components/admin/charts/realtime-metrics-chart.tsx +0 -511
  124. package/template/apps/web/src/components/admin/charts/role-distribution-chart.tsx +0 -102
  125. package/template/apps/web/src/components/admin/charts/session-activity-chart.tsx +0 -90
  126. package/template/apps/web/src/components/admin/charts/user-growth-chart.tsx +0 -108
  127. package/template/apps/web/src/components/admin/health-indicator.tsx +0 -175
  128. package/template/apps/web/src/components/admin/refresh-control.tsx +0 -90
  129. package/template/apps/web/src/components/admin/session-revoke-all-dialog.tsx +0 -79
  130. package/template/apps/web/src/components/admin/session-revoke-dialog.tsx +0 -74
  131. package/template/apps/web/src/components/admin/sessions-management-table.tsx +0 -372
  132. package/template/apps/web/src/components/admin/stat-card.tsx +0 -137
  133. package/template/apps/web/src/components/admin/user-create-dialog.tsx +0 -152
  134. package/template/apps/web/src/components/admin/user-delete-dialog.tsx +0 -73
  135. package/template/apps/web/src/components/admin/user-edit-dialog.tsx +0 -170
  136. package/template/apps/web/src/components/admin/users-management-table.tsx +0 -285
  137. package/template/apps/web/src/components/auth/email-verification-banner.tsx +0 -85
  138. package/template/apps/web/src/components/auth/github-button.tsx +0 -40
  139. package/template/apps/web/src/components/auth/google-button.tsx +0 -54
  140. package/template/apps/web/src/components/auth/protected-route.tsx +0 -66
  141. package/template/apps/web/src/components/auth/redirect-if-authenticated.tsx +0 -31
  142. package/template/apps/web/src/components/auth/with-auth.tsx +0 -30
  143. package/template/apps/web/src/components/error/error-card.tsx +0 -47
  144. package/template/apps/web/src/components/error/forbidden.tsx +0 -25
  145. package/template/apps/web/src/components/landing/command-block.tsx +0 -64
  146. package/template/apps/web/src/components/landing/feature-card.tsx +0 -60
  147. package/template/apps/web/src/components/landing/included-feature-card.tsx +0 -63
  148. package/template/apps/web/src/components/landing/logo.tsx +0 -41
  149. package/template/apps/web/src/components/landing/tech-badge.tsx +0 -11
  150. package/template/apps/web/src/components/layout/auth-nav.tsx +0 -58
  151. package/template/apps/web/src/components/layout/footer.tsx +0 -3
  152. package/template/apps/web/src/config/landing-data.ts +0 -152
  153. package/template/apps/web/src/config/site.ts +0 -5
  154. package/template/apps/web/src/hooks/api/__tests__/use-users.test.tsx +0 -181
  155. package/template/apps/web/src/hooks/api/use-admin-sessions.ts +0 -75
  156. package/template/apps/web/src/hooks/api/use-admin-stats.ts +0 -33
  157. package/template/apps/web/src/hooks/api/use-sessions.ts +0 -52
  158. package/template/apps/web/src/hooks/api/use-uploads.ts +0 -156
  159. package/template/apps/web/src/hooks/api/use-users.ts +0 -149
  160. package/template/apps/web/src/hooks/use-mobile.ts +0 -21
  161. package/template/apps/web/src/hooks/use-realtime-metrics.ts +0 -120
  162. package/template/apps/web/src/lib/__tests__/utils.test.ts +0 -29
  163. package/template/apps/web/src/lib/api.ts +0 -151
  164. package/template/apps/web/src/lib/auth.ts +0 -13
  165. package/template/apps/web/src/lib/env.ts +0 -52
  166. package/template/apps/web/src/lib/form-utils.ts +0 -11
  167. package/template/apps/web/src/lib/utils.ts +0 -1
  168. package/template/apps/web/src/providers.tsx +0 -34
  169. package/template/apps/web/src/store/atoms.ts +0 -15
  170. package/template/apps/web/src/test/helpers/test-utils.tsx +0 -44
  171. package/template/apps/web/src/test/setup.ts +0 -8
  172. package/template/apps/web/tailwind.config.ts +0 -5
  173. package/template/apps/web/tsconfig.json +0 -26
  174. package/template/apps/web/vitest.config.ts +0 -32
  175. package/template/assets/logo-512.png +0 -0
  176. package/template/assets/logo.svg +0 -4
  177. package/template/docker-compose.prod.yml +0 -66
  178. package/template/docker-compose.yml +0 -36
  179. package/template/eslint.config.ts +0 -119
  180. package/template/package.json +0 -77
  181. package/template/packages/tailwind-config/package.json +0 -9
  182. package/template/packages/tailwind-config/theme.css +0 -179
  183. package/template/packages/types/package.json +0 -29
  184. package/template/packages/types/src/__tests__/schemas.test.ts +0 -255
  185. package/template/packages/types/src/api-response.ts +0 -53
  186. package/template/packages/types/src/health-check.ts +0 -11
  187. package/template/packages/types/src/pagination.ts +0 -41
  188. package/template/packages/types/src/role.ts +0 -5
  189. package/template/packages/types/src/session.ts +0 -48
  190. package/template/packages/types/src/stats.ts +0 -113
  191. package/template/packages/types/src/upload.ts +0 -51
  192. package/template/packages/types/src/user.ts +0 -36
  193. package/template/packages/types/tsconfig.json +0 -5
  194. package/template/packages/types/vitest.config.ts +0 -21
  195. package/template/packages/ui/components.json +0 -21
  196. package/template/packages/ui/package.json +0 -108
  197. package/template/packages/ui/src/__tests__/button.test.tsx +0 -70
  198. package/template/packages/ui/src/alert-dialog.tsx +0 -141
  199. package/template/packages/ui/src/alert.tsx +0 -66
  200. package/template/packages/ui/src/animated-theme-toggler.tsx +0 -167
  201. package/template/packages/ui/src/avatar.tsx +0 -53
  202. package/template/packages/ui/src/badge.tsx +0 -36
  203. package/template/packages/ui/src/button.tsx +0 -84
  204. package/template/packages/ui/src/card.tsx +0 -92
  205. package/template/packages/ui/src/checkbox.tsx +0 -32
  206. package/template/packages/ui/src/data-table/data-table-column-header.tsx +0 -68
  207. package/template/packages/ui/src/data-table/data-table-pagination.tsx +0 -99
  208. package/template/packages/ui/src/data-table/data-table-toolbar.tsx +0 -55
  209. package/template/packages/ui/src/data-table/data-table-view-options.tsx +0 -63
  210. package/template/packages/ui/src/data-table/data-table.tsx +0 -167
  211. package/template/packages/ui/src/dialog.tsx +0 -143
  212. package/template/packages/ui/src/dropdown-menu.tsx +0 -257
  213. package/template/packages/ui/src/empty-state.tsx +0 -52
  214. package/template/packages/ui/src/file-upload-input.tsx +0 -202
  215. package/template/packages/ui/src/form.tsx +0 -168
  216. package/template/packages/ui/src/hooks/use-mobile.ts +0 -19
  217. package/template/packages/ui/src/icons/brand-icons.tsx +0 -16
  218. package/template/packages/ui/src/input.tsx +0 -21
  219. package/template/packages/ui/src/label.tsx +0 -24
  220. package/template/packages/ui/src/lib/utils.ts +0 -6
  221. package/template/packages/ui/src/password-input.tsx +0 -102
  222. package/template/packages/ui/src/popover.tsx +0 -48
  223. package/template/packages/ui/src/radio-group.tsx +0 -45
  224. package/template/packages/ui/src/scroll-area.tsx +0 -58
  225. package/template/packages/ui/src/select.tsx +0 -187
  226. package/template/packages/ui/src/separator.tsx +0 -28
  227. package/template/packages/ui/src/sheet.tsx +0 -139
  228. package/template/packages/ui/src/sidebar.tsx +0 -726
  229. package/template/packages/ui/src/skeleton-variants.tsx +0 -87
  230. package/template/packages/ui/src/skeleton.tsx +0 -13
  231. package/template/packages/ui/src/slider.tsx +0 -63
  232. package/template/packages/ui/src/sonner.tsx +0 -25
  233. package/template/packages/ui/src/spinner.tsx +0 -16
  234. package/template/packages/ui/src/switch.tsx +0 -31
  235. package/template/packages/ui/src/table.tsx +0 -116
  236. package/template/packages/ui/src/tabs.tsx +0 -66
  237. package/template/packages/ui/src/textarea.tsx +0 -18
  238. package/template/packages/ui/src/tooltip.tsx +0 -61
  239. package/template/packages/ui/src/user-avatar.tsx +0 -97
  240. package/template/packages/ui/test-config.js +0 -3
  241. package/template/packages/ui/tsconfig.json +0 -12
  242. package/template/packages/ui/turbo.json +0 -18
  243. package/template/packages/ui/vitest.config.ts +0 -17
  244. package/template/packages/ui/vitest.setup.ts +0 -1
  245. package/template/packages/utils/package.json +0 -23
  246. package/template/packages/utils/src/__tests__/utils.test.ts +0 -223
  247. package/template/packages/utils/src/array.ts +0 -18
  248. package/template/packages/utils/src/async.ts +0 -3
  249. package/template/packages/utils/src/date.ts +0 -77
  250. package/template/packages/utils/src/errors.ts +0 -73
  251. package/template/packages/utils/src/number.ts +0 -11
  252. package/template/packages/utils/src/string.ts +0 -13
  253. package/template/packages/utils/tsconfig.json +0 -5
  254. package/template/packages/utils/vitest.config.ts +0 -21
  255. package/template/pnpm-workspace.yaml +0 -4
  256. package/template/tsconfig.base.json +0 -32
  257. package/template/turbo.json +0 -133
  258. package/template/vitest.shared.ts +0 -26
  259. package/template/vitest.workspace.ts +0 -9
@@ -1,88 +0,0 @@
1
- import { Button, Text } from '@react-email/components';
2
- import * as React from 'react';
3
-
4
- import { EmailLayout } from './components/email-layout';
5
- import { emailConfig } from './config';
6
-
7
- interface PasswordChangedEmailProps {
8
- userEmail: string;
9
- changedAt: string;
10
- resetPasswordUrl: string;
11
- }
12
-
13
- export default function PasswordChangedEmail({
14
- userEmail = 'user@example.com',
15
- changedAt = new Date().toLocaleString('en-US', {
16
- dateStyle: 'medium',
17
- timeStyle: 'short',
18
- }),
19
- resetPasswordUrl = 'https://yourapp.com/forgot-password',
20
- }: PasswordChangedEmailProps) {
21
- const { appName } = emailConfig;
22
-
23
- return (
24
- <EmailLayout
25
- preview={`Your ${appName} password was changed`}
26
- heading="Your password was changed"
27
- >
28
- <Text style={paragraph}>
29
- The password for your account (<strong>{userEmail}</strong>) was
30
- successfully changed on {changedAt}.
31
- </Text>
32
-
33
- <Text style={paragraph}>
34
- If you made this change, no further action is required.
35
- </Text>
36
-
37
- <Text style={warningText}>
38
- If you didn't change your password, your account may be compromised.
39
- Reset your password immediately:
40
- </Text>
41
-
42
- <Button style={dangerButton} href={resetPasswordUrl}>
43
- Reset Password
44
- </Button>
45
-
46
- <Text style={paragraphSmall}>
47
- For security, this email was sent to notify you of account changes.
48
- </Text>
49
- </EmailLayout>
50
- );
51
- }
52
-
53
- const paragraph: React.CSSProperties = {
54
- color: '#334155',
55
- fontSize: '15px',
56
- lineHeight: '24px',
57
- margin: '0 0 24px',
58
- };
59
-
60
- const warningText: React.CSSProperties = {
61
- color: '#b45309',
62
- fontSize: '15px',
63
- lineHeight: '24px',
64
- margin: '0 0 24px',
65
- padding: '16px',
66
- backgroundColor: '#fef3c7',
67
- borderRadius: '8px',
68
- border: '1px solid #fcd34d',
69
- };
70
-
71
- const paragraphSmall: React.CSSProperties = {
72
- color: '#94a3b8',
73
- fontSize: '13px',
74
- lineHeight: '20px',
75
- margin: '24px 0 0',
76
- };
77
-
78
- const dangerButton: React.CSSProperties = {
79
- borderRadius: '8px',
80
- backgroundColor: '#dc2626',
81
- color: '#ffffff',
82
- fontSize: '15px',
83
- fontWeight: '600',
84
- textDecoration: 'none',
85
- textAlign: 'center',
86
- display: 'inline-block',
87
- padding: '12px 32px',
88
- };
@@ -1,86 +0,0 @@
1
- import { Button, Link, Text } from '@react-email/components';
2
- import * as React from 'react';
3
-
4
- import { EmailLayout } from './components/email-layout';
5
- import { emailConfig } from './config';
6
-
7
- interface PasswordResetEmailProps {
8
- resetUrl: string;
9
- userEmail: string;
10
- }
11
-
12
- export default function PasswordResetEmail({
13
- resetUrl = 'https://example.com/reset-password?token=abc123',
14
- userEmail = 'user@example.com',
15
- }: PasswordResetEmailProps) {
16
- const { primaryColor } = emailConfig;
17
-
18
- return (
19
- <EmailLayout preview="Reset your password" heading="Reset your password">
20
- <Text style={paragraph}>
21
- We received a request to reset the password for{' '}
22
- <strong>{userEmail}</strong>.
23
- </Text>
24
-
25
- <Text style={paragraph}>
26
- Click the button below to choose a new password:
27
- </Text>
28
-
29
- <Button
30
- style={{ ...button, backgroundColor: primaryColor }}
31
- href={resetUrl}
32
- >
33
- Reset Password
34
- </Button>
35
-
36
- <Text style={paragraphMuted}>Or copy this link into your browser:</Text>
37
- <Link href={resetUrl} style={link}>
38
- {resetUrl}
39
- </Link>
40
-
41
- <Text style={paragraphSmall}>
42
- This link expires in 1 hour. If you didn't request this, you can safely
43
- ignore this email — your password won't be changed.
44
- </Text>
45
- </EmailLayout>
46
- );
47
- }
48
-
49
- const paragraph: React.CSSProperties = {
50
- color: '#334155',
51
- fontSize: '15px',
52
- lineHeight: '24px',
53
- margin: '0 0 24px',
54
- };
55
-
56
- const paragraphMuted: React.CSSProperties = {
57
- color: '#64748b',
58
- fontSize: '13px',
59
- lineHeight: '20px',
60
- margin: '24px 0 8px',
61
- };
62
-
63
- const paragraphSmall: React.CSSProperties = {
64
- color: '#94a3b8',
65
- fontSize: '13px',
66
- lineHeight: '20px',
67
- margin: '24px 0 0',
68
- };
69
-
70
- const button: React.CSSProperties = {
71
- borderRadius: '8px',
72
- color: '#ffffff',
73
- fontSize: '15px',
74
- fontWeight: '600',
75
- textDecoration: 'none',
76
- textAlign: 'center',
77
- display: 'inline-block',
78
- padding: '12px 32px',
79
- };
80
-
81
- const link: React.CSSProperties = {
82
- color: '#2563eb',
83
- fontSize: '13px',
84
- textDecoration: 'underline',
85
- wordBreak: 'break-all',
86
- };
@@ -1,85 +0,0 @@
1
- import { Button, Link, Text } from '@react-email/components';
2
- import * as React from 'react';
3
-
4
- import { EmailLayout } from './components/email-layout';
5
- import { emailConfig } from './config';
6
-
7
- interface VerificationEmailProps {
8
- verificationUrl: string;
9
- userEmail: string;
10
- }
11
-
12
- export default function VerificationEmail({
13
- verificationUrl = 'https://example.com/verify?token=abc123',
14
- userEmail = 'user@example.com',
15
- }: VerificationEmailProps) {
16
- const { appName, primaryColor } = emailConfig;
17
-
18
- return (
19
- <EmailLayout
20
- preview={`Verify your email to get started with ${appName}`}
21
- heading="Verify your email"
22
- >
23
- <Text style={paragraph}>
24
- Thanks for signing up! Please verify your email address (
25
- <strong>{userEmail}</strong>) to complete your registration.
26
- </Text>
27
-
28
- <Button
29
- style={{ ...button, backgroundColor: primaryColor }}
30
- href={verificationUrl}
31
- >
32
- Verify Email Address
33
- </Button>
34
-
35
- <Text style={paragraphMuted}>Or copy this link into your browser:</Text>
36
- <Link href={verificationUrl} style={link}>
37
- {verificationUrl}
38
- </Link>
39
-
40
- <Text style={paragraphSmall}>
41
- This link expires in 24 hours. If you didn't create an account, ignore
42
- this email.
43
- </Text>
44
- </EmailLayout>
45
- );
46
- }
47
-
48
- const paragraph: React.CSSProperties = {
49
- color: '#334155',
50
- fontSize: '15px',
51
- lineHeight: '24px',
52
- margin: '0 0 24px',
53
- };
54
-
55
- const paragraphMuted: React.CSSProperties = {
56
- color: '#64748b',
57
- fontSize: '13px',
58
- lineHeight: '20px',
59
- margin: '24px 0 8px',
60
- };
61
-
62
- const paragraphSmall: React.CSSProperties = {
63
- color: '#94a3b8',
64
- fontSize: '13px',
65
- lineHeight: '20px',
66
- margin: '24px 0 0',
67
- };
68
-
69
- const button: React.CSSProperties = {
70
- borderRadius: '8px',
71
- color: '#ffffff',
72
- fontSize: '15px',
73
- fontWeight: '600',
74
- textDecoration: 'none',
75
- textAlign: 'center',
76
- display: 'inline-block',
77
- padding: '12px 32px',
78
- };
79
-
80
- const link: React.CSSProperties = {
81
- color: '#2563eb',
82
- fontSize: '13px',
83
- textDecoration: 'underline',
84
- wordBreak: 'break-all',
85
- };
@@ -1,70 +0,0 @@
1
- import { Button, Text } from '@react-email/components';
2
- import * as React from 'react';
3
-
4
- import { EmailLayout } from './components/email-layout';
5
- import { emailConfig } from './config';
6
-
7
- interface WelcomeEmailProps {
8
- userName: string;
9
- dashboardUrl: string;
10
- }
11
-
12
- export default function WelcomeEmail({
13
- userName = 'there',
14
- dashboardUrl = 'https://yourapp.com/dashboard',
15
- }: WelcomeEmailProps) {
16
- const { appName, primaryColor } = emailConfig;
17
-
18
- return (
19
- <EmailLayout
20
- preview={`Welcome to ${appName}! Your account is ready.`}
21
- heading={`Welcome to ${appName}!`}
22
- >
23
- <Text style={paragraph}>Hi {userName},</Text>
24
-
25
- <Text style={paragraph}>
26
- Your email has been verified and your account is all set up. We're
27
- excited to have you on board.
28
- </Text>
29
-
30
- <Text style={paragraph}>Get started by exploring your dashboard:</Text>
31
-
32
- <Button
33
- style={{ ...button, backgroundColor: primaryColor }}
34
- href={dashboardUrl}
35
- >
36
- Go to Dashboard
37
- </Button>
38
-
39
- <Text style={paragraphSmall}>
40
- If you have any questions, just reply to this email — we're here to
41
- help.
42
- </Text>
43
- </EmailLayout>
44
- );
45
- }
46
-
47
- const paragraph: React.CSSProperties = {
48
- color: '#334155',
49
- fontSize: '15px',
50
- lineHeight: '24px',
51
- margin: '0 0 24px',
52
- };
53
-
54
- const paragraphSmall: React.CSSProperties = {
55
- color: '#94a3b8',
56
- fontSize: '13px',
57
- lineHeight: '20px',
58
- margin: '24px 0 0',
59
- };
60
-
61
- const button: React.CSSProperties = {
62
- borderRadius: '8px',
63
- color: '#ffffff',
64
- fontSize: '15px',
65
- fontWeight: '600',
66
- textDecoration: 'none',
67
- textAlign: 'center',
68
- display: 'inline-block',
69
- padding: '12px 32px',
70
- };
@@ -1,84 +0,0 @@
1
- {
2
- "name": "@repo/api",
3
- "version": "1.0.0",
4
- "private": true,
5
- "type": "module",
6
- "scripts": {
7
- "dev": "tsx watch --clear-screen=false --ignore '../../packages/**' --ignore '**/node_modules/**' src/server.ts",
8
- "build": "tsc && tsc-alias -p tsconfig.json --resolve-full-paths",
9
- "start": "node dist/src/server.js",
10
- "start:dev": "tsx src/server.ts",
11
- "typecheck": "tsc --noEmit",
12
- "lint": "eslint \"src/**/*.ts\"",
13
- "lint:fix": "eslint \"src/**/*.ts\" --fix",
14
- "test": "vitest run",
15
- "test:unit": "vitest run src/",
16
- "test:integration": "vitest run test/integration/",
17
- "test:watch": "vitest",
18
- "test:coverage": "vitest run --coverage",
19
- "email:dev": "email dev --dir emails --port 3001",
20
- "db:generate": "prisma generate",
21
- "db:migrate": "prisma migrate dev",
22
- "db:push": "prisma db push",
23
- "db:studio": "prisma studio",
24
- "db:seed": "tsx prisma/seed.ts",
25
- "db:reset": "prisma migrate reset --force --skip-seed",
26
- "db:reset:seed": "prisma migrate reset --force"
27
- },
28
- "dependencies": {
29
- "@aws-sdk/client-s3": "^3.934.0",
30
- "@fastify/cookie": "^11.0.1",
31
- "@fastify/cors": "^10.0.1",
32
- "@fastify/formbody": "^8.0.1",
33
- "@fastify/helmet": "^12.0.1",
34
- "@fastify/multipart": "^9.3.0",
35
- "@fastify/rate-limit": "^10.1.1",
36
- "@fastify/schedule": "^5.0.2",
37
- "@fastify/static": "^8.3.0",
38
- "@fastify/swagger": "^9.3.0",
39
- "@fastify/swagger-ui": "^5.0.1",
40
- "@prisma/adapter-pg": "^7.0.1",
41
- "@prisma/client": "7.0.1",
42
- "@react-email/components": "^1.0.1",
43
- "@react-email/preview-server": "^5.0.4",
44
- "@repo/packages-types": "workspace:*",
45
- "@scalar/fastify-api-reference": "^1.39.3",
46
- "bcryptjs": "^3.0.2",
47
- "better-auth": "^1.3.27",
48
- "close-with-grace": "^2.1.0",
49
- "dotenv-flow": "^4.1.0",
50
- "fastify": "^5.2.0",
51
- "fastify-plugin": "^5.0.1",
52
- "fastify-type-provider-zod": "^5.0.1",
53
- "pg": "^8.16.3",
54
- "pino": "^10.0.0",
55
- "pino-pretty": "^13.1.2",
56
- "react": "^19.0.0",
57
- "react-dom": "^19.0.0",
58
- "react-email": "^5.0.4",
59
- "resend": "^6.5.0",
60
- "sharp": "^0.34.5",
61
- "toad-scheduler": "^3.1.0",
62
- "zod": "^4.1.12"
63
- },
64
- "devDependencies": {
65
- "@repo/packages-utils": "workspace:*",
66
- "@types/bcryptjs": "^3.0.0",
67
- "@types/node": "^24.7.1",
68
- "@types/pg": "^8.15.6",
69
- "@types/react": "^19.0.6",
70
- "@types/react-dom": "^19.0.2",
71
- "@typescript-eslint/eslint-plugin": "^8.20.0",
72
- "@typescript-eslint/parser": "^8.20.0",
73
- "dotenv": "^17.2.3",
74
- "dotenv-cli": "^10.0.0",
75
- "eslint": "^9.18.0",
76
- "eslint-config-prettier": "^10.1.8",
77
- "prisma": "7.0.1",
78
- "tsc-alias": "^1.8.16",
79
- "tsx": "^4.20.6",
80
- "typescript": "^5.7.2",
81
- "vite-tsconfig-paths": "^5.1.4",
82
- "vitest": "^3.2.4"
83
- }
84
- }
@@ -1,13 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "users" (
3
- "id" TEXT NOT NULL,
4
- "email" TEXT NOT NULL,
5
- "name" TEXT,
6
- "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
7
- "updatedAt" TIMESTAMP(3) NOT NULL,
8
-
9
- CONSTRAINT "users_pkey" PRIMARY KEY ("id")
10
- );
11
-
12
- -- CreateIndex
13
- CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
@@ -1,67 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "users" ADD COLUMN "emailVerified" BOOLEAN NOT NULL DEFAULT false,
3
- ADD COLUMN "image" TEXT;
4
-
5
- -- CreateTable
6
- CREATE TABLE "sessions" (
7
- "id" TEXT NOT NULL,
8
- "userId" TEXT NOT NULL,
9
- "expiresAt" TIMESTAMP(3) NOT NULL,
10
- "token" TEXT NOT NULL,
11
- "ipAddress" TEXT,
12
- "userAgent" TEXT,
13
- "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
14
- "updatedAt" TIMESTAMP(3) NOT NULL,
15
-
16
- CONSTRAINT "sessions_pkey" PRIMARY KEY ("id")
17
- );
18
-
19
- -- CreateTable
20
- CREATE TABLE "accounts" (
21
- "id" TEXT NOT NULL,
22
- "userId" TEXT NOT NULL,
23
- "accountId" TEXT NOT NULL,
24
- "providerId" TEXT NOT NULL,
25
- "accessToken" TEXT,
26
- "refreshToken" TEXT,
27
- "idToken" TEXT,
28
- "expiresAt" TIMESTAMP(3),
29
- "password" TEXT,
30
- "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
31
- "updatedAt" TIMESTAMP(3) NOT NULL,
32
-
33
- CONSTRAINT "accounts_pkey" PRIMARY KEY ("id")
34
- );
35
-
36
- -- CreateTable
37
- CREATE TABLE "verifications" (
38
- "id" TEXT NOT NULL,
39
- "identifier" TEXT NOT NULL,
40
- "value" TEXT NOT NULL,
41
- "expiresAt" TIMESTAMP(3) NOT NULL,
42
- "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
43
- "updatedAt" TIMESTAMP(3) NOT NULL,
44
-
45
- CONSTRAINT "verifications_pkey" PRIMARY KEY ("id")
46
- );
47
-
48
- -- CreateIndex
49
- CREATE UNIQUE INDEX "sessions_token_key" ON "sessions"("token");
50
-
51
- -- CreateIndex
52
- CREATE INDEX "sessions_userId_idx" ON "sessions"("userId");
53
-
54
- -- CreateIndex
55
- CREATE INDEX "accounts_userId_idx" ON "accounts"("userId");
56
-
57
- -- CreateIndex
58
- CREATE UNIQUE INDEX "accounts_providerId_accountId_key" ON "accounts"("providerId", "accountId");
59
-
60
- -- CreateIndex
61
- CREATE UNIQUE INDEX "verifications_identifier_value_key" ON "verifications"("identifier", "value");
62
-
63
- -- AddForeignKey
64
- ALTER TABLE "sessions" ADD CONSTRAINT "sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
65
-
66
- -- AddForeignKey
67
- ALTER TABLE "accounts" ADD CONSTRAINT "accounts_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -1,5 +0,0 @@
1
- -- CreateEnum
2
- CREATE TYPE "Role" AS ENUM ('user', 'admin', 'super_admin');
3
-
4
- -- AlterTable
5
- ALTER TABLE "users" ADD COLUMN "role" "Role" NOT NULL DEFAULT 'user';
@@ -1,7 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "sessions" ADD COLUMN "impersonatedBy" TEXT;
3
-
4
- -- AlterTable
5
- ALTER TABLE "users" ADD COLUMN "banExpires" TIMESTAMP(3),
6
- ADD COLUMN "banReason" TEXT,
7
- ADD COLUMN "banned" BOOLEAN NOT NULL DEFAULT false;
@@ -1,2 +0,0 @@
1
- -- CreateIndex
2
- CREATE INDEX "sessions_expiresAt_idx" ON "sessions"("expiresAt");
@@ -1,26 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "uploads" (
3
- "id" TEXT NOT NULL,
4
- "filename" TEXT NOT NULL,
5
- "originalName" TEXT NOT NULL,
6
- "mimeType" TEXT NOT NULL,
7
- "size" INTEGER NOT NULL,
8
- "url" TEXT NOT NULL,
9
- "userId" TEXT NOT NULL,
10
- "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
- "updatedAt" TIMESTAMP(3) NOT NULL,
12
-
13
- CONSTRAINT "uploads_pkey" PRIMARY KEY ("id")
14
- );
15
-
16
- -- CreateIndex
17
- CREATE UNIQUE INDEX "uploads_filename_key" ON "uploads"("filename");
18
-
19
- -- CreateIndex
20
- CREATE INDEX "uploads_userId_idx" ON "uploads"("userId");
21
-
22
- -- CreateIndex
23
- CREATE INDEX "uploads_createdAt_idx" ON "uploads"("createdAt");
24
-
25
- -- AddForeignKey
26
- ALTER TABLE "uploads" ADD CONSTRAINT "uploads_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -1,2 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "accounts" ADD COLUMN "scope" TEXT;
@@ -1,10 +0,0 @@
1
- /*
2
- Warnings:
3
-
4
- - You are about to drop the column `expiresAt` on the `accounts` table. All the data in the column will be lost.
5
-
6
- */
7
- -- AlterTable
8
- ALTER TABLE "accounts" DROP COLUMN "expiresAt",
9
- ADD COLUMN "accessTokenExpiresAt" TIMESTAMP(3),
10
- ADD COLUMN "refreshTokenExpiresAt" TIMESTAMP(3);
@@ -1,29 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "audit_logs" (
3
- "id" TEXT NOT NULL,
4
- "userId" TEXT NOT NULL,
5
- "action" TEXT NOT NULL,
6
- "resourceType" TEXT NOT NULL,
7
- "resourceId" TEXT,
8
- "changes" JSONB,
9
- "ipAddress" TEXT,
10
- "userAgent" TEXT,
11
- "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
12
-
13
- CONSTRAINT "audit_logs_pkey" PRIMARY KEY ("id")
14
- );
15
-
16
- -- CreateIndex
17
- CREATE INDEX "audit_logs_userId_idx" ON "audit_logs"("userId");
18
-
19
- -- CreateIndex
20
- CREATE INDEX "audit_logs_action_idx" ON "audit_logs"("action");
21
-
22
- -- CreateIndex
23
- CREATE INDEX "audit_logs_createdAt_idx" ON "audit_logs"("createdAt");
24
-
25
- -- CreateIndex
26
- CREATE INDEX "audit_logs_resourceType_idx" ON "audit_logs"("resourceType");
27
-
28
- -- AddForeignKey
29
- ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -1,8 +0,0 @@
1
- /*
2
- Warnings:
3
-
4
- - You are about to drop the column `impersonatedBy` on the `sessions` table. All the data in the column will be lost.
5
-
6
- */
7
- -- AlterTable
8
- ALTER TABLE "sessions" DROP COLUMN "impersonatedBy";
@@ -1,11 +0,0 @@
1
- /*
2
- Warnings:
3
-
4
- - You are about to drop the `audit_logs` table. If the table is not empty, all the data it contains will be lost.
5
-
6
- */
7
- -- DropForeignKey
8
- ALTER TABLE "audit_logs" DROP CONSTRAINT "audit_logs_userId_fkey";
9
-
10
- -- DropTable
11
- DROP TABLE "audit_logs";
@@ -1,3 +0,0 @@
1
- # Please do not edit this file manually
2
- # It should be added in your version-control system (e.g., Git)
3
- provider = "postgresql"