dialog-survey 1.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/CHANGELOG.md +95 -0
- package/README.md +242 -0
- package/VERSION +1 -0
- package/dist/api/admin-templates.d.ts +15 -0
- package/dist/api/admin-templates.d.ts.map +1 -0
- package/dist/api/admin-templates.js +611 -0
- package/dist/api/admin-templates.js.map +1 -0
- package/dist/api/analysis.d.ts +8 -0
- package/dist/api/analysis.d.ts.map +1 -0
- package/dist/api/analysis.js +106 -0
- package/dist/api/analysis.js.map +1 -0
- package/dist/api/health.d.ts +6 -0
- package/dist/api/health.d.ts.map +1 -0
- package/dist/api/health.js +116 -0
- package/dist/api/health.js.map +1 -0
- package/dist/api/plans.d.ts +3 -0
- package/dist/api/plans.d.ts.map +1 -0
- package/dist/api/plans.js +184 -0
- package/dist/api/plans.js.map +1 -0
- package/dist/api/templates.d.ts +9 -0
- package/dist/api/templates.d.ts.map +1 -0
- package/dist/api/templates.js +211 -0
- package/dist/api/templates.js.map +1 -0
- package/dist/core/graph.d.ts +7 -0
- package/dist/core/graph.d.ts.map +1 -0
- package/dist/core/graph.js +31 -0
- package/dist/core/graph.js.map +1 -0
- package/dist/core/nodes/analyzing.d.ts +3 -0
- package/dist/core/nodes/analyzing.d.ts.map +1 -0
- package/dist/core/nodes/analyzing.js +38 -0
- package/dist/core/nodes/analyzing.js.map +1 -0
- package/dist/core/nodes/completed.d.ts +3 -0
- package/dist/core/nodes/completed.d.ts.map +1 -0
- package/dist/core/nodes/completed.js +8 -0
- package/dist/core/nodes/completed.js.map +1 -0
- package/dist/core/nodes/interviewing.d.ts +13 -0
- package/dist/core/nodes/interviewing.d.ts.map +1 -0
- package/dist/core/nodes/interviewing.js +130 -0
- package/dist/core/nodes/interviewing.js.map +1 -0
- package/dist/core/nodes/planning.d.ts +15 -0
- package/dist/core/nodes/planning.d.ts.map +1 -0
- package/dist/core/nodes/planning.js +40 -0
- package/dist/core/nodes/planning.js.map +1 -0
- package/dist/core/types/index.d.ts +69 -0
- package/dist/core/types/index.d.ts.map +1 -0
- package/dist/core/types/index.js +49 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/domains/interview/entities/interview.entity.d.ts +21 -0
- package/dist/domains/interview/entities/interview.entity.d.ts.map +1 -0
- package/dist/domains/interview/entities/interview.entity.js +20 -0
- package/dist/domains/interview/entities/interview.entity.js.map +1 -0
- package/dist/domains/interview/entities/message.entity.d.ts +15 -0
- package/dist/domains/interview/entities/message.entity.d.ts.map +1 -0
- package/dist/domains/interview/entities/message.entity.js +11 -0
- package/dist/domains/interview/entities/message.entity.js.map +1 -0
- package/dist/domains/interview/entities/response.entity.d.ts +17 -0
- package/dist/domains/interview/entities/response.entity.d.ts.map +1 -0
- package/dist/domains/interview/entities/response.entity.js +12 -0
- package/dist/domains/interview/entities/response.entity.js.map +1 -0
- package/dist/domains/interview/services/interview.domain.d.ts +8 -0
- package/dist/domains/interview/services/interview.domain.d.ts.map +1 -0
- package/dist/domains/interview/services/interview.domain.js +30 -0
- package/dist/domains/interview/services/interview.domain.js.map +1 -0
- package/dist/integrations/dingtalk/client.d.ts +32 -0
- package/dist/integrations/dingtalk/client.d.ts.map +1 -0
- package/dist/integrations/dingtalk/client.js +89 -0
- package/dist/integrations/dingtalk/client.js.map +1 -0
- package/dist/integrations/dingtalk/message-sender.d.ts +24 -0
- package/dist/integrations/dingtalk/message-sender.d.ts.map +1 -0
- package/dist/integrations/dingtalk/message-sender.js +81 -0
- package/dist/integrations/dingtalk/message-sender.js.map +1 -0
- package/dist/integrations/dingtalk/middleware.d.ts +4 -0
- package/dist/integrations/dingtalk/middleware.d.ts.map +1 -0
- package/dist/integrations/dingtalk/middleware.js +29 -0
- package/dist/integrations/dingtalk/middleware.js.map +1 -0
- package/dist/integrations/dingtalk/stream-client.d.ts +112 -0
- package/dist/integrations/dingtalk/stream-client.d.ts.map +1 -0
- package/dist/integrations/dingtalk/stream-client.js +305 -0
- package/dist/integrations/dingtalk/stream-client.js.map +1 -0
- package/dist/integrations/dingtalk/token-manager.d.ts +22 -0
- package/dist/integrations/dingtalk/token-manager.d.ts.map +1 -0
- package/dist/integrations/dingtalk/token-manager.js +109 -0
- package/dist/integrations/dingtalk/token-manager.js.map +1 -0
- package/dist/integrations/llm/alibaba.d.ts +10 -0
- package/dist/integrations/llm/alibaba.d.ts.map +1 -0
- package/dist/integrations/llm/alibaba.js +60 -0
- package/dist/integrations/llm/alibaba.js.map +1 -0
- package/dist/integrations/llm/base.d.ts +28 -0
- package/dist/integrations/llm/base.d.ts.map +1 -0
- package/dist/integrations/llm/base.js +2 -0
- package/dist/integrations/llm/base.js.map +1 -0
- package/dist/integrations/llm/volcengine.d.ts +12 -0
- package/dist/integrations/llm/volcengine.d.ts.map +1 -0
- package/dist/integrations/llm/volcengine.js +80 -0
- package/dist/integrations/llm/volcengine.js.map +1 -0
- package/dist/middleware/admin-auth.d.ts +3 -0
- package/dist/middleware/admin-auth.d.ts.map +1 -0
- package/dist/middleware/admin-auth.js +37 -0
- package/dist/middleware/admin-auth.js.map +1 -0
- package/dist/middleware/api-auth.d.ts +10 -0
- package/dist/middleware/api-auth.d.ts.map +1 -0
- package/dist/middleware/api-auth.js +30 -0
- package/dist/middleware/api-auth.js.map +1 -0
- package/dist/repositories/interview-state-mapper.d.ts +28 -0
- package/dist/repositories/interview-state-mapper.d.ts.map +1 -0
- package/dist/repositories/interview-state-mapper.js +32 -0
- package/dist/repositories/interview-state-mapper.js.map +1 -0
- package/dist/repositories/interview-state.repository.d.ts +34 -0
- package/dist/repositories/interview-state.repository.d.ts.map +1 -0
- package/dist/repositories/interview-state.repository.js +220 -0
- package/dist/repositories/interview-state.repository.js.map +1 -0
- package/dist/repositories/interview.repository.d.ts +29 -0
- package/dist/repositories/interview.repository.d.ts.map +1 -0
- package/dist/repositories/interview.repository.js +36 -0
- package/dist/repositories/interview.repository.js.map +1 -0
- package/dist/repositories/message.repository.d.ts +17 -0
- package/dist/repositories/message.repository.d.ts.map +1 -0
- package/dist/repositories/message.repository.js +37 -0
- package/dist/repositories/message.repository.js.map +1 -0
- package/dist/repositories/template.repository.d.ts +117 -0
- package/dist/repositories/template.repository.d.ts.map +1 -0
- package/dist/repositories/template.repository.js +280 -0
- package/dist/repositories/template.repository.js.map +1 -0
- package/dist/schemas/dimensions.d.ts +61 -0
- package/dist/schemas/dimensions.d.ts.map +1 -0
- package/dist/schemas/dimensions.js +44 -0
- package/dist/schemas/dimensions.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +217 -0
- package/dist/server.js.map +1 -0
- package/dist/services/analysis.service.d.ts +81 -0
- package/dist/services/analysis.service.d.ts.map +1 -0
- package/dist/services/analysis.service.js +229 -0
- package/dist/services/analysis.service.js.map +1 -0
- package/dist/services/analytics.service.d.ts +44 -0
- package/dist/services/analytics.service.d.ts.map +1 -0
- package/dist/services/analytics.service.js +222 -0
- package/dist/services/analytics.service.js.map +1 -0
- package/dist/services/asr.service.d.ts +9 -0
- package/dist/services/asr.service.d.ts.map +1 -0
- package/dist/services/asr.service.js +41 -0
- package/dist/services/asr.service.js.map +1 -0
- package/dist/services/audit-cleanup.service.d.ts +9 -0
- package/dist/services/audit-cleanup.service.d.ts.map +1 -0
- package/dist/services/audit-cleanup.service.js +27 -0
- package/dist/services/audit-cleanup.service.js.map +1 -0
- package/dist/services/batch-aggregation.service.d.ts +34 -0
- package/dist/services/batch-aggregation.service.d.ts.map +1 -0
- package/dist/services/batch-aggregation.service.js +91 -0
- package/dist/services/batch-aggregation.service.js.map +1 -0
- package/dist/services/conversation-engine.d.ts +16 -0
- package/dist/services/conversation-engine.d.ts.map +1 -0
- package/dist/services/conversation-engine.js +49 -0
- package/dist/services/conversation-engine.js.map +1 -0
- package/dist/services/dead-letter.service.d.ts +12 -0
- package/dist/services/dead-letter.service.d.ts.map +1 -0
- package/dist/services/dead-letter.service.js +24 -0
- package/dist/services/dead-letter.service.js.map +1 -0
- package/dist/services/followup.service.d.ts +18 -0
- package/dist/services/followup.service.d.ts.map +1 -0
- package/dist/services/followup.service.js +146 -0
- package/dist/services/followup.service.js.map +1 -0
- package/dist/services/interview-plan-base.service.d.ts +226 -0
- package/dist/services/interview-plan-base.service.d.ts.map +1 -0
- package/dist/services/interview-plan-base.service.js +217 -0
- package/dist/services/interview-plan-base.service.js.map +1 -0
- package/dist/services/interview-plan-members.service.d.ts +45 -0
- package/dist/services/interview-plan-members.service.d.ts.map +1 -0
- package/dist/services/interview-plan-members.service.js +237 -0
- package/dist/services/interview-plan-members.service.js.map +1 -0
- package/dist/services/interview-plan-send.service.d.ts +27 -0
- package/dist/services/interview-plan-send.service.d.ts.map +1 -0
- package/dist/services/interview-plan-send.service.js +250 -0
- package/dist/services/interview-plan-send.service.js.map +1 -0
- package/dist/services/interview-plan.service.d.ts +8 -0
- package/dist/services/interview-plan.service.d.ts.map +1 -0
- package/dist/services/interview-plan.service.js +8 -0
- package/dist/services/interview-plan.service.js.map +1 -0
- package/dist/services/llm-clustering.d.ts +16 -0
- package/dist/services/llm-clustering.d.ts.map +1 -0
- package/dist/services/llm-clustering.js +91 -0
- package/dist/services/llm-clustering.js.map +1 -0
- package/dist/services/prompt.service.d.ts +13 -0
- package/dist/services/prompt.service.d.ts.map +1 -0
- package/dist/services/prompt.service.js +151 -0
- package/dist/services/prompt.service.js.map +1 -0
- package/dist/services/report.service.d.ts +28 -0
- package/dist/services/report.service.d.ts.map +1 -0
- package/dist/services/report.service.js +169 -0
- package/dist/services/report.service.js.map +1 -0
- package/dist/services/stream-message-utils.d.ts +31 -0
- package/dist/services/stream-message-utils.d.ts.map +1 -0
- package/dist/services/stream-message-utils.js +80 -0
- package/dist/services/stream-message-utils.js.map +1 -0
- package/dist/services/stream-message.service.d.ts +29 -0
- package/dist/services/stream-message.service.d.ts.map +1 -0
- package/dist/services/stream-message.service.js +184 -0
- package/dist/services/stream-message.service.js.map +1 -0
- package/dist/services/template-dimension.service.d.ts +21 -0
- package/dist/services/template-dimension.service.d.ts.map +1 -0
- package/dist/services/template-dimension.service.js +9 -0
- package/dist/services/template-dimension.service.js.map +1 -0
- package/dist/utils/db.d.ts +10 -0
- package/dist/utils/db.d.ts.map +1 -0
- package/dist/utils/db.js +21 -0
- package/dist/utils/db.js.map +1 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +21 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.d.ts +2 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +39 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/pii-anonymizer.d.ts +2 -0
- package/dist/utils/pii-anonymizer.d.ts.map +1 -0
- package/dist/utils/pii-anonymizer.js +13 -0
- package/dist/utils/pii-anonymizer.js.map +1 -0
- package/dist/utils/retry.d.ts +8 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +28 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/security.d.ts +26 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +99 -0
- package/dist/utils/security.js.map +1 -0
- package/package.json +80 -0
- package/prisma/schema.prisma +228 -0
- package/public/css/admin.css +73 -0
- package/public/js/alpine.min.js +2670 -0
- package/public/js/htmx.min.js +3422 -0
- package/scripts/cli.mjs +794 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PrismaClient } from '@prisma/client';
|
|
2
|
+
import type { FastifyInstance } from 'fastify';
|
|
3
|
+
interface AnalysisRoutesOptions {
|
|
4
|
+
prisma: PrismaClient;
|
|
5
|
+
}
|
|
6
|
+
export declare function analysisRoutes(fastify: FastifyInstance, opts: AnalysisRoutesOptions): Promise<void>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=analysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../../src/api/analysis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQ/C,UAAU,qBAAqB;IAC7B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,qBAAqB,iBAgHzF"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AnalysisService } from '../services/analysis.service.js';
|
|
3
|
+
const analyzeSingleSchema = z.object({
|
|
4
|
+
interviewId: z.string().uuid(),
|
|
5
|
+
});
|
|
6
|
+
export async function analysisRoutes(fastify, opts) {
|
|
7
|
+
const analysisService = new AnalysisService(opts.prisma);
|
|
8
|
+
fastify.post('/api/analysis/single', async (request, reply) => {
|
|
9
|
+
const { interviewId } = analyzeSingleSchema.parse(request.body);
|
|
10
|
+
try {
|
|
11
|
+
const result = await analysisService.analyzeInterview(interviewId);
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
const errorMsg = e instanceof Error ? e.message : 'Unknown error';
|
|
16
|
+
return reply.status(500).send({ error: errorMsg });
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
fastify.post('/api/analysis/batch', async (request, reply) => {
|
|
20
|
+
const { planId } = request.body;
|
|
21
|
+
if (!planId) {
|
|
22
|
+
return reply.status(400).send({ error: 'planId is required' });
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const results = await analysisService.batchAnalyze(planId);
|
|
26
|
+
return {
|
|
27
|
+
total: results.length,
|
|
28
|
+
results: results.map((r) => ({
|
|
29
|
+
interviewId: r.interviewId,
|
|
30
|
+
metrics: r.metrics,
|
|
31
|
+
})),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
const errorMsg = e instanceof Error ? e.message : 'Unknown error';
|
|
36
|
+
return reply.status(500).send({ error: errorMsg });
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
fastify.get('/api/analysis/cluster/:planId', async (request, reply) => {
|
|
40
|
+
const { planId } = request.params;
|
|
41
|
+
try {
|
|
42
|
+
const clusters = await analysisService.compareClusters([planId]);
|
|
43
|
+
return { clusters };
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
const errorMsg = e instanceof Error ? e.message : 'Unknown error';
|
|
47
|
+
return reply.status(500).send({ error: errorMsg });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
fastify.get('/api/analysis/report/:interviewId', async (request, reply) => {
|
|
51
|
+
const { interviewId } = request.params;
|
|
52
|
+
const report = await analysisService.getReportByInterviewId(interviewId);
|
|
53
|
+
if (!report) {
|
|
54
|
+
return reply.status(404).send({ error: 'Report not found' });
|
|
55
|
+
}
|
|
56
|
+
return report;
|
|
57
|
+
});
|
|
58
|
+
fastify.post('/api/analysis/aggregate/:planId', async (request, reply) => {
|
|
59
|
+
const { planId } = request.params;
|
|
60
|
+
try {
|
|
61
|
+
const result = await analysisService.createBatchReportIfEligible(planId);
|
|
62
|
+
switch (result.kind) {
|
|
63
|
+
case 'created':
|
|
64
|
+
return reply.status(201).send({
|
|
65
|
+
batchReportId: result.report.id,
|
|
66
|
+
status: result.report.status,
|
|
67
|
+
});
|
|
68
|
+
case 'conflict':
|
|
69
|
+
return reply.status(409).send({
|
|
70
|
+
error: 'Aggregate analysis already running',
|
|
71
|
+
existingReportId: result.existingId,
|
|
72
|
+
});
|
|
73
|
+
case 'no-completed':
|
|
74
|
+
return reply.status(400).send({
|
|
75
|
+
error: 'No COMPLETED interviews found in this plan',
|
|
76
|
+
});
|
|
77
|
+
case 'plan-not-found':
|
|
78
|
+
return reply.status(404).send({ error: 'Plan not found' });
|
|
79
|
+
default: {
|
|
80
|
+
const _exhaustive = result;
|
|
81
|
+
throw new Error(`Unhandled result kind: ${JSON.stringify(_exhaustive)}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
const errorMsg = e instanceof Error ? e.message : 'Unknown error';
|
|
87
|
+
return reply.status(500).send({ error: errorMsg });
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
fastify.get('/api/analysis/aggregate/:batchReportId', async (request, reply) => {
|
|
91
|
+
const { batchReportId } = request.params;
|
|
92
|
+
try {
|
|
93
|
+
const report = await analysisService.getBatchReportById(batchReportId);
|
|
94
|
+
if (!report) {
|
|
95
|
+
return reply.status(404).send({ error: 'Aggregate report not found' });
|
|
96
|
+
}
|
|
97
|
+
return reply.status(200).send(report);
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
const errorMsg = e instanceof Error ? e.message : 'Unknown error';
|
|
101
|
+
fastify.log.error({ error: errorMsg }, 'GET aggregate endpoint error');
|
|
102
|
+
return reply.status(500).send({ error: errorMsg });
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../../src/api/analysis.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;CAC/B,CAAC,CAAC;AAMH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAwB,EAAE,IAA2B;IACxF,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEzD,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC5D,MAAM,EAAE,WAAW,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEhE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;YACnE,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAClE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC3D,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAA0B,CAAC;QAEtD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAC3D,OAAO;gBACL,KAAK,EAAE,OAAO,CAAC,MAAM;gBACrB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC3B,WAAW,EAAE,CAAC,CAAC,WAAW;oBAC1B,OAAO,EAAE,CAAC,CAAC,OAAO;iBACnB,CAAC,CAAC;aACJ,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAClE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACpE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAA4B,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACjE,OAAO,EAAE,QAAQ,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAClE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACxE,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,MAAiC,CAAC;QAElE,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;QAEzE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAA4B,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,2BAA2B,CAAC,MAAM,CAAC,CAAC;YAEzE,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;gBACpB,KAAK,SAAS;oBACZ,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBAC5B,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE;wBAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;qBAC7B,CAAC,CAAC;gBACL,KAAK,UAAU;oBACb,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBAC5B,KAAK,EAAE,oCAAoC;wBAC3C,gBAAgB,EAAE,MAAM,CAAC,UAAU;qBACpC,CAAC,CAAC;gBACL,KAAK,cAAc;oBACjB,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBAC5B,KAAK,EAAE,4CAA4C;qBACpD,CAAC,CAAC;gBACL,KAAK,gBAAgB;oBACnB,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;gBAC7D,OAAO,CAAC,CAAC,CAAC;oBACR,MAAM,WAAW,GAAU,MAAM,CAAC;oBAClC,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBAC3E,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAClE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QAC7E,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,MAAmC,CAAC;QAEtE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;YAEvE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;YACzE,CAAC;YAED,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,8BAA8B,CAAC,CAAC;YACvE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/api/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA2H/C,wBAAsB,YAAY,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,iBAoC1F"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { error, info } from '../utils/logger.js';
|
|
2
|
+
let llmCacheTime = null;
|
|
3
|
+
async function checkDatabase(prisma) {
|
|
4
|
+
try {
|
|
5
|
+
const start = Date.now();
|
|
6
|
+
await prisma.$queryRaw `SELECT 1`;
|
|
7
|
+
const latencyMs = Date.now() - start;
|
|
8
|
+
return { status: 'ok', latencyMs };
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
const errMsg = e instanceof Error ? e.message : 'Unknown error';
|
|
12
|
+
error('Database health check failed', { error: errMsg });
|
|
13
|
+
return { status: 'error', error: errMsg };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async function checkLLM() {
|
|
17
|
+
if (llmCacheTime && Date.now() - llmCacheTime < 60000) {
|
|
18
|
+
return { status: 'ok' };
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const apiKey = process.env.LLM_API_KEY || process.env.VOLCENGINE_API_KEY;
|
|
22
|
+
if (!apiKey) {
|
|
23
|
+
return { status: 'degraded', error: 'API key not configured' };
|
|
24
|
+
}
|
|
25
|
+
const baseUrl = process.env.LLM_BASE_URL ||
|
|
26
|
+
process.env.VOLCENGINE_BASE_URL ||
|
|
27
|
+
'https://ark.cn-beijing.volces.com/api/coding';
|
|
28
|
+
const model = process.env.LLM_MODEL || process.env.VOLCENGINE_MODEL || 'deepseek-v3.2';
|
|
29
|
+
const start = Date.now();
|
|
30
|
+
const response = await fetch(`${baseUrl}${baseUrl.endsWith('/') ? '' : '/'}v1/chat/completions`, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: `Bearer ${apiKey}`,
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify({
|
|
37
|
+
model,
|
|
38
|
+
messages: [{ role: 'user', content: 'health check' }],
|
|
39
|
+
max_tokens: 10,
|
|
40
|
+
}),
|
|
41
|
+
signal: AbortSignal.timeout(30000),
|
|
42
|
+
});
|
|
43
|
+
const latencyMs = Date.now() - start;
|
|
44
|
+
if (response.ok) {
|
|
45
|
+
llmCacheTime = Date.now();
|
|
46
|
+
return { status: 'ok', latencyMs };
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
status: 'degraded',
|
|
50
|
+
latencyMs,
|
|
51
|
+
error: `HTTP ${response.status}`,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
const errMsg = e instanceof Error ? e.message : 'Unknown error';
|
|
56
|
+
if (errMsg.includes('timeout') || errMsg.includes('abort')) {
|
|
57
|
+
return { status: 'degraded', error: 'timeout' };
|
|
58
|
+
}
|
|
59
|
+
error('LLM health check failed', { error: errMsg });
|
|
60
|
+
return { status: 'error', error: errMsg };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function checkDingTalk() {
|
|
64
|
+
// Check Stream mode configuration (Stream client uses WebSocket, not webhook URL)
|
|
65
|
+
const clientId = process.env.DINGTALK_CLIENT_ID;
|
|
66
|
+
const clientSecret = process.env.DINGTALK_CLIENT_SECRET;
|
|
67
|
+
const agentId = process.env.DINGTALK_AGENT_ID;
|
|
68
|
+
if (!clientId || !clientSecret || !agentId) {
|
|
69
|
+
return {
|
|
70
|
+
status: 'degraded',
|
|
71
|
+
error: 'DingTalk Stream credentials not configured (missing CLIENT_ID, CLIENT_SECRET, or AGENT_ID)',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (clientId.includes('xxx') || clientSecret.includes('xxx')) {
|
|
75
|
+
return {
|
|
76
|
+
status: 'degraded',
|
|
77
|
+
error: 'DingTalk Stream credentials contain placeholder values',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return { status: 'ok' };
|
|
81
|
+
}
|
|
82
|
+
export async function healthRoutes(fastify, opts) {
|
|
83
|
+
fastify.get('/health', async (_request, reply) => {
|
|
84
|
+
info('Health check requested');
|
|
85
|
+
const [dbCheck, llmCheck, dingtalkCheck] = await Promise.all([
|
|
86
|
+
checkDatabase(opts.prisma),
|
|
87
|
+
checkLLM(),
|
|
88
|
+
checkDingTalk(),
|
|
89
|
+
]);
|
|
90
|
+
const dbOk = dbCheck.status === 'ok';
|
|
91
|
+
const llmOk = llmCheck.status === 'ok';
|
|
92
|
+
const dingtalkOk = dingtalkCheck.status === 'ok';
|
|
93
|
+
let status;
|
|
94
|
+
if (dbOk && llmOk && dingtalkOk) {
|
|
95
|
+
status = 'healthy';
|
|
96
|
+
}
|
|
97
|
+
else if (dbOk) {
|
|
98
|
+
status = 'degraded';
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
status = 'unhealthy';
|
|
102
|
+
}
|
|
103
|
+
const response = {
|
|
104
|
+
status,
|
|
105
|
+
timestamp: new Date().toISOString(),
|
|
106
|
+
checks: {
|
|
107
|
+
db: dbCheck,
|
|
108
|
+
llm: llmCheck,
|
|
109
|
+
dingtalk: dingtalkCheck,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
const statusCode = status === 'healthy' ? 200 : status === 'degraded' ? 200 : 503;
|
|
113
|
+
return reply.status(statusCode).send(response);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/api/health.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAgBjD,IAAI,YAAY,GAAkB,IAAI,CAAC;AAEvC,KAAK,UAAU,aAAa,CAAC,MAAoB;IAK/C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,MAAM,CAAC,SAAS,CAAA,UAAU,CAAC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QACrC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAChE,KAAK,CAAC,8BAA8B,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACzD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ;IAKrB,IAAI,YAAY,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,GAAG,KAAK,EAAE,CAAC;QACtD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACzE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC;QACjE,CAAC;QAED,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,YAAY;YACxB,OAAO,CAAC,GAAG,CAAC,mBAAmB;YAC/B,8CAA8C,CAAC;QACjD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,eAAe,CAAC;QAEvF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAC1B,GAAG,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,qBAAqB,EAClE;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,EAAE;gBACjC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK;gBACL,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;gBACrD,UAAU,EAAE,EAAE;aACf,CAAC;YACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CACF,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAErC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC1B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACrC,CAAC;QACD,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,SAAS;YACT,KAAK,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE;SACjC,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAChE,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3D,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAClD,CAAC;QACD,KAAK,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACpD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa;IAI1B,kFAAkF;IAClF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAChD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IACxD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAE9C,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3C,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,KAAK,EACH,4FAA4F;SAC/F,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7D,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,wDAAwD;SAChE,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAwB,EAAE,IAA8B;IACzF,OAAO,CAAC,GAAG,CAA4B,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC1E,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAE/B,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC3D,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;YAC1B,QAAQ,EAAE;YACV,aAAa,EAAE;SAChB,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC;QACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC;QACvC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,KAAK,IAAI,CAAC;QAEjD,IAAI,MAA4C,CAAC;QACjD,IAAI,IAAI,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;YAChC,MAAM,GAAG,SAAS,CAAC;QACrB,CAAC;aAAM,IAAI,IAAI,EAAE,CAAC;YAChB,MAAM,GAAG,UAAU,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,WAAW,CAAC;QACvB,CAAC;QAED,MAAM,QAAQ,GAAmB;YAC/B,MAAM;YACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE;gBACN,EAAE,EAAE,OAAO;gBACX,GAAG,EAAE,QAAQ;gBACb,QAAQ,EAAE,aAAa;aACxB;SACF,CAAC;QAEF,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAClF,OAAO,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../../src/api/plans.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA2E/C,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,eAAe,iBAqJjE"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { adminAuth } from '../middleware/admin-auth.js';
|
|
3
|
+
import { InterviewNotFoundError, InterviewPlanService, InvalidMemberInputError, InvalidStateError, MemberConflictError, MemberNotFoundError, PlanNotFoundError, parseInviteeText, } from '../services/interview-plan.service.js';
|
|
4
|
+
const createPlanSchema = z.object({
|
|
5
|
+
name: z.string().min(1),
|
|
6
|
+
description: z.string().optional(),
|
|
7
|
+
templateId: z.string().uuid(),
|
|
8
|
+
targetDate: z.string().optional(),
|
|
9
|
+
schedule: z.string().optional(),
|
|
10
|
+
invitees: z.string().optional(),
|
|
11
|
+
publish: z.coerce.boolean().optional().default(false),
|
|
12
|
+
});
|
|
13
|
+
const importInviteesSchema = z.object({
|
|
14
|
+
invitees: z.array(z.object({
|
|
15
|
+
userId: z.string(),
|
|
16
|
+
name: z.string(),
|
|
17
|
+
email: z.string().optional(),
|
|
18
|
+
phone: z.string().optional(),
|
|
19
|
+
customFields: z.record(z.string(), z.unknown()).optional(),
|
|
20
|
+
})),
|
|
21
|
+
});
|
|
22
|
+
const addMemberSchema = z
|
|
23
|
+
.object({
|
|
24
|
+
userId: z.string().min(1).optional(),
|
|
25
|
+
phone: z
|
|
26
|
+
.string()
|
|
27
|
+
.regex(/^1[3-9]\d{9}$/, 'Invalid phone format')
|
|
28
|
+
.optional(),
|
|
29
|
+
name: z.string().min(1).optional(),
|
|
30
|
+
})
|
|
31
|
+
.refine((data) => data.userId !== undefined || data.phone !== undefined, {
|
|
32
|
+
message: 'Either userId or phone is required',
|
|
33
|
+
path: ['userId', 'phone'],
|
|
34
|
+
});
|
|
35
|
+
const remindSchema = z.object({
|
|
36
|
+
interviewId: z.string().min(1).optional(),
|
|
37
|
+
});
|
|
38
|
+
function mapServiceErrorToStatus(err) {
|
|
39
|
+
if (err instanceof PlanNotFoundError || err instanceof InterviewNotFoundError) {
|
|
40
|
+
return { status: 404, message: err.message };
|
|
41
|
+
}
|
|
42
|
+
if (err instanceof MemberNotFoundError) {
|
|
43
|
+
return { status: 404, message: err.message };
|
|
44
|
+
}
|
|
45
|
+
if (err instanceof MemberConflictError) {
|
|
46
|
+
return { status: 409, message: err.message };
|
|
47
|
+
}
|
|
48
|
+
if (err instanceof InvalidStateError) {
|
|
49
|
+
return { status: 400, message: err.message };
|
|
50
|
+
}
|
|
51
|
+
if (err instanceof InvalidMemberInputError) {
|
|
52
|
+
return { status: 400, message: err.message };
|
|
53
|
+
}
|
|
54
|
+
const message = err instanceof Error ? err.message : 'Unexpected error';
|
|
55
|
+
return { status: 502, message };
|
|
56
|
+
}
|
|
57
|
+
export async function interviewPlanRoutes(fastify) {
|
|
58
|
+
const planService = new InterviewPlanService();
|
|
59
|
+
fastify.post('/api/plans', async (request, _reply) => {
|
|
60
|
+
const input = createPlanSchema.parse(request.body);
|
|
61
|
+
// Always create the plan first
|
|
62
|
+
const planId = await planService.createPlan({
|
|
63
|
+
name: input.name,
|
|
64
|
+
description: input.description,
|
|
65
|
+
templateId: input.templateId,
|
|
66
|
+
targetDate: input.targetDate ? new Date(input.targetDate) : undefined,
|
|
67
|
+
schedule: input.schedule,
|
|
68
|
+
});
|
|
69
|
+
if (input.invitees) {
|
|
70
|
+
const inviteeData = parseInviteeText(input.invitees);
|
|
71
|
+
const importResult = await planService.importInvitees(planId, inviteeData);
|
|
72
|
+
let sent = 0;
|
|
73
|
+
let failed = 0;
|
|
74
|
+
if (input.publish === true) {
|
|
75
|
+
const sendResult = await planService.sendInvitations(planId);
|
|
76
|
+
sent = sendResult.sent;
|
|
77
|
+
failed = sendResult.failed;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
id: planId,
|
|
81
|
+
imported: importResult.success,
|
|
82
|
+
sent,
|
|
83
|
+
failed,
|
|
84
|
+
errors: importResult.errors,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return { id: planId };
|
|
88
|
+
});
|
|
89
|
+
fastify.get('/api/plans', async (request) => {
|
|
90
|
+
const { status, limit, offset } = request.query;
|
|
91
|
+
return planService.listPlans({ status, limit, offset });
|
|
92
|
+
});
|
|
93
|
+
fastify.get('/api/plans/:id', async (request, reply) => {
|
|
94
|
+
const { id } = request.params;
|
|
95
|
+
const plan = await planService.getPlan(id);
|
|
96
|
+
if (!plan) {
|
|
97
|
+
return reply.status(404).send({ error: 'Plan not found' });
|
|
98
|
+
}
|
|
99
|
+
return plan;
|
|
100
|
+
});
|
|
101
|
+
fastify.put('/api/plans/:id', async (request, _reply) => {
|
|
102
|
+
const { id } = request.params;
|
|
103
|
+
const input = createPlanSchema.parse(request.body);
|
|
104
|
+
await planService.updatePlan(id, {
|
|
105
|
+
name: input.name,
|
|
106
|
+
description: input.description,
|
|
107
|
+
targetDate: input.targetDate,
|
|
108
|
+
schedule: input.schedule,
|
|
109
|
+
invitees: input.invitees,
|
|
110
|
+
});
|
|
111
|
+
return { id };
|
|
112
|
+
});
|
|
113
|
+
fastify.post('/api/plans/:id/invitees', async (request, _reply) => {
|
|
114
|
+
const { id } = request.params;
|
|
115
|
+
const { invitees } = importInviteesSchema.parse(request.body);
|
|
116
|
+
const result = await planService.importInvitees(id, invitees);
|
|
117
|
+
return result;
|
|
118
|
+
});
|
|
119
|
+
fastify.post('/api/plans/:id/send', async (request, _reply) => {
|
|
120
|
+
const { id } = request.params;
|
|
121
|
+
const result = await planService.sendInvitations(id);
|
|
122
|
+
return result;
|
|
123
|
+
});
|
|
124
|
+
fastify.post('/api/plans/:id/interviews/:interviewId/send', async (request, _reply) => {
|
|
125
|
+
const { id, interviewId } = request.params;
|
|
126
|
+
const result = await planService.resendToInterview(id, interviewId);
|
|
127
|
+
return result;
|
|
128
|
+
});
|
|
129
|
+
fastify.post('/api/plans/:id/pause', async (request, _reply) => {
|
|
130
|
+
const { id } = request.params;
|
|
131
|
+
await planService.pausePlan(id);
|
|
132
|
+
return { status: 'paused' };
|
|
133
|
+
});
|
|
134
|
+
fastify.post('/api/plans/:id/resume', async (request, _reply) => {
|
|
135
|
+
const { id } = request.params;
|
|
136
|
+
await planService.resumePlan(id);
|
|
137
|
+
return { status: 'running' };
|
|
138
|
+
});
|
|
139
|
+
fastify.post('/api/plans/:id/cancel', async (request, _reply) => {
|
|
140
|
+
const { id } = request.params;
|
|
141
|
+
await planService.cancelPlan(id);
|
|
142
|
+
return { status: 'cancelled' };
|
|
143
|
+
});
|
|
144
|
+
fastify.post('/api/plans/:id/members', { preHandler: adminAuth }, async (request, reply) => {
|
|
145
|
+
const { id } = request.params;
|
|
146
|
+
const input = addMemberSchema.parse(request.body);
|
|
147
|
+
try {
|
|
148
|
+
const result = await planService.addMember(id, {
|
|
149
|
+
userId: input.userId,
|
|
150
|
+
phone: input.phone,
|
|
151
|
+
name: input.name,
|
|
152
|
+
});
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
const { status, message } = mapServiceErrorToStatus(e);
|
|
157
|
+
return reply.status(status).send({ error: message });
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
fastify.delete('/api/plans/:id/members/:interviewId', { preHandler: adminAuth }, async (request, reply) => {
|
|
161
|
+
const { id, interviewId } = request.params;
|
|
162
|
+
try {
|
|
163
|
+
await planService.removeMember(id, interviewId);
|
|
164
|
+
return { status: 'removed' };
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
const { status, message } = mapServiceErrorToStatus(e);
|
|
168
|
+
return reply.status(status).send({ error: message });
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
fastify.post('/api/plans/:id/remind', { preHandler: adminAuth }, async (request, reply) => {
|
|
172
|
+
const { id } = request.params;
|
|
173
|
+
const { interviewId } = remindSchema.parse(request.body ?? {});
|
|
174
|
+
try {
|
|
175
|
+
const result = await planService.sendReminder(id, interviewId);
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
catch (e) {
|
|
179
|
+
const { status, message } = mapServiceErrorToStatus(e);
|
|
180
|
+
return reply.status(status).send({ error: message });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=plans.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plans.js","sourceRoot":"","sources":["../../src/api/plans.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PrismaClient } from '@prisma/client';
|
|
2
|
+
import type { FastifyInstance } from 'fastify';
|
|
3
|
+
import type { TemplateRepository } from '../repositories/template.repository.js';
|
|
4
|
+
export interface TemplateRoutesOptions {
|
|
5
|
+
templateRepo: TemplateRepository;
|
|
6
|
+
prisma: PrismaClient;
|
|
7
|
+
}
|
|
8
|
+
export declare function templateRoutes(fastify: FastifyInstance, opts: TemplateRoutesOptions): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/api/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAGjF,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,kBAAkB,CAAC;IACjC,MAAM,EAAE,YAAY,CAAC;CACtB;AAsCD,wBAAsB,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,qBAAqB,iBA4NzF"}
|