for first push
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
"@shieldai/db": "0.1.0",
|
||||
"@shieldai/types": "0.1.0",
|
||||
"fastify": "^5.2.0",
|
||||
"@shieldai/darkwatch": "0.1.0"
|
||||
"@shieldai/darkwatch": "0.1.0",
|
||||
"@shieldai/voiceprint": "0.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,3 +13,10 @@ export function darkwatchRoutes(fastify: FastifyInstance) {
|
||||
root.register(scans, { prefix: "/scan" });
|
||||
}, { prefix: "/api/v1/darkwatch" });
|
||||
}
|
||||
|
||||
export function voiceprintRoutes(fastify: FastifyInstance) {
|
||||
fastify.register(async (root) => {
|
||||
const voiceprint = (await import("./voiceprint.routes")).voiceprintRoutes;
|
||||
root.register(voiceprint);
|
||||
}, { prefix: "/api/v1/voiceprint" });
|
||||
}
|
||||
|
||||
94
packages/api/src/routes/voiceprint.routes.ts
Normal file
94
packages/api/src/routes/voiceprint.routes.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import { FastifyInstance } from "fastify";
|
||||
import { VoiceEnrollmentService } from "@shieldai/voiceprint";
|
||||
import { AnalysisService } from "@shieldai/voiceprint";
|
||||
import { BatchAnalysisService } from "@shieldai/voiceprint";
|
||||
|
||||
export function voiceprintRoutes(fastify: FastifyInstance) {
|
||||
const enrollmentService = new VoiceEnrollmentService();
|
||||
const analysisService = new AnalysisService();
|
||||
const batchService = new BatchAnalysisService();
|
||||
|
||||
fastify.post("/enroll", async (request, reply) => {
|
||||
const userId = (request.user as { id: string })?.id;
|
||||
if (!userId) return reply.code(401).send({ error: "User not authenticated" });
|
||||
|
||||
const body = request.body as { label: string; audio: string; sampleRate?: number };
|
||||
|
||||
const audioBuffer = Buffer.from(body.audio, "base64");
|
||||
const enrollment = await enrollmentService.enroll(
|
||||
{ label: body.label, audioBuffer, sampleRate: body.sampleRate },
|
||||
userId
|
||||
);
|
||||
return reply.code(201).send(enrollment);
|
||||
});
|
||||
|
||||
fastify.get("/enrollments", async (request, reply) => {
|
||||
const userId = (request.user as { id: string })?.id;
|
||||
if (!userId) return reply.code(401).send({ error: "User not authenticated" });
|
||||
|
||||
const enrollments = await enrollmentService.listEnrollments(userId);
|
||||
return reply.send(enrollments);
|
||||
});
|
||||
|
||||
fastify.delete("/enrollments/:id", async (request, reply) => {
|
||||
const userId = (request.user as { id: string })?.id;
|
||||
if (!userId) return reply.code(401).send({ error: "User not authenticated" });
|
||||
|
||||
const enrollmentId = (request.params as { id: string }).id;
|
||||
const result = await enrollmentService.removeEnrollment(userId, enrollmentId);
|
||||
return reply.send({ removed: result });
|
||||
});
|
||||
|
||||
fastify.post("/analyze", async (request, reply) => {
|
||||
const userId = (request.user as { id: string })?.id;
|
||||
if (!userId) return reply.code(401).send({ error: "User not authenticated" });
|
||||
|
||||
const body = request.body as { audio: string; sampleRate?: number; analysisType?: string };
|
||||
const audioBuffer = Buffer.from(body.audio, "base64");
|
||||
|
||||
const result = await analysisService.analyze(
|
||||
{ audioBuffer, sampleRate: body.sampleRate, analysisType: body.analysisType },
|
||||
userId
|
||||
);
|
||||
return reply.code(201).send(result);
|
||||
});
|
||||
|
||||
fastify.get("/results/:id", async (request, reply) => {
|
||||
const jobId = (request.params as { id: string }).id;
|
||||
const result = await analysisService.getResult(jobId);
|
||||
|
||||
if (!result) return reply.code(404).send({ error: "Analysis result not found" });
|
||||
return reply.send(result);
|
||||
});
|
||||
|
||||
fastify.get("/results", async (request, reply) => {
|
||||
const userId = (request.user as { id: string })?.id;
|
||||
if (!userId) return reply.code(401).send({ error: "User not authenticated" });
|
||||
|
||||
const limit = parseInt((request.query as { limit?: string }).limit || "20", 10);
|
||||
const results = await analysisService.getUserResults(userId, limit);
|
||||
return reply.send(results);
|
||||
});
|
||||
|
||||
fastify.post("/batch", async (request, reply) => {
|
||||
const userId = (request.user as { id: string })?.id;
|
||||
if (!userId) return reply.code(401).send({ error: "User not authenticated" });
|
||||
|
||||
const body = request.body as {
|
||||
files: Array<{ name: string; audio: string; sampleRate?: number }>;
|
||||
analysisType?: string;
|
||||
};
|
||||
|
||||
const audioBuffers = body.files.map((f) => ({
|
||||
name: f.name,
|
||||
buffer: Buffer.from(f.audio, "base64"),
|
||||
sampleRate: f.sampleRate,
|
||||
}));
|
||||
|
||||
const result = await batchService.analyzeBatch(
|
||||
{ audioBuffers, analysisType: body.analysisType },
|
||||
userId
|
||||
);
|
||||
return reply.code(201).send(result);
|
||||
});
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import Fastify from "fastify";
|
||||
import cors from "@fastify/cors";
|
||||
import helmet from "@fastify/helmet";
|
||||
import sensible from "@fastify/sensible";
|
||||
import { darkwatchRoutes } from "./routes";
|
||||
import { darkwatchRoutes, voiceprintRoutes } from "./routes";
|
||||
|
||||
const app = Fastify({
|
||||
logger: {
|
||||
@@ -16,6 +16,7 @@ async function bootstrap() {
|
||||
await app.register(sensible);
|
||||
|
||||
await app.register(darkwatchRoutes);
|
||||
await app.register(voiceprintRoutes);
|
||||
|
||||
app.get("/health", async () => ({ status: "ok", timestamp: new Date().toISOString() }));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user