Results API
Endpoints
POST /results/search
: Search and retrieve results with paginationDELETE /results/:id
: Soft-delete a result by id (marks as DELETED and removes payload)POST /results/:id/feedback
: Add feedback to a result
Authentication
All endpoints are protected by JWT. Pass a valid bearer token.
Search
Request body:
interface SearchResultsRequest {
userEmails: string[]; // Required
type?: 'thread';
dateFrom?: Date;
dateTo?: Date;
page?: number; // default: 1
pageSize?: number; // default: 10
}
Response:
interface SearchResultsResponse {
results: OmnilexResult[]; // Can include items with status === 'DELETED'
pagination: {
currentPage: number;
pageSize: number;
totalPages: number;
totalCount: number;
hasNextPage: boolean;
hasPreviousPage: boolean;
};
}
Example:
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"userEmails": ["user@example.com"],
"type": "table",
"page": 1,
"pageSize": 10
}' \
http://localhost:3000/results-history/search
Soft-delete
Deletes do not remove the DB row. The item is marked as DELETED
and its payload is removed.
- Endpoint:
DELETE /results-history/:id
- Authorization: The requester must be the
ownerUsername
or be listed incan_write
. - Effect:
status
becomesDELETED
- Payload field is removed based on
type
:thread
→ thethread
field is removed
- Other metadata (id, owner, permissions, date, type) are preserved
Responses:
// 200 OK
{ "success": true }
// 404 Not Found
{ "error": "Result not found" }
// 403 Forbidden
{ "error": "You do not have permission to delete this result" }
Example:
curl -X DELETE \
-H "Authorization: Bearer <TOKEN>" \
http://localhost:3000/results-history/00000000-0000-0000-0000-000000000000
Feedback
Adds user feedback to a specific result.
- Endpoint:
POST /results/:id/feedback
- Authorization: Requires valid JWT token
Request body:
interface AddFeedbackRequest {
vote: 'upvote' | 'downvote' | 'undefined'; // FeedbackVote enum
feedback: string; // User's feedback text
}
Response:
interface AddFeedbackResponse {
success: boolean;
message?: string;
}
Responses:
// 200 OK
{
"success": true,
"message": "Feedback added successfully"
}
// 403 Forbidden (if no permission)
{
"success": false,
"message": "You do not have permission to add feedback to this result"
}
// 404 Not Found
{
"success": false,
"message": "Result not found"
}
// 500 Internal Server Error
{
"success": false,
"message": "Failed to add feedback"
}
Example:
curl -X POST \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"vote": "upvote",
"feedback": "This was very helpful!"
}' \
http://localhost:3000/results/00000000-0000-0000-0000-000000000000/feedback
Frontend usage (search)
async function fetchResults(page = 1, pageSize = 20) {
const response = await fetch('/api/results-history/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ userEmails: ['user@example.com'], page, pageSize })
});
return response.json();
}
Frontend usage (feedback)
async function addFeedback(resultId: string, vote: 'upvote' | 'downvote' | 'undefined', feedback: string) {
const response = await fetch(`/api/results/${resultId}/feedback`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${getToken()}`
},
body: JSON.stringify({ vote, feedback })
});
return response.json();
}
Notes
- Results are ordered by
updatedAt
timestamp - Pagination uses offset-based implementation internally
- Responses include pagination metadata
- Default page size is 10