Files
tool-evaluator/lib/api-spec/openapi.yaml
T
cheffe01 c5ca3ca992 Add local user authentication and admin capabilities
Implement local user authentication with password hashing, add admin roles for user management and audit log viewing, and introduce audit logging for critical actions.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 776963d0-f75d-42e2-a57b-cc36bdff8495
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 832a44ff-12ae-4096-8a0d-666ec083d536
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0683fb79-a27c-485c-9333-5f4b288c4567/776963d0-f75d-42e2-a57b-cc36bdff8495/1p7jhzu
Replit-Helium-Checkpoint-Created: true
2026-05-25 14:11:02 +00:00

861 lines
20 KiB
YAML

openapi: 3.1.0
info:
# Do not change the title, if the title changes, the import paths will be broken
title: Api
version: 0.1.0
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
- name: auth
description: Authentication
- name: users
description: User management (admin only)
- name: audit
description: Audit log
paths:
/healthz:
get:
operationId: healthCheck
tags: [health]
summary: Health check
description: Returns server health status
responses:
"200":
description: Healthy
content:
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
/features/all:
get:
operationId: listAllFeatures
tags: [tools]
summary: List all distinct feature strings across all tools
responses:
"200":
description: All known features
content:
application/json:
schema:
type: array
items:
type: string
/auth/mode:
get:
operationId: getAuthMode
tags: [auth]
summary: Get authentication mode (oidc or local)
responses:
"200":
description: Auth mode
content:
application/json:
schema:
$ref: "#/components/schemas/AuthMode"
/auth/login:
post:
operationId: localLogin
tags: [auth]
summary: Local username/password login
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/LocalLoginInput"
responses:
"200":
description: Logged in successfully
content:
application/json:
schema:
$ref: "#/components/schemas/AuthUser"
"401":
description: Invalid credentials
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/auth/me:
get:
operationId: getMe
tags: [auth]
summary: Get current authenticated user
responses:
"200":
description: Current user info
content:
application/json:
schema:
$ref: "#/components/schemas/AuthUser"
"401":
description: Not authenticated
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/users:
get:
operationId: listUsers
tags: [users]
summary: List all local users (admin only)
responses:
"200":
description: User list
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/User"
"401":
description: Not authenticated
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: Forbidden
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
post:
operationId: createUser
tags: [users]
summary: Create a new local user (admin only)
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UserCreateInput"
responses:
"201":
description: Created user
content:
application/json:
schema:
$ref: "#/components/schemas/User"
"400":
description: Validation error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"409":
description: Username already exists
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/users/{id}:
patch:
operationId: updateUser
tags: [users]
summary: Update user role (admin only)
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UserRoleUpdate"
responses:
"200":
description: Updated user
content:
application/json:
schema:
$ref: "#/components/schemas/User"
"404":
description: User not found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
delete:
operationId: deleteUser
tags: [users]
summary: Delete a user (admin only)
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
"204":
description: Deleted
/audit-logs:
get:
operationId: listAuditLogs
tags: [audit]
summary: List audit log entries (admin only)
parameters:
- name: entityType
in: query
required: false
schema:
type: string
- name: entityId
in: query
required: false
schema:
type: integer
- name: limit
in: query
required: false
schema:
type: integer
responses:
"200":
description: Audit log entries
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/AuditLog"
components:
schemas:
HealthStatus:
type: object
properties:
status:
type: string
required:
- status
AuthMode:
type: object
required: [mode]
properties:
mode:
type: string
enum: [oidc, local]
LocalLoginInput:
type: object
required: [username, password]
properties:
username:
type: string
password:
type: string
User:
type: object
required: [id, username, role, createdAt]
properties:
id:
type: integer
username:
type: string
email:
type: ["string", "null"]
role:
type: string
enum: [admin, user]
createdAt:
type: string
format: date-time
UserCreateInput:
type: object
required: [username, password]
properties:
username:
type: string
minLength: 2
password:
type: string
minLength: 6
email:
type: string
role:
type: string
enum: [admin, user]
UserRoleUpdate:
type: object
required: [role]
properties:
role:
type: string
enum: [admin, user]
AuditLog:
type: object
required: [id, entityType, action, userId, username, createdAt]
properties:
id:
type: integer
entityType:
type: string
entityId:
type: ["integer", "null"]
action:
type: string
userId:
type: string
username:
type: string
changes:
type: ["string", "null"]
createdAt:
type: string
format: date-time
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"]
iconUrl:
type: ["string", "null"]
createdBy:
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"]
iconUrl:
type: ["string", "null"]
createdBy:
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
iconUrl:
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
iconUrl:
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
AuthUser:
type: object
required: [sub]
properties:
sub:
type: string
email:
type: ["string", "null"]
name:
type: ["string", "null"]
preferredUsername:
type: ["string", "null"]
role:
type: string
enum: [admin, user]
isLocal:
type: boolean
ErrorResponse:
type: object
required: [error]
properties:
error:
type: string