feat: 基础框架搭建完毕
Checks / verify (push) Failing after 2m37s

This commit is contained in:
2026-10-07 09:27:47 +08:00
parent ba6dfffab7
commit bffdb3858b
64 changed files with 326 additions and 332 deletions
+319
View File
@@ -0,0 +1,319 @@
openapi: 3.0.3
info:
title: Veyra API
version: 0.2.0
description: 工程基础、开发身份和账户初始化;密码登录仅限 local/test。
servers:
- url: http://127.0.0.1:8080
paths:
/healthz:
get:
operationId: getLiveness
responses:
'200':
description: API 进程存活,与依赖是否就绪无关
content:
application/json:
schema:
type: object
required: [status]
properties:
status: {type: string, enum: [alive]}
/readyz:
get:
operationId: getReadiness
responses:
'200': {$ref: '#/components/responses/Health'}
'503': {$ref: '#/components/responses/Health'}
/api/v1/system/health:
get:
operationId: getSystemHealth
responses:
'200': {$ref: '#/components/responses/Health'}
'503': {$ref: '#/components/responses/Health'}
/api/admin/v1/auth/login:
post:
operationId: adminLogin
description: 开发环境登录,要求同源 Origin;会话只在 HttpOnly Cookie 中返回。
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/LoginRequest'}
responses:
'200':
description: 已创建管理端会话
headers:
Set-Cookie: {schema: {type: string}, description: veyra_admin_session; HttpOnly; SameSite=Strict; Path=/api/admin}
content:
application/json:
schema:
allOf:
- {$ref: '#/components/schemas/Envelope'}
- properties:
data: {$ref: '#/components/schemas/AdminLogin'}
'401': {$ref: '#/components/responses/Error'}
'403': {$ref: '#/components/responses/Error'}
'422': {$ref: '#/components/responses/Error'}
'429': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
/api/v1/auth/login:
post:
operationId: developmentAppLogin
description: local/test 开发登录,返回 App 专用会话。正式短信登录与刷新流程待接入。
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/LoginRequest'}
responses:
'200':
description: 已创建 App 会话
content:
application/json:
schema:
allOf:
- {$ref: '#/components/schemas/Envelope'}
- properties:
data: {$ref: '#/components/schemas/AppLogin'}
'401': {$ref: '#/components/responses/Error'}
'422': {$ref: '#/components/responses/Error'}
'429': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
/api/admin/v1/me:
get:
operationId: getAdminIdentity
security: [{adminCookie: []}]
responses:
'200': {$ref: '#/components/responses/Identity'}
'401': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
/api/v1/me:
get:
operationId: getAppIdentity
security: [{appBearer: []}]
responses:
'200': {$ref: '#/components/responses/Identity'}
'401': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
/api/admin/v1/auth/logout:
post:
operationId: adminLogout
description: 同源 Origin 请求,撤销会话并清除管理端 Cookie。
security: [{adminCookie: []}]
responses:
'200': {$ref: '#/components/responses/Logout'}
'401': {$ref: '#/components/responses/Error'}
'403': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
/api/v1/auth/logout:
post:
operationId: appLogout
security: [{appBearer: []}]
responses:
'200': {$ref: '#/components/responses/Logout'}
'401': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
/api/admin/v1/users:
get:
operationId: listAppUsers
description: 最近创建的 100 位 App 用户,不包含密码、登录名或后台权限。
security: [{adminCookie: []}]
responses:
'200':
description: App 用户列表
content:
application/json:
schema:
allOf:
- {$ref: '#/components/schemas/Envelope'}
- properties:
data:
type: array
items: {$ref: '#/components/schemas/User'}
'401': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
/api/v1/accounts:
get:
operationId: listOwnAccounts
security: [{appBearer: []}]
responses:
'200':
description: 当前用户账户列表
content:
application/json:
schema:
allOf:
- {$ref: '#/components/schemas/Envelope'}
- properties:
data:
type: array
items: {$ref: '#/components/schemas/AccountSummary'}
'401': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
post:
operationId: createOwnAccount
description: simulation 要求 initial_cash,manual_real 必须省略;每种模式仅一个账户。
security: [{appBearer: []}]
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/CreateAccount'}
responses:
'201': {$ref: '#/components/responses/AccountSummary'}
'401': {$ref: '#/components/responses/Error'}
'409': {$ref: '#/components/responses/Error'}
'422': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
/api/v1/accounts/{id}/summary:
get:
operationId: getOwnAccountSummary
security: [{appBearer: []}]
parameters:
- name: id
in: path
required: true
schema: {type: string, format: uuid}
responses:
'200': {$ref: '#/components/responses/AccountSummary'}
'401': {$ref: '#/components/responses/Error'}
'404': {$ref: '#/components/responses/Error'}
'503': {$ref: '#/components/responses/Error'}
components:
securitySchemes:
adminCookie: {type: apiKey, in: cookie, name: veyra_admin_session}
appBearer: {type: http, scheme: bearer}
responses:
Error:
description: 标准业务错误
content:
application/json:
schema:
type: object
required: [error, meta]
properties:
error:
type: object
required: [code, message, retryable]
properties:
code: {type: string}
message: {type: string}
retryable: {type: boolean}
meta: {$ref: '#/components/schemas/Meta'}
Identity:
description: 当前身份
content:
application/json:
schema:
allOf:
- {$ref: '#/components/schemas/Envelope'}
- properties:
data: {$ref: '#/components/schemas/User'}
Logout:
description: 会话已撤销
content:
application/json:
schema:
allOf:
- {$ref: '#/components/schemas/Envelope'}
- properties:
data:
type: object
required: [revoked]
properties:
revoked: {type: boolean}
AccountSummary:
description: 账户与账本估算现金
content:
application/json:
schema:
allOf:
- {$ref: '#/components/schemas/Envelope'}
- properties:
data: {$ref: '#/components/schemas/AccountSummary'}
Health:
description: PostgreSQL 和 Redis 都正常时为 200,任一不可用或未配置时为 503
content:
application/json:
schema:
$ref: '#/components/schemas/Health'
schemas:
Meta:
type: object
required: [request_id]
properties:
request_id: {type: string, format: uuid}
server_time: {type: string, format: date-time}
Envelope:
type: object
required: [data, meta]
properties:
data: {}
meta: {$ref: '#/components/schemas/Meta'}
User:
type: object
required: [id, display_name, status, created_at, updated_at]
properties:
id: {type: string, format: uuid}
display_name: {type: string}
status: {type: string, enum: [ACTIVE, DISABLED]}
created_at: {type: string, format: date-time}
updated_at: {type: string, format: date-time}
LoginRequest:
type: object
additionalProperties: false
required: [login_name, password]
properties:
login_name: {type: string, minLength: 3, maxLength: 64}
password: {type: string, minLength: 1, maxLength: 72, writeOnly: true}
AdminLogin:
type: object
required: [user, expires_at]
properties:
user: {$ref: '#/components/schemas/User'}
expires_at: {type: string, format: date-time}
AppLogin:
allOf:
- {$ref: '#/components/schemas/AdminLogin'}
- type: object
required: [access_token]
properties:
access_token: {type: string}
CreateAccount:
type: object
additionalProperties: false
required: [mode, name]
properties:
mode: {type: string, enum: [simulation, manual_real]}
name: {type: string, minLength: 1, maxLength: 80}
initial_cash: {type: string, description: CNY 十进制字符串,最多两位小数,范围 0 至 1000000000.00}
AccountSummary:
type: object
required: [id, user_id, mode, name, currency, ledger_status, created_at, cash_balance]
properties:
id: {type: string, format: uuid}
user_id: {type: string, format: uuid}
mode: {type: string, enum: [simulation, manual_real]}
name: {type: string}
currency: {type: string, enum: [CNY]}
ledger_status: {type: string, enum: [COMPLETE, INCOMPLETE]}
created_at: {type: string, format: date-time}
cash_balance: {type: string, nullable: true, description: CNY 十进制字符串,现金历史不完整时为 null}
Health:
type: object
required: [status, checked_at, components]
properties:
status: {type: string, enum: [ready, not_ready]}
checked_at: {type: string, format: date-time}
components:
type: object
required: [postgresql, redis]
properties:
postgresql: {$ref: '#/components/schemas/Component'}
redis: {$ref: '#/components/schemas/Component'}
Component:
type: object
required: [status]
properties:
status: {type: string, enum: [ready, unavailable, not_configured]}