create-tigra 3.0.2 → 3.0.3

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 (33) hide show
  1. package/package.json +1 -1
  2. package/template/client/.env.example +19 -0
  3. package/template/client/Dockerfile +3 -3
  4. package/template/client/next.config.ts +7 -42
  5. package/template/client/package-lock.json +1896 -146
  6. package/template/client/package.json +2 -0
  7. package/template/client/src/app/layout.tsx +10 -3
  8. package/template/client/src/app/providers.tsx +15 -2
  9. package/template/client/src/instrumentation-client.ts +30 -0
  10. package/template/client/src/instrumentation.ts +38 -0
  11. package/template/client/src/lib/env.ts +13 -2
  12. package/template/client/src/middleware.ts +105 -18
  13. package/template/server/.env.example +22 -1
  14. package/template/server/.env.example.production +16 -1
  15. package/template/server/Dockerfile +7 -5
  16. package/template/server/package-lock.json +2136 -86
  17. package/template/server/package.json +6 -0
  18. package/template/server/src/app.ts +30 -11
  19. package/template/server/src/config/env.ts +23 -2
  20. package/template/server/src/config/rate-limit.config.ts +6 -0
  21. package/template/server/src/libs/logger.ts +15 -0
  22. package/template/server/src/libs/observability/sentry.ts +42 -0
  23. package/template/server/src/libs/requestLogger.ts +8 -2
  24. package/template/server/src/libs/storage/file-storage.service.ts +144 -16
  25. package/template/server/src/modules/admin/__tests__/admin.integration.test.ts +128 -0
  26. package/template/server/src/modules/auth/__tests__/auth.integration.test.ts +138 -0
  27. package/template/server/src/modules/files/__tests__/files.integration.test.ts +157 -0
  28. package/template/server/src/modules/files/files.controller.ts +180 -0
  29. package/template/server/src/modules/files/files.routes.ts +46 -0
  30. package/template/server/src/server.ts +6 -0
  31. package/template/server/src/test/integration.setup.ts +170 -0
  32. package/template/server/vitest.config.ts +10 -1
  33. package/template/server/vitest.integration.config.ts +50 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-tigra",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
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
@@ -7,7 +7,7 @@
7
7
  # ===================================================================
8
8
  # Stage 1: Dependencies (cached layer)
9
9
  # ===================================================================
10
- FROM node:20-alpine AS dependencies
10
+ FROM node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS dependencies
11
11
 
12
12
  WORKDIR /app
13
13
 
@@ -26,7 +26,7 @@ RUN if [ -f pnpm-lock.yaml ]; then \
26
26
  # ===================================================================
27
27
  # Stage 2: Build (compile Next.js)
28
28
  # ===================================================================
29
- FROM node:20-alpine AS builder
29
+ FROM node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS builder
30
30
 
31
31
  WORKDIR /app
32
32
 
@@ -54,7 +54,7 @@ RUN npm run build
54
54
  # ===================================================================
55
55
  # Stage 3: Production Runtime
56
56
  # ===================================================================
57
- FROM node:20-alpine AS production
57
+ FROM node:20-alpine@sha256:fb4cd12c85ee03686f6af5362a0b0d56d50c58a04632e6c0fb8363f609372293 AS production
58
58
 
59
59
  # Install dumb-init for proper signal handling
60
60
  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;