create-tigra 3.0.2 → 3.0.5

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 (38) hide show
  1. package/README.md +4 -0
  2. package/package.json +1 -1
  3. package/template/client/.env.example +19 -0
  4. package/template/client/Dockerfile +14 -4
  5. package/template/client/next.config.ts +7 -42
  6. package/template/client/package-lock.json +1896 -146
  7. package/template/client/package.json +3 -1
  8. package/template/client/scripts/next-dev.cjs +47 -0
  9. package/template/client/src/app/layout.tsx +10 -3
  10. package/template/client/src/app/providers.tsx +15 -2
  11. package/template/client/src/instrumentation-client.ts +38 -0
  12. package/template/client/src/instrumentation.ts +42 -0
  13. package/template/client/src/lib/env.ts +13 -2
  14. package/template/client/src/middleware.ts +105 -18
  15. package/template/server/.env.example +22 -1
  16. package/template/server/.env.example.production +16 -1
  17. package/template/server/Dockerfile +16 -8
  18. package/template/server/package-lock.json +2136 -86
  19. package/template/server/package.json +6 -0
  20. package/template/server/src/app.ts +30 -11
  21. package/template/server/src/config/env.ts +23 -2
  22. package/template/server/src/config/rate-limit.config.ts +6 -0
  23. package/template/server/src/libs/logger.ts +15 -0
  24. package/template/server/src/libs/observability/sentry.ts +42 -0
  25. package/template/server/src/libs/requestLogger.ts +8 -2
  26. package/template/server/src/libs/storage/file-storage.service.ts +144 -16
  27. package/template/server/src/modules/admin/__tests__/admin.integration.test.ts +128 -0
  28. package/template/server/src/modules/auth/__tests__/auth.integration.test.ts +138 -0
  29. package/template/server/src/modules/auth/__tests__/auth.service.test.ts +25 -41
  30. package/template/server/src/modules/auth/auth.repo.ts +0 -12
  31. package/template/server/src/modules/auth/auth.service.ts +29 -57
  32. package/template/server/src/modules/files/__tests__/files.integration.test.ts +157 -0
  33. package/template/server/src/modules/files/files.controller.ts +180 -0
  34. package/template/server/src/modules/files/files.routes.ts +46 -0
  35. package/template/server/src/server.ts +6 -0
  36. package/template/server/src/test/integration.setup.ts +170 -0
  37. package/template/server/vitest.config.ts +10 -1
  38. package/template/server/vitest.integration.config.ts +50 -0
package/README.md CHANGED
@@ -82,6 +82,10 @@ cd my-app/server
82
82
  docker compose --profile tools up -d
83
83
  ```
84
84
 
85
+ ## Security and Migration Notes
86
+
87
+ - [Account deactivation login reactivation: issue, fix, and existing-project migration](docs/account-deactivation-login-reactivation.md)
88
+
85
89
  ## License
86
90
 
87
91
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-tigra",
3
- "version": "3.0.2",
3
+ "version": "3.0.5",
4
4
  "type": "module",
5
5
  "description": "Create a production-ready full-stack app with Next.js 16 + Fastify 5 + Prisma + Redis",
6
6
  "bin": {
@@ -3,3 +3,22 @@ NEXT_PUBLIC_API_BASE_URL=http://localhost:8000/api/v1
3
3
 
4
4
  # App name displayed in the UI
5
5
  NEXT_PUBLIC_APP_NAME={{PROJECT_DISPLAY_NAME}}
6
+
7
+ # ===================================================================
8
+ # ERROR TRACKING (Optional, Sentry)
9
+ # ===================================================================
10
+ #
11
+ # Leave unset to disable Sentry entirely — instrumentation only inits when a
12
+ # DSN is present, so the build and runtime are fully inert without it.
13
+ # This setup is runtime-only and env-gated: next.config.ts is NOT wrapped with
14
+ # withSentryConfig, so `next build` needs NO Sentry auth token. Source-map
15
+ # upload (withSentryConfig + SENTRY_AUTH_TOKEN) is the opt-in upgrade.
16
+ #
17
+ # Public DSN (safe to expose to the browser). Inits both the browser and the
18
+ # Next.js server/edge runtimes.
19
+ # Example: NEXT_PUBLIC_SENTRY_DSN="https://examplePublicKey@o0.ingest.sentry.io/0"
20
+ # NEXT_PUBLIC_SENTRY_DSN=""
21
+
22
+ # Fraction of transactions sampled for browser performance tracing (0.0–1.0).
23
+ # Defaults to 0.1 when unset. Only takes effect when the DSN is set.
24
+ # NEXT_PUBLIC_SENTRY_TRACES_SAMPLE_RATE=0.1
@@ -1,13 +1,18 @@
1
+ # syntax=docker/dockerfile:1
1
2
  # ===================================================================
2
3
  # Multi-stage Dockerfile for Next.js Production Deployment
3
4
  # Optimized for Coolify, Docker Compose, and Kubernetes
4
5
  # Requires `output: "standalone"` in next.config.ts
5
6
  # ===================================================================
7
+ # BuildKit cache mount (--mount=type=cache) keeps the npm download cache warm
8
+ # across builds, so a lockfile/dep-change rebuild re-installs from cache
9
+ # (measured ~2.8x: 49s->18s on a real create-tigra client) instead of
10
+ # re-downloading every tarball. Requires the `# syntax` line above (BuildKit).
6
11
 
7
12
  # ===================================================================
8
13
  # Stage 1: Dependencies (cached layer)
9
14
  # ===================================================================
10
- FROM node:20-alpine AS dependencies
15
+ FROM node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS dependencies
11
16
 
12
17
  WORKDIR /app
13
18
 
@@ -15,7 +20,8 @@ WORKDIR /app
15
20
  COPY package.json package-lock.json* pnpm-lock.yaml* yarn.lock* ./
16
21
 
17
22
  # Install dependencies (use the lockfile that exists)
18
- RUN if [ -f pnpm-lock.yaml ]; then \
23
+ RUN --mount=type=cache,target=/root/.npm \
24
+ if [ -f pnpm-lock.yaml ]; then \
19
25
  npm install -g pnpm && pnpm install --frozen-lockfile; \
20
26
  elif [ -f yarn.lock ]; then \
21
27
  yarn install --frozen-lockfile; \
@@ -26,7 +32,7 @@ RUN if [ -f pnpm-lock.yaml ]; then \
26
32
  # ===================================================================
27
33
  # Stage 2: Build (compile Next.js)
28
34
  # ===================================================================
29
- FROM node:20-alpine AS builder
35
+ FROM node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS builder
30
36
 
31
37
  WORKDIR /app
32
38
 
@@ -49,12 +55,16 @@ ENV NEXT_PUBLIC_APP_NAME=$NEXT_PUBLIC_APP_NAME
49
55
  ENV NEXT_TELEMETRY_DISABLED=1
50
56
 
51
57
  # Build the application (outputs to .next/standalone)
58
+ # NOTE: a `--mount=type=cache,target=/app/.next/cache` was tested here and REMOVED —
59
+ # it measured SLOWER (next build 29s→58s on a real create-tigra client), because Next's
60
+ # persistent-cache serialization overhead exceeds the incremental savings for small/mid
61
+ # apps. Re-add it only for a genuinely large client after measuring a win.
52
62
  RUN npm run build
53
63
 
54
64
  # ===================================================================
55
65
  # Stage 3: Production Runtime
56
66
  # ===================================================================
57
- FROM node:20-alpine AS production
67
+ FROM node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS production
58
68
 
59
69
  # Install dumb-init for proper signal handling
60
70
  RUN apk add --no-cache dumb-init
@@ -1,19 +1,12 @@
1
1
  import type { NextConfig } from "next";
2
2
 
3
- const apiBaseUrl = process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000";
4
- const apiOrigin = (() => {
5
- try {
6
- return new URL(apiBaseUrl).origin;
7
- } catch {
8
- return "http://localhost:8000";
9
- }
10
- })();
11
-
12
- // 'unsafe-eval' is required by Next.js dev mode (HMR/react-refresh) but must
13
- // NOT ship to production. 'unsafe-inline' stays in both modes — the Next.js
14
- // inline runtime requires it unless a full nonce infrastructure is added.
15
- const isDev = process.env.NODE_ENV === "development";
16
- const scriptSrc = `script-src 'self'${isDev ? " 'unsafe-eval'" : ""} 'unsafe-inline'`;
3
+ // SECURITY HEADERS / CSP NOTE:
4
+ // All security headers — including the Content-Security-Policy — are set in
5
+ // src/middleware.ts, which is the SINGLE SOURCE OF TRUTH for them. The CSP is
6
+ // per-request and nonce-based ('strict-dynamic'), which a static headers() block
7
+ // here cannot express, and emitting a CSP from both places would produce a
8
+ // conflicting duplicate Content-Security-Policy header. Do NOT add a headers()
9
+ // CSP back here. HSTS is managed at the Cloudflare edge.
17
10
 
18
11
  const nextConfig: NextConfig = {
19
12
  output: "standalone",
@@ -24,34 +17,6 @@ const nextConfig: NextConfig = {
24
17
  // dynamic: 0 (still unconstrained) is what protects data pages — never raise it.
25
18
  staleTimes: { dynamic: 0, static: 30 },
26
19
  },
27
- async headers() {
28
- return [
29
- {
30
- source: "/(.*)",
31
- headers: [
32
- { key: "X-Frame-Options", value: "DENY" },
33
- { key: "X-Content-Type-Options", value: "nosniff" },
34
- { key: "Referrer-Policy", value: "origin-when-cross-origin" },
35
- { key: "X-XSS-Protection", value: "1; mode=block" },
36
- {
37
- key: "Content-Security-Policy",
38
- value: [
39
- "default-src 'self'",
40
- scriptSrc,
41
- "style-src 'self' 'unsafe-inline'",
42
- `img-src 'self' blob: data: https: ${apiOrigin}`,
43
- "font-src 'self'",
44
- "object-src 'none'",
45
- "base-uri 'self'",
46
- "form-action 'self'",
47
- "frame-ancestors 'none'",
48
- `connect-src 'self' ${apiOrigin}`,
49
- ].join("; "),
50
- },
51
- ],
52
- },
53
- ];
54
- },
55
20
  };
56
21
 
57
22
  export default nextConfig;