Add API endpoints and frontend components for tool management and analytics

Implement CRUD operations for tools and ratings, introduce analytics endpoints, and develop frontend components for displaying tools, ratings, and analytics data.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 776963d0-f75d-42e2-a57b-cc36bdff8495
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: feaa4ce1-5aed-4cc0-bcea-47855b615b48
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0683fb79-a27c-485c-9333-5f4b288c4567/776963d0-f75d-42e2-a57b-cc36bdff8495/rx9K7bW
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
cheffe01
2026-05-25 13:04:53 +00:00
parent 1de22a6979
commit 036973ea32
111 changed files with 11006 additions and 96 deletions
+260 -5
View File
@@ -1,16 +1,271 @@
/**
* Generated by orval v8.5.3 🍺
* Generated by orval v8.9.1 🍺
* Do not edit manually.
* Api
* API specification
* ToolRate API — Tool listing and rating platform
* OpenAPI spec version: 0.1.0
*/
import * as zod from "zod";
import * as zod from 'zod';
/**
* Returns server health status
* @summary Health check
*/
export const HealthCheckResponse = zod.object({
status: zod.string(),
});
"status": zod.string()
})
/**
* @summary List all tools
*/
export const ListToolsQueryParams = zod.object({
"category": zod.coerce.string().optional(),
"search": zod.coerce.string().optional(),
"sort": zod.enum(['newest', 'top_rated', 'most_reviewed']).optional()
})
export const ListToolsResponseItem = zod.object({
"id": zod.number(),
"name": zod.string(),
"description": zod.string(),
"category": zod.string(),
"websiteUrl": zod.string().nullish(),
"features": zod.array(zod.string()).optional(),
"tags": zod.array(zod.string()).optional(),
"createdAt": zod.coerce.date(),
"updatedAt": zod.coerce.date(),
"ratingCount": zod.number(),
"avgUsefulness": zod.number().nullable(),
"avgUsability": zod.number().nullable(),
"avgCombined": zod.number().nullable()
})
export const ListToolsResponse = zod.array(ListToolsResponseItem)
/**
* @summary Create a new tool
*/
export const CreateToolBody = zod.object({
"name": zod.string().min(1),
"description": zod.string().min(1),
"category": zod.string().min(1),
"websiteUrl": zod.string().optional(),
"features": zod.array(zod.string()).optional(),
"tags": zod.array(zod.string()).optional()
})
/**
* @summary Get a tool by ID
*/
export const GetToolParams = zod.object({
"id": zod.coerce.number()
})
export const GetToolResponse = zod.object({
"id": zod.number(),
"name": zod.string(),
"description": zod.string(),
"category": zod.string(),
"websiteUrl": zod.string().nullish(),
"features": zod.array(zod.string()).optional(),
"tags": zod.array(zod.string()).optional(),
"createdAt": zod.coerce.date(),
"updatedAt": zod.coerce.date(),
"ratingCount": zod.number(),
"avgUsefulness": zod.number().nullable(),
"avgUsability": zod.number().nullable(),
"avgCombined": zod.number().nullable()
})
/**
* @summary Update a tool
*/
export const UpdateToolParams = zod.object({
"id": zod.coerce.number()
})
export const UpdateToolBody = zod.object({
"name": zod.string().min(1).optional(),
"description": zod.string().optional(),
"category": zod.string().optional(),
"websiteUrl": zod.string().optional(),
"features": zod.array(zod.string()).optional(),
"tags": zod.array(zod.string()).optional()
})
export const UpdateToolResponse = zod.object({
"id": zod.number(),
"name": zod.string(),
"description": zod.string(),
"category": zod.string(),
"websiteUrl": zod.string().nullish(),
"features": zod.array(zod.string()).optional(),
"tags": zod.array(zod.string()).optional(),
"createdAt": zod.coerce.date(),
"updatedAt": zod.coerce.date()
})
/**
* @summary Delete a tool
*/
export const DeleteToolParams = zod.object({
"id": zod.coerce.number()
})
/**
* @summary List ratings for a tool
*/
export const ListToolRatingsParams = zod.object({
"id": zod.coerce.number()
})
export const listToolRatingsResponseUsefulnessMax = 5;
export const listToolRatingsResponseUsabilityMax = 5;
export const ListToolRatingsResponseItem = zod.object({
"id": zod.number(),
"toolId": zod.number(),
"usefulness": zod.number().min(1).max(listToolRatingsResponseUsefulnessMax),
"usability": zod.number().min(1).max(listToolRatingsResponseUsabilityMax),
"comment": zod.string().nullish(),
"reviewerName": zod.string().nullish(),
"createdAt": zod.coerce.date()
})
export const ListToolRatingsResponse = zod.array(ListToolRatingsResponseItem)
/**
* @summary Submit a rating for a tool
*/
export const CreateRatingParams = zod.object({
"id": zod.coerce.number()
})
export const createRatingBodyUsefulnessMax = 5;
export const createRatingBodyUsabilityMax = 5;
export const CreateRatingBody = zod.object({
"usefulness": zod.number().min(1).max(createRatingBodyUsefulnessMax),
"usability": zod.number().min(1).max(createRatingBodyUsabilityMax),
"comment": zod.string().optional(),
"reviewerName": zod.string().optional()
})
/**
* @summary Overall platform statistics
*/
export const GetAnalyticsSummaryResponse = zod.object({
"totalTools": zod.number(),
"totalRatings": zod.number(),
"avgUsefulness": zod.number().nullable(),
"avgUsability": zod.number().nullable(),
"avgCombined": zod.number().nullable(),
"categoriesCount": zod.number(),
"mostRatedTool": zod.object({
"id": zod.number(),
"name": zod.string(),
"description": zod.string(),
"category": zod.string(),
"websiteUrl": zod.string().nullish(),
"features": zod.array(zod.string()).optional(),
"tags": zod.array(zod.string()).optional(),
"createdAt": zod.coerce.date(),
"updatedAt": zod.coerce.date(),
"ratingCount": zod.number(),
"avgUsefulness": zod.number().nullable(),
"avgUsability": zod.number().nullable(),
"avgCombined": zod.number().nullable()
}).optional()
})
/**
* @summary Top-rated tools
*/
export const GetTopToolsQueryParams = zod.object({
"limit": zod.coerce.number().optional(),
"metric": zod.enum(['usefulness', 'usability', 'combined']).optional()
})
export const GetTopToolsResponseItem = zod.object({
"tool": zod.object({
"id": zod.number(),
"name": zod.string(),
"description": zod.string(),
"category": zod.string(),
"websiteUrl": zod.string().nullish(),
"features": zod.array(zod.string()).optional(),
"tags": zod.array(zod.string()).optional(),
"createdAt": zod.coerce.date(),
"updatedAt": zod.coerce.date(),
"ratingCount": zod.number(),
"avgUsefulness": zod.number().nullable(),
"avgUsability": zod.number().nullable(),
"avgCombined": zod.number().nullable()
}),
"score": zod.number(),
"ratingCount": zod.number()
})
export const GetTopToolsResponse = zod.array(GetTopToolsResponseItem)
/**
* @summary Rating statistics grouped by category
*/
export const GetAnalyticsByCategoryResponseItem = zod.object({
"category": zod.string(),
"toolCount": zod.number(),
"totalRatings": zod.number(),
"avgUsefulness": zod.number().nullable(),
"avgUsability": zod.number().nullable()
})
export const GetAnalyticsByCategoryResponse = zod.array(GetAnalyticsByCategoryResponseItem)
/**
* @summary Distribution of rating scores across the platform
*/
export const GetRatingDistributionQueryParams = zod.object({
"toolId": zod.coerce.number().optional()
})
export const GetRatingDistributionResponse = zod.object({
"usefulness": zod.array(zod.object({
"score": zod.number(),
"count": zod.number()
})),
"usability": zod.array(zod.object({
"score": zod.number(),
"count": zod.number()
}))
})
/**
* @summary List all distinct tool categories
*/
export const ListCategoriesResponseItem = zod.string()
export const ListCategoriesResponse = zod.array(ListCategoriesResponseItem)