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.
- package/README.md +530 -0
- package/dist/analyzers/dead-code.d.ts +95 -0
- package/dist/analyzers/dead-code.js +327 -0
- package/dist/analyzers/duplication.d.ts +90 -0
- package/dist/analyzers/duplication.js +344 -0
- package/dist/analyzers/security.d.ts +79 -0
- package/dist/analyzers/security.js +484 -0
- package/dist/architecture/index.d.ts +35 -0
- package/dist/architecture/index.js +249 -0
- package/dist/cli/commands/analyzers.d.ts +6 -0
- package/dist/cli/commands/analyzers.js +431 -0
- package/dist/cli/commands/export.d.ts +6 -0
- package/dist/cli/commands/export.js +78 -0
- package/dist/cli/commands/index.d.ts +8 -0
- package/dist/cli/commands/index.js +8 -0
- package/dist/cli/commands/init.d.ts +26 -0
- package/dist/cli/commands/init.js +140 -0
- package/dist/cli/commands/interactive.d.ts +7 -0
- package/dist/cli/commands/interactive.js +522 -0
- package/dist/cli/commands/projects.d.ts +6 -0
- package/dist/cli/commands/projects.js +249 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/ui/box.d.ts +17 -0
- package/dist/cli/ui/box.js +62 -0
- package/dist/cli/ui/colors.d.ts +49 -0
- package/dist/cli/ui/colors.js +86 -0
- package/dist/cli/ui/index.d.ts +9 -0
- package/dist/cli/ui/index.js +9 -0
- package/dist/cli/ui/prompt.d.ts +34 -0
- package/dist/cli/ui/prompt.js +122 -0
- package/dist/cli/ui/spinner.d.ts +29 -0
- package/dist/cli/ui/spinner.js +80 -0
- package/dist/cli/ui/table.d.ts +33 -0
- package/dist/cli/ui/table.js +84 -0
- package/dist/cli/utils/config.d.ts +23 -0
- package/dist/cli/utils/config.js +73 -0
- package/dist/cli/utils/index.d.ts +6 -0
- package/dist/cli/utils/index.js +6 -0
- package/dist/cli/utils/session.d.ts +27 -0
- package/dist/cli/utils/session.js +117 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +295 -0
- package/dist/code-index/ast-parser.d.ts +16 -0
- package/dist/code-index/ast-parser.js +330 -0
- package/dist/code-index/dependency-graph.d.ts +16 -0
- package/dist/code-index/dependency-graph.js +161 -0
- package/dist/code-index/index.d.ts +44 -0
- package/dist/code-index/index.js +124 -0
- package/dist/code-index/symbol-extractor.d.ts +13 -0
- package/dist/code-index/symbol-extractor.js +150 -0
- package/dist/export/index.d.ts +92 -0
- package/dist/export/index.js +676 -0
- package/dist/github/github-service.d.ts +146 -0
- package/dist/github/github-service.js +609 -0
- package/dist/impact-engine/index.d.ts +25 -0
- package/dist/impact-engine/index.js +284 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +149 -0
- package/dist/metrics/index.d.ts +136 -0
- package/dist/metrics/index.js +525 -0
- package/dist/orchestrator/deepseek-optimizer.d.ts +67 -0
- package/dist/orchestrator/deepseek-optimizer.js +320 -0
- package/dist/orchestrator/index.d.ts +34 -0
- package/dist/orchestrator/index.js +305 -0
- package/dist/pr-guardian/index.d.ts +143 -0
- package/dist/pr-guardian/index.js +553 -0
- package/dist/refactoring/index.d.ts +108 -0
- package/dist/refactoring/index.js +580 -0
- package/dist/rules-engine/index.d.ts +129 -0
- package/dist/rules-engine/index.js +482 -0
- package/dist/semantic-memory/embedding-service.d.ts +24 -0
- package/dist/semantic-memory/embedding-service.js +120 -0
- package/dist/semantic-memory/index.d.ts +45 -0
- package/dist/semantic-memory/index.js +206 -0
- package/dist/semantic-memory/vector-store.d.ts +27 -0
- package/dist/semantic-memory/vector-store.js +166 -0
- package/dist/server/index.d.ts +28 -0
- package/dist/server/index.js +141 -0
- package/dist/server/middleware/api-auth.d.ts +43 -0
- package/dist/server/middleware/api-auth.js +256 -0
- package/dist/server/routes/admin.d.ts +5 -0
- package/dist/server/routes/admin.js +123 -0
- package/dist/server/routes/api.d.ts +7 -0
- package/dist/server/routes/api.js +362 -0
- package/dist/server/routes/auth.d.ts +16 -0
- package/dist/server/routes/auth.js +191 -0
- package/dist/server/routes/developer.d.ts +8 -0
- package/dist/server/routes/developer.js +439 -0
- package/dist/server/routes/github.d.ts +7 -0
- package/dist/server/routes/github.js +495 -0
- package/dist/server/routes/upload.d.ts +7 -0
- package/dist/server/routes/upload.js +196 -0
- package/dist/server/services/api-key-service.d.ts +81 -0
- package/dist/server/services/api-key-service.js +281 -0
- package/dist/server/services/auth-service.d.ts +40 -0
- package/dist/server/services/auth-service.js +315 -0
- package/dist/server/services/project-service.d.ts +123 -0
- package/dist/server/services/project-service.js +533 -0
- package/dist/server/services/token-service.d.ts +107 -0
- package/dist/server/services/token-service.js +416 -0
- package/dist/server/services/upload-service.d.ts +93 -0
- package/dist/server/services/upload-service.js +464 -0
- package/dist/types/api.d.ts +188 -0
- package/dist/types/api.js +86 -0
- package/dist/types/github.d.ts +335 -0
- package/dist/types/github.js +5 -0
- package/dist/types/index.d.ts +265 -0
- package/dist/types/index.js +32 -0
- package/dist/types/user.d.ts +69 -0
- package/dist/types/user.js +42 -0
- package/dist/utils/file-utils.d.ts +20 -0
- package/dist/utils/file-utils.js +163 -0
- package/dist/utils/logger.d.ts +17 -0
- package/dist/utils/logger.js +41 -0
- package/dist/watcher/index.d.ts +125 -0
- package/dist/watcher/index.js +397 -0
- package/package.json +71 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Developer API Routes for ArchiCore
|
|
3
|
+
*
|
|
4
|
+
* REST API для разработчиков с токенизированной тарификацией
|
|
5
|
+
* Формат ответов совместим с OpenAI/Anthropic API
|
|
6
|
+
*/
|
|
7
|
+
import { Router } from 'express';
|
|
8
|
+
import { ApiKeyService } from '../services/api-key-service.js';
|
|
9
|
+
import { TokenService } from '../services/token-service.js';
|
|
10
|
+
import { ProjectService } from '../services/project-service.js';
|
|
11
|
+
import { authMiddleware } from './auth.js';
|
|
12
|
+
import { apiKeyAuth, requirePermission, trackUsage, apiErrorHandler } from '../middleware/api-auth.js';
|
|
13
|
+
import { Logger } from '../../utils/logger.js';
|
|
14
|
+
export const developerRouter = Router();
|
|
15
|
+
// Services
|
|
16
|
+
const apiKeyService = new ApiKeyService();
|
|
17
|
+
const tokenService = new TokenService();
|
|
18
|
+
const projectService = new ProjectService();
|
|
19
|
+
// ========================================
|
|
20
|
+
// API KEY MANAGEMENT (requires user auth)
|
|
21
|
+
// ========================================
|
|
22
|
+
/**
|
|
23
|
+
* POST /api/developer/keys
|
|
24
|
+
* Создание нового API ключа
|
|
25
|
+
*/
|
|
26
|
+
developerRouter.post('/keys', authMiddleware, async (req, res) => {
|
|
27
|
+
try {
|
|
28
|
+
if (!req.user) {
|
|
29
|
+
res.status(401).json({ error: { message: 'Not authenticated' } });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const request = {
|
|
33
|
+
name: req.body.name || 'Default Key',
|
|
34
|
+
permissions: req.body.permissions,
|
|
35
|
+
expiresIn: req.body.expiresIn,
|
|
36
|
+
rateLimit: req.body.rateLimit
|
|
37
|
+
};
|
|
38
|
+
const result = await apiKeyService.createKey(req.user.id, request);
|
|
39
|
+
if (!result.success) {
|
|
40
|
+
res.status(400).json({ error: { message: result.error } });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
res.status(201).json({
|
|
44
|
+
success: true,
|
|
45
|
+
data: result.apiKey,
|
|
46
|
+
message: 'API key created successfully. Save the key now - it will not be shown again!'
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
Logger.error('Create API key error:', error);
|
|
51
|
+
res.status(500).json({ error: { message: 'Failed to create API key' } });
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
/**
|
|
55
|
+
* GET /api/developer/keys
|
|
56
|
+
* Получение списка API ключей
|
|
57
|
+
*/
|
|
58
|
+
developerRouter.get('/keys', authMiddleware, async (req, res) => {
|
|
59
|
+
try {
|
|
60
|
+
if (!req.user) {
|
|
61
|
+
res.status(401).json({ error: { message: 'Not authenticated' } });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const result = await apiKeyService.listKeys(req.user.id);
|
|
65
|
+
res.json({ success: true, data: result.keys });
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
Logger.error('List API keys error:', error);
|
|
69
|
+
res.status(500).json({ error: { message: 'Failed to list API keys' } });
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
/**
|
|
73
|
+
* DELETE /api/developer/keys/:keyId
|
|
74
|
+
* Удаление API ключа
|
|
75
|
+
*/
|
|
76
|
+
developerRouter.delete('/keys/:keyId', authMiddleware, async (req, res) => {
|
|
77
|
+
try {
|
|
78
|
+
if (!req.user) {
|
|
79
|
+
res.status(401).json({ error: { message: 'Not authenticated' } });
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const deleted = await apiKeyService.deleteKey(req.params.keyId, req.user.id);
|
|
83
|
+
if (!deleted) {
|
|
84
|
+
res.status(404).json({ error: { message: 'API key not found' } });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
res.json({ success: true, message: 'API key deleted' });
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
Logger.error('Delete API key error:', error);
|
|
91
|
+
res.status(500).json({ error: { message: 'Failed to delete API key' } });
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
/**
|
|
95
|
+
* POST /api/developer/keys/:keyId/revoke
|
|
96
|
+
* Отзыв API ключа (деактивация без удаления)
|
|
97
|
+
*/
|
|
98
|
+
developerRouter.post('/keys/:keyId/revoke', authMiddleware, async (req, res) => {
|
|
99
|
+
try {
|
|
100
|
+
if (!req.user) {
|
|
101
|
+
res.status(401).json({ error: { message: 'Not authenticated' } });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const revoked = await apiKeyService.revokeKey(req.params.keyId, req.user.id);
|
|
105
|
+
if (!revoked) {
|
|
106
|
+
res.status(404).json({ error: { message: 'API key not found' } });
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
res.json({ success: true, message: 'API key revoked' });
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
Logger.error('Revoke API key error:', error);
|
|
113
|
+
res.status(500).json({ error: { message: 'Failed to revoke API key' } });
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
// ========================================
|
|
117
|
+
// USAGE & BILLING (requires user auth)
|
|
118
|
+
// ========================================
|
|
119
|
+
/**
|
|
120
|
+
* GET /api/developer/usage
|
|
121
|
+
* Получение статистики использования
|
|
122
|
+
*/
|
|
123
|
+
developerRouter.get('/usage', authMiddleware, async (req, res) => {
|
|
124
|
+
try {
|
|
125
|
+
if (!req.user) {
|
|
126
|
+
res.status(401).json({ error: { message: 'Not authenticated' } });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const period = req.query.period || 'month';
|
|
130
|
+
const stats = await tokenService.getUsageStats(req.user.id, period);
|
|
131
|
+
const billing = await tokenService.getBillingAccount(req.user.id);
|
|
132
|
+
res.json({
|
|
133
|
+
success: true,
|
|
134
|
+
data: {
|
|
135
|
+
stats,
|
|
136
|
+
billing: {
|
|
137
|
+
tier: billing.pricingTier,
|
|
138
|
+
balance: billing.balance / 100, // в долларах
|
|
139
|
+
tokensUsed: billing.tokensUsedThisMonth,
|
|
140
|
+
tokensIncluded: billing.tokensIncludedThisMonth,
|
|
141
|
+
tokensRemaining: Math.max(0, billing.tokensIncludedThisMonth - billing.tokensUsedThisMonth),
|
|
142
|
+
billingCycleEnd: billing.billingCycleEnd
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
Logger.error('Get usage error:', error);
|
|
149
|
+
res.status(500).json({ error: { message: 'Failed to get usage stats' } });
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
/**
|
|
153
|
+
* GET /api/developer/usage/history
|
|
154
|
+
* История использования
|
|
155
|
+
*/
|
|
156
|
+
developerRouter.get('/usage/history', authMiddleware, async (req, res) => {
|
|
157
|
+
try {
|
|
158
|
+
if (!req.user) {
|
|
159
|
+
res.status(401).json({ error: { message: 'Not authenticated' } });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const history = await tokenService.getUsageHistory(req.user.id, {
|
|
163
|
+
limit: parseInt(req.query.limit) || 100,
|
|
164
|
+
offset: parseInt(req.query.offset) || 0,
|
|
165
|
+
apiKeyId: req.query.keyId,
|
|
166
|
+
operation: req.query.operation
|
|
167
|
+
});
|
|
168
|
+
res.json({ success: true, data: history });
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
Logger.error('Get usage history error:', error);
|
|
172
|
+
res.status(500).json({ error: { message: 'Failed to get usage history' } });
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
/**
|
|
176
|
+
* POST /api/developer/billing/credits
|
|
177
|
+
* Пополнение баланса (интеграция с платёжной системой)
|
|
178
|
+
*/
|
|
179
|
+
developerRouter.post('/billing/credits', authMiddleware, async (req, res) => {
|
|
180
|
+
try {
|
|
181
|
+
if (!req.user) {
|
|
182
|
+
res.status(401).json({ error: { message: 'Not authenticated' } });
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const { amount } = req.body; // в центах
|
|
186
|
+
if (!amount || amount < 500) { // минимум $5
|
|
187
|
+
res.status(400).json({ error: { message: 'Minimum amount is $5 (500 cents)' } });
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// TODO: Интеграция с Stripe/PayPal
|
|
191
|
+
// Сейчас просто добавляем кредиты
|
|
192
|
+
const billing = await tokenService.addCredits(req.user.id, amount);
|
|
193
|
+
res.json({
|
|
194
|
+
success: true,
|
|
195
|
+
data: {
|
|
196
|
+
newBalance: billing.balance / 100,
|
|
197
|
+
message: 'Credits added successfully'
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
Logger.error('Add credits error:', error);
|
|
203
|
+
res.status(500).json({ error: { message: 'Failed to add credits' } });
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
// ========================================
|
|
207
|
+
// PUBLIC API (requires API key)
|
|
208
|
+
// ========================================
|
|
209
|
+
/**
|
|
210
|
+
* POST /api/v1/projects
|
|
211
|
+
* Создание проекта через API
|
|
212
|
+
*/
|
|
213
|
+
developerRouter.post('/v1/projects', apiKeyAuth, requirePermission('write:projects'), trackUsage('index'), async (req, res) => {
|
|
214
|
+
try {
|
|
215
|
+
const { name, repositoryUrl, localPath } = req.body;
|
|
216
|
+
if (!name) {
|
|
217
|
+
res.status(400).json({ error: { message: 'Project name is required' } });
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
// Для API создаём проект по URL или пути
|
|
221
|
+
const project = await projectService.createProject(name, localPath || repositoryUrl);
|
|
222
|
+
res.status(201).json({
|
|
223
|
+
success: true,
|
|
224
|
+
data: { project }
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
Logger.error('Create project error:', error);
|
|
229
|
+
res.status(500).json({ error: { message: 'Failed to create project' } });
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
/**
|
|
233
|
+
* GET /api/v1/projects
|
|
234
|
+
* Список проектов
|
|
235
|
+
*/
|
|
236
|
+
developerRouter.get('/v1/projects', apiKeyAuth, requirePermission('read:projects'), async (_req, res) => {
|
|
237
|
+
try {
|
|
238
|
+
const projects = await projectService.listProjects();
|
|
239
|
+
res.json({ success: true, data: { projects } });
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
Logger.error('List projects error:', error);
|
|
243
|
+
res.status(500).json({ error: { message: 'Failed to list projects' } });
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
/**
|
|
247
|
+
* POST /api/v1/projects/:id/index
|
|
248
|
+
* Индексация проекта
|
|
249
|
+
*/
|
|
250
|
+
developerRouter.post('/v1/projects/:id/index', apiKeyAuth, requirePermission('write:projects'), trackUsage('index'), async (req, res) => {
|
|
251
|
+
try {
|
|
252
|
+
const result = await projectService.indexProject(req.params.id);
|
|
253
|
+
res.json({ success: true, data: result });
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
Logger.error('Index project error:', error);
|
|
257
|
+
res.status(500).json({ error: { message: 'Failed to index project' } });
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
/**
|
|
261
|
+
* POST /api/v1/analyze/impact
|
|
262
|
+
* Анализ влияния изменений
|
|
263
|
+
*/
|
|
264
|
+
developerRouter.post('/v1/analyze/impact', apiKeyAuth, requirePermission('analyze:impact'), trackUsage('analyze'), async (req, res) => {
|
|
265
|
+
try {
|
|
266
|
+
const { projectId, description, files, symbols, type } = req.body;
|
|
267
|
+
if (!projectId || !description) {
|
|
268
|
+
res.status(400).json({
|
|
269
|
+
error: { message: 'projectId and description are required' }
|
|
270
|
+
});
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const impact = await projectService.analyzeImpact(projectId, {
|
|
274
|
+
description,
|
|
275
|
+
files: files || [],
|
|
276
|
+
symbols: symbols || [],
|
|
277
|
+
type: type || 'modify'
|
|
278
|
+
});
|
|
279
|
+
res.json({ success: true, data: impact });
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
Logger.error('Analyze impact error:', error);
|
|
283
|
+
res.status(500).json({ error: { message: 'Failed to analyze impact' } });
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
/**
|
|
287
|
+
* POST /api/v1/analyze/security
|
|
288
|
+
* Анализ безопасности
|
|
289
|
+
*/
|
|
290
|
+
developerRouter.post('/v1/analyze/security', apiKeyAuth, requirePermission('analyze:security'), trackUsage('analyze'), async (req, res) => {
|
|
291
|
+
try {
|
|
292
|
+
const { projectId } = req.body;
|
|
293
|
+
if (!projectId) {
|
|
294
|
+
res.status(400).json({ error: { message: 'projectId is required' } });
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const result = await projectService.analyzeSecurity(projectId);
|
|
298
|
+
res.json({ success: true, data: result });
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
Logger.error('Analyze security error:', error);
|
|
302
|
+
res.status(500).json({ error: { message: 'Failed to analyze security' } });
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
/**
|
|
306
|
+
* POST /api/v1/analyze/full
|
|
307
|
+
* Полный анализ проекта
|
|
308
|
+
*/
|
|
309
|
+
developerRouter.post('/v1/analyze/full', apiKeyAuth, requirePermission('analyze:full'), trackUsage('analyze'), async (req, res) => {
|
|
310
|
+
try {
|
|
311
|
+
const { projectId } = req.body;
|
|
312
|
+
if (!projectId) {
|
|
313
|
+
res.status(400).json({ error: { message: 'projectId is required' } });
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const result = await projectService.runFullAnalysis(projectId);
|
|
317
|
+
res.json({ success: true, data: result });
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
Logger.error('Full analysis error:', error);
|
|
321
|
+
res.status(500).json({ error: { message: 'Failed to run full analysis' } });
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
/**
|
|
325
|
+
* POST /api/v1/search
|
|
326
|
+
* Семантический поиск
|
|
327
|
+
*/
|
|
328
|
+
developerRouter.post('/v1/search', apiKeyAuth, requirePermission('search:semantic'), trackUsage('search'), async (req, res) => {
|
|
329
|
+
try {
|
|
330
|
+
const { projectId, query, limit } = req.body;
|
|
331
|
+
if (!projectId || !query) {
|
|
332
|
+
res.status(400).json({
|
|
333
|
+
error: { message: 'projectId and query are required' }
|
|
334
|
+
});
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
const results = await projectService.semanticSearch(projectId, query, limit || 10);
|
|
338
|
+
res.json({ success: true, data: { results } });
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
Logger.error('Semantic search error:', error);
|
|
342
|
+
res.status(500).json({ error: { message: 'Failed to search' } });
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
/**
|
|
346
|
+
* POST /api/v1/ask
|
|
347
|
+
* Вопрос архитектору
|
|
348
|
+
*/
|
|
349
|
+
developerRouter.post('/v1/ask', apiKeyAuth, requirePermission('ask:architect'), trackUsage('ask'), async (req, res) => {
|
|
350
|
+
try {
|
|
351
|
+
const { projectId, question, language } = req.body;
|
|
352
|
+
if (!projectId || !question) {
|
|
353
|
+
res.status(400).json({
|
|
354
|
+
error: { message: 'projectId and question are required' }
|
|
355
|
+
});
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const answer = await projectService.askArchitect(projectId, question, language || 'en');
|
|
359
|
+
res.json({
|
|
360
|
+
success: true,
|
|
361
|
+
data: {
|
|
362
|
+
question,
|
|
363
|
+
answer,
|
|
364
|
+
model: 'archicore-v1'
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
Logger.error('Ask architect error:', error);
|
|
370
|
+
res.status(500).json({ error: { message: 'Failed to process question' } });
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
/**
|
|
374
|
+
* GET /api/v1/projects/:id/architecture
|
|
375
|
+
* Получение архитектурной модели
|
|
376
|
+
*/
|
|
377
|
+
developerRouter.get('/v1/projects/:id/architecture', apiKeyAuth, requirePermission('read:projects'), async (req, res) => {
|
|
378
|
+
try {
|
|
379
|
+
const architecture = await projectService.getArchitecture(req.params.id);
|
|
380
|
+
res.json({ success: true, data: architecture });
|
|
381
|
+
}
|
|
382
|
+
catch (error) {
|
|
383
|
+
Logger.error('Get architecture error:', error);
|
|
384
|
+
res.status(500).json({ error: { message: 'Failed to get architecture' } });
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
/**
|
|
388
|
+
* GET /api/v1/projects/:id/graph
|
|
389
|
+
* Получение графа зависимостей
|
|
390
|
+
*/
|
|
391
|
+
developerRouter.get('/v1/projects/:id/graph', apiKeyAuth, requirePermission('read:projects'), async (req, res) => {
|
|
392
|
+
try {
|
|
393
|
+
const graph = await projectService.getDependencyGraph(req.params.id);
|
|
394
|
+
res.json({ success: true, data: graph });
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
Logger.error('Get graph error:', error);
|
|
398
|
+
res.status(500).json({ error: { message: 'Failed to get dependency graph' } });
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
/**
|
|
402
|
+
* GET /api/v1/projects/:id/metrics
|
|
403
|
+
* Получение метрик
|
|
404
|
+
*/
|
|
405
|
+
developerRouter.get('/v1/projects/:id/metrics', apiKeyAuth, requirePermission('read:projects'), async (req, res) => {
|
|
406
|
+
try {
|
|
407
|
+
const metrics = await projectService.getMetrics(req.params.id);
|
|
408
|
+
res.json({ success: true, data: metrics });
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
Logger.error('Get metrics error:', error);
|
|
412
|
+
res.status(500).json({ error: { message: 'Failed to get metrics' } });
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
/**
|
|
416
|
+
* POST /api/v1/export
|
|
417
|
+
* Экспорт данных
|
|
418
|
+
*/
|
|
419
|
+
developerRouter.post('/v1/export', apiKeyAuth, requirePermission('export:data'), trackUsage('export'), async (req, res) => {
|
|
420
|
+
try {
|
|
421
|
+
const { projectId, format } = req.body;
|
|
422
|
+
if (!projectId || !format) {
|
|
423
|
+
res.status(400).json({
|
|
424
|
+
error: { message: 'projectId and format are required' }
|
|
425
|
+
});
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
const exportData = await projectService.getExportData(projectId);
|
|
429
|
+
// Здесь можно добавить разные форматы экспорта
|
|
430
|
+
res.json({ success: true, data: exportData });
|
|
431
|
+
}
|
|
432
|
+
catch (error) {
|
|
433
|
+
Logger.error('Export error:', error);
|
|
434
|
+
res.status(500).json({ error: { message: 'Failed to export data' } });
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
// Error handler
|
|
438
|
+
developerRouter.use(apiErrorHandler);
|
|
439
|
+
//# sourceMappingURL=developer.js.map
|