mirror of
https://github.com/SamyRai/tercul-frontend.git
synced 2025-12-27 04:51:34 +00:00
Enable analysis and annotation features for literary works on the platform
Implements new API routes in `server/routes.ts` for fetching, creating, and retrieving analysis results and annotations, including user enrichment. Replit-Commit-Author: Agent Replit-Commit-Session-Id: cbacfb18-842a-4116-a907-18c0105ad8ec Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/39b5c689-6e8a-4d5a-9792-69cc81a56534/15578bf6-749f-46f9-89a4-2849cb59c0ac.jpg
This commit is contained in:
parent
085270ea6f
commit
fc3a941647
145
server/routes.ts
145
server/routes.ts
@ -600,6 +600,151 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
res.json(works);
|
res.json(works);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Analysis results routes
|
||||||
|
app.get("/api/works/:slug/analysis", async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const work = await storage.getWorkBySlug(req.params.slug);
|
||||||
|
if (!work) {
|
||||||
|
return res.status(404).json({ message: "Work not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = await storage.getAnalysisResultsByWorkId(work.id);
|
||||||
|
res.json(results);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching analysis results:", error);
|
||||||
|
res.status(500).json({ message: "Failed to fetch analysis results" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/works/:slug/analysis/:type", async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const work = await storage.getWorkBySlug(req.params.slug);
|
||||||
|
if (!work) {
|
||||||
|
return res.status(404).json({ message: "Work not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await storage.getAnalysisResultByWorkAndType(work.id, req.params.type);
|
||||||
|
if (!result) {
|
||||||
|
return res.status(404).json({ message: "Analysis result not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json(result);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching analysis result:", error);
|
||||||
|
res.status(500).json({ message: "Failed to fetch analysis result" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/api/analysis", async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
// Validate request body using zod
|
||||||
|
const analysisData = z.object({
|
||||||
|
workId: z.number(),
|
||||||
|
type: z.string(),
|
||||||
|
data: z.any()
|
||||||
|
}).parse(req.body);
|
||||||
|
|
||||||
|
const result = await storage.createAnalysisResult(analysisData);
|
||||||
|
res.status(201).json(result);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof z.ZodError) {
|
||||||
|
return res.status(400).json({ message: error.errors });
|
||||||
|
}
|
||||||
|
console.error("Error creating analysis result:", error);
|
||||||
|
res.status(500).json({ message: "Failed to create analysis result" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Annotations routes
|
||||||
|
app.get("/api/works/:slug/annotations", async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const work = await storage.getWorkBySlug(req.params.slug);
|
||||||
|
if (!work) {
|
||||||
|
return res.status(404).json({ message: "Work not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const annotations = await storage.getAnnotationsByWorkId(work.id);
|
||||||
|
|
||||||
|
// Enrich annotations with user information
|
||||||
|
const enrichedAnnotations = await Promise.all(annotations.map(async (annotation) => {
|
||||||
|
const user = await storage.getUser(annotation.userId);
|
||||||
|
if (!user) return annotation;
|
||||||
|
|
||||||
|
const { password, ...safeUser } = user;
|
||||||
|
return { ...annotation, user: safeUser };
|
||||||
|
}));
|
||||||
|
|
||||||
|
res.json(enrichedAnnotations);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching annotations:", error);
|
||||||
|
res.status(500).json({ message: "Failed to fetch annotations" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/works/:slug/line/:lineNumber/annotations", async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const work = await storage.getWorkBySlug(req.params.slug);
|
||||||
|
if (!work) {
|
||||||
|
return res.status(404).json({ message: "Work not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const lineNumber = Number(req.params.lineNumber);
|
||||||
|
const translationId = req.query.translationId ? Number(req.query.translationId) : undefined;
|
||||||
|
|
||||||
|
const annotations = await storage.getAnnotationsByLine(
|
||||||
|
work.id,
|
||||||
|
lineNumber,
|
||||||
|
translationId
|
||||||
|
);
|
||||||
|
|
||||||
|
// Enrich annotations with user information
|
||||||
|
const enrichedAnnotations = await Promise.all(annotations.map(async (annotation) => {
|
||||||
|
const user = await storage.getUser(annotation.userId);
|
||||||
|
if (!user) return annotation;
|
||||||
|
|
||||||
|
const { password, ...safeUser } = user;
|
||||||
|
return { ...annotation, user: safeUser };
|
||||||
|
}));
|
||||||
|
|
||||||
|
res.json(enrichedAnnotations);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching line annotations:", error);
|
||||||
|
res.status(500).json({ message: "Failed to fetch line annotations" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/api/annotations", async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
// Validate request body using zod
|
||||||
|
const annotationData = z.object({
|
||||||
|
workId: z.number(),
|
||||||
|
translationId: z.number().nullable().optional(),
|
||||||
|
lineNumber: z.number().nullable().optional(),
|
||||||
|
content: z.string(),
|
||||||
|
type: z.string(),
|
||||||
|
userId: z.number(),
|
||||||
|
isOfficial: z.boolean()
|
||||||
|
}).parse(req.body);
|
||||||
|
|
||||||
|
const annotation = await storage.createAnnotation(annotationData);
|
||||||
|
|
||||||
|
// Get user details
|
||||||
|
const user = await storage.getUser(annotation.userId);
|
||||||
|
if (user) {
|
||||||
|
const { password, ...safeUser } = user;
|
||||||
|
res.status(201).json({ ...annotation, user: safeUser });
|
||||||
|
} else {
|
||||||
|
res.status(201).json(annotation);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof z.ZodError) {
|
||||||
|
return res.status(400).json({ message: error.errors });
|
||||||
|
}
|
||||||
|
console.error("Error creating annotation:", error);
|
||||||
|
res.status(500).json({ message: "Failed to create annotation" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const httpServer = createServer(app);
|
const httpServer = createServer(app);
|
||||||
return httpServer;
|
return httpServer;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user