@next-friday/create-app 2.0.0 → 2.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 (86) hide show
  1. package/README.md +16 -15
  2. package/dist/main.mjs +18 -7
  3. package/package.json +2 -2
  4. package/templates/base/pnpm-workspace.yaml +24 -2
  5. package/templates/payload/README.md +1 -1
  6. package/templates/payload/package.json +0 -1
  7. package/templates/payload/src/payload.config.test.ts +31 -0
  8. package/templates/turborepo/.agents/rules/typescript-first.md +7 -0
  9. package/templates/turborepo/.agents/rules.json +41 -0
  10. package/templates/turborepo/.claude/rules/deterministic-testing.md +21 -0
  11. package/templates/turborepo/.claude/rules/typescript-first.md +15 -0
  12. package/templates/turborepo/.cursor/rules/deterministic-testing.mdc +21 -0
  13. package/templates/turborepo/.cursor/rules/typescript-first.mdc +13 -0
  14. package/templates/turborepo/.dockerignore +12 -0
  15. package/templates/turborepo/.editorconfig-checker.json +3 -0
  16. package/templates/turborepo/.env.example +4 -0
  17. package/templates/turborepo/.github/ISSUE_TEMPLATE/bug.yml +66 -0
  18. package/templates/turborepo/.github/ISSUE_TEMPLATE/feature.yml +51 -0
  19. package/templates/turborepo/.github/dependabot.yml +79 -0
  20. package/templates/turborepo/.github/labeler.yml +25 -0
  21. package/templates/turborepo/.github/pull_request_template.md +25 -0
  22. package/templates/turborepo/.github/scripts/affected-apps.sh +31 -0
  23. package/templates/turborepo/.github/workflows/ci.yml +300 -0
  24. package/templates/turborepo/.github/workflows/deploy.yml +200 -0
  25. package/templates/turborepo/.github/workflows/sast.yml +46 -0
  26. package/templates/turborepo/.lintstagedrc.json +11 -0
  27. package/templates/turborepo/.prettierignore +5 -0
  28. package/templates/turborepo/AGENTS.md +20 -0
  29. package/templates/turborepo/CONTRIBUTING.md +58 -0
  30. package/templates/turborepo/README.md +114 -0
  31. package/templates/turborepo/_gitignore +53 -0
  32. package/templates/turborepo/apps/app/.dependency-cruiser.json +34 -0
  33. package/templates/turborepo/apps/app/Dockerfile +25 -0
  34. package/templates/turborepo/apps/app/app/favicon.ico +0 -0
  35. package/templates/turborepo/apps/app/app/globals.css +26 -0
  36. package/templates/turborepo/apps/app/app/health/route.test.ts +20 -0
  37. package/templates/turborepo/apps/app/app/health/route.ts +23 -0
  38. package/templates/turborepo/apps/app/app/layout.tsx +29 -0
  39. package/templates/turborepo/apps/app/app/page.test.ts +11 -0
  40. package/templates/turborepo/apps/app/app/page.tsx +8 -0
  41. package/templates/turborepo/apps/app/next.config.ts +40 -0
  42. package/templates/turborepo/apps/app/package.json +41 -0
  43. package/templates/turborepo/apps/app/playwright.config.ts +27 -0
  44. package/templates/turborepo/apps/app/postcss.config.mjs +7 -0
  45. package/templates/turborepo/apps/app/test/home.e2e.test.ts +11 -0
  46. package/templates/turborepo/apps/app/tsconfig.json +33 -0
  47. package/templates/turborepo/apps/app/vitest.config.ts +12 -0
  48. package/templates/turborepo/apps/backoffice/.dependency-cruiser.json +34 -0
  49. package/templates/turborepo/apps/backoffice/Dockerfile +28 -0
  50. package/templates/turborepo/apps/backoffice/next.config.ts +48 -0
  51. package/templates/turborepo/apps/backoffice/package.json +49 -0
  52. package/templates/turborepo/apps/backoffice/playwright.config.ts +27 -0
  53. package/templates/turborepo/apps/backoffice/src/app/(frontend)/layout.tsx +18 -0
  54. package/templates/turborepo/apps/backoffice/src/app/(frontend)/page.test.ts +14 -0
  55. package/templates/turborepo/apps/backoffice/src/app/(frontend)/page.tsx +14 -0
  56. package/templates/turborepo/apps/backoffice/src/app/(frontend)/styles.css +15 -0
  57. package/templates/turborepo/apps/backoffice/src/app/(payload)/admin/[[...segments]]/not-found.tsx +24 -0
  58. package/templates/turborepo/apps/backoffice/src/app/(payload)/admin/[[...segments]]/page.tsx +24 -0
  59. package/templates/turborepo/apps/backoffice/src/app/(payload)/admin/importMap.ts +6 -0
  60. package/templates/turborepo/apps/backoffice/src/app/(payload)/api/[...slug]/route.ts +19 -0
  61. package/templates/turborepo/apps/backoffice/src/app/(payload)/custom.scss +0 -0
  62. package/templates/turborepo/apps/backoffice/src/app/(payload)/layout.tsx +31 -0
  63. package/templates/turborepo/apps/backoffice/src/app/health/route.test.ts +20 -0
  64. package/templates/turborepo/apps/backoffice/src/app/health/route.ts +23 -0
  65. package/templates/turborepo/apps/backoffice/src/collections/media.test.ts +27 -0
  66. package/templates/turborepo/apps/backoffice/src/collections/media.ts +18 -0
  67. package/templates/turborepo/apps/backoffice/src/collections/users.test.ts +10 -0
  68. package/templates/turborepo/apps/backoffice/src/collections/users.ts +10 -0
  69. package/templates/turborepo/apps/backoffice/src/environment.test.ts +32 -0
  70. package/templates/turborepo/apps/backoffice/src/environment.ts +27 -0
  71. package/templates/turborepo/apps/backoffice/src/migrations/20261030_005055_initial.json +969 -0
  72. package/templates/turborepo/apps/backoffice/src/migrations/20261030_005055_initial.ts +134 -0
  73. package/templates/turborepo/apps/backoffice/src/migrations/index.ts +9 -0
  74. package/templates/turborepo/apps/backoffice/src/payload-types.ts +339 -0
  75. package/templates/turborepo/apps/backoffice/src/payload.config.test.ts +31 -0
  76. package/templates/turborepo/apps/backoffice/src/payload.config.ts +50 -0
  77. package/templates/turborepo/apps/backoffice/test/home.e2e.test.ts +16 -0
  78. package/templates/turborepo/apps/backoffice/tsconfig.json +34 -0
  79. package/templates/turborepo/apps/backoffice/vitest.config.ts +19 -0
  80. package/templates/turborepo/eslint.config.ts +40 -0
  81. package/templates/turborepo/knip.json +9 -0
  82. package/templates/turborepo/package.json +70 -0
  83. package/templates/turborepo/pnpm-workspace.yaml +46 -0
  84. package/templates/turborepo/prettier.config.ts +11 -0
  85. package/templates/turborepo/tsconfig.json +16 -0
  86. package/templates/turborepo/turbo.json +45 -0
package/README.md CHANGED
@@ -16,12 +16,13 @@ Without a terminal, as in CI or an agent, the name and `--stack` are required. P
16
16
 
17
17
  ## Stacks
18
18
 
19
- | `--stack` | Starts with |
20
- | :-------- | :---------------------------------------------------------------- |
21
- | `nodejs` | A TypeScript HTTP server on `node:http` with a `/health` endpoint |
22
- | `nestjs` | A NestJS app with a Terminus `/health` endpoint |
23
- | `nextjs` | A Next.js App Router app with React and Tailwind CSS |
24
- | `payload` | Payload CMS on Next.js with PostgreSQL |
19
+ | `--stack` | Starts with |
20
+ | :---------- | :---------------------------------------------------------------- |
21
+ | `nodejs` | A TypeScript HTTP server on `node:http` with a `/health` endpoint |
22
+ | `nestjs` | A NestJS app with a Terminus `/health` endpoint |
23
+ | `nextjs` | A Next.js App Router app with React and Tailwind CSS |
24
+ | `payload` | Payload CMS on Next.js with PostgreSQL |
25
+ | `turborepo` | A Turborepo workspace with a Next.js app and a Payload backoffice |
25
26
 
26
27
  Every stack is built from [`templates/base`](templates/base), which holds the shared company setup, plus its own directory under [`templates/`](templates), which holds the stack-specific files.
27
28
 
@@ -43,17 +44,17 @@ Every stack is built from [`templates/base`](templates/base), which holds the sh
43
44
  ## Options
44
45
 
45
46
  ```text
46
- pnpm create @next-friday/app [name] [--stack nodejs|nestjs|nextjs|payload]
47
+ pnpm create @next-friday/app [name] [--stack nodejs|nestjs|nextjs|payload|turborepo]
47
48
  ```
48
49
 
49
- | Option | Description |
50
- | :--------------- | :--------------------------------------------------------------- |
51
- | `name` | Project directory and package name. Asked when left out. |
52
- | `--stack` | `nodejs`, `nestjs`, `nextjs`, or `payload`. Asked when left out. |
53
- | `--skip-git` | Do not run `git init`. |
54
- | `--skip-install` | Do not run `pnpm install`. |
55
- | `-v, --version` | Print the version. |
56
- | `-h, --help` | Print the usage. |
50
+ | Option | Description |
51
+ | :--------------- | :---------------------------------------------------------------------------- |
52
+ | `name` | Project directory and package name. Asked when left out. |
53
+ | `--stack` | `nodejs`, `nestjs`, `nextjs`, `payload`, or `turborepo`. Asked when left out. |
54
+ | `--skip-git` | Do not run `git init`. |
55
+ | `--skip-install` | Do not run `pnpm install`. |
56
+ | `-v, --version` | Print the version. |
57
+ | `-h, --help` | Print the usage. |
57
58
 
58
59
  The name must:
59
60
 
package/dist/main.mjs CHANGED
@@ -12,29 +12,40 @@ const stacks = [
12
12
  {
13
13
  id: "nodejs",
14
14
  label: "Node.js",
15
- hint: "HTTP service without a framework"
15
+ hint: "HTTP service without a framework",
16
+ requiresDatabase: false
16
17
  },
17
18
  {
18
19
  id: "nestjs",
19
20
  label: "NestJS",
20
- hint: "HTTP API"
21
+ hint: "HTTP API",
22
+ requiresDatabase: false
21
23
  },
22
24
  {
23
25
  id: "nextjs",
24
26
  label: "Next.js",
25
- hint: "Web app"
27
+ hint: "Web app",
28
+ requiresDatabase: false
26
29
  },
27
30
  {
28
31
  id: "payload",
29
32
  label: "Payload",
30
- hint: "Headless CMS on Next.js and PostgreSQL"
33
+ hint: "Headless CMS on Next.js and PostgreSQL",
34
+ requiresDatabase: true
35
+ },
36
+ {
37
+ id: "turborepo",
38
+ label: "Turborepo",
39
+ hint: "Next.js app and Payload backoffice",
40
+ requiresDatabase: true
31
41
  }
32
42
  ];
33
43
  const developmentScripts = {
34
44
  nodejs: "start:dev",
35
45
  nestjs: "start:dev",
36
46
  nextjs: "dev",
37
- payload: "dev"
47
+ payload: "dev",
48
+ turborepo: "dev"
38
49
  };
39
50
  /**
40
51
  * Check whether a string names a supported stack.
@@ -131,7 +142,7 @@ function ownEntries(directory) {
131
142
  return readdirSync(directory).filter((entry) => entry !== ".git");
132
143
  }
133
144
  // src/arguments.ts
134
- const usage = `Usage: pnpm create @next-friday/app [name] [--stack nodejs|nestjs|nextjs|payload]
145
+ const usage = `Usage: pnpm create @next-friday/app [name] [--stack nodejs|nestjs|nextjs|payload|turborepo]
135
146
 
136
147
  name Project directory and package name, or . for the current directory. Asked when left out.
137
148
  --stack Template stack. Asked when left out.
@@ -368,7 +379,7 @@ function nextSteps(name, stack, git, isInstalled) {
368
379
  hasGit && isInstalled ? [] : ["pnpm install"],
369
380
  [`pnpm ${developmentScripts[stack]}`]
370
381
  ].flat();
371
- const database = stack === "payload" ? `Set DATABASE_URL in .env to your PostgreSQL database before pnpm ${developmentScripts[stack]}.\n` : "";
382
+ const database = stacks.find((item) => item.id === stack)?.requiresDatabase ? `Set DATABASE_URL in .env to your PostgreSQL database before pnpm ${developmentScripts[stack]}.\n` : "";
372
383
  const readme = name === "." ? "README.md" : `${name}/README.md`;
373
384
  return `Next steps:\n${commands.map((command) => ` ${command}`).join("\n")}\n${database}Before the first commit, follow "After creating a project from this template" in ${readme}.`;
374
385
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@next-friday/create-app",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "Create a Next Friday project from a template.",
5
5
  "keywords": [
6
6
  "create",
@@ -52,7 +52,7 @@
52
52
  "prettier": "3.9.10",
53
53
  "publint": "0.3.25",
54
54
  "sort-package-json": "4.1.0",
55
- "tsdown": "0.23.1",
55
+ "tsdown": "0.23.2",
56
56
  "typescript": "6.0.3",
57
57
  "vitest": "5.0.5"
58
58
  },
@@ -10,12 +10,34 @@ overrides:
10
10
  "esbuild@<0.27.0": ^0.28.2
11
11
  "graphql-scalars@<2.0.1": ^2.0.1
12
12
  "happy-dom@<21.0.4": ^21.0.4
13
+ "minimatch@<11.0.1": ^11.0.1
13
14
  minimumReleaseAgeExclude:
14
15
  - "@next-friday/commitlint-config-friday@4.0.0"
15
16
  - "@next-friday/eslint-config-friday@5.0.0"
16
17
  - "@next-friday/eslint-config-friday@5.1.0"
17
18
  - "@next-friday/prettier-config-friday@4.0.0"
18
19
  - "@next-friday/eslint-plugin-friday@1.1.3"
20
+ packageExtensions:
21
+ payload:
22
+ peerDependenciesMeta:
23
+ graphql:
24
+ optional: true
25
+ "@payloadcms/next":
26
+ peerDependenciesMeta:
27
+ graphql:
28
+ optional: true
29
+ "@payloadcms/graphql":
30
+ peerDependenciesMeta:
31
+ graphql:
32
+ optional: true
33
+ graphql-http:
34
+ peerDependenciesMeta:
35
+ graphql:
36
+ optional: true
37
+ graphql-scalars:
38
+ peerDependenciesMeta:
39
+ graphql:
40
+ optional: true
19
41
  peerDependencyRules:
20
- allowedVersions:
21
- graphql: 17.0.2
42
+ ignoreMissing:
43
+ - graphql
@@ -1,6 +1,6 @@
1
1
  # next-friday-template-payload
2
2
 
3
- Next Friday starter for Payload CMS on Next.js and PostgreSQL.
3
+ Next Friday starter for Payload CMS on Next.js and PostgreSQL. The API is REST at `/api`.
4
4
 
5
5
  ## Getting started
6
6
 
@@ -48,7 +48,6 @@
48
48
  "@payloadcms/db-postgres": "3.92.1",
49
49
  "@payloadcms/next": "3.92.1",
50
50
  "@payloadcms/richtext-lexical": "3.92.1",
51
- "graphql": "17.0.2",
52
51
  "next": "16.4.3",
53
52
  "payload": "3.92.1",
54
53
  "react": "19.3.1",
@@ -0,0 +1,31 @@
1
+ import {afterEach, describe, expect, it, vi} from "vitest";
2
+ import {readFileSync} from "node:fs";
3
+
4
+ interface PackageManifest {
5
+ dependencies?: Record<string, string>;
6
+ }
7
+
8
+ afterEach(() => {
9
+ vi.unstubAllEnvs();
10
+ });
11
+
12
+ describe("payload config", () => {
13
+ it("keeps the HTTP API on REST", async () => {
14
+ vi.stubEnv("APP_URL", "http://localhost:3000");
15
+ vi.stubEnv("PAYLOAD_SECRET", "test-secret");
16
+ vi.stubEnv("DATABASE_URL", "postgres://postgres:postgres@127.0.0.1:5432/payload");
17
+
18
+ const {default: config} = await import("./payload.config");
19
+ const resolved = await config;
20
+
21
+ expect(resolved.graphQL.disable).toBe(true);
22
+ });
23
+
24
+ it("does not add an extra peer dependency", () => {
25
+ const manifest = JSON.parse(
26
+ readFileSync(new URL("../package.json", import.meta.url), "utf8"),
27
+ ) as PackageManifest;
28
+
29
+ expect(manifest.dependencies?.graphql).toBeUndefined();
30
+ });
31
+ });
@@ -0,0 +1,7 @@
1
+ # TypeScript-First
2
+
3
+ In a TypeScript-capable app or package, write source, tests, and scripts as `.ts`, and JSX as `.tsx`. Use that extension for new work and for any JavaScript file whose implementation this change already touches, then update its imports, scripts, tests, and configuration in the same change.
4
+
5
+ Keep other languages in separately maintained components. Use a non-TypeScript extension when the runtime, tool, or public contract requires it.
6
+
7
+ _Completion criterion_: Every file this change created or materially rewrote in a TypeScript-capable project uses the TypeScript extension the runtime accepts, and its imports and scripts resolve.
@@ -0,0 +1,41 @@
1
+ {
2
+ "automation-owned-checks": {
3
+ "description": "Owned checks: hooks and CI define what must pass; run checks by hand to verify"
4
+ },
5
+ "code-comments": {
6
+ "description": "Required comments: comment only where a tool or rule needs it, or for a reason the code cannot show"
7
+ },
8
+ "current-state-authority": {
9
+ "description": "Current state: implement from user requirements and the working tree"
10
+ },
11
+ "demand-driven-configuration": {
12
+ "description": "Demand-driven configuration: add a setting only for an active requirement"
13
+ },
14
+ "dependency-security": {
15
+ "description": "Dependencies: add a package only when code or a contract uses it",
16
+ "globs": ["package.json", "pnpm-lock.yaml", "pnpm-workspace.yaml"]
17
+ },
18
+ "deterministic-testing": {
19
+ "description": "Test admission: add a case only when it catches a defect current tests miss",
20
+ "globs": ["**/*.test.ts", "**/*.test.tsx"]
21
+ },
22
+ "diagnostics-and-error-handling": {
23
+ "description": "Diagnostics: fix runtime failures at the source and keep the root cause"
24
+ },
25
+ "git-workflow": {
26
+ "description": "Git workflow: trunk-based branches, commits, and pull requests"
27
+ },
28
+ "no-suppression": {
29
+ "description": "Findings: fix scanner and linter reports without inline suppressions"
30
+ },
31
+ "script-driven-changes": {
32
+ "description": "Scripts: apply a repeated edit across many files with a script"
33
+ },
34
+ "single-author-style": {
35
+ "description": "Sibling style: match layout, naming, and composition in the same project"
36
+ },
37
+ "typescript-first": {
38
+ "description": "TypeScript-first: write source, tests, and scripts as .ts or .tsx",
39
+ "globs": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"]
40
+ }
41
+ }
@@ -0,0 +1,21 @@
1
+ ---
2
+ paths:
3
+ - "**/*.test.ts"
4
+ - "**/*.test.tsx"
5
+ ---
6
+
7
+ # Test Admission
8
+
9
+ Keep tests as small, deterministic protections for observable contracts.
10
+
11
+ Name the contract and the distinct defect a proposed test can detect before writing it. Admit a test for externally observable behavior, a public contract, a demonstrated regression, a non-trivial invariant, a meaningful failure mode, or an explicit repository verification requirement.
12
+
13
+ Choose the narrowest existing layer that owns that contract. Give each test one defect to detect. Add a case only when it catches a defect remaining cases miss. Treat coverage percentage as a measurement.
14
+
15
+ Search existing coverage first. Extend the file that already owns the contract. Create a file only when the contract has no owner or needs a different harness. Follow the nearest directory and naming pattern. Keep setup local until multiple tests share live runtime logic, then extract one helper.
16
+
17
+ Use the framework's standard assertions. Use an inline snippet unless filesystem paths, module resolution, or compiler services are the contract. Keep fixtures declarative and read-only.
18
+
19
+ When the user asks to run tests, run the narrowest owning file or filter.
20
+
21
+ _Completion criterion_: Every added or modified case maps to an admitted contract and a defect current cases would miss. Tests stay unchanged when no proposed case survives admission.
@@ -0,0 +1,15 @@
1
+ ---
2
+ paths:
3
+ - "**/*.ts"
4
+ - "**/*.tsx"
5
+ - "**/*.js"
6
+ - "**/*.jsx"
7
+ ---
8
+
9
+ # TypeScript-First
10
+
11
+ In a TypeScript-capable app or package, write source, tests, and scripts as `.ts`, and JSX as `.tsx`. Use that extension for new work and for any JavaScript file whose implementation this change already touches, then update its imports, scripts, tests, and configuration in the same change.
12
+
13
+ Keep other languages in separately maintained components. Use a non-TypeScript extension when the runtime, tool, or public contract requires it.
14
+
15
+ _Completion criterion_: Every file this change created or materially rewrote in a TypeScript-capable project uses the TypeScript extension the runtime accepts, and its imports and scripts resolve.
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: "Test admission: add a case only when it catches a defect current tests miss"
3
+ globs: "**/*.test.ts,**/*.test.tsx"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Test Admission
8
+
9
+ Keep tests as small, deterministic protections for observable contracts.
10
+
11
+ Name the contract and the distinct defect a proposed test can detect before writing it. Admit a test for externally observable behavior, a public contract, a demonstrated regression, a non-trivial invariant, a meaningful failure mode, or an explicit repository verification requirement.
12
+
13
+ Choose the narrowest existing layer that owns that contract. Give each test one defect to detect. Add a case only when it catches a defect remaining cases miss. Treat coverage percentage as a measurement.
14
+
15
+ Search existing coverage first. Extend the file that already owns the contract. Create a file only when the contract has no owner or needs a different harness. Follow the nearest directory and naming pattern. Keep setup local until multiple tests share live runtime logic, then extract one helper.
16
+
17
+ Use the framework's standard assertions. Use an inline snippet unless filesystem paths, module resolution, or compiler services are the contract. Keep fixtures declarative and read-only.
18
+
19
+ When the user asks to run tests, run the narrowest owning file or filter.
20
+
21
+ _Completion criterion_: Every added or modified case maps to an admitted contract and a defect current cases would miss. Tests stay unchanged when no proposed case survives admission.
@@ -0,0 +1,13 @@
1
+ ---
2
+ description: "TypeScript-first: write source, tests, and scripts as .ts or .tsx"
3
+ globs: "**/*.ts,**/*.tsx,**/*.js,**/*.jsx"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # TypeScript-First
8
+
9
+ In a TypeScript-capable app or package, write source, tests, and scripts as `.ts`, and JSX as `.tsx`. Use that extension for new work and for any JavaScript file whose implementation this change already touches, then update its imports, scripts, tests, and configuration in the same change.
10
+
11
+ Keep other languages in separately maintained components. Use a non-TypeScript extension when the runtime, tool, or public contract requires it.
12
+
13
+ _Completion criterion_: Every file this change created or materially rewrote in a TypeScript-capable project uses the TypeScript extension the runtime accepts, and its imports and scripts resolve.
@@ -0,0 +1,12 @@
1
+ node_modules
2
+ **/node_modules
3
+ **/.next
4
+ **/.turbo
5
+ **/coverage
6
+ **/.env
7
+ **/.env.*
8
+ !**/.env.example
9
+ .git
10
+ .github
11
+ **/*.test.ts
12
+ **/*.test.tsx
@@ -0,0 +1,3 @@
1
+ {
2
+ "Exclude": ["^apps/backoffice/src/migrations/", "^apps/backoffice/src/payload-types\\.ts$"]
3
+ }
@@ -0,0 +1,4 @@
1
+ # Copy to .env and fill in. List every environment variable the app reads, with a safe example value.
2
+ DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/payload
3
+ PAYLOAD_SECRET=
4
+ APP_URL=http://localhost:3001
@@ -0,0 +1,66 @@
1
+ name: Bug report
2
+ description: Report crashes, incorrect behavior, or setup problems.
3
+ labels: ["bug", "needs triage"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Reproduce the issue with the supported Node.js version.
9
+ Remove credentials, secrets, personal or customer data, and proprietary source code before submitting.
10
+ - type: checkboxes
11
+ id: preflight
12
+ attributes:
13
+ label: Before you submit
14
+ description: Confirm these items before submitting the report.
15
+ options:
16
+ - label: I searched existing issues and didn't find a matching report.
17
+ required: true
18
+ - label: I can reproduce this issue on the latest commit of the default branch.
19
+ required: true
20
+ - type: input
21
+ id: version
22
+ attributes:
23
+ label: Commit
24
+ placeholder: 769e0ef
25
+ validations:
26
+ required: true
27
+ - type: textarea
28
+ id: environment
29
+ attributes:
30
+ label: Environment
31
+ description: List Node.js, operating system, package manager, browser, and device.
32
+ placeholder: |
33
+ Node.js: 24.22.1
34
+ OS: Ubuntu 24.04 / macOS
35
+ Package manager: pnpm 12.6.0
36
+ Browser: Chrome on Android
37
+ validations:
38
+ required: true
39
+ - type: textarea
40
+ id: reproduction
41
+ attributes:
42
+ label: Minimal reproduction
43
+ description: Link to a minimal public reproduction or provide sanitized code and configuration that reproduce the issue.
44
+ validations:
45
+ required: true
46
+ - type: textarea
47
+ id: expected
48
+ attributes:
49
+ label: Expected behavior
50
+ description: Describe the behavior you expected.
51
+ validations:
52
+ required: true
53
+ - type: textarea
54
+ id: actual
55
+ attributes:
56
+ label: Actual behavior
57
+ description: Describe what happened, including errors and logs.
58
+ validations:
59
+ required: true
60
+ - type: checkboxes
61
+ id: safety
62
+ attributes:
63
+ label: Sensitive information
64
+ options:
65
+ - label: I removed credentials, secrets, personal or customer data, and proprietary code from this report.
66
+ required: true
@@ -0,0 +1,51 @@
1
+ name: Feature request
2
+ description: Suggest a specific change to next-friday-template-turborepo.
3
+ labels: ["enhancement", "needs triage"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Use this form for changes that are ready to evaluate.
9
+ - type: dropdown
10
+ id: scope
11
+ attributes:
12
+ label: Affected area
13
+ description: Select the area this request affects.
14
+ options:
15
+ - App pages and routes
16
+ - Backoffice collections and admin panel
17
+ - Components and styling
18
+ - Configuration and environment
19
+ - Tooling / CI
20
+ - Documentation
21
+ - Repository governance
22
+ validations:
23
+ required: true
24
+ - type: textarea
25
+ id: problem
26
+ attributes:
27
+ label: Problem
28
+ description: Describe the problem or use case.
29
+ validations:
30
+ required: true
31
+ - type: textarea
32
+ id: proposal
33
+ attributes:
34
+ label: Proposed change
35
+ description: Describe the smallest change that solves the problem.
36
+ validations:
37
+ required: true
38
+ - type: textarea
39
+ id: alternatives
40
+ attributes:
41
+ label: Alternatives considered
42
+ description: List existing options you considered.
43
+ validations:
44
+ required: false
45
+ - type: checkboxes
46
+ id: breaking
47
+ attributes:
48
+ label: Breaking change
49
+ description: Indicate whether this request changes behavior for existing users.
50
+ options:
51
+ - label: This request changes an existing page route, collection, API, or public contract.
@@ -0,0 +1,79 @@
1
+ version: 2
2
+
3
+ updates:
4
+ - package-ecosystem: npm
5
+ directory: /
6
+ schedule:
7
+ interval: weekly
8
+ day: monday
9
+ time: "09:00"
10
+ timezone: Asia/Bangkok
11
+ cooldown:
12
+ default-days: 7
13
+ open-pull-requests-limit: 10
14
+ commit-message:
15
+ prefix: chore
16
+ prefix-development: chore
17
+ include: scope
18
+ ignore:
19
+ - dependency-name: "*"
20
+ update-types:
21
+ - version-update:semver-major
22
+ groups:
23
+ minor-patch:
24
+ applies-to: version-updates
25
+ patterns:
26
+ - "*"
27
+ update-types:
28
+ - minor
29
+ - patch
30
+
31
+ - package-ecosystem: github-actions
32
+ directories:
33
+ - /
34
+ schedule:
35
+ interval: weekly
36
+ day: monday
37
+ time: "09:30"
38
+ timezone: Asia/Bangkok
39
+ cooldown:
40
+ default-days: 7
41
+ commit-message:
42
+ prefix: chore
43
+ include: scope
44
+ groups:
45
+ github-actions:
46
+ patterns:
47
+ - "*"
48
+
49
+ - package-ecosystem: docker
50
+ directories:
51
+ - /apps/app
52
+ - /apps/backoffice
53
+ schedule:
54
+ interval: weekly
55
+ day: monday
56
+ time: "10:00"
57
+ timezone: Asia/Bangkok
58
+ cooldown:
59
+ default-days: 7
60
+ commit-message:
61
+ prefix: chore
62
+ include: scope
63
+ ignore:
64
+ - dependency-name: node
65
+ update-types:
66
+ - version-update:semver-major
67
+
68
+ - package-ecosystem: pip
69
+ directory: /.github/requirements
70
+ schedule:
71
+ interval: weekly
72
+ day: monday
73
+ time: "10:30"
74
+ timezone: Asia/Bangkok
75
+ cooldown:
76
+ default-days: 7
77
+ commit-message:
78
+ prefix: chore
79
+ include: scope
@@ -0,0 +1,25 @@
1
+ documentation:
2
+ - changed-files:
3
+ - any-glob-to-any-file:
4
+ - "**/*.md"
5
+
6
+ ci:
7
+ - changed-files:
8
+ - any-glob-to-any-file:
9
+ - ".github/workflows/**"
10
+ - ".github/file-filters.yml"
11
+ - ".github/dependabot.yml"
12
+ - ".github/labeler.yml"
13
+ - ".github/zizmor.yml"
14
+ - ".github/requirements/**"
15
+ - ".github/CODEOWNERS"
16
+ - ".husky/**"
17
+
18
+ dependencies:
19
+ - changed-files:
20
+ - any-glob-to-any-file:
21
+ - "**/package.json"
22
+ - "**/pnpm-lock.yaml"
23
+ - "pnpm-workspace.yaml"
24
+ - "**/Dockerfile"
25
+ - ".github/requirements/**"
@@ -0,0 +1,25 @@
1
+ <!-- Title: `<type>(<scope>): <subject>` with a lowercase scope and a subject of 50 characters or fewer. Repository workflows validate it. The squash merge puts the title on `main`. Delete a section that has nothing to say, except Scope. -->
2
+
3
+ ## Why
4
+
5
+ <!-- The problem and the approach in 1-3 short sentences. No SHAs or rebase history. Link a related issue with `Closes #123`. -->
6
+
7
+ ## What changed
8
+
9
+ <!-- 1-3 short bullets. Name a symbol or path only when it carries the change, and both sides of a rename. Name every added, changed, or removed page, collection or field, migration, and environment variable. Document new variables in `.env.example`. -->
10
+
11
+ ## Scope
12
+
13
+ <!-- 1-3 short items: what this covers and what it deliberately leaves out. -->
14
+
15
+ ## Tradeoffs
16
+
17
+ <!-- Only rejected alternatives a reviewer would ask about. -->
18
+
19
+ ## Blast Radius
20
+
21
+ <!-- 1-2 sentences on who or what this touches and why that is safe or risky. If main is red, state the cost of leaving it red. -->
22
+
23
+ ## Verification
24
+
25
+ <!-- 1-3 bullets, each a check you ran and its outcome. For a perf change, one number as before -> after. After this section, attach videos or screenshots that prove a claim. -->
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ base="${1-}"
5
+ head="${2:-HEAD}"
6
+
7
+ if [[ -z "$base" ]]; then
8
+ printf '%s\n' app backoffice
9
+ exit 0
10
+ fi
11
+
12
+ query="$(pnpm exec turbo query affected --packages --base "$base" --head "$head")"
13
+ paths="$(printf '%s' "$query" | jq -r '.data.affectedPackages.items[].path // empty')"
14
+
15
+ app=false
16
+ backoffice=false
17
+
18
+ while IFS= read -r path; do
19
+ case "$path" in
20
+ apps/app) app=true ;;
21
+ apps/backoffice) backoffice=true ;;
22
+ esac
23
+ done <<< "$paths"
24
+
25
+ if [[ "$app" == true ]]; then
26
+ printf '%s\n' app
27
+ fi
28
+
29
+ if [[ "$backoffice" == true ]]; then
30
+ printf '%s\n' backoffice
31
+ fi