teamshare-bridge 0.22.7 → 0.22.8

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 (82) hide show
  1. package/README.md +383 -383
  2. package/dist/bridge/daemon.js +43 -20
  3. package/dist/bridge/daemon.js.map +1 -1
  4. package/dist/bridge/install-verify.js +8 -8
  5. package/dist/bridge/spawn.d.ts +14 -0
  6. package/dist/bridge/spawn.js +7 -1
  7. package/dist/bridge/spawn.js.map +1 -1
  8. package/dist/bridge/wake-handler.d.ts +8 -15
  9. package/dist/bridge/wake-handler.js +109 -14
  10. package/dist/bridge/wake-handler.js.map +1 -1
  11. package/dist/bridge/wake-outbox.js +7 -0
  12. package/dist/bridge/wake-outbox.js.map +1 -1
  13. package/dist/cli/commands/plan.js +4 -0
  14. package/dist/cli/commands/plan.js.map +1 -1
  15. package/dist/lib/browser/human-input-guard.js +98 -98
  16. package/dist/lib/browser/screen-change.js +60 -60
  17. package/dist/lib/llm/usage-reader.js +4 -4
  18. package/dist/lib/workspace/classify.d.ts +29 -0
  19. package/dist/lib/workspace/classify.js +62 -0
  20. package/dist/lib/workspace/classify.js.map +1 -1
  21. package/dist/lib/workspace/presence.d.ts +31 -0
  22. package/dist/lib/workspace/presence.js +35 -1
  23. package/dist/lib/workspace/presence.js.map +1 -1
  24. package/dist/lib/workspace/shim-runner.js +23 -0
  25. package/dist/lib/workspace/shim-runner.js.map +1 -1
  26. package/package.json +70 -70
  27. package/skills/THIRD_PARTY_NOTICES.md +26 -26
  28. package/skills/architect/LICENSE +21 -21
  29. package/skills/codebase-design/LICENSE +21 -21
  30. package/skills/diagnosing-bugs/LICENSE +21 -21
  31. package/skills/domain-modeling/LICENSE +21 -21
  32. package/skills/improve-codebase-architecture/LICENSE +21 -21
  33. package/skills/recover/LICENSE +21 -21
  34. package/skills/review/LICENSE +21 -21
  35. package/skills/tdd/LICENSE +21 -21
  36. package/skills/teamshare-auth-rbac/SKILL.md +78 -78
  37. package/skills/teamshare-cdd/SKILL.md +205 -205
  38. package/skills/teamshare-modularity/SKILL.md +146 -146
  39. package/skills/teamshare-orchestrator-ask/SKILL.md +77 -77
  40. package/skills/teamshare-scaffold/SKILL.md +116 -116
  41. package/templates/backend/.env.example.tpl +13 -13
  42. package/templates/backend/nest-cli.json.tpl +8 -8
  43. package/templates/backend/package.json.tpl +41 -41
  44. package/templates/backend/prisma/schema.prisma.tpl +39 -39
  45. package/templates/backend/src/app.module.ts.tpl +24 -24
  46. package/templates/backend/src/common/filters/all-exceptions.filter.ts.tpl +59 -59
  47. package/templates/backend/src/common/guards/jwt-auth.guard.ts.tpl +27 -27
  48. package/templates/backend/src/common/guards/rbac.guard.ts.tpl +48 -48
  49. package/templates/backend/src/common/interceptors/transform.interceptor.ts.tpl +44 -44
  50. package/templates/backend/src/common/pipes/zod-validation.pipe.ts.tpl +29 -29
  51. package/templates/backend/src/common/swagger/envelope.schemas.ts.tpl +53 -53
  52. package/templates/backend/src/common/swagger/error.schemas.ts.tpl +62 -62
  53. package/templates/backend/src/main.ts.tpl +27 -27
  54. package/templates/backend/src/modules/example/example.controller.ts.tpl +102 -102
  55. package/templates/backend/src/modules/example/example.dto.ts.tpl +14 -14
  56. package/templates/backend/src/modules/example/example.module.ts.tpl +10 -10
  57. package/templates/backend/src/modules/example/example.service.ts.tpl +45 -45
  58. package/templates/backend/tsconfig.json.tpl +26 -26
  59. package/templates/common/.gitignore.tpl +42 -42
  60. package/templates/common/AGENTS.md.tpl +58 -58
  61. package/templates/common/docs/adr/README.md +25 -25
  62. package/templates/common/docs/api-contract.md.tpl +72 -72
  63. package/templates/web/next.config.ts.tpl +7 -7
  64. package/templates/web/package.json.tpl +37 -37
  65. package/templates/web/src/app/globals.css.tpl +48 -48
  66. package/templates/web/src/app/layout.tsx.tpl +25 -25
  67. package/templates/web/src/components/shared/app-button.tsx.tpl +59 -59
  68. package/templates/web/src/components/shared/app-empty-state.tsx.tpl +39 -39
  69. package/templates/web/src/components/shared/app-list-toolbar.tsx.tpl +63 -63
  70. package/templates/web/src/components/shared/app-skeleton.tsx.tpl +14 -14
  71. package/templates/web/src/components/shared/app-table.tsx.tpl +128 -128
  72. package/templates/web/src/components/shared/index.ts.tpl +5 -5
  73. package/templates/web/src/hooks/use-list-state.ts.tpl +72 -72
  74. package/templates/web/src/hooks/use-url-tab.ts.tpl +25 -25
  75. package/templates/web/src/lib/api/client.ts.tpl +123 -123
  76. package/templates/web/src/lib/providers.tsx.tpl +35 -35
  77. package/templates/web/src/lib/query-keys.ts.tpl +21 -21
  78. package/templates/web/src/lib/utils.ts.tpl +7 -7
  79. package/templates/web/src/lib/validation/schemas.ts.tpl +15 -15
  80. package/templates/web/src/modules/example/views/example-list-view.tsx.tpl +97 -97
  81. package/templates/web/tsconfig.json.tpl +23 -23
  82. package/tools/workspace-arbitration-check.mjs +389 -389
@@ -1,38 +1,38 @@
1
- ---
2
- name: teamshare-scaffold
3
- description: "Enforce TeamShare standards when scaffolding new codebases, auditing existing ones, or cleaning up code. Covers stack decisions, folder layouts, view recipes, RBAC guards, loading states, safety patterns (no lint-disable unless worse), and the audit report format."
4
- ---
5
-
6
- # teamshare-scaffold
7
-
8
- Standards enforcement for TeamShare codebases. Use when scaffolding a new repo, auditing an existing codebase, or cleaning up code.
9
-
10
- ## Stack Decisions
11
-
12
- | Layer | Stack |
13
- |-------|-------|
14
- | Web | Next.js App Router + TS + Tailwind v4 + shadcn (radix-nova) + TS* wrappers |
15
- | Icons | iconsax-react (variant+color always, no emoji) |
16
- | Tables | @tanstack/react-table v8 (NOT v9) |
17
- | Forms | TSForm + zodResolver + zod schemas mirroring backend |
18
- | State | useListState + useUrlTab (URL-driven) |
19
- | Backend | NestJS 11 + Prisma 6 + zod-first DTOs + envelope |
20
- | Mobile | Expo SDK 57 + NativeWind v4 + reusables |
21
-
1
+ ---
2
+ name: teamshare-scaffold
3
+ description: "Enforce TeamShare standards when scaffolding new codebases, auditing existing ones, or cleaning up code. Covers stack decisions, folder layouts, view recipes, RBAC guards, loading states, safety patterns (no lint-disable unless worse), and the audit report format."
4
+ ---
5
+
6
+ # teamshare-scaffold
7
+
8
+ Standards enforcement for TeamShare codebases. Use when scaffolding a new repo, auditing an existing codebase, or cleaning up code.
9
+
10
+ ## Stack Decisions
11
+
12
+ | Layer | Stack |
13
+ |-------|-------|
14
+ | Web | Next.js App Router + TS + Tailwind v4 + shadcn (radix-nova) + TS* wrappers |
15
+ | Icons | iconsax-react (variant+color always, no emoji) |
16
+ | Tables | @tanstack/react-table v8 (NOT v9) |
17
+ | Forms | TSForm + zodResolver + zod schemas mirroring backend |
18
+ | State | useListState + useUrlTab (URL-driven) |
19
+ | Backend | NestJS 11 + Prisma 6 + zod-first DTOs + envelope |
20
+ | Mobile | Expo SDK 57 + NativeWind v4 + reusables |
21
+
22
22
  ## Frontend Layout
23
23
 
24
24
  - `src/components/ui/` = VENDOR shadcn. DO NOT EDIT. DO NOT IMPORT from app code.
25
25
  - `src/components/shared/` = Shared wrappers (AppButton, AppTable, etc). Barrel index.ts.
26
26
  - `src/modules/<feature>/{views,components,columns,hooks,utils}`
27
27
  - `src/lib/api/<feature>.ts` + `src/lib/query-keys.ts` + `src/lib/validation/schemas.ts`
28
- - Pages stay thin. Views do the work.
29
-
30
- ## Backend Layout
31
-
32
- - `src/modules/<feature>/{controller,service,dto,module}`
33
- - `src/common/{guards,filters,interceptors,pipes,swagger,constants,utils,prisma,logging}`
34
- - Prisma schema.prisma is canonical. `npx prisma migrate deploy` only.
35
-
28
+ - Pages stay thin. Views do the work.
29
+
30
+ ## Backend Layout
31
+
32
+ - `src/modules/<feature>/{controller,service,dto,module}`
33
+ - `src/common/{guards,filters,interceptors,pipes,swagger,constants,utils,prisma,logging}`
34
+ - Prisma schema.prisma is canonical. `npx prisma migrate deploy` only.
35
+
36
36
  ## View Recipe (every list view)
37
37
 
38
38
  1. `useListState({ pageSize })` - URL-driven
@@ -43,91 +43,91 @@ Standards enforcement for TeamShare codebases. Use when scaffolding a new repo,
43
43
  6. Toolbar: `AppListToolbar` with actions slot (create button always visible)
44
44
  7. Mutations: `useMutation` + toast success/error + `queryClient.invalidateQueries`
45
45
 
46
- Every view MUST handle loading, error, and empty states. Never show white screen.
47
-
48
- ## RBAC Guard Table
49
-
50
- | Who | Guard stack |
51
- |-----|-------------|
52
- | Human only | `@Permissions('entity.action')` |
53
- | Agent + human | `@Public()` + `AgentsDualAuthGuard` + `@ApiKeyScopes` |
54
- | Truly public | `@Public()` only |
55
- | MCP | `ApiKeyGuard` + `canUseTool()` |
56
-
57
- Never combine @Permissions with AgentsDualAuthGuard on same route.
58
-
59
- Three enforcement layers: capability + key scope + project access. Never less than two.
60
-
61
- ## IconSax Rules
62
-
63
- Every icon instance MUST pass `variant` and `color` props. Default variant="Outline".
64
- - Bold for active nav
65
- - TwoTone for empty-state illustrations
66
- - Broken for destructive confirmations
67
- - Sizes: 16/20/24/32
68
-
69
- ## Safety Patterns
70
-
71
- 1. **eslint-disable only when fix is worse.** Add `// eslint-disable-next-line <rule> -- <reason>`. Inventoried for revert.
72
- 2. **Never hand-edit generated/ or vendor ui/.**
73
- 3. **Build/typecheck verified.** Failed fixes reverted + noted.
74
- 4. **Cleanup in worktrees/branches.**
75
- 5. **Secrets never in code/logs/messages.**
76
- 6. **Existing repos: additive fixes only.** Never restructure.
77
- 7. **Max 120 chars per line.**
78
-
79
- ## Audit Report Format
80
-
81
- When running an audit, produce findings in this structure:
82
-
83
- ```
84
- # Audit Report — [repo-name]
85
-
86
- **Date:** YYYY-MM-DD
87
- **Scope:** [files scanned]
88
-
89
- ## Critical / Security
90
- - [finding] [file:line] [evidence] [suggested fix]
91
-
92
- ## Modularity
93
- - [finding] [file:line] [evidence] [suggested fix]
94
-
95
- ## Quality
96
- - [finding] [file:line] [evidence] [suggested fix]
97
-
98
- ## Advisory (existing code)
99
- - [finding] [file:line] [note]
100
-
101
- ## Summary
102
- - Total findings: N (Critical: X, Security: Y, Modularity: Z, Quality: W)
103
- - Gate status: build [pass/fail], typecheck [pass/fail]
104
- ```
105
-
106
- Severity levels: Critical (security, data loss), High (broken patterns, missing guards),
107
- Medium (quality, missing states), Low (style, naming), Advisory (existing code deviations).
108
-
109
- ## Scaffold Task Flow
110
-
111
- When asked to scaffold a new codebase:
112
- 1. Ask questions first (stack, auth provider, DB, package manager) if --ask
113
- 2. Write plan.md before generating
114
- 3. Create folder tree from template
115
- 4. Write AGENTS.md + docs/ skeleton
116
- 5. Generate module skeletons with full guard stack + loading states
117
- 6. Run build/typecheck gates
118
- 7. Write summary.md with what was built
119
-
120
- When asked to audit an existing codebase:
121
- 1. Scan all dimensions (security, modularity, rbac, errors, quality, ux, docs, gates)
122
- 2. Existing code deviations = Advisory only (never force restructure)
123
- 3. New code deviations = High/Critical findings
124
- 4. Produce detailed markdown report with file:line evidence
125
- 5. Suggest fixes for each finding
126
-
127
- When asked to clean up code:
128
- 1. Run audit first
129
- 2. Group findings into fix tasks
130
- 3. Apply mechanical fixes (line length, naming, imports)
131
- 4. For complex fixes: ask_human or route to orchestrator
132
- 5. Every fix verified by build/typecheck
46
+ Every view MUST handle loading, error, and empty states. Never show white screen.
47
+
48
+ ## RBAC Guard Table
49
+
50
+ | Who | Guard stack |
51
+ |-----|-------------|
52
+ | Human only | `@Permissions('entity.action')` |
53
+ | Agent + human | `@Public()` + `AgentsDualAuthGuard` + `@ApiKeyScopes` |
54
+ | Truly public | `@Public()` only |
55
+ | MCP | `ApiKeyGuard` + `canUseTool()` |
56
+
57
+ Never combine @Permissions with AgentsDualAuthGuard on same route.
58
+
59
+ Three enforcement layers: capability + key scope + project access. Never less than two.
60
+
61
+ ## IconSax Rules
62
+
63
+ Every icon instance MUST pass `variant` and `color` props. Default variant="Outline".
64
+ - Bold for active nav
65
+ - TwoTone for empty-state illustrations
66
+ - Broken for destructive confirmations
67
+ - Sizes: 16/20/24/32
68
+
69
+ ## Safety Patterns
70
+
71
+ 1. **eslint-disable only when fix is worse.** Add `// eslint-disable-next-line <rule> -- <reason>`. Inventoried for revert.
72
+ 2. **Never hand-edit generated/ or vendor ui/.**
73
+ 3. **Build/typecheck verified.** Failed fixes reverted + noted.
74
+ 4. **Cleanup in worktrees/branches.**
75
+ 5. **Secrets never in code/logs/messages.**
76
+ 6. **Existing repos: additive fixes only.** Never restructure.
77
+ 7. **Max 120 chars per line.**
78
+
79
+ ## Audit Report Format
80
+
81
+ When running an audit, produce findings in this structure:
82
+
83
+ ```
84
+ # Audit Report — [repo-name]
85
+
86
+ **Date:** YYYY-MM-DD
87
+ **Scope:** [files scanned]
88
+
89
+ ## Critical / Security
90
+ - [finding] [file:line] [evidence] [suggested fix]
91
+
92
+ ## Modularity
93
+ - [finding] [file:line] [evidence] [suggested fix]
94
+
95
+ ## Quality
96
+ - [finding] [file:line] [evidence] [suggested fix]
97
+
98
+ ## Advisory (existing code)
99
+ - [finding] [file:line] [note]
100
+
101
+ ## Summary
102
+ - Total findings: N (Critical: X, Security: Y, Modularity: Z, Quality: W)
103
+ - Gate status: build [pass/fail], typecheck [pass/fail]
104
+ ```
105
+
106
+ Severity levels: Critical (security, data loss), High (broken patterns, missing guards),
107
+ Medium (quality, missing states), Low (style, naming), Advisory (existing code deviations).
108
+
109
+ ## Scaffold Task Flow
110
+
111
+ When asked to scaffold a new codebase:
112
+ 1. Ask questions first (stack, auth provider, DB, package manager) if --ask
113
+ 2. Write plan.md before generating
114
+ 3. Create folder tree from template
115
+ 4. Write AGENTS.md + docs/ skeleton
116
+ 5. Generate module skeletons with full guard stack + loading states
117
+ 6. Run build/typecheck gates
118
+ 7. Write summary.md with what was built
119
+
120
+ When asked to audit an existing codebase:
121
+ 1. Scan all dimensions (security, modularity, rbac, errors, quality, ux, docs, gates)
122
+ 2. Existing code deviations = Advisory only (never force restructure)
123
+ 3. New code deviations = High/Critical findings
124
+ 4. Produce detailed markdown report with file:line evidence
125
+ 5. Suggest fixes for each finding
126
+
127
+ When asked to clean up code:
128
+ 1. Run audit first
129
+ 2. Group findings into fix tasks
130
+ 3. Apply mechanical fixes (line length, naming, imports)
131
+ 4. For complex fixes: ask_human or route to orchestrator
132
+ 5. Every fix verified by build/typecheck
133
133
  6. Failed fixes reverted + noted in report
@@ -1,13 +1,13 @@
1
- # Database
2
- DATABASE_URL="postgresql://user:password@localhost:5432/{{slug}}?schema=public"
3
-
4
- # JWT
5
- JWT_SECRET="change-me-to-a-random-secret"
6
- JWT_EXPIRES_IN="7d"
7
-
8
- # Server
9
- PORT={{apiPort}}
10
- NODE_ENV=development
11
-
12
- # CORS
13
- CORS_ORIGIN="http://localhost:{{port}}"
1
+ # Database
2
+ DATABASE_URL="postgresql://user:password@localhost:5432/{{slug}}?schema=public"
3
+
4
+ # JWT
5
+ JWT_SECRET="change-me-to-a-random-secret"
6
+ JWT_EXPIRES_IN="7d"
7
+
8
+ # Server
9
+ PORT={{apiPort}}
10
+ NODE_ENV=development
11
+
12
+ # CORS
13
+ CORS_ORIGIN="http://localhost:{{port}}"
@@ -1,8 +1,8 @@
1
- {
2
- "$schema": "https://json.schemastore.org/nest-cli",
3
- "collection": "@nestjs/schematics",
4
- "sourceRoot": "src",
5
- "compilerOptions": {
6
- "deleteOutDir": true
7
- }
8
- }
1
+ {
2
+ "$schema": "https://json.schemastore.org/nest-cli",
3
+ "collection": "@nestjs/schematics",
4
+ "sourceRoot": "src",
5
+ "compilerOptions": {
6
+ "deleteOutDir": true
7
+ }
8
+ }
@@ -1,41 +1,41 @@
1
- {
2
- "name": "{{packageName}}",
3
- "version": "0.1.0",
4
- "private": true,
5
- "description": "{{description}}",
6
- "scripts": {
7
- "build": "nest build",
8
- "start": "nest start",
9
- "start:dev": "nest start --watch",
10
- "prisma:generate": "prisma generate",
11
- "prisma:migrate": "prisma migrate dev",
12
- "lint": "eslint src"
13
- },
14
- "dependencies": {
15
- "@nestjs/common": "^11.0.0",
16
- "@nestjs/config": "^4.0.0",
17
- "@nestjs/core": "^11.0.0",
18
- "@nestjs/passport": "^11.0.0",
19
- "@nestjs/platform-express": "^11.0.0",
20
- "@nestjs/swagger": "^11.0.0",
21
- "@prisma/client": "^6.0.0",
22
- "argon2": "^0.41.0",
23
- "class-transformer": "^0.5.1",
24
- "class-validator": "^0.14.0",
25
- "passport": "^0.7.0",
26
- "passport-jwt": "^4.0.1",
27
- "prisma-zod-generator": "^0.9.0",
28
- "reflect-metadata": "^0.2.0",
29
- "rxjs": "^7.8.0",
30
- "socket.io": "^4.8.0",
31
- "zod": "^3.23.0"
32
- },
33
- "devDependencies": {
34
- "@nestjs/cli": "^11.0.0",
35
- "@nestjs/schematics": "^11.0.0",
36
- "@types/node": "^22.0.0",
37
- "@types/passport-jwt": "^4.0.0",
38
- "prisma": "^6.0.0",
39
- "typescript": "^5.6.0"
40
- }
41
- }
1
+ {
2
+ "name": "{{packageName}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "{{description}}",
6
+ "scripts": {
7
+ "build": "nest build",
8
+ "start": "nest start",
9
+ "start:dev": "nest start --watch",
10
+ "prisma:generate": "prisma generate",
11
+ "prisma:migrate": "prisma migrate dev",
12
+ "lint": "eslint src"
13
+ },
14
+ "dependencies": {
15
+ "@nestjs/common": "^11.0.0",
16
+ "@nestjs/config": "^4.0.0",
17
+ "@nestjs/core": "^11.0.0",
18
+ "@nestjs/passport": "^11.0.0",
19
+ "@nestjs/platform-express": "^11.0.0",
20
+ "@nestjs/swagger": "^11.0.0",
21
+ "@prisma/client": "^6.0.0",
22
+ "argon2": "^0.41.0",
23
+ "class-transformer": "^0.5.1",
24
+ "class-validator": "^0.14.0",
25
+ "passport": "^0.7.0",
26
+ "passport-jwt": "^4.0.1",
27
+ "prisma-zod-generator": "^0.9.0",
28
+ "reflect-metadata": "^0.2.0",
29
+ "rxjs": "^7.8.0",
30
+ "socket.io": "^4.8.0",
31
+ "zod": "^3.23.0"
32
+ },
33
+ "devDependencies": {
34
+ "@nestjs/cli": "^11.0.0",
35
+ "@nestjs/schematics": "^11.0.0",
36
+ "@types/node": "^22.0.0",
37
+ "@types/passport-jwt": "^4.0.0",
38
+ "prisma": "^6.0.0",
39
+ "typescript": "^5.6.0"
40
+ }
41
+ }
@@ -1,39 +1,39 @@
1
- generator client {
2
- provider = "prisma-client-js"
3
- }
4
-
5
- generator zod {
6
- provider = "prisma-zod-generator"
7
- output = "../src/generated/zod"
8
- }
9
-
10
- datasource db {
11
- provider = "postgresql"
12
- url = env("DATABASE_URL")
13
- }
14
-
15
- model User {
16
- id String @id @default(uuid()) @db.Uuid
17
- email String @unique
18
- name String?
19
- password String
20
- createdAt DateTime @default(now()) @map("created_at")
21
- updatedAt DateTime @updatedAt @map("updated_at")
22
-
23
- apiKey ApiKey[]
24
-
25
- @@map("users")
26
- }
27
-
28
- model ApiKey {
29
- id String @id @default(uuid()) @db.Uuid
30
- key String @unique
31
- name String
32
- userId String @map("user_id") @db.Uuid
33
- createdAt DateTime @default(now()) @map("created_at")
34
- lastUsed DateTime? @map("last_used")
35
-
36
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
37
-
38
- @@map("api_keys")
39
- }
1
+ generator client {
2
+ provider = "prisma-client-js"
3
+ }
4
+
5
+ generator zod {
6
+ provider = "prisma-zod-generator"
7
+ output = "../src/generated/zod"
8
+ }
9
+
10
+ datasource db {
11
+ provider = "postgresql"
12
+ url = env("DATABASE_URL")
13
+ }
14
+
15
+ model User {
16
+ id String @id @default(uuid()) @db.Uuid
17
+ email String @unique
18
+ name String?
19
+ password String
20
+ createdAt DateTime @default(now()) @map("created_at")
21
+ updatedAt DateTime @updatedAt @map("updated_at")
22
+
23
+ apiKey ApiKey[]
24
+
25
+ @@map("users")
26
+ }
27
+
28
+ model ApiKey {
29
+ id String @id @default(uuid()) @db.Uuid
30
+ key String @unique
31
+ name String
32
+ userId String @map("user_id") @db.Uuid
33
+ createdAt DateTime @default(now()) @map("created_at")
34
+ lastUsed DateTime? @map("last_used")
35
+
36
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
37
+
38
+ @@map("api_keys")
39
+ }
@@ -1,24 +1,24 @@
1
- import { Module } from "@nestjs/common";
2
- import { ConfigModule } from "@nestjs/config";
3
- import { APP_GUARD, APP_FILTER, APP_INTERCEPTOR } from "@nestjs/core";
4
- import { AuthGuard } from "./common/guards/jwt-auth.guard";
5
- import { RbacGuard } from "./common/guards/rbac.guard";
6
- import { AllExceptionsFilter } from "./common/filters/all-exceptions.filter";
7
- import { TransformInterceptor } from "./common/interceptors/transform.interceptor";
8
- import { PrismaModule } from "./prisma/prisma.module";
9
- import { ExampleModule } from "./modules/example/example.module";
10
-
11
- @Module({
12
- imports: [
13
- ConfigModule.forRoot({ isGlobal: true }),
14
- PrismaModule,
15
- ExampleModule,
16
- ],
17
- providers: [
18
- { provide: APP_GUARD, useClass: AuthGuard },
19
- { provide: APP_GUARD, useClass: RbacGuard },
20
- { provide: APP_FILTER, useClass: AllExceptionsFilter },
21
- { provide: APP_INTERCEPTOR, useClass: TransformInterceptor },
22
- ],
23
- })
24
- export class AppModule {}
1
+ import { Module } from "@nestjs/common";
2
+ import { ConfigModule } from "@nestjs/config";
3
+ import { APP_GUARD, APP_FILTER, APP_INTERCEPTOR } from "@nestjs/core";
4
+ import { AuthGuard } from "./common/guards/jwt-auth.guard";
5
+ import { RbacGuard } from "./common/guards/rbac.guard";
6
+ import { AllExceptionsFilter } from "./common/filters/all-exceptions.filter";
7
+ import { TransformInterceptor } from "./common/interceptors/transform.interceptor";
8
+ import { PrismaModule } from "./prisma/prisma.module";
9
+ import { ExampleModule } from "./modules/example/example.module";
10
+
11
+ @Module({
12
+ imports: [
13
+ ConfigModule.forRoot({ isGlobal: true }),
14
+ PrismaModule,
15
+ ExampleModule,
16
+ ],
17
+ providers: [
18
+ { provide: APP_GUARD, useClass: AuthGuard },
19
+ { provide: APP_GUARD, useClass: RbacGuard },
20
+ { provide: APP_FILTER, useClass: AllExceptionsFilter },
21
+ { provide: APP_INTERCEPTOR, useClass: TransformInterceptor },
22
+ ],
23
+ })
24
+ export class AppModule {}
@@ -1,59 +1,59 @@
1
- import {
2
- ExceptionFilter,
3
- Catch,
4
- ArgumentsHost,
5
- HttpException,
6
- HttpStatus,
7
- } from "@nestjs/common";
8
- import { Response } from "express";
9
-
10
- @Catch()
11
- export class AllExceptionsFilter implements ExceptionFilter {
12
- catch(exception: unknown, host: ArgumentsHost) {
13
- const ctx = host.switchToHttp();
14
- const response = ctx.getResponse<Response>();
15
-
16
- let status = HttpStatus.INTERNAL_SERVER_ERROR;
17
- let code = "INTERNAL_ERROR";
18
- let message = "An unexpected error occurred";
19
- let details: unknown = undefined;
20
-
21
- if (exception instanceof HttpException) {
22
- status = exception.getStatus();
23
- const res = exception.getResponse();
24
- if (typeof res === "string") {
25
- message = res;
26
- } else if (typeof res === "object" && res !== null) {
27
- const obj = res as Record<string, unknown>;
28
- message = (obj.message as string) ?? message;
29
- code = (obj.error as string) ?? code;
30
- details = obj.details;
31
- }
32
- code = this.codeFromStatus(status);
33
- } else if (exception instanceof Error) {
34
- message = exception.message;
35
- }
36
-
37
- response.status(status).json({
38
- success: false,
39
- error: {
40
- code,
41
- message,
42
- details,
43
- },
44
- });
45
- }
46
-
47
- private codeFromStatus(status: number): string {
48
- const map: Record<number, string> = {
49
- 400: "BAD_REQUEST",
50
- 401: "UNAUTHORIZED",
51
- 403: "FORBIDDEN",
52
- 404: "NOT_FOUND",
53
- 409: "CONFLICT",
54
- 422: "UNPROCESSABLE_ENTITY",
55
- 429: "TOO_MANY_REQUESTS",
56
- };
57
- return map[status] ?? "INTERNAL_ERROR";
58
- }
59
- }
1
+ import {
2
+ ExceptionFilter,
3
+ Catch,
4
+ ArgumentsHost,
5
+ HttpException,
6
+ HttpStatus,
7
+ } from "@nestjs/common";
8
+ import { Response } from "express";
9
+
10
+ @Catch()
11
+ export class AllExceptionsFilter implements ExceptionFilter {
12
+ catch(exception: unknown, host: ArgumentsHost) {
13
+ const ctx = host.switchToHttp();
14
+ const response = ctx.getResponse<Response>();
15
+
16
+ let status = HttpStatus.INTERNAL_SERVER_ERROR;
17
+ let code = "INTERNAL_ERROR";
18
+ let message = "An unexpected error occurred";
19
+ let details: unknown = undefined;
20
+
21
+ if (exception instanceof HttpException) {
22
+ status = exception.getStatus();
23
+ const res = exception.getResponse();
24
+ if (typeof res === "string") {
25
+ message = res;
26
+ } else if (typeof res === "object" && res !== null) {
27
+ const obj = res as Record<string, unknown>;
28
+ message = (obj.message as string) ?? message;
29
+ code = (obj.error as string) ?? code;
30
+ details = obj.details;
31
+ }
32
+ code = this.codeFromStatus(status);
33
+ } else if (exception instanceof Error) {
34
+ message = exception.message;
35
+ }
36
+
37
+ response.status(status).json({
38
+ success: false,
39
+ error: {
40
+ code,
41
+ message,
42
+ details,
43
+ },
44
+ });
45
+ }
46
+
47
+ private codeFromStatus(status: number): string {
48
+ const map: Record<number, string> = {
49
+ 400: "BAD_REQUEST",
50
+ 401: "UNAUTHORIZED",
51
+ 403: "FORBIDDEN",
52
+ 404: "NOT_FOUND",
53
+ 409: "CONFLICT",
54
+ 422: "UNPROCESSABLE_ENTITY",
55
+ 429: "TOO_MANY_REQUESTS",
56
+ };
57
+ return map[status] ?? "INTERNAL_ERROR";
58
+ }
59
+ }