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:
+506
-1
@@ -3,13 +3,19 @@ info:
|
||||
# Do not change the title, if the title changes, the import paths will be broken
|
||||
title: Api
|
||||
version: 0.1.0
|
||||
description: API specification
|
||||
description: ToolRate API — Tool listing and rating platform
|
||||
servers:
|
||||
- url: /api
|
||||
description: Base API path
|
||||
tags:
|
||||
- name: health
|
||||
description: Health operations
|
||||
- name: tools
|
||||
description: Tool management
|
||||
- name: ratings
|
||||
description: Tool ratings
|
||||
- name: analytics
|
||||
description: Analytics and aggregated statistics
|
||||
paths:
|
||||
/healthz:
|
||||
get:
|
||||
@@ -24,6 +30,280 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/HealthStatus"
|
||||
|
||||
/tools:
|
||||
get:
|
||||
operationId: listTools
|
||||
tags: [tools]
|
||||
summary: List all tools
|
||||
parameters:
|
||||
- name: category
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: search
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
- name: sort
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [newest, top_rated, most_reviewed]
|
||||
responses:
|
||||
"200":
|
||||
description: List of tools
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ToolWithStats"
|
||||
post:
|
||||
operationId: createTool
|
||||
tags: [tools]
|
||||
summary: Create a new tool
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ToolInput"
|
||||
responses:
|
||||
"201":
|
||||
description: Created tool
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Tool"
|
||||
"400":
|
||||
description: Validation error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/tools/{id}:
|
||||
get:
|
||||
operationId: getTool
|
||||
tags: [tools]
|
||||
summary: Get a tool by ID
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
description: Tool details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ToolWithStats"
|
||||
"404":
|
||||
description: Not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
patch:
|
||||
operationId: updateTool
|
||||
tags: [tools]
|
||||
summary: Update a tool
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ToolUpdate"
|
||||
responses:
|
||||
"200":
|
||||
description: Updated tool
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Tool"
|
||||
"404":
|
||||
description: Not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
delete:
|
||||
operationId: deleteTool
|
||||
tags: [tools]
|
||||
summary: Delete a tool
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
"204":
|
||||
description: Deleted
|
||||
"404":
|
||||
description: Not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/tools/{id}/ratings:
|
||||
get:
|
||||
operationId: listToolRatings
|
||||
tags: [ratings]
|
||||
summary: List ratings for a tool
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
description: Ratings list
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Rating"
|
||||
post:
|
||||
operationId: createRating
|
||||
tags: [ratings]
|
||||
summary: Submit a rating for a tool
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/RatingInput"
|
||||
responses:
|
||||
"201":
|
||||
description: Created rating
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Rating"
|
||||
"400":
|
||||
description: Validation error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
"404":
|
||||
description: Tool not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/analytics/summary:
|
||||
get:
|
||||
operationId: getAnalyticsSummary
|
||||
tags: [analytics]
|
||||
summary: Overall platform statistics
|
||||
responses:
|
||||
"200":
|
||||
description: Platform-level summary stats
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/AnalyticsSummary"
|
||||
|
||||
/analytics/top-tools:
|
||||
get:
|
||||
operationId: getTopTools
|
||||
tags: [analytics]
|
||||
summary: Top-rated tools
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
- name: metric
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum: [usefulness, usability, combined]
|
||||
responses:
|
||||
"200":
|
||||
description: Top tools list
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TopToolEntry"
|
||||
|
||||
/analytics/by-category:
|
||||
get:
|
||||
operationId: getAnalyticsByCategory
|
||||
tags: [analytics]
|
||||
summary: Rating statistics grouped by category
|
||||
responses:
|
||||
"200":
|
||||
description: Per-category statistics
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/CategoryStats"
|
||||
|
||||
/analytics/rating-distribution:
|
||||
get:
|
||||
operationId: getRatingDistribution
|
||||
tags: [analytics]
|
||||
summary: Distribution of rating scores across the platform
|
||||
parameters:
|
||||
- name: toolId
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
"200":
|
||||
description: Rating score distribution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/RatingDistribution"
|
||||
|
||||
/categories:
|
||||
get:
|
||||
operationId: listCategories
|
||||
tags: [tools]
|
||||
summary: List all distinct tool categories
|
||||
responses:
|
||||
"200":
|
||||
description: Categories list
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
components:
|
||||
schemas:
|
||||
HealthStatus:
|
||||
@@ -34,3 +314,228 @@ components:
|
||||
required:
|
||||
- status
|
||||
|
||||
Tool:
|
||||
type: object
|
||||
required: [id, name, description, category, createdAt, updatedAt]
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
category:
|
||||
type: string
|
||||
websiteUrl:
|
||||
type: ["string", "null"]
|
||||
features:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
ToolWithStats:
|
||||
type: object
|
||||
required: [id, name, description, category, createdAt, updatedAt, ratingCount, avgUsefulness, avgUsability, avgCombined]
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
category:
|
||||
type: string
|
||||
websiteUrl:
|
||||
type: ["string", "null"]
|
||||
features:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
ratingCount:
|
||||
type: integer
|
||||
avgUsefulness:
|
||||
type: ["number", "null"]
|
||||
avgUsability:
|
||||
type: ["number", "null"]
|
||||
avgCombined:
|
||||
type: ["number", "null"]
|
||||
|
||||
ToolInput:
|
||||
type: object
|
||||
required: [name, description, category]
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
description:
|
||||
type: string
|
||||
minLength: 1
|
||||
category:
|
||||
type: string
|
||||
minLength: 1
|
||||
websiteUrl:
|
||||
type: string
|
||||
features:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
ToolUpdate:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
description:
|
||||
type: string
|
||||
category:
|
||||
type: string
|
||||
websiteUrl:
|
||||
type: string
|
||||
features:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
Rating:
|
||||
type: object
|
||||
required: [id, toolId, usefulness, usability, createdAt]
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
toolId:
|
||||
type: integer
|
||||
usefulness:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 5
|
||||
usability:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 5
|
||||
comment:
|
||||
type: ["string", "null"]
|
||||
reviewerName:
|
||||
type: ["string", "null"]
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
RatingInput:
|
||||
type: object
|
||||
required: [usefulness, usability]
|
||||
properties:
|
||||
usefulness:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 5
|
||||
usability:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 5
|
||||
comment:
|
||||
type: string
|
||||
reviewerName:
|
||||
type: string
|
||||
|
||||
AnalyticsSummary:
|
||||
type: object
|
||||
required: [totalTools, totalRatings, avgUsefulness, avgUsability, avgCombined, categoriesCount]
|
||||
properties:
|
||||
totalTools:
|
||||
type: integer
|
||||
totalRatings:
|
||||
type: integer
|
||||
avgUsefulness:
|
||||
type: ["number", "null"]
|
||||
avgUsability:
|
||||
type: ["number", "null"]
|
||||
avgCombined:
|
||||
type: ["number", "null"]
|
||||
categoriesCount:
|
||||
type: integer
|
||||
mostRatedTool:
|
||||
$ref: "#/components/schemas/ToolWithStats"
|
||||
|
||||
TopToolEntry:
|
||||
type: object
|
||||
required: [tool, score, ratingCount]
|
||||
properties:
|
||||
tool:
|
||||
$ref: "#/components/schemas/ToolWithStats"
|
||||
score:
|
||||
type: number
|
||||
ratingCount:
|
||||
type: integer
|
||||
|
||||
CategoryStats:
|
||||
type: object
|
||||
required: [category, toolCount, totalRatings, avgUsefulness, avgUsability]
|
||||
properties:
|
||||
category:
|
||||
type: string
|
||||
toolCount:
|
||||
type: integer
|
||||
totalRatings:
|
||||
type: integer
|
||||
avgUsefulness:
|
||||
type: ["number", "null"]
|
||||
avgUsability:
|
||||
type: ["number", "null"]
|
||||
|
||||
RatingDistribution:
|
||||
type: object
|
||||
required: [usefulness, usability]
|
||||
properties:
|
||||
usefulness:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ScoreBucket"
|
||||
usability:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ScoreBucket"
|
||||
|
||||
ScoreBucket:
|
||||
type: object
|
||||
required: [score, count]
|
||||
properties:
|
||||
score:
|
||||
type: integer
|
||||
count:
|
||||
type: integer
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
required: [error]
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
|
||||
Reference in New Issue
Block a user