feat: admin OpenAPI type generation (gen:api) + envelope/entity types
This commit is contained in:
@ -10,7 +10,8 @@
|
||||
"generate-routes": "tsr generate",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"test": "vitest run"
|
||||
"test": "vitest run",
|
||||
"gen:api": "openapi-typescript ../gig-platform/public/api-docs/admin/openapi.yaml -o src/api/types.gen.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^5.4.0",
|
||||
@ -64,4 +65,4 @@
|
||||
"lightningcss"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4101
src/api/types.gen.ts
Normal file
4101
src/api/types.gen.ts
Normal file
File diff suppressed because it is too large
Load Diff
257
src/api/types.ts
Normal file
257
src/api/types.ts
Normal file
@ -0,0 +1,257 @@
|
||||
/**
|
||||
* Hand-written types for the gig-platform admin API.
|
||||
*
|
||||
* The scribe-generated `types.gen.ts` covers paths/params, but its response
|
||||
* schemas are example-based and incomplete — the envelope and entities below
|
||||
* are the source of truth for data shapes (mirrors CLAUDE.md API design).
|
||||
*/
|
||||
|
||||
// ---------- envelope ----------
|
||||
|
||||
export interface ApiResponse<T = unknown> {
|
||||
success: boolean
|
||||
data: T
|
||||
message?: string
|
||||
meta?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface Pagination {
|
||||
current_page: number
|
||||
next_page: number | null
|
||||
page_size: number
|
||||
prev_page: number | null
|
||||
total_count: number
|
||||
total_pages: number
|
||||
}
|
||||
|
||||
export interface PaginatedResponse<T> extends ApiResponse<T[]> {
|
||||
pagination: Pagination
|
||||
}
|
||||
|
||||
export interface ApiErrorPayload {
|
||||
success: false
|
||||
code: string
|
||||
message: string
|
||||
data?: { errors?: Record<string, string[]> } & Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface ListParams {
|
||||
page?: number
|
||||
page_size?: number
|
||||
[key: string]: string | number | boolean | undefined
|
||||
}
|
||||
|
||||
// ---------- auth ----------
|
||||
|
||||
export interface TokenGrant {
|
||||
token_type: string
|
||||
expires_in: number
|
||||
access_token: string
|
||||
refresh_token?: string
|
||||
}
|
||||
|
||||
export interface AdminUser {
|
||||
kind: 'user'
|
||||
uid: string
|
||||
sid?: string | null
|
||||
username: string | null
|
||||
email: string | null
|
||||
phone: string | null
|
||||
display_name: string | null
|
||||
avatar: string | null
|
||||
status: boolean | string
|
||||
is_robot?: boolean
|
||||
}
|
||||
|
||||
export interface MeResponse extends ApiResponse<AdminUser> {
|
||||
meta: {
|
||||
roles: string[]
|
||||
permissions: string[]
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- category ----------
|
||||
|
||||
export interface Category {
|
||||
kind: 'category'
|
||||
id: string
|
||||
parent_id: string | null
|
||||
level: number
|
||||
slug: string
|
||||
name: string
|
||||
description: string | null
|
||||
status: string
|
||||
sort_order: number
|
||||
is_leaf?: boolean
|
||||
created_by_uid?: string | null
|
||||
children?: Category[]
|
||||
created_at?: string
|
||||
updated_at?: string
|
||||
}
|
||||
|
||||
export interface CategoryTranslation {
|
||||
locale: string
|
||||
name: string
|
||||
description: string | null
|
||||
}
|
||||
|
||||
// ---------- studio ----------
|
||||
|
||||
export type ArticleStatus =
|
||||
| 'planned'
|
||||
| 'drafting'
|
||||
| 'drafted'
|
||||
| 'published'
|
||||
| 'scheduled'
|
||||
|
||||
export interface StudioArticle {
|
||||
kind: 'studio_article'
|
||||
id: string
|
||||
series_id: string
|
||||
robot_author_id: string
|
||||
category_id: string | null
|
||||
subtopic_id: string | null
|
||||
article_number: number
|
||||
plan: Record<string, unknown> | null
|
||||
outline: Record<string, unknown> | null
|
||||
title: string | null
|
||||
summary: string | null
|
||||
key_takeaways: string[] | null
|
||||
cta: string | null
|
||||
tags: string[] | null
|
||||
seo_keywords: string[] | null
|
||||
cover_image_prompt: string | null
|
||||
cover_asset_id: string | null
|
||||
cover_image: { url: string; alt?: string | null } | null
|
||||
inline_images: Array<{ url: string; alt?: string | null }> | null
|
||||
inline_image_prompts: unknown[] | null
|
||||
status: ArticleStatus
|
||||
publish_schedule: Record<string, unknown> | null
|
||||
dimzou_document_id: number | null
|
||||
dimzou_publication_id: number | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export type RobotAuthorStatus = 'pending' | 'profiling' | 'ready' | 'paused'
|
||||
|
||||
export interface StudioRobotAuthor {
|
||||
kind: 'studio_robot_author'
|
||||
id: string
|
||||
user_uid: string
|
||||
category_id: string
|
||||
subtopic_id: string | null
|
||||
persona: string | null
|
||||
positioning: string | null
|
||||
target_readers: string | null
|
||||
article_style: Record<string, unknown> | null
|
||||
image_style: Record<string, unknown> | null
|
||||
publishing_rules: Record<string, unknown> | null
|
||||
status: RobotAuthorStatus
|
||||
source: 'user' | 'category'
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export type SeriesStatus = 'planned' | 'in_progress' | 'complete'
|
||||
|
||||
export interface StudioSeries {
|
||||
kind: 'studio_series'
|
||||
id: string
|
||||
category_id: string
|
||||
subtopic_id: string | null
|
||||
robot_author_id: string
|
||||
goal: string | null
|
||||
reader_journey: string | null
|
||||
target_article_count: number | null
|
||||
planned_articles: unknown[] | null
|
||||
status: SeriesStatus
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface StudioSubtopic {
|
||||
kind: 'studio_subtopic'
|
||||
id: string
|
||||
category_id: string
|
||||
title: string
|
||||
target_audience: string | null
|
||||
pain_points: string | null
|
||||
content_value: string | null
|
||||
expandability_score: number | null
|
||||
status: 'active' | 'archived'
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface StudioCategoryBrief {
|
||||
kind: 'studio_category_brief'
|
||||
id: string
|
||||
category_id: string
|
||||
description: string | null
|
||||
target_audience: string | null
|
||||
content_angles: string[] | null
|
||||
risk_notes: string | null
|
||||
subtopic_count: number
|
||||
author_count: number
|
||||
article_count: number
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface StudioStylePreset {
|
||||
kind: 'studio_style_preset'
|
||||
id: string
|
||||
type: 'article' | 'image' | 'bundle'
|
||||
name: string
|
||||
payload: Record<string, unknown>
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export interface StudioAgentToken {
|
||||
kind: 'studio_agent_token'
|
||||
id: string
|
||||
scopes: string[] | null
|
||||
created_at: string | null
|
||||
expires_at: string | null
|
||||
}
|
||||
|
||||
export interface StudioAgentTokenGrant extends TokenGrant {
|
||||
kind: 'studio_agent_token_grant'
|
||||
connect: { endpoint: string; header: string }
|
||||
}
|
||||
|
||||
// ---------- sid / locales / devices ----------
|
||||
|
||||
export interface SidRule {
|
||||
key: string
|
||||
value: unknown
|
||||
description?: string | null
|
||||
}
|
||||
|
||||
export interface LuckyNumber {
|
||||
id: number | string
|
||||
number: string
|
||||
price?: number | null
|
||||
status?: string
|
||||
reserved_for_uid?: string | null
|
||||
created_at?: string
|
||||
}
|
||||
|
||||
export interface LocaleRow {
|
||||
code: string
|
||||
name: string
|
||||
native_name?: string | null
|
||||
enabled?: boolean
|
||||
is_default?: boolean
|
||||
}
|
||||
|
||||
export interface NotificationDevice {
|
||||
id: number | string
|
||||
user_uid: string
|
||||
platform?: string
|
||||
token?: string
|
||||
last_seen_at?: string | null
|
||||
created_at?: string
|
||||
}
|
||||
Reference in New Issue
Block a user