feat: Add Step Library API foundation (Phase 1: B.1-B.3, B.7)
Implements foundational types and API clients for Step Library: Task B.3 - TypeScript Types: - Created types/step.ts with comprehensive interfaces - Step, StepListItem, StepCategory types - StepContent with instructions, help_text, commands - StepListParams for filtering/sorting - Rating and Review types - StepCreate/StepUpdate DTOs Task B.1 - Steps API Client: - Created api/steps.ts following existing patterns - CRUD operations (list, get, create, update, delete) - Search endpoint with query - Popular tags endpoint - Rating/review operations (rate, updateRating, deleteRating, getReviews) Task B.2 - Step Categories API Client: - Created api/stepCategories.ts - List and get operations for categories Task B.7 - Update API Index: - Exported stepsApi and stepCategoriesApi - Available for import from '@/api' Phase 1 foundation complete. Ready for Phase 2 (UI components). Build tested successfully. Related: Issue #10 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,3 +6,5 @@ export { default as inviteApi } from './invite'
|
|||||||
export { default as tagsApi } from './tags'
|
export { default as tagsApi } from './tags'
|
||||||
export { default as categoriesApi } from './categories'
|
export { default as categoriesApi } from './categories'
|
||||||
export { default as foldersApi } from './folders'
|
export { default as foldersApi } from './folders'
|
||||||
|
export { default as stepsApi } from './steps'
|
||||||
|
export { default as stepCategoriesApi } from './stepCategories'
|
||||||
|
|||||||
16
frontend/src/api/stepCategories.ts
Normal file
16
frontend/src/api/stepCategories.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import apiClient from './client'
|
||||||
|
import type { StepCategory } from '@/types/step'
|
||||||
|
|
||||||
|
export const stepCategoriesApi = {
|
||||||
|
async list(): Promise<StepCategory[]> {
|
||||||
|
const response = await apiClient.get<StepCategory[]>('/step-categories')
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async get(id: string): Promise<StepCategory> {
|
||||||
|
const response = await apiClient.get<StepCategory>(`/step-categories/${id}`)
|
||||||
|
return response.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default stepCategoriesApi
|
||||||
72
frontend/src/api/steps.ts
Normal file
72
frontend/src/api/steps.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import apiClient from './client'
|
||||||
|
import type {
|
||||||
|
Step,
|
||||||
|
StepListItem,
|
||||||
|
StepCreate,
|
||||||
|
StepUpdate,
|
||||||
|
StepListParams,
|
||||||
|
PopularTag,
|
||||||
|
RatingCreate,
|
||||||
|
RatingUpdate,
|
||||||
|
Rating,
|
||||||
|
Review
|
||||||
|
} from '@/types/step'
|
||||||
|
|
||||||
|
export const stepsApi = {
|
||||||
|
async list(params?: StepListParams): Promise<StepListItem[]> {
|
||||||
|
const response = await apiClient.get<StepListItem[]>('/steps', { params })
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async get(id: string): Promise<Step> {
|
||||||
|
const response = await apiClient.get<Step>(`/steps/${id}`)
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async create(data: StepCreate): Promise<Step> {
|
||||||
|
const response = await apiClient.post<Step>('/steps', data)
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async update(id: string, data: StepUpdate): Promise<Step> {
|
||||||
|
const response = await apiClient.put<Step>(`/steps/${id}`, data)
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async delete(id: string): Promise<void> {
|
||||||
|
await apiClient.delete(`/steps/${id}`)
|
||||||
|
},
|
||||||
|
|
||||||
|
async search(query: string): Promise<StepListItem[]> {
|
||||||
|
const response = await apiClient.get<StepListItem[]>('/steps/search', {
|
||||||
|
params: { q: query }
|
||||||
|
})
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async getPopularTags(): Promise<PopularTag[]> {
|
||||||
|
const response = await apiClient.get<PopularTag[]>('/steps/popular-tags')
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async rate(id: string, data: RatingCreate): Promise<Rating> {
|
||||||
|
const response = await apiClient.post<Rating>(`/steps/${id}/ratings`, data)
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async updateRating(id: string, data: RatingUpdate): Promise<Rating> {
|
||||||
|
const response = await apiClient.put<Rating>(`/steps/${id}/ratings`, data)
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
|
||||||
|
async deleteRating(id: string): Promise<void> {
|
||||||
|
await apiClient.delete(`/steps/${id}/ratings`)
|
||||||
|
},
|
||||||
|
|
||||||
|
async getReviews(id: string): Promise<Review[]> {
|
||||||
|
const response = await apiClient.get<Review[]>(`/steps/${id}/reviews`)
|
||||||
|
return response.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default stepsApi
|
||||||
124
frontend/src/types/step.ts
Normal file
124
frontend/src/types/step.ts
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
// Step Library Types
|
||||||
|
|
||||||
|
export interface StepCommand {
|
||||||
|
label: string
|
||||||
|
command: string
|
||||||
|
command_type?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StepContent {
|
||||||
|
instructions: string
|
||||||
|
help_text?: string
|
||||||
|
commands?: StepCommand[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Step {
|
||||||
|
id: string
|
||||||
|
title: string
|
||||||
|
step_type: 'decision' | 'action' | 'solution'
|
||||||
|
content: StepContent
|
||||||
|
visibility: 'private' | 'team' | 'public'
|
||||||
|
category_id?: string
|
||||||
|
category_name?: string
|
||||||
|
tags: string[]
|
||||||
|
usage_count: number
|
||||||
|
rating_average: number
|
||||||
|
rating_count: number
|
||||||
|
helpful_yes: number
|
||||||
|
helpful_no: number
|
||||||
|
is_featured: boolean
|
||||||
|
is_verified: boolean
|
||||||
|
created_by: string
|
||||||
|
author_name?: string
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StepListItem {
|
||||||
|
id: string
|
||||||
|
title: string
|
||||||
|
step_type: string
|
||||||
|
visibility: string
|
||||||
|
category_id?: string
|
||||||
|
category_name?: string
|
||||||
|
tags: string[]
|
||||||
|
usage_count: number
|
||||||
|
rating_average: number
|
||||||
|
rating_count: number
|
||||||
|
is_featured: boolean
|
||||||
|
created_by: string
|
||||||
|
author_name?: string
|
||||||
|
created_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StepCategory {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
description?: string
|
||||||
|
display_order: number
|
||||||
|
team_id?: string
|
||||||
|
is_active: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StepListParams {
|
||||||
|
visibility?: 'private' | 'team' | 'public'
|
||||||
|
category_id?: string
|
||||||
|
tags?: string[]
|
||||||
|
min_rating?: number
|
||||||
|
step_type?: 'decision' | 'action' | 'solution'
|
||||||
|
sort_by?: 'recent' | 'popular' | 'highest_rated' | 'most_used'
|
||||||
|
limit?: number
|
||||||
|
offset?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PopularTag {
|
||||||
|
tag: string
|
||||||
|
count: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StepCreate {
|
||||||
|
title: string
|
||||||
|
step_type: 'decision' | 'action' | 'solution'
|
||||||
|
content: StepContent
|
||||||
|
visibility: 'private' | 'team' | 'public'
|
||||||
|
category_id?: string
|
||||||
|
tags?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StepUpdate {
|
||||||
|
title?: string
|
||||||
|
step_type?: 'decision' | 'action' | 'solution'
|
||||||
|
content?: StepContent
|
||||||
|
visibility?: 'private' | 'team' | 'public'
|
||||||
|
category_id?: string
|
||||||
|
tags?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RatingCreate {
|
||||||
|
rating: number
|
||||||
|
review_text?: string
|
||||||
|
verified_use: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RatingUpdate {
|
||||||
|
rating?: number
|
||||||
|
review_text?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Rating {
|
||||||
|
id: string
|
||||||
|
step_id: string
|
||||||
|
user_id: string
|
||||||
|
rating: number
|
||||||
|
review_text?: string
|
||||||
|
verified_use: boolean
|
||||||
|
helpful_yes: number
|
||||||
|
helpful_no: number
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
user_name?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Review extends Rating {
|
||||||
|
// Same as Rating, just an alias for clarity
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user