create-tigra 2.7.2 → 3.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 (54) hide show
  1. package/README.md +10 -3
  2. package/bin/create-tigra.js +77 -37
  3. package/package.json +5 -5
  4. package/template/_claude/commands/create-server.md +8 -2
  5. package/template/_claude/rules/client/01-project-structure.md +12 -0
  6. package/template/_claude/rules/client/03-data-and-state.md +44 -5
  7. package/template/_claude/rules/client/04-design-system.md +23 -0
  8. package/template/_claude/rules/client/05-security.md +1 -1
  9. package/template/_claude/rules/client/07-deployment.md +99 -0
  10. package/template/_claude/rules/client/08-lockfile-cross-platform.md +79 -0
  11. package/template/_claude/rules/client/core.md +1 -0
  12. package/template/_claude/rules/global/core.md +20 -1
  13. package/template/_claude/rules/global/investigation-before-conclusions.md +57 -0
  14. package/template/_claude/rules/server/core.md +2 -0
  15. package/template/_claude/rules/server/deployment.md +78 -0
  16. package/template/client/next.config.ts +15 -2
  17. package/template/client/package-lock.json +12345 -0
  18. package/template/client/package.json +3 -2
  19. package/template/client/src/app/globals.css +8 -0
  20. package/template/client/src/app/layout.tsx +7 -1
  21. package/template/client/src/app/providers.tsx +5 -4
  22. package/template/client/src/components/common/SafeImage.tsx +2 -1
  23. package/template/client/src/features/admin/hooks/useAdminSessions.ts +3 -0
  24. package/template/client/src/features/admin/hooks/useAdminUsers.ts +5 -0
  25. package/template/client/src/features/auth/components/AuthInitializer.tsx +27 -44
  26. package/template/client/src/features/auth/hooks/useAuth.ts +6 -2
  27. package/template/client/src/features/auth/hooks/useCurrentUser.ts +50 -0
  28. package/template/client/src/lib/api/axios.config.ts +19 -4
  29. package/template/client/src/middleware.ts +7 -0
  30. package/template/gitignore +1 -0
  31. package/template/server/.env.example +42 -0
  32. package/template/server/.env.example.production +40 -0
  33. package/template/server/Dockerfile +29 -5
  34. package/template/server/docker-compose.yml +15 -4
  35. package/template/server/package-lock.json +6544 -6823
  36. package/template/server/package.json +76 -76
  37. package/template/server/prisma/seed.ts +20 -4
  38. package/template/server/src/app.ts +41 -15
  39. package/template/server/src/config/env.ts +72 -28
  40. package/template/server/src/config/rate-limit.config.ts +17 -0
  41. package/template/server/src/libs/__tests__/http.test.ts +23 -9
  42. package/template/server/src/libs/__tests__/origin-check.test.ts +53 -0
  43. package/template/server/src/libs/auth.ts +15 -18
  44. package/template/server/src/libs/cookies.ts +1 -1
  45. package/template/server/src/libs/duration.ts +30 -0
  46. package/template/server/src/libs/ip-block.ts +10 -4
  47. package/template/server/src/libs/origin-check.ts +38 -0
  48. package/template/server/src/libs/redis.ts +1 -1
  49. package/template/server/src/modules/auth/__tests__/auth.service.test.ts +274 -44
  50. package/template/server/src/modules/auth/auth.controller.ts +16 -5
  51. package/template/server/src/modules/auth/auth.repo.ts +2 -0
  52. package/template/server/src/modules/auth/auth.service.ts +103 -12
  53. package/template/server/src/test/setup.ts +22 -2
  54. package/template/server/vitest.config.ts +43 -43
@@ -0,0 +1,57 @@
1
+ > **SCOPE**: These rules apply to the **entire workspace** (server + client). Always active.
2
+
3
+ # Investigation Before Conclusions
4
+
5
+ This project (create-tigra) generates starter templates for developers who may not have deep coding experience. They trust AI output without questioning it. **A wrong suggestion that "fixes" a non-existent problem can introduce real problems.** Every recommendation must be grounded in verified understanding of how the code actually works.
6
+
7
+ ---
8
+
9
+ ## The Rule
10
+
11
+ **Never suggest fixes, changes, or improvements until you have fully traced how the relevant system works in this codebase.** Seeing a file, a config, or a pattern is not enough. You must follow the code path end-to-end before making any claim.
12
+
13
+ ---
14
+
15
+ ## Before Answering "Is This a Bug?" or "Does This Need Fixing?"
16
+
17
+ 1. **Trace the actual workflow.** If the question is about uploads, go read the upload service, follow where files are saved, how they're served, how they're deleted. If it's about auth, trace the full auth flow. Don't stop at the first file you find.
18
+
19
+ 2. **Understand the runtime environment.** Ask yourself: does this code run in Docker or locally? Is this a dev tool or a production path? Does docker-compose run the server or just infrastructure services (MySQL, Redis)? Don't assume — verify.
20
+
21
+ 3. **Verify the problem exists in the real workflow.** Not in theory, not in a hypothetical scenario — in the actual way developers use this project. If no one would ever hit the issue in normal usage, it's not a problem worth fixing.
22
+
23
+ 4. **Don't pattern-match to conclusions.** "Uploads + Docker + no volume = must fix" is pattern-matching, not investigation. The server runs locally with `npm run dev`, not inside Docker. The `docker-compose.yml` is for MySQL and Redis only. A volume for uploads in docker-compose would solve nothing.
24
+
25
+ 5. **If you're unsure, say so.** "I need to check how this works before I can answer" is always better than a confident wrong answer.
26
+
27
+ ---
28
+
29
+ ## What NOT to Do
30
+
31
+ | Bad behavior | Why it's dangerous |
32
+ |---|---|
33
+ | See a Dockerfile, immediately suggest `VOLUME` | The server may not run in Docker locally |
34
+ | See docker-compose.yml, suggest adding volumes | docker-compose may only run infrastructure, not the app |
35
+ | Find a missing config and assume it's a bug | It may be intentionally absent because it's not needed |
36
+ | Suggest "best practice" improvements unprompted | Unnecessary changes confuse beginners and can introduce real bugs |
37
+ | Stop researching after finding the first related file | The first file is not the full picture — trace the complete flow |
38
+ | Offer a fix before confirming the problem is real | Fixing non-existent problems wastes time and creates new problems |
39
+
40
+ ---
41
+
42
+ ## The Standard
43
+
44
+ Before every suggestion, ask yourself:
45
+
46
+ 1. **Did I trace the full code path?** Not just one file — the whole flow.
47
+ 2. **Do I understand the runtime environment?** Where does this code actually run?
48
+ 3. **Would a real developer actually hit this problem?** In normal usage, not edge cases.
49
+ 4. **Am I solving a real problem or a theoretical one?**
50
+
51
+ If the answer to any of these is "no" — keep investigating before responding.
52
+
53
+ ---
54
+
55
+ ## Why This Matters
56
+
57
+ create-tigra exists to help developers who are learning to code with AI assistance. These developers will trust your suggestions without pushback. A confident but wrong suggestion — like adding a Docker volume for a service that doesn't run in Docker — will send them down a rabbit hole debugging something that was never broken. **Your job is to understand what actually works and why, not to guess based on patterns.**
@@ -17,6 +17,7 @@
17
17
  | Writing service or business logic | `project-conventions.md` (Layer Responsibilities) |
18
18
  | Changing DB schema, migrations, indexes | `database.md` |
19
19
  | Adding or changing API endpoints | `project-conventions.md` (Postman Collection) |
20
+ | Adding dependencies, changing ports, entry points, or env vars | `deployment.md` |
20
21
  | Unsure where to start | This file |
21
22
 
22
23
  ---
@@ -48,3 +49,4 @@ Request
48
49
  5. **Logging**: Use `logger` from `src/libs/logger`. Never `console.log`.
49
50
  6. **Routes**: All prefixed with `/api/v1`. Registered as Fastify plugins.
50
51
  7. **Postman**: Every new or modified endpoint must be reflected in `postman/collection.json`. Create the collection if it doesn't exist.
52
+ 8. **Deployment**: Every change must remain compatible with the Dockerfile. Read `deployment.md` when adding system dependencies, changing ports, renaming entry points, or adding env vars.
@@ -0,0 +1,78 @@
1
+ > **SCOPE**: These rules apply specifically to the **server** directory.
2
+
3
+ # Deployment & Docker
4
+
5
+ This project is deployed via **Docker** on **Coolify** (or any Docker-based platform). The `Dockerfile` is the production deployment contract. Every code change must remain compatible with it.
6
+
7
+ ---
8
+
9
+ ## Dockerfile Architecture
10
+
11
+ The server uses a **3-stage multi-stage build**:
12
+
13
+ ```
14
+ Stage 1 (dependencies) → Installs prod-only node_modules (cached layer)
15
+ Stage 2 (builder) → Installs all deps, generates Prisma client, compiles TypeScript
16
+ Stage 3 (production) → Alpine + dumb-init, non-root user, copies dist + prod node_modules + Prisma
17
+ ```
18
+
19
+ **Entry point**: the container `CMD` runs `npx prisma migrate deploy` and then starts `node dist/server.js` — pending migrations are applied automatically on every container boot (migrate-on-boot).
20
+ **Health check**: `GET /api/v1/live` — this endpoint MUST always exist and return 200.
21
+
22
+ ---
23
+
24
+ ## When to Update the Dockerfile
25
+
26
+ | You did this... | Update Dockerfile? | What to change |
27
+ |---|---|---|
28
+ | Added a new npm dependency | No | Automatic — `npm ci` installs from `package.json` |
29
+ | Added a native/system dependency (e.g., `sharp`, `bcrypt`) | **Yes** | Add `apk add` in the production stage for required system libraries |
30
+ | Changed the build command or output directory | **Yes** | Update the `RUN npm run build` or `COPY` paths in stage 2/3 |
31
+ | Changed the entry point file (e.g., renamed `server.ts`) | **Yes** | Update the `CMD` to run `dist/<new-name>.js` (keep the `prisma migrate deploy` step before it) |
32
+ | Changed the default port | **Yes** | Update `EXPOSE` and the `HEALTHCHECK` port |
33
+ | Added/renamed a health check endpoint | **Yes** | Update the `HEALTHCHECK` URL path |
34
+ | Added files needed at runtime (e.g., templates, static assets) | **Yes** | Add a `COPY` line in stage 3 |
35
+ | Changed Prisma schema | No | Automatic — `npx prisma generate` runs in stage 2 |
36
+ | Added a new env var | Maybe | If it's needed at **build time**, add `ARG` + `ENV` in the builder stage |
37
+ | Added file upload functionality | **Yes** | Add a `VOLUME` directive or ensure the upload directory is writable |
38
+
39
+ ---
40
+
41
+ ## Critical Rules
42
+
43
+ 1. **Health endpoint is sacred.** The route `GET /api/v1/live` must always exist and return HTTP 200. Coolify, Docker, and load balancers use it to determine if the container is alive. Never remove, rename, or gate it behind auth.
44
+
45
+ 2. **Never break the build chain.** If you rename the build output directory, the entry file, or change `tsconfig.json` `outDir`, update the Dockerfile `COPY` paths and `CMD` accordingly.
46
+
47
+ 3. **System dependencies must be explicit.** If a new npm package requires native binaries (e.g., `sharp` needs `libvips`, `bcrypt` needs `build-base`), add `apk add --no-cache <package>` in the production stage. The build will succeed locally but fail in Docker without this.
48
+
49
+ 4. **Non-root user.** The app runs as `nodejs:nodejs` (UID 1001). Any files the app needs to write (uploads, logs) must be in directories owned by this user. Add `RUN mkdir -p /app/<dir> && chown nodejs:nodejs /app/<dir>` if needed.
50
+
51
+ 5. **No secrets in the image.** Environment variables are injected at runtime via Coolify/Docker. Never hardcode secrets, never `COPY .env`, never use `ENV` for sensitive values. Only use `ARG`/`ENV` for non-secret build-time config.
52
+
53
+ 6. **Keep `.dockerignore` in sync.** When adding new directories or file types that should NOT be in the Docker build context (test fixtures, docs, local scripts), add them to `.dockerignore`. When adding files that ARE needed at build time, make sure they're not ignored.
54
+
55
+ 7. **Port consistency.** The default port is `8000`. If you change the port in `src/config/env.ts`, also update `EXPOSE` and the `HEALTHCHECK` in the Dockerfile.
56
+
57
+ ---
58
+
59
+ ## Coolify-Specific Notes
60
+
61
+ - **Environment variables**: Set in Coolify's UI, injected at container runtime. No `.env` file needed.
62
+ - **Build arguments**: For build-time vars, use Coolify's "Build Arguments" section → maps to `docker build --build-arg`.
63
+ - **Persistent storage**: For file uploads, mount a volume in Coolify to `/app/uploads`. Add to Dockerfile: `RUN mkdir -p /app/uploads && chown nodejs:nodejs /app/uploads` before `USER nodejs`.
64
+ - **Database migrations**: Applied automatically at container startup — the Dockerfile `CMD` runs `npx prisma migrate deploy` before starting the server, so no Coolify configuration is needed. (Alternative: remove the migrate step from the `CMD` and run `npx prisma migrate deploy` as a pre-deploy command in Coolify instead.)
65
+
66
+ ---
67
+
68
+ ## Files That Matter for Deployment
69
+
70
+ | File | Purpose | Must exist? |
71
+ |---|---|---|
72
+ | `Dockerfile` | Production build instructions | Yes |
73
+ | `.dockerignore` | Excludes files from Docker build context | Yes |
74
+ | `package.json` | Dependencies and build script | Yes |
75
+ | `tsconfig.json` | TypeScript compilation config | Yes |
76
+ | `prisma/schema.prisma` | Database schema (copied to runtime) | Yes |
77
+ | `prisma/migrations/` | Migration files (copied to runtime) | Yes |
78
+ | `src/server.ts` | Entry point (compiled to `dist/server.js`) | Yes |
@@ -9,8 +9,21 @@ const apiOrigin = (() => {
9
9
  }
10
10
  })();
11
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'`;
17
+
12
18
  const nextConfig: NextConfig = {
13
19
  output: "standalone",
20
+ experimental: {
21
+ // Next 16.2+ rejects staleTimes.static below 30 (config schema enforces gte(30));
22
+ // an invalid value is ignored entirely, silently re-enabling the Router Cache.
23
+ // 30s is the closest allowed to "never serve stale RSC payloads on back-navigation".
24
+ // dynamic: 0 (still unconstrained) is what protects data pages — never raise it.
25
+ staleTimes: { dynamic: 0, static: 30 },
26
+ },
14
27
  async headers() {
15
28
  return [
16
29
  {
@@ -24,9 +37,9 @@ const nextConfig: NextConfig = {
24
37
  key: "Content-Security-Policy",
25
38
  value: [
26
39
  "default-src 'self'",
27
- "script-src 'self' 'unsafe-eval' 'unsafe-inline'",
40
+ scriptSrc,
28
41
  "style-src 'self' 'unsafe-inline'",
29
- "img-src 'self' blob: data: https:",
42
+ `img-src 'self' blob: data: https: ${apiOrigin}`,
30
43
  "font-src 'self'",
31
44
  "object-src 'none'",
32
45
  "base-uri 'self'",