@chrishdx/llm-dev-server 1.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 (184) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +164 -0
  3. package/backend/bin/llm-dev-server.js +3 -0
  4. package/backend/dist/cli.d.ts +15 -0
  5. package/backend/dist/cli.d.ts.map +1 -0
  6. package/backend/dist/cli.js +326 -0
  7. package/backend/dist/cli.js.map +1 -0
  8. package/backend/dist/config/database.d.ts +10 -0
  9. package/backend/dist/config/database.d.ts.map +1 -0
  10. package/backend/dist/config/database.js +61 -0
  11. package/backend/dist/config/database.js.map +1 -0
  12. package/backend/dist/config/environment.d.ts +20 -0
  13. package/backend/dist/config/environment.d.ts.map +1 -0
  14. package/backend/dist/config/environment.js +77 -0
  15. package/backend/dist/config/environment.js.map +1 -0
  16. package/backend/dist/controllers/AuthController.d.ts +18 -0
  17. package/backend/dist/controllers/AuthController.d.ts.map +1 -0
  18. package/backend/dist/controllers/AuthController.js +282 -0
  19. package/backend/dist/controllers/AuthController.js.map +1 -0
  20. package/backend/dist/controllers/ConversationController.d.ts +44 -0
  21. package/backend/dist/controllers/ConversationController.d.ts.map +1 -0
  22. package/backend/dist/controllers/ConversationController.js +193 -0
  23. package/backend/dist/controllers/ConversationController.js.map +1 -0
  24. package/backend/dist/controllers/JobController.d.ts +49 -0
  25. package/backend/dist/controllers/JobController.d.ts.map +1 -0
  26. package/backend/dist/controllers/JobController.js +227 -0
  27. package/backend/dist/controllers/JobController.js.map +1 -0
  28. package/backend/dist/index.d.ts +2 -0
  29. package/backend/dist/index.d.ts.map +1 -0
  30. package/backend/dist/index.js +160 -0
  31. package/backend/dist/index.js.map +1 -0
  32. package/backend/dist/middleware/auth.middleware.d.ts +25 -0
  33. package/backend/dist/middleware/auth.middleware.d.ts.map +1 -0
  34. package/backend/dist/middleware/auth.middleware.js +116 -0
  35. package/backend/dist/middleware/auth.middleware.js.map +1 -0
  36. package/backend/dist/middleware/authelia.middleware.d.ts +26 -0
  37. package/backend/dist/middleware/authelia.middleware.d.ts.map +1 -0
  38. package/backend/dist/middleware/authelia.middleware.js +165 -0
  39. package/backend/dist/middleware/authelia.middleware.js.map +1 -0
  40. package/backend/dist/middleware/error.middleware.d.ts +23 -0
  41. package/backend/dist/middleware/error.middleware.d.ts.map +1 -0
  42. package/backend/dist/middleware/error.middleware.js +59 -0
  43. package/backend/dist/middleware/error.middleware.js.map +1 -0
  44. package/backend/dist/models/AuthToken.d.ts +42 -0
  45. package/backend/dist/models/AuthToken.d.ts.map +1 -0
  46. package/backend/dist/models/AuthToken.js +97 -0
  47. package/backend/dist/models/AuthToken.js.map +1 -0
  48. package/backend/dist/models/Conversation.d.ts +36 -0
  49. package/backend/dist/models/Conversation.d.ts.map +1 -0
  50. package/backend/dist/models/Conversation.js +100 -0
  51. package/backend/dist/models/Conversation.js.map +1 -0
  52. package/backend/dist/models/FileOperation.d.ts +36 -0
  53. package/backend/dist/models/FileOperation.d.ts.map +1 -0
  54. package/backend/dist/models/FileOperation.js +117 -0
  55. package/backend/dist/models/FileOperation.js.map +1 -0
  56. package/backend/dist/models/Job.d.ts +48 -0
  57. package/backend/dist/models/Job.d.ts.map +1 -0
  58. package/backend/dist/models/Job.js +87 -0
  59. package/backend/dist/models/Job.js.map +1 -0
  60. package/backend/dist/models/Message.d.ts +38 -0
  61. package/backend/dist/models/Message.d.ts.map +1 -0
  62. package/backend/dist/models/Message.js +87 -0
  63. package/backend/dist/models/Message.js.map +1 -0
  64. package/backend/dist/models/User.d.ts +26 -0
  65. package/backend/dist/models/User.d.ts.map +1 -0
  66. package/backend/dist/models/User.js +67 -0
  67. package/backend/dist/models/User.js.map +1 -0
  68. package/backend/dist/models/index.d.ts +13 -0
  69. package/backend/dist/models/index.d.ts.map +1 -0
  70. package/backend/dist/models/index.js +24 -0
  71. package/backend/dist/models/index.js.map +1 -0
  72. package/backend/dist/routes/auth.routes.d.ts +3 -0
  73. package/backend/dist/routes/auth.routes.d.ts.map +1 -0
  74. package/backend/dist/routes/auth.routes.js +27 -0
  75. package/backend/dist/routes/auth.routes.js.map +1 -0
  76. package/backend/dist/routes/conversation.routes.d.ts +3 -0
  77. package/backend/dist/routes/conversation.routes.d.ts.map +1 -0
  78. package/backend/dist/routes/conversation.routes.js +17 -0
  79. package/backend/dist/routes/conversation.routes.js.map +1 -0
  80. package/backend/dist/routes/filesystem.routes.d.ts +3 -0
  81. package/backend/dist/routes/filesystem.routes.d.ts.map +1 -0
  82. package/backend/dist/routes/filesystem.routes.js +64 -0
  83. package/backend/dist/routes/filesystem.routes.js.map +1 -0
  84. package/backend/dist/routes/index.d.ts +3 -0
  85. package/backend/dist/routes/index.d.ts.map +1 -0
  86. package/backend/dist/routes/index.js +27 -0
  87. package/backend/dist/routes/index.js.map +1 -0
  88. package/backend/dist/routes/job.routes.d.ts +3 -0
  89. package/backend/dist/routes/job.routes.d.ts.map +1 -0
  90. package/backend/dist/routes/job.routes.js +18 -0
  91. package/backend/dist/routes/job.routes.js.map +1 -0
  92. package/backend/dist/services/auth/BaseAuthService.d.ts +49 -0
  93. package/backend/dist/services/auth/BaseAuthService.d.ts.map +1 -0
  94. package/backend/dist/services/auth/BaseAuthService.js +97 -0
  95. package/backend/dist/services/auth/BaseAuthService.js.map +1 -0
  96. package/backend/dist/services/auth/ClaudeAuthService.d.ts +69 -0
  97. package/backend/dist/services/auth/ClaudeAuthService.d.ts.map +1 -0
  98. package/backend/dist/services/auth/ClaudeAuthService.js +401 -0
  99. package/backend/dist/services/auth/ClaudeAuthService.js.map +1 -0
  100. package/backend/dist/services/auth/CodexAuthService.d.ts +37 -0
  101. package/backend/dist/services/auth/CodexAuthService.d.ts.map +1 -0
  102. package/backend/dist/services/auth/CodexAuthService.js +186 -0
  103. package/backend/dist/services/auth/CodexAuthService.js.map +1 -0
  104. package/backend/dist/services/auth/GeminiAuthService.d.ts +50 -0
  105. package/backend/dist/services/auth/GeminiAuthService.d.ts.map +1 -0
  106. package/backend/dist/services/auth/GeminiAuthService.js +284 -0
  107. package/backend/dist/services/auth/GeminiAuthService.js.map +1 -0
  108. package/backend/dist/services/auth/JwtService.d.ts +27 -0
  109. package/backend/dist/services/auth/JwtService.d.ts.map +1 -0
  110. package/backend/dist/services/auth/JwtService.js +65 -0
  111. package/backend/dist/services/auth/JwtService.js.map +1 -0
  112. package/backend/dist/services/auth/TokenRefreshService.d.ts +36 -0
  113. package/backend/dist/services/auth/TokenRefreshService.d.ts.map +1 -0
  114. package/backend/dist/services/auth/TokenRefreshService.js +178 -0
  115. package/backend/dist/services/auth/TokenRefreshService.js.map +1 -0
  116. package/backend/dist/services/conversation/ConversationService.d.ts +89 -0
  117. package/backend/dist/services/conversation/ConversationService.d.ts.map +1 -0
  118. package/backend/dist/services/conversation/ConversationService.js +255 -0
  119. package/backend/dist/services/conversation/ConversationService.js.map +1 -0
  120. package/backend/dist/services/job/JobService.d.ts +83 -0
  121. package/backend/dist/services/job/JobService.d.ts.map +1 -0
  122. package/backend/dist/services/job/JobService.js +213 -0
  123. package/backend/dist/services/job/JobService.js.map +1 -0
  124. package/backend/dist/services/job/WorkingDirectoryService.d.ts +73 -0
  125. package/backend/dist/services/job/WorkingDirectoryService.d.ts.map +1 -0
  126. package/backend/dist/services/job/WorkingDirectoryService.js +289 -0
  127. package/backend/dist/services/job/WorkingDirectoryService.js.map +1 -0
  128. package/backend/dist/services/llm/ClaudeProvider.d.ts +16 -0
  129. package/backend/dist/services/llm/ClaudeProvider.d.ts.map +1 -0
  130. package/backend/dist/services/llm/ClaudeProvider.js +229 -0
  131. package/backend/dist/services/llm/ClaudeProvider.js.map +1 -0
  132. package/backend/dist/services/llm/CodexProvider.d.ts +15 -0
  133. package/backend/dist/services/llm/CodexProvider.d.ts.map +1 -0
  134. package/backend/dist/services/llm/CodexProvider.js +301 -0
  135. package/backend/dist/services/llm/CodexProvider.js.map +1 -0
  136. package/backend/dist/services/llm/GeminiProvider.d.ts +17 -0
  137. package/backend/dist/services/llm/GeminiProvider.d.ts.map +1 -0
  138. package/backend/dist/services/llm/GeminiProvider.js +190 -0
  139. package/backend/dist/services/llm/GeminiProvider.js.map +1 -0
  140. package/backend/dist/services/llm/LLMProviderBase.d.ts +76 -0
  141. package/backend/dist/services/llm/LLMProviderBase.d.ts.map +1 -0
  142. package/backend/dist/services/llm/LLMProviderBase.js +34 -0
  143. package/backend/dist/services/llm/LLMProviderBase.js.map +1 -0
  144. package/backend/dist/services/llm/ProviderFactory.d.ts +17 -0
  145. package/backend/dist/services/llm/ProviderFactory.d.ts.map +1 -0
  146. package/backend/dist/services/llm/ProviderFactory.js +58 -0
  147. package/backend/dist/services/llm/ProviderFactory.js.map +1 -0
  148. package/backend/dist/utils/crypto.d.ts +33 -0
  149. package/backend/dist/utils/crypto.d.ts.map +1 -0
  150. package/backend/dist/utils/crypto.js +165 -0
  151. package/backend/dist/utils/crypto.js.map +1 -0
  152. package/backend/dist/utils/logger.d.ts +4 -0
  153. package/backend/dist/utils/logger.d.ts.map +1 -0
  154. package/backend/dist/utils/logger.js +44 -0
  155. package/backend/dist/utils/logger.js.map +1 -0
  156. package/backend/dist/utils/validators.d.ts +22 -0
  157. package/backend/dist/utils/validators.d.ts.map +1 -0
  158. package/backend/dist/utils/validators.js +127 -0
  159. package/backend/dist/utils/validators.js.map +1 -0
  160. package/backend/package.json +45 -0
  161. package/backend/public/assets/index-C207-KqP.js +188 -0
  162. package/backend/public/index.html +12 -0
  163. package/package.json +96 -0
  164. package/shared/dist/index.d.ts +5 -0
  165. package/shared/dist/index.d.ts.map +1 -0
  166. package/shared/dist/index.js +25 -0
  167. package/shared/dist/index.js.map +1 -0
  168. package/shared/dist/types/api.d.ts +27 -0
  169. package/shared/dist/types/api.d.ts.map +1 -0
  170. package/shared/dist/types/api.js +3 -0
  171. package/shared/dist/types/api.js.map +1 -0
  172. package/shared/dist/types/auth.d.ts +62 -0
  173. package/shared/dist/types/auth.d.ts.map +1 -0
  174. package/shared/dist/types/auth.js +3 -0
  175. package/shared/dist/types/auth.js.map +1 -0
  176. package/shared/dist/types/conversation.d.ts +98 -0
  177. package/shared/dist/types/conversation.d.ts.map +1 -0
  178. package/shared/dist/types/conversation.js +3 -0
  179. package/shared/dist/types/conversation.js.map +1 -0
  180. package/shared/dist/types/job.d.ts +93 -0
  181. package/shared/dist/types/job.d.ts.map +1 -0
  182. package/shared/dist/types/job.js +3 -0
  183. package/shared/dist/types/job.js.map +1 -0
  184. package/shared/package.json +15 -0
@@ -0,0 +1,26 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+ export interface AutheliaUser {
3
+ username: string;
4
+ email?: string;
5
+ displayName?: string;
6
+ groups: string[];
7
+ }
8
+ /**
9
+ * Parse Authelia headers from request
10
+ */
11
+ export declare function parseAutheliaHeaders(req: Request): AutheliaUser | null;
12
+ /**
13
+ * Authelia authentication middleware
14
+ *
15
+ * Checks for Authelia headers (Remote-User, Remote-Email, Remote-Groups)
16
+ * and authenticates/creates user accordingly.
17
+ *
18
+ * Returns true if authentication was successful, false if headers not present.
19
+ */
20
+ export declare function authenticateWithAuthelia(req: Request): Promise<boolean>;
21
+ /**
22
+ * Standalone Authelia middleware (for routes that ONLY accept Authelia auth)
23
+ */
24
+ export declare function autheliaMiddleware(req: Request, res: Response, next: NextFunction): void;
25
+ export default autheliaMiddleware;
26
+ //# sourceMappingURL=authelia.middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authelia.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/authelia.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAW1D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CAiBtE;AA0ED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CA2B7E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAsCN;AAED,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseAutheliaHeaders = parseAutheliaHeaders;
7
+ exports.authenticateWithAuthelia = authenticateWithAuthelia;
8
+ exports.autheliaMiddleware = autheliaMiddleware;
9
+ const models_1 = require("../models");
10
+ const environment_1 = __importDefault(require("../config/environment"));
11
+ const logger_1 = __importDefault(require("../utils/logger"));
12
+ // Standard Authelia headers
13
+ const HEADER_USER = "Remote-User";
14
+ const HEADER_EMAIL = "Remote-Email";
15
+ const HEADER_GROUPS = "Remote-Groups";
16
+ const HEADER_NAME = "Remote-Name";
17
+ /**
18
+ * Parse Authelia headers from request
19
+ */
20
+ function parseAutheliaHeaders(req) {
21
+ const username = req.get(HEADER_USER);
22
+ if (!username) {
23
+ return null;
24
+ }
25
+ return {
26
+ username,
27
+ email: req.get(HEADER_EMAIL) || undefined,
28
+ displayName: req.get(HEADER_NAME) || undefined,
29
+ groups: req
30
+ .get(HEADER_GROUPS)
31
+ ?.split(",")
32
+ .map((g) => g.trim()) || [],
33
+ };
34
+ }
35
+ /**
36
+ * Determine role based on Authelia groups
37
+ */
38
+ function determineRole(groups) {
39
+ const adminGroups = environment_1.default.AUTHELIA_ADMIN_GROUPS;
40
+ const isAdmin = groups.some((group) => adminGroups.includes(group));
41
+ return isAdmin ? "admin" : "user";
42
+ }
43
+ /**
44
+ * Find or create user from Authelia headers
45
+ */
46
+ async function findOrCreateAutheliaUser(autheliaUser) {
47
+ // Try to find existing user
48
+ let user = await models_1.User.findOne({
49
+ where: { username: autheliaUser.username },
50
+ });
51
+ const role = determineRole(autheliaUser.groups);
52
+ if (user) {
53
+ // Update email and role if changed
54
+ let needsUpdate = false;
55
+ if (autheliaUser.email && user.email !== autheliaUser.email) {
56
+ user.email = autheliaUser.email;
57
+ needsUpdate = true;
58
+ }
59
+ if (user.role !== role) {
60
+ user.role = role;
61
+ needsUpdate = true;
62
+ }
63
+ // Mark as authelia provider if was local
64
+ if (user.authProvider !== "authelia") {
65
+ user.authProvider = "authelia";
66
+ needsUpdate = true;
67
+ }
68
+ if (needsUpdate) {
69
+ await user.save();
70
+ logger_1.default.debug("Updated Authelia user", {
71
+ username: user.username,
72
+ role: user.role,
73
+ });
74
+ }
75
+ return user;
76
+ }
77
+ // Create new user
78
+ user = await models_1.User.create({
79
+ username: autheliaUser.username,
80
+ email: autheliaUser.email || null,
81
+ passwordHash: null, // No password for Authelia users
82
+ role,
83
+ authProvider: "authelia",
84
+ });
85
+ logger_1.default.info("Created new user from Authelia", {
86
+ username: user.username,
87
+ email: user.email,
88
+ role: user.role,
89
+ groups: autheliaUser.groups,
90
+ });
91
+ return user;
92
+ }
93
+ /**
94
+ * Authelia authentication middleware
95
+ *
96
+ * Checks for Authelia headers (Remote-User, Remote-Email, Remote-Groups)
97
+ * and authenticates/creates user accordingly.
98
+ *
99
+ * Returns true if authentication was successful, false if headers not present.
100
+ */
101
+ async function authenticateWithAuthelia(req) {
102
+ if (!environment_1.default.AUTHELIA_ENABLED) {
103
+ return false;
104
+ }
105
+ const autheliaUser = parseAutheliaHeaders(req);
106
+ if (!autheliaUser) {
107
+ return false;
108
+ }
109
+ try {
110
+ const user = await findOrCreateAutheliaUser(autheliaUser);
111
+ // Set req.user in the same format as JWT middleware
112
+ req.user = {
113
+ userId: user.id,
114
+ username: user.username,
115
+ role: user.role,
116
+ };
117
+ logger_1.default.debug("Authenticated via Authelia", { username: user.username });
118
+ return true;
119
+ }
120
+ catch (error) {
121
+ logger_1.default.error("Authelia authentication error:", error);
122
+ return false;
123
+ }
124
+ }
125
+ /**
126
+ * Standalone Authelia middleware (for routes that ONLY accept Authelia auth)
127
+ */
128
+ function autheliaMiddleware(req, res, next) {
129
+ if (!environment_1.default.AUTHELIA_ENABLED) {
130
+ res.status(500).json({
131
+ error: "Configuration Error",
132
+ message: "Authelia authentication is not enabled",
133
+ statusCode: 500,
134
+ });
135
+ return;
136
+ }
137
+ const autheliaUser = parseAutheliaHeaders(req);
138
+ if (!autheliaUser) {
139
+ res.status(401).json({
140
+ error: "Unauthorized",
141
+ message: "Not authenticated via Authelia",
142
+ statusCode: 401,
143
+ });
144
+ return;
145
+ }
146
+ findOrCreateAutheliaUser(autheliaUser)
147
+ .then((user) => {
148
+ req.user = {
149
+ userId: user.id,
150
+ username: user.username,
151
+ role: user.role,
152
+ };
153
+ next();
154
+ })
155
+ .catch((error) => {
156
+ logger_1.default.error("Authelia middleware error:", error);
157
+ res.status(500).json({
158
+ error: "Internal Server Error",
159
+ message: "Failed to process Authelia authentication",
160
+ statusCode: 500,
161
+ });
162
+ });
163
+ }
164
+ exports.default = autheliaMiddleware;
165
+ //# sourceMappingURL=authelia.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authelia.middleware.js","sourceRoot":"","sources":["../../src/middleware/authelia.middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ export interface ApiError extends Error {
3
+ statusCode?: number;
4
+ details?: any;
5
+ }
6
+ /**
7
+ * Global error handling middleware
8
+ */
9
+ export declare function errorMiddleware(error: ApiError, req: Request, res: Response, next: NextFunction): void;
10
+ /**
11
+ * 404 Not Found middleware
12
+ */
13
+ export declare function notFoundMiddleware(req: Request, res: Response, next: NextFunction): void;
14
+ /**
15
+ * Create custom API error
16
+ */
17
+ export declare class CustomApiError extends Error implements ApiError {
18
+ statusCode: number;
19
+ details?: any;
20
+ constructor(message: string, statusCode?: number, details?: any);
21
+ }
22
+ export default errorMiddleware;
23
+ //# sourceMappingURL=error.middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/error.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,MAAM,WAAW,QAAS,SAAQ,KAAK;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAuBN;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAMN;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAM,YAAW,QAAQ;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,GAAG,CAAC;gBAEF,OAAO,EAAE,MAAM,EAAE,UAAU,GAAE,MAAY,EAAE,OAAO,CAAC,EAAE,GAAG;CAOrE;AAED,eAAe,eAAe,CAAC"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CustomApiError = void 0;
7
+ exports.errorMiddleware = errorMiddleware;
8
+ exports.notFoundMiddleware = notFoundMiddleware;
9
+ const logger_1 = __importDefault(require("../utils/logger"));
10
+ /**
11
+ * Global error handling middleware
12
+ */
13
+ function errorMiddleware(error, req, res, next) {
14
+ // Log error
15
+ logger_1.default.error('API Error:', {
16
+ error: error.message,
17
+ stack: error.stack,
18
+ url: req.url,
19
+ method: req.method,
20
+ statusCode: error.statusCode,
21
+ });
22
+ // Determine status code
23
+ const statusCode = error.statusCode || 500;
24
+ // Send error response
25
+ res.status(statusCode).json({
26
+ error: error.name || 'Internal Server Error',
27
+ message: error.message || 'An unexpected error occurred',
28
+ statusCode,
29
+ ...(error.details && { details: error.details }),
30
+ ...(process.env.NODE_ENV === 'development' && {
31
+ stack: error.stack,
32
+ }),
33
+ });
34
+ }
35
+ /**
36
+ * 404 Not Found middleware
37
+ */
38
+ function notFoundMiddleware(req, res, next) {
39
+ res.status(404).json({
40
+ error: 'Not Found',
41
+ message: `Route ${req.method} ${req.url} not found`,
42
+ statusCode: 404,
43
+ });
44
+ }
45
+ /**
46
+ * Create custom API error
47
+ */
48
+ class CustomApiError extends Error {
49
+ constructor(message, statusCode = 500, details) {
50
+ super(message);
51
+ this.name = 'ApiError';
52
+ this.statusCode = statusCode;
53
+ this.details = details;
54
+ Error.captureStackTrace(this, this.constructor);
55
+ }
56
+ }
57
+ exports.CustomApiError = CustomApiError;
58
+ exports.default = errorMiddleware;
59
+ //# sourceMappingURL=error.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.middleware.js","sourceRoot":"","sources":["../../src/middleware/error.middleware.ts"],"names":[],"mappings":";;;;;;AAWA,0CA4BC;AAKD,gDAUC;AArDD,6DAAqC;AAOrC;;GAEG;AACH,SAAgB,eAAe,CAC7B,KAAe,EACf,GAAY,EACZ,GAAa,EACb,IAAkB;IAElB,YAAY;IACZ,gBAAM,CAAC,KAAK,CAAC,YAAY,EAAE;QACzB,KAAK,EAAE,KAAK,CAAC,OAAO;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC,CAAC;IAEH,wBAAwB;IACxB,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC;IAE3C,sBAAsB;IACtB,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC1B,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,uBAAuB;QAC5C,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,8BAA8B;QACxD,UAAU;QACV,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAChD,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,IAAI;YAC5C,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAChC,GAAY,EACZ,GAAa,EACb,IAAkB;IAElB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,KAAK,EAAE,WAAW;QAClB,OAAO,EAAE,SAAS,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,YAAY;QACnD,UAAU,EAAE,GAAG;KAChB,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAa,cAAe,SAAQ,KAAK;IAIvC,YAAY,OAAe,EAAE,aAAqB,GAAG,EAAE,OAAa;QAClE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;CACF;AAXD,wCAWC;AAED,kBAAe,eAAe,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { Model, Optional } from 'sequelize';
2
+ export type LLMProvider = 'claude' | 'codex' | 'gemini';
3
+ export interface AuthTokenAttributes {
4
+ id: string;
5
+ provider: LLMProvider;
6
+ accessToken: string;
7
+ refreshToken?: string;
8
+ tokenType: string;
9
+ expiresAt?: Date;
10
+ issuedAt: Date;
11
+ scopes?: string[];
12
+ email?: string;
13
+ organization?: string;
14
+ codeVerifier?: string;
15
+ sessionId?: string;
16
+ isActive: boolean;
17
+ lastRefreshed?: Date;
18
+ createdAt: Date;
19
+ updatedAt: Date;
20
+ }
21
+ export interface AuthTokenCreationAttributes extends Optional<AuthTokenAttributes, 'id' | 'refreshToken' | 'expiresAt' | 'scopes' | 'email' | 'organization' | 'codeVerifier' | 'sessionId' | 'lastRefreshed' | 'createdAt' | 'updatedAt'> {
22
+ }
23
+ export declare class AuthToken extends Model<AuthTokenAttributes, AuthTokenCreationAttributes> implements AuthTokenAttributes {
24
+ id: string;
25
+ provider: LLMProvider;
26
+ accessToken: string;
27
+ refreshToken?: string;
28
+ tokenType: string;
29
+ expiresAt?: Date;
30
+ issuedAt: Date;
31
+ scopes?: string[];
32
+ email?: string;
33
+ organization?: string;
34
+ codeVerifier?: string;
35
+ sessionId?: string;
36
+ isActive: boolean;
37
+ lastRefreshed?: Date;
38
+ createdAt: Date;
39
+ updatedAt: Date;
40
+ }
41
+ export default AuthToken;
42
+ //# sourceMappingURL=AuthToken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthToken.d.ts","sourceRoot":"","sources":["../../src/models/AuthToken.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGvD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAExD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,WAAW,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,2BACf,SAAQ,QAAQ,CACd,mBAAmB,EACjB,IAAI,GACJ,cAAc,GACd,WAAW,GACX,QAAQ,GACR,OAAO,GACP,cAAc,GACd,cAAc,GACd,WAAW,GACX,eAAe,GACf,WAAW,GACX,WAAW,CACd;CAAG;AAEN,qBAAa,SACX,SAAQ,KAAK,CAAC,mBAAmB,EAAE,2BAA2B,CAC9D,YAAW,mBAAmB;IAEtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,WAAW,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACzB;AA6FD,eAAe,SAAS,CAAC"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuthToken = void 0;
4
+ const sequelize_1 = require("sequelize");
5
+ const database_1 = require("../config/database");
6
+ class AuthToken extends sequelize_1.Model {
7
+ }
8
+ exports.AuthToken = AuthToken;
9
+ AuthToken.init({
10
+ id: {
11
+ type: sequelize_1.DataTypes.UUID,
12
+ defaultValue: sequelize_1.DataTypes.UUIDV4,
13
+ primaryKey: true,
14
+ },
15
+ provider: {
16
+ type: sequelize_1.DataTypes.ENUM('claude', 'codex', 'gemini'),
17
+ allowNull: false,
18
+ },
19
+ accessToken: {
20
+ type: sequelize_1.DataTypes.TEXT,
21
+ allowNull: false,
22
+ comment: 'AES-256 encrypted',
23
+ },
24
+ refreshToken: {
25
+ type: sequelize_1.DataTypes.TEXT,
26
+ allowNull: true,
27
+ comment: 'AES-256 encrypted',
28
+ },
29
+ tokenType: {
30
+ type: sequelize_1.DataTypes.STRING,
31
+ allowNull: false,
32
+ defaultValue: 'Bearer',
33
+ },
34
+ expiresAt: {
35
+ type: sequelize_1.DataTypes.DATE,
36
+ allowNull: true,
37
+ },
38
+ issuedAt: {
39
+ type: sequelize_1.DataTypes.DATE,
40
+ allowNull: false,
41
+ },
42
+ scopes: {
43
+ type: sequelize_1.DataTypes.JSON,
44
+ allowNull: true,
45
+ },
46
+ email: {
47
+ type: sequelize_1.DataTypes.STRING,
48
+ allowNull: true,
49
+ },
50
+ organization: {
51
+ type: sequelize_1.DataTypes.STRING,
52
+ allowNull: true,
53
+ },
54
+ codeVerifier: {
55
+ type: sequelize_1.DataTypes.TEXT,
56
+ allowNull: true,
57
+ comment: 'PKCE code verifier (encrypted)',
58
+ },
59
+ sessionId: {
60
+ type: sequelize_1.DataTypes.STRING,
61
+ allowNull: true,
62
+ comment: 'Provider session ID',
63
+ },
64
+ isActive: {
65
+ type: sequelize_1.DataTypes.BOOLEAN,
66
+ allowNull: false,
67
+ defaultValue: true,
68
+ },
69
+ lastRefreshed: {
70
+ type: sequelize_1.DataTypes.DATE,
71
+ allowNull: true,
72
+ },
73
+ createdAt: {
74
+ type: sequelize_1.DataTypes.DATE,
75
+ allowNull: false,
76
+ },
77
+ updatedAt: {
78
+ type: sequelize_1.DataTypes.DATE,
79
+ allowNull: false,
80
+ },
81
+ }, {
82
+ sequelize: database_1.database.sequelize,
83
+ tableName: 'auth_tokens',
84
+ indexes: [
85
+ {
86
+ fields: ['provider'],
87
+ },
88
+ {
89
+ fields: ['isActive'],
90
+ },
91
+ {
92
+ fields: ['provider', 'isActive'],
93
+ },
94
+ ],
95
+ });
96
+ exports.default = AuthToken;
97
+ //# sourceMappingURL=AuthToken.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthToken.js","sourceRoot":"","sources":["../../src/models/AuthToken.ts"],"names":[],"mappings":";;;AAAA,yCAAuD;AACvD,iDAA8C;AAuC9C,MAAa,SACX,SAAQ,iBAAuD;CAmBhE;AApBD,8BAoBC;AAED,SAAS,CAAC,IAAI,CACZ;IACE,EAAE,EAAE;QACF,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,YAAY,EAAE,qBAAS,CAAC,MAAM;QAC9B,UAAU,EAAE,IAAI;KACjB;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,qBAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;QACjD,SAAS,EAAE,KAAK;KACjB;IACD,WAAW,EAAE;QACX,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,KAAK;QAChB,OAAO,EAAE,mBAAmB;KAC7B;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,mBAAmB;KAC7B;IACD,SAAS,EAAE;QACT,IAAI,EAAE,qBAAS,CAAC,MAAM;QACtB,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,QAAQ;KACvB;IACD,SAAS,EAAE;QACT,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,IAAI;KAChB;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,KAAK;KACjB;IACD,MAAM,EAAE;QACN,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,IAAI;KAChB;IACD,KAAK,EAAE;QACL,IAAI,EAAE,qBAAS,CAAC,MAAM;QACtB,SAAS,EAAE,IAAI;KAChB;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,qBAAS,CAAC,MAAM;QACtB,SAAS,EAAE,IAAI;KAChB;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,gCAAgC;KAC1C;IACD,SAAS,EAAE;QACT,IAAI,EAAE,qBAAS,CAAC,MAAM;QACtB,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,qBAAqB;KAC/B;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,qBAAS,CAAC,OAAO;QACvB,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,IAAI;KACnB;IACD,aAAa,EAAE;QACb,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,IAAI;KAChB;IACD,SAAS,EAAE;QACT,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,KAAK;KACjB;IACD,SAAS,EAAE;QACT,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,KAAK;KACjB;CACF,EACD;IACE,SAAS,EAAE,mBAAQ,CAAC,SAAS;IAC7B,SAAS,EAAE,aAAa;IACxB,OAAO,EAAE;QACP;YACE,MAAM,EAAE,CAAC,UAAU,CAAC;SACrB;QACD;YACE,MAAM,EAAE,CAAC,UAAU,CAAC;SACrB;QACD;YACE,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;SACjC;KACF;CACF,CACF,CAAC;AAEF,kBAAe,SAAS,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { Model, Optional } from 'sequelize';
2
+ import { LLMProvider } from './AuthToken';
3
+ export interface ConversationAttributes {
4
+ id: string;
5
+ jobId: string;
6
+ provider: LLMProvider;
7
+ sessionId?: string;
8
+ isActive: boolean;
9
+ title?: string;
10
+ model: string;
11
+ systemPrompt?: string;
12
+ messageCount: number;
13
+ totalTokens?: number;
14
+ lastMessageAt?: Date;
15
+ createdAt: Date;
16
+ updatedAt: Date;
17
+ }
18
+ export interface ConversationCreationAttributes extends Optional<ConversationAttributes, 'id' | 'sessionId' | 'isActive' | 'title' | 'systemPrompt' | 'messageCount' | 'totalTokens' | 'lastMessageAt' | 'createdAt' | 'updatedAt'> {
19
+ }
20
+ export declare class Conversation extends Model<ConversationAttributes, ConversationCreationAttributes> implements ConversationAttributes {
21
+ id: string;
22
+ jobId: string;
23
+ provider: LLMProvider;
24
+ sessionId?: string;
25
+ isActive: boolean;
26
+ title?: string;
27
+ model: string;
28
+ systemPrompt?: string;
29
+ messageCount: number;
30
+ totalTokens?: number;
31
+ lastMessageAt?: Date;
32
+ createdAt: Date;
33
+ updatedAt: Date;
34
+ }
35
+ export default Conversation;
36
+ //# sourceMappingURL=Conversation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Conversation.d.ts","sourceRoot":"","sources":["../../src/models/Conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,8BACf,SAAQ,QAAQ,CACd,sBAAsB,EACpB,IAAI,GACJ,WAAW,GACX,UAAU,GACV,OAAO,GACP,cAAc,GACd,cAAc,GACd,aAAa,GACb,eAAe,GACf,WAAW,GACX,WAAW,CACd;CAAG;AAEN,qBAAa,YACX,SAAQ,KAAK,CAAC,sBAAsB,EAAE,8BAA8B,CACpE,YAAW,sBAAsB;IAEzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACzB;AA8FD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Conversation = void 0;
7
+ const sequelize_1 = require("sequelize");
8
+ const database_1 = require("../config/database");
9
+ const Job_1 = __importDefault(require("./Job"));
10
+ class Conversation extends sequelize_1.Model {
11
+ }
12
+ exports.Conversation = Conversation;
13
+ Conversation.init({
14
+ id: {
15
+ type: sequelize_1.DataTypes.UUID,
16
+ defaultValue: sequelize_1.DataTypes.UUIDV4,
17
+ primaryKey: true,
18
+ },
19
+ jobId: {
20
+ type: sequelize_1.DataTypes.UUID,
21
+ allowNull: false,
22
+ references: {
23
+ model: 'jobs',
24
+ key: 'id',
25
+ },
26
+ onDelete: 'CASCADE',
27
+ },
28
+ provider: {
29
+ type: sequelize_1.DataTypes.ENUM('claude', 'codex', 'gemini'),
30
+ allowNull: false,
31
+ },
32
+ sessionId: {
33
+ type: sequelize_1.DataTypes.STRING,
34
+ allowNull: true,
35
+ comment: 'Provider-specific session ID for resumption',
36
+ },
37
+ isActive: {
38
+ type: sequelize_1.DataTypes.BOOLEAN,
39
+ allowNull: false,
40
+ defaultValue: true,
41
+ },
42
+ title: {
43
+ type: sequelize_1.DataTypes.STRING,
44
+ allowNull: true,
45
+ },
46
+ model: {
47
+ type: sequelize_1.DataTypes.STRING,
48
+ allowNull: false,
49
+ },
50
+ systemPrompt: {
51
+ type: sequelize_1.DataTypes.TEXT,
52
+ allowNull: true,
53
+ },
54
+ messageCount: {
55
+ type: sequelize_1.DataTypes.INTEGER,
56
+ allowNull: false,
57
+ defaultValue: 0,
58
+ },
59
+ totalTokens: {
60
+ type: sequelize_1.DataTypes.INTEGER,
61
+ allowNull: true,
62
+ },
63
+ lastMessageAt: {
64
+ type: sequelize_1.DataTypes.DATE,
65
+ allowNull: true,
66
+ },
67
+ createdAt: {
68
+ type: sequelize_1.DataTypes.DATE,
69
+ allowNull: false,
70
+ },
71
+ updatedAt: {
72
+ type: sequelize_1.DataTypes.DATE,
73
+ allowNull: false,
74
+ },
75
+ }, {
76
+ sequelize: database_1.database.sequelize,
77
+ tableName: 'conversations',
78
+ indexes: [
79
+ {
80
+ fields: ['jobId'],
81
+ },
82
+ {
83
+ fields: ['sessionId'],
84
+ },
85
+ {
86
+ fields: ['isActive'],
87
+ },
88
+ ],
89
+ });
90
+ // Define associations
91
+ Conversation.belongsTo(Job_1.default, {
92
+ foreignKey: 'jobId',
93
+ as: 'job',
94
+ });
95
+ Job_1.default.hasMany(Conversation, {
96
+ foreignKey: 'jobId',
97
+ as: 'conversations',
98
+ });
99
+ exports.default = Conversation;
100
+ //# sourceMappingURL=Conversation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Conversation.js","sourceRoot":"","sources":["../../src/models/Conversation.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAuD;AACvD,iDAA8C;AAE9C,gDAAwB;AAiCxB,MAAa,YACX,SAAQ,iBAA6D;CAgBtE;AAjBD,oCAiBC;AAED,YAAY,CAAC,IAAI,CACf;IACE,EAAE,EAAE;QACF,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,YAAY,EAAE,qBAAS,CAAC,MAAM;QAC9B,UAAU,EAAE,IAAI;KACjB;IACD,KAAK,EAAE;QACL,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,KAAK;QAChB,UAAU,EAAE;YACV,KAAK,EAAE,MAAM;YACb,GAAG,EAAE,IAAI;SACV;QACD,QAAQ,EAAE,SAAS;KACpB;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,qBAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;QACjD,SAAS,EAAE,KAAK;KACjB;IACD,SAAS,EAAE;QACT,IAAI,EAAE,qBAAS,CAAC,MAAM;QACtB,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,6CAA6C;KACvD;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,qBAAS,CAAC,OAAO;QACvB,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,IAAI;KACnB;IACD,KAAK,EAAE;QACL,IAAI,EAAE,qBAAS,CAAC,MAAM;QACtB,SAAS,EAAE,IAAI;KAChB;IACD,KAAK,EAAE;QACL,IAAI,EAAE,qBAAS,CAAC,MAAM;QACtB,SAAS,EAAE,KAAK;KACjB;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,IAAI;KAChB;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,qBAAS,CAAC,OAAO;QACvB,SAAS,EAAE,KAAK;QAChB,YAAY,EAAE,CAAC;KAChB;IACD,WAAW,EAAE;QACX,IAAI,EAAE,qBAAS,CAAC,OAAO;QACvB,SAAS,EAAE,IAAI;KAChB;IACD,aAAa,EAAE;QACb,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,IAAI;KAChB;IACD,SAAS,EAAE;QACT,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,KAAK;KACjB;IACD,SAAS,EAAE;QACT,IAAI,EAAE,qBAAS,CAAC,IAAI;QACpB,SAAS,EAAE,KAAK;KACjB;CACF,EACD;IACE,SAAS,EAAE,mBAAQ,CAAC,SAAS;IAC7B,SAAS,EAAE,eAAe;IAC1B,OAAO,EAAE;QACP;YACE,MAAM,EAAE,CAAC,OAAO,CAAC;SAClB;QACD;YACE,MAAM,EAAE,CAAC,WAAW,CAAC;SACtB;QACD;YACE,MAAM,EAAE,CAAC,UAAU,CAAC;SACrB;KACF;CACF,CACF,CAAC;AAEF,sBAAsB;AACtB,YAAY,CAAC,SAAS,CAAC,aAAG,EAAE;IAC1B,UAAU,EAAE,OAAO;IACnB,EAAE,EAAE,KAAK;CACV,CAAC,CAAC;AAEH,aAAG,CAAC,OAAO,CAAC,YAAY,EAAE;IACxB,UAAU,EAAE,OAAO;IACnB,EAAE,EAAE,eAAe;CACpB,CAAC,CAAC;AAEH,kBAAe,YAAY,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { Model, Optional } from 'sequelize';
2
+ export type FileOperationType = 'read' | 'write' | 'edit' | 'delete' | 'create';
3
+ export interface FileOperationAttributes {
4
+ id: string;
5
+ jobId: string;
6
+ conversationId?: string;
7
+ operation: FileOperationType;
8
+ filePath: string;
9
+ relativeFilePath?: string;
10
+ contentBefore?: string;
11
+ contentAfter?: string;
12
+ fileSize?: number;
13
+ mimeType?: string;
14
+ success: boolean;
15
+ errorMessage?: string;
16
+ createdAt: Date;
17
+ }
18
+ export interface FileOperationCreationAttributes extends Optional<FileOperationAttributes, 'id' | 'conversationId' | 'relativeFilePath' | 'contentBefore' | 'contentAfter' | 'fileSize' | 'mimeType' | 'errorMessage' | 'createdAt'> {
19
+ }
20
+ export declare class FileOperation extends Model<FileOperationAttributes, FileOperationCreationAttributes> implements FileOperationAttributes {
21
+ id: string;
22
+ jobId: string;
23
+ conversationId?: string;
24
+ operation: FileOperationType;
25
+ filePath: string;
26
+ relativeFilePath?: string;
27
+ contentBefore?: string;
28
+ contentAfter?: string;
29
+ fileSize?: number;
30
+ mimeType?: string;
31
+ success: boolean;
32
+ errorMessage?: string;
33
+ createdAt: Date;
34
+ }
35
+ export default FileOperation;
36
+ //# sourceMappingURL=FileOperation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileOperation.d.ts","sourceRoot":"","sources":["../../src/models/FileOperation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAKvD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEhF,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,+BACf,SAAQ,QAAQ,CACd,uBAAuB,EACrB,IAAI,GACJ,gBAAgB,GAChB,kBAAkB,GAClB,eAAe,GACf,cAAc,GACd,UAAU,GACV,UAAU,GACV,cAAc,GACd,WAAW,CACd;CAAG;AAEN,qBAAa,aACX,SAAQ,KAAK,CAAC,uBAAuB,EAAE,+BAA+B,CACtE,YAAW,uBAAuB;IAE1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,IAAI,CAAC;CACzB;AAgHD,eAAe,aAAa,CAAC"}