archicore 0.1.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 (118) hide show
  1. package/README.md +530 -0
  2. package/dist/analyzers/dead-code.d.ts +95 -0
  3. package/dist/analyzers/dead-code.js +327 -0
  4. package/dist/analyzers/duplication.d.ts +90 -0
  5. package/dist/analyzers/duplication.js +344 -0
  6. package/dist/analyzers/security.d.ts +79 -0
  7. package/dist/analyzers/security.js +484 -0
  8. package/dist/architecture/index.d.ts +35 -0
  9. package/dist/architecture/index.js +249 -0
  10. package/dist/cli/commands/analyzers.d.ts +6 -0
  11. package/dist/cli/commands/analyzers.js +431 -0
  12. package/dist/cli/commands/export.d.ts +6 -0
  13. package/dist/cli/commands/export.js +78 -0
  14. package/dist/cli/commands/index.d.ts +8 -0
  15. package/dist/cli/commands/index.js +8 -0
  16. package/dist/cli/commands/init.d.ts +26 -0
  17. package/dist/cli/commands/init.js +140 -0
  18. package/dist/cli/commands/interactive.d.ts +7 -0
  19. package/dist/cli/commands/interactive.js +522 -0
  20. package/dist/cli/commands/projects.d.ts +6 -0
  21. package/dist/cli/commands/projects.js +249 -0
  22. package/dist/cli/index.d.ts +7 -0
  23. package/dist/cli/index.js +7 -0
  24. package/dist/cli/ui/box.d.ts +17 -0
  25. package/dist/cli/ui/box.js +62 -0
  26. package/dist/cli/ui/colors.d.ts +49 -0
  27. package/dist/cli/ui/colors.js +86 -0
  28. package/dist/cli/ui/index.d.ts +9 -0
  29. package/dist/cli/ui/index.js +9 -0
  30. package/dist/cli/ui/prompt.d.ts +34 -0
  31. package/dist/cli/ui/prompt.js +122 -0
  32. package/dist/cli/ui/spinner.d.ts +29 -0
  33. package/dist/cli/ui/spinner.js +80 -0
  34. package/dist/cli/ui/table.d.ts +33 -0
  35. package/dist/cli/ui/table.js +84 -0
  36. package/dist/cli/utils/config.d.ts +23 -0
  37. package/dist/cli/utils/config.js +73 -0
  38. package/dist/cli/utils/index.d.ts +6 -0
  39. package/dist/cli/utils/index.js +6 -0
  40. package/dist/cli/utils/session.d.ts +27 -0
  41. package/dist/cli/utils/session.js +117 -0
  42. package/dist/cli.d.ts +8 -0
  43. package/dist/cli.js +295 -0
  44. package/dist/code-index/ast-parser.d.ts +16 -0
  45. package/dist/code-index/ast-parser.js +330 -0
  46. package/dist/code-index/dependency-graph.d.ts +16 -0
  47. package/dist/code-index/dependency-graph.js +161 -0
  48. package/dist/code-index/index.d.ts +44 -0
  49. package/dist/code-index/index.js +124 -0
  50. package/dist/code-index/symbol-extractor.d.ts +13 -0
  51. package/dist/code-index/symbol-extractor.js +150 -0
  52. package/dist/export/index.d.ts +92 -0
  53. package/dist/export/index.js +676 -0
  54. package/dist/github/github-service.d.ts +146 -0
  55. package/dist/github/github-service.js +609 -0
  56. package/dist/impact-engine/index.d.ts +25 -0
  57. package/dist/impact-engine/index.js +284 -0
  58. package/dist/index.d.ts +60 -0
  59. package/dist/index.js +149 -0
  60. package/dist/metrics/index.d.ts +136 -0
  61. package/dist/metrics/index.js +525 -0
  62. package/dist/orchestrator/deepseek-optimizer.d.ts +67 -0
  63. package/dist/orchestrator/deepseek-optimizer.js +320 -0
  64. package/dist/orchestrator/index.d.ts +34 -0
  65. package/dist/orchestrator/index.js +305 -0
  66. package/dist/pr-guardian/index.d.ts +143 -0
  67. package/dist/pr-guardian/index.js +553 -0
  68. package/dist/refactoring/index.d.ts +108 -0
  69. package/dist/refactoring/index.js +580 -0
  70. package/dist/rules-engine/index.d.ts +129 -0
  71. package/dist/rules-engine/index.js +482 -0
  72. package/dist/semantic-memory/embedding-service.d.ts +24 -0
  73. package/dist/semantic-memory/embedding-service.js +120 -0
  74. package/dist/semantic-memory/index.d.ts +45 -0
  75. package/dist/semantic-memory/index.js +206 -0
  76. package/dist/semantic-memory/vector-store.d.ts +27 -0
  77. package/dist/semantic-memory/vector-store.js +166 -0
  78. package/dist/server/index.d.ts +28 -0
  79. package/dist/server/index.js +141 -0
  80. package/dist/server/middleware/api-auth.d.ts +43 -0
  81. package/dist/server/middleware/api-auth.js +256 -0
  82. package/dist/server/routes/admin.d.ts +5 -0
  83. package/dist/server/routes/admin.js +123 -0
  84. package/dist/server/routes/api.d.ts +7 -0
  85. package/dist/server/routes/api.js +362 -0
  86. package/dist/server/routes/auth.d.ts +16 -0
  87. package/dist/server/routes/auth.js +191 -0
  88. package/dist/server/routes/developer.d.ts +8 -0
  89. package/dist/server/routes/developer.js +439 -0
  90. package/dist/server/routes/github.d.ts +7 -0
  91. package/dist/server/routes/github.js +495 -0
  92. package/dist/server/routes/upload.d.ts +7 -0
  93. package/dist/server/routes/upload.js +196 -0
  94. package/dist/server/services/api-key-service.d.ts +81 -0
  95. package/dist/server/services/api-key-service.js +281 -0
  96. package/dist/server/services/auth-service.d.ts +40 -0
  97. package/dist/server/services/auth-service.js +315 -0
  98. package/dist/server/services/project-service.d.ts +123 -0
  99. package/dist/server/services/project-service.js +533 -0
  100. package/dist/server/services/token-service.d.ts +107 -0
  101. package/dist/server/services/token-service.js +416 -0
  102. package/dist/server/services/upload-service.d.ts +93 -0
  103. package/dist/server/services/upload-service.js +464 -0
  104. package/dist/types/api.d.ts +188 -0
  105. package/dist/types/api.js +86 -0
  106. package/dist/types/github.d.ts +335 -0
  107. package/dist/types/github.js +5 -0
  108. package/dist/types/index.d.ts +265 -0
  109. package/dist/types/index.js +32 -0
  110. package/dist/types/user.d.ts +69 -0
  111. package/dist/types/user.js +42 -0
  112. package/dist/utils/file-utils.d.ts +20 -0
  113. package/dist/utils/file-utils.js +163 -0
  114. package/dist/utils/logger.d.ts +17 -0
  115. package/dist/utils/logger.js +41 -0
  116. package/dist/watcher/index.d.ts +125 -0
  117. package/dist/watcher/index.js +397 -0
  118. package/package.json +71 -0
@@ -0,0 +1,362 @@
1
+ /**
2
+ * ArchiCore API Routes
3
+ *
4
+ * REST API для Architecture Digital Twin
5
+ */
6
+ import { Router } from 'express';
7
+ import { ProjectService } from '../services/project-service.js';
8
+ import { Logger } from '../../utils/logger.js';
9
+ import { ExportManager } from '../../export/index.js';
10
+ export const apiRouter = Router();
11
+ // Singleton сервиса проектов
12
+ const projectService = new ProjectService();
13
+ /**
14
+ * GET /api/projects
15
+ * Получить список проектов
16
+ */
17
+ apiRouter.get('/projects', async (_req, res) => {
18
+ try {
19
+ const projects = await projectService.listProjects();
20
+ res.json({ projects });
21
+ }
22
+ catch (error) {
23
+ Logger.error('Failed to list projects:', error);
24
+ res.status(500).json({ error: 'Failed to list projects' });
25
+ }
26
+ });
27
+ /**
28
+ * POST /api/projects
29
+ * Создать/подключить новый проект
30
+ */
31
+ apiRouter.post('/projects', async (req, res) => {
32
+ try {
33
+ const { name, path: projectPath } = req.body;
34
+ if (!name || !projectPath) {
35
+ res.status(400).json({ error: 'Name and path are required' });
36
+ return;
37
+ }
38
+ const project = await projectService.createProject(name, projectPath);
39
+ res.json({ project });
40
+ }
41
+ catch (error) {
42
+ Logger.error('Failed to create project:', error);
43
+ res.status(500).json({ error: 'Failed to create project' });
44
+ }
45
+ });
46
+ /**
47
+ * GET /api/projects/:id
48
+ * Получить информацию о проекте
49
+ */
50
+ apiRouter.get('/projects/:id', async (req, res) => {
51
+ try {
52
+ const { id } = req.params;
53
+ const project = await projectService.getProject(id);
54
+ if (!project) {
55
+ res.status(404).json({ error: 'Project not found' });
56
+ return;
57
+ }
58
+ res.json({ project });
59
+ }
60
+ catch (error) {
61
+ Logger.error('Failed to get project:', error);
62
+ res.status(500).json({ error: 'Failed to get project' });
63
+ }
64
+ });
65
+ /**
66
+ * POST /api/projects/:id/index
67
+ * Запустить индексацию проекта
68
+ */
69
+ apiRouter.post('/projects/:id/index', async (req, res) => {
70
+ try {
71
+ const { id } = req.params;
72
+ const result = await projectService.indexProject(id);
73
+ res.json(result);
74
+ }
75
+ catch (error) {
76
+ Logger.error('Failed to index project:', error);
77
+ res.status(500).json({ error: 'Failed to index project' });
78
+ }
79
+ });
80
+ /**
81
+ * GET /api/projects/:id/architecture
82
+ * Получить архитектурную модель (Digital Twin)
83
+ */
84
+ apiRouter.get('/projects/:id/architecture', async (req, res) => {
85
+ try {
86
+ const { id } = req.params;
87
+ const architecture = await projectService.getArchitecture(id);
88
+ res.json(architecture);
89
+ }
90
+ catch (error) {
91
+ Logger.error('Failed to get architecture:', error);
92
+ res.status(500).json({ error: 'Failed to get architecture' });
93
+ }
94
+ });
95
+ /**
96
+ * GET /api/projects/:id/graph
97
+ * Получить граф зависимостей для визуализации
98
+ */
99
+ apiRouter.get('/projects/:id/graph', async (req, res) => {
100
+ try {
101
+ const { id } = req.params;
102
+ const graph = await projectService.getDependencyGraph(id);
103
+ res.json(graph);
104
+ }
105
+ catch (error) {
106
+ Logger.error('Failed to get dependency graph:', error);
107
+ res.status(500).json({ error: 'Failed to get dependency graph' });
108
+ }
109
+ });
110
+ /**
111
+ * POST /api/projects/:id/analyze
112
+ * Анализ влияния изменений
113
+ */
114
+ apiRouter.post('/projects/:id/analyze', async (req, res) => {
115
+ try {
116
+ const { id } = req.params;
117
+ const { description, files, symbols, type } = req.body;
118
+ if (!description) {
119
+ res.status(400).json({ error: 'Description is required' });
120
+ return;
121
+ }
122
+ const impact = await projectService.analyzeImpact(id, {
123
+ description,
124
+ files: files || [],
125
+ symbols: symbols || [],
126
+ type: type || 'modify'
127
+ });
128
+ res.json(impact);
129
+ }
130
+ catch (error) {
131
+ Logger.error('Failed to analyze impact:', error);
132
+ res.status(500).json({ error: 'Failed to analyze impact' });
133
+ }
134
+ });
135
+ /**
136
+ * POST /api/projects/:id/simulate
137
+ * Симуляция изменения (что будет если...)
138
+ */
139
+ apiRouter.post('/projects/:id/simulate', async (req, res) => {
140
+ try {
141
+ const { id } = req.params;
142
+ const { change } = req.body;
143
+ if (!change) {
144
+ res.status(400).json({ error: 'Change description is required' });
145
+ return;
146
+ }
147
+ const simulation = await projectService.simulateChange(id, change);
148
+ res.json(simulation);
149
+ }
150
+ catch (error) {
151
+ Logger.error('Failed to simulate change:', error);
152
+ res.status(500).json({ error: 'Failed to simulate change' });
153
+ }
154
+ });
155
+ /**
156
+ * POST /api/projects/:id/search
157
+ * Семантический поиск по коду
158
+ */
159
+ apiRouter.post('/projects/:id/search', async (req, res) => {
160
+ try {
161
+ const { id } = req.params;
162
+ const { query, limit = 10 } = req.body;
163
+ if (!query) {
164
+ res.status(400).json({ error: 'Query is required' });
165
+ return;
166
+ }
167
+ const results = await projectService.semanticSearch(id, query, limit);
168
+ res.json({ results });
169
+ }
170
+ catch (error) {
171
+ Logger.error('Failed to search:', error);
172
+ res.status(500).json({ error: 'Failed to search' });
173
+ }
174
+ });
175
+ /**
176
+ * POST /api/projects/:id/ask
177
+ * Задать вопрос AI-архитектору
178
+ */
179
+ apiRouter.post('/projects/:id/ask', async (req, res) => {
180
+ try {
181
+ const { id } = req.params;
182
+ const { question, language } = req.body;
183
+ if (!question) {
184
+ res.status(400).json({ error: 'Question is required' });
185
+ return;
186
+ }
187
+ const answer = await projectService.askArchitect(id, question, language || 'en');
188
+ res.json({ answer });
189
+ }
190
+ catch (error) {
191
+ Logger.error('Failed to ask architect:', error);
192
+ res.status(500).json({ error: 'Failed to ask architect' });
193
+ }
194
+ });
195
+ /**
196
+ * GET /api/projects/:id/stats
197
+ * Получить статистику проекта
198
+ */
199
+ apiRouter.get('/projects/:id/stats', async (req, res) => {
200
+ try {
201
+ const { id } = req.params;
202
+ const stats = await projectService.getStatistics(id);
203
+ res.json(stats);
204
+ }
205
+ catch (error) {
206
+ Logger.error('Failed to get stats:', error);
207
+ res.status(500).json({ error: 'Failed to get statistics' });
208
+ }
209
+ });
210
+ /**
211
+ * DELETE /api/projects/:id
212
+ * Удалить проект
213
+ */
214
+ apiRouter.delete('/projects/:id', async (req, res) => {
215
+ try {
216
+ const { id } = req.params;
217
+ await projectService.deleteProject(id);
218
+ res.json({ success: true });
219
+ }
220
+ catch (error) {
221
+ Logger.error('Failed to delete project:', error);
222
+ res.status(500).json({ error: 'Failed to delete project' });
223
+ }
224
+ });
225
+ /**
226
+ * GET /api/projects/:id/metrics
227
+ * Получить метрики кода
228
+ */
229
+ apiRouter.get('/projects/:id/metrics', async (req, res) => {
230
+ try {
231
+ const { id } = req.params;
232
+ const metrics = await projectService.getMetrics(id);
233
+ res.json(metrics);
234
+ }
235
+ catch (error) {
236
+ Logger.error('Failed to get metrics:', error);
237
+ res.status(500).json({ error: 'Failed to get metrics' });
238
+ }
239
+ });
240
+ /**
241
+ * GET /api/projects/:id/rules
242
+ * Проверить правила архитектуры
243
+ */
244
+ apiRouter.get('/projects/:id/rules', async (req, res) => {
245
+ try {
246
+ const { id } = req.params;
247
+ const result = await projectService.checkRules(id);
248
+ res.json(result);
249
+ }
250
+ catch (error) {
251
+ Logger.error('Failed to check rules:', error);
252
+ res.status(500).json({ error: 'Failed to check rules' });
253
+ }
254
+ });
255
+ /**
256
+ * GET /api/projects/:id/dead-code
257
+ * Найти мёртвый код
258
+ */
259
+ apiRouter.get('/projects/:id/dead-code', async (req, res) => {
260
+ try {
261
+ const { id } = req.params;
262
+ const result = await projectService.findDeadCode(id);
263
+ res.json(result);
264
+ }
265
+ catch (error) {
266
+ Logger.error('Failed to find dead code:', error);
267
+ res.status(500).json({ error: 'Failed to find dead code' });
268
+ }
269
+ });
270
+ /**
271
+ * GET /api/projects/:id/duplication
272
+ * Найти дублирование кода
273
+ */
274
+ apiRouter.get('/projects/:id/duplication', async (req, res) => {
275
+ try {
276
+ const { id } = req.params;
277
+ const result = await projectService.findDuplication(id);
278
+ res.json(result);
279
+ }
280
+ catch (error) {
281
+ Logger.error('Failed to find duplication:', error);
282
+ res.status(500).json({ error: 'Failed to find duplication' });
283
+ }
284
+ });
285
+ /**
286
+ * GET /api/projects/:id/security
287
+ * Анализ безопасности
288
+ */
289
+ apiRouter.get('/projects/:id/security', async (req, res) => {
290
+ try {
291
+ const { id } = req.params;
292
+ const result = await projectService.analyzeSecurity(id);
293
+ res.json(result);
294
+ }
295
+ catch (error) {
296
+ Logger.error('Failed to analyze security:', error);
297
+ res.status(500).json({ error: 'Failed to analyze security' });
298
+ }
299
+ });
300
+ /**
301
+ * GET /api/projects/:id/refactoring
302
+ * Получить предложения по рефакторингу
303
+ */
304
+ apiRouter.get('/projects/:id/refactoring', async (req, res) => {
305
+ try {
306
+ const { id } = req.params;
307
+ const result = await projectService.getRefactoringSuggestions(id);
308
+ res.json(result);
309
+ }
310
+ catch (error) {
311
+ Logger.error('Failed to get refactoring suggestions:', error);
312
+ res.status(500).json({ error: 'Failed to get refactoring suggestions' });
313
+ }
314
+ });
315
+ /**
316
+ * POST /api/projects/:id/export
317
+ * Экспорт данных проекта
318
+ */
319
+ apiRouter.post('/projects/:id/export', async (req, res) => {
320
+ try {
321
+ const { id } = req.params;
322
+ const options = req.body;
323
+ if (!options.format) {
324
+ res.status(400).json({ error: 'Format is required' });
325
+ return;
326
+ }
327
+ const exportData = await projectService.getExportData(id);
328
+ const exportManager = new ExportManager();
329
+ const result = await exportManager.export(exportData, options);
330
+ // Устанавливаем правильный content-type
331
+ const contentTypes = {
332
+ json: 'application/json',
333
+ html: 'text/html',
334
+ markdown: 'text/markdown',
335
+ csv: 'text/csv',
336
+ graphml: 'application/xml'
337
+ };
338
+ res.setHeader('Content-Type', contentTypes[options.format] || 'text/plain');
339
+ res.setHeader('Content-Disposition', `attachment; filename="archicore-export.${options.format === 'markdown' ? 'md' : options.format}"`);
340
+ res.send(result);
341
+ }
342
+ catch (error) {
343
+ Logger.error('Failed to export:', error);
344
+ res.status(500).json({ error: 'Failed to export' });
345
+ }
346
+ });
347
+ /**
348
+ * POST /api/projects/:id/full-analysis
349
+ * Полный анализ проекта (все анализаторы)
350
+ */
351
+ apiRouter.post('/projects/:id/full-analysis', async (req, res) => {
352
+ try {
353
+ const { id } = req.params;
354
+ const result = await projectService.runFullAnalysis(id);
355
+ res.json(result);
356
+ }
357
+ catch (error) {
358
+ Logger.error('Failed to run full analysis:', error);
359
+ res.status(500).json({ error: 'Failed to run full analysis' });
360
+ }
361
+ });
362
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Authentication API Routes for ArchiCore
3
+ */
4
+ import { Request, Response, NextFunction } from 'express';
5
+ import { User } from '../../types/user.js';
6
+ export declare const authRouter: import("express-serve-static-core").Router;
7
+ declare global {
8
+ namespace Express {
9
+ interface Request {
10
+ user?: User;
11
+ }
12
+ }
13
+ }
14
+ export declare function authMiddleware(req: Request, res: Response, next: NextFunction): Promise<void>;
15
+ export declare function adminMiddleware(req: Request, res: Response, next: NextFunction): Promise<void>;
16
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Authentication API Routes for ArchiCore
3
+ */
4
+ import { Router } from 'express';
5
+ import { AuthService } from '../services/auth-service.js';
6
+ import { Logger } from '../../utils/logger.js';
7
+ export const authRouter = Router();
8
+ const authService = new AuthService();
9
+ // Middleware to check authentication
10
+ export async function authMiddleware(req, res, next) {
11
+ const authHeader = req.headers.authorization;
12
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
13
+ res.status(401).json({ error: 'No token provided' });
14
+ return;
15
+ }
16
+ const token = authHeader.substring(7);
17
+ const user = await authService.validateToken(token);
18
+ if (!user) {
19
+ res.status(401).json({ error: 'Invalid or expired token' });
20
+ return;
21
+ }
22
+ req.user = user;
23
+ next();
24
+ }
25
+ // Middleware to check admin role
26
+ export async function adminMiddleware(req, res, next) {
27
+ if (!req.user || req.user.tier !== 'admin') {
28
+ res.status(403).json({ error: 'Admin access required' });
29
+ return;
30
+ }
31
+ next();
32
+ }
33
+ /**
34
+ * POST /api/auth/register
35
+ * Register new user
36
+ */
37
+ authRouter.post('/register', async (req, res) => {
38
+ try {
39
+ const { email, username, password } = req.body;
40
+ if (!email || !username || !password) {
41
+ res.status(400).json({ success: false, error: 'Email, username, and password are required' });
42
+ return;
43
+ }
44
+ if (password.length < 8) {
45
+ res.status(400).json({ success: false, error: 'Password must be at least 8 characters' });
46
+ return;
47
+ }
48
+ const result = await authService.register(email, username, password);
49
+ res.json(result);
50
+ }
51
+ catch (error) {
52
+ Logger.error('Registration error:', error);
53
+ res.status(500).json({ success: false, error: 'Registration failed' });
54
+ }
55
+ });
56
+ /**
57
+ * POST /api/auth/login
58
+ * Login with email/password
59
+ */
60
+ authRouter.post('/login', async (req, res) => {
61
+ try {
62
+ const { email, password } = req.body;
63
+ if (!email || !password) {
64
+ res.status(400).json({ success: false, error: 'Email and password are required' });
65
+ return;
66
+ }
67
+ const result = await authService.login(email, password);
68
+ res.json(result);
69
+ }
70
+ catch (error) {
71
+ Logger.error('Login error:', error);
72
+ res.status(500).json({ success: false, error: 'Login failed' });
73
+ }
74
+ });
75
+ /**
76
+ * POST /api/auth/logout
77
+ * Logout current user
78
+ */
79
+ authRouter.post('/logout', authMiddleware, async (req, res) => {
80
+ try {
81
+ const token = req.headers.authorization?.substring(7);
82
+ if (token) {
83
+ await authService.logout(token);
84
+ }
85
+ res.json({ success: true });
86
+ }
87
+ catch (error) {
88
+ Logger.error('Logout error:', error);
89
+ res.status(500).json({ success: false, error: 'Logout failed' });
90
+ }
91
+ });
92
+ /**
93
+ * GET /api/auth/me
94
+ * Get current user info
95
+ */
96
+ authRouter.get('/me', authMiddleware, async (req, res) => {
97
+ try {
98
+ if (!req.user) {
99
+ res.status(401).json({ error: 'Not authenticated' });
100
+ return;
101
+ }
102
+ // Remove sensitive data
103
+ const { passwordHash, ...user } = req.user;
104
+ res.json({ user });
105
+ }
106
+ catch (error) {
107
+ Logger.error('Get user error:', error);
108
+ res.status(500).json({ error: 'Failed to get user info' });
109
+ }
110
+ });
111
+ /**
112
+ * PUT /api/auth/me
113
+ * Update current user profile
114
+ */
115
+ authRouter.put('/me', authMiddleware, async (req, res) => {
116
+ try {
117
+ const { username, email, avatar } = req.body;
118
+ if (!req.user) {
119
+ res.status(401).json({ error: 'Not authenticated' });
120
+ return;
121
+ }
122
+ const updated = await authService.updateUser(req.user.id, { username, email, avatar });
123
+ if (!updated) {
124
+ res.status(400).json({ error: 'Failed to update profile' });
125
+ return;
126
+ }
127
+ const user = await authService.getUser(req.user.id);
128
+ if (user) {
129
+ const { passwordHash, ...sanitized } = user;
130
+ res.json({ success: true, user: sanitized });
131
+ }
132
+ else {
133
+ res.status(404).json({ error: 'User not found' });
134
+ }
135
+ }
136
+ catch (error) {
137
+ Logger.error('Update user error:', error);
138
+ res.status(500).json({ error: 'Failed to update profile' });
139
+ }
140
+ });
141
+ /**
142
+ * POST /api/auth/oauth/:provider
143
+ * OAuth login (GitHub, Google)
144
+ */
145
+ authRouter.post('/oauth/:provider', async (req, res) => {
146
+ try {
147
+ const { provider } = req.params;
148
+ const { profile } = req.body;
149
+ if (provider !== 'github' && provider !== 'google') {
150
+ res.status(400).json({ success: false, error: 'Invalid provider' });
151
+ return;
152
+ }
153
+ if (!profile || !profile.id || !profile.email) {
154
+ res.status(400).json({ success: false, error: 'Invalid profile data' });
155
+ return;
156
+ }
157
+ const result = await authService.oauthLogin(provider, profile);
158
+ res.json(result);
159
+ }
160
+ catch (error) {
161
+ Logger.error('OAuth error:', error);
162
+ res.status(500).json({ success: false, error: 'OAuth login failed' });
163
+ }
164
+ });
165
+ /**
166
+ * GET /api/auth/usage
167
+ * Get current user's usage stats
168
+ */
169
+ authRouter.get('/usage', authMiddleware, async (req, res) => {
170
+ try {
171
+ if (!req.user) {
172
+ res.status(401).json({ error: 'Not authenticated' });
173
+ return;
174
+ }
175
+ const user = await authService.getUser(req.user.id);
176
+ if (!user) {
177
+ res.status(404).json({ error: 'User not found' });
178
+ return;
179
+ }
180
+ res.json({
181
+ tier: user.tier,
182
+ usage: user.usage,
183
+ subscription: user.subscription
184
+ });
185
+ }
186
+ catch (error) {
187
+ Logger.error('Get usage error:', error);
188
+ res.status(500).json({ error: 'Failed to get usage' });
189
+ }
190
+ });
191
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Developer API Routes for ArchiCore
3
+ *
4
+ * REST API для разработчиков с токенизированной тарификацией
5
+ * Формат ответов совместим с OpenAI/Anthropic API
6
+ */
7
+ export declare const developerRouter: import("express-serve-static-core").Router;
8
+ //# sourceMappingURL=developer.d.ts.map