chore: seal Design Vision v1 and monorepo scaffold

Archive the differentiated YuXinGu product docs, AI engineering system,
design contract, and Go/Vue scaffold. Next execution prioritizes Cece-parity
over early innovation (see .ai/product/STRATEGY.md).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-02 16:00:44 +08:00
co-authored by Cursor
parent 2686866376
commit 2fb1dfee14
193 changed files with 8854 additions and 1851 deletions
+75
View File
@@ -0,0 +1,75 @@
import type { ApiResponse } from '@yuxingu/types'
/** Platform adapters so H5 and mini-program share one client. */
export interface RequestOptions {
method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
path: string
body?: unknown
headers?: Record<string, string>
}
export interface ClientAdapters {
/** Perform HTTP and return parsed JSON envelope. */
request: <T>(opts: RequestOptions) => Promise<ApiResponse<T>>
getToken?: () => string | null | Promise<string | null>
}
export interface CreateClientOptions {
baseURL: string
adapters: ClientAdapters
}
/**
* createClient builds a typed API facade.
* Side effect: network via adapters.request.
*/
export function createClient(opts: CreateClientOptions) {
const { baseURL, adapters } = opts
async function call<T>(path: string, init?: Omit<RequestOptions, 'path'>): Promise<T> {
const token = adapters.getToken ? await adapters.getToken() : null
const headers: Record<string, string> = { ...(init?.headers || {}) }
if (token) headers.Authorization = `Bearer ${token}`
const res = await adapters.request<T>({
method: init?.method || 'GET',
path: joinURL(baseURL, path),
body: init?.body,
headers,
})
if (res.code !== 0) {
throw new Error(res.message || `api error ${res.code}`)
}
return res.data as T
}
return {
healthz: () => call<{ status: string }>('/api/v1/healthz'),
ping: () => call<{ pong: boolean }>('/api/v1/ping'),
}
}
/** Browser fetch adapter for user-h5. */
export function createBrowserAdapters(): ClientAdapters {
return {
request: async <T>({ method = 'GET', path, body, headers }) => {
const res = await fetch(path, {
method,
headers: {
'Content-Type': 'application/json',
...(headers || {}),
},
body: body === undefined ? undefined : JSON.stringify(body),
})
return (await res.json()) as ApiResponse<T>
},
getToken: () => localStorage.getItem('yxg_token'),
}
}
function joinURL(base: string, path: string): string {
if (path.startsWith('http')) return path
const b = base.replace(/\/$/, '')
const p = path.startsWith('/') ? path : `/${path}`
return `${b}${p}`
}