初始化项目

This commit is contained in:
2026-01-18 10:35:27 +08:00
parent 85042841ae
commit 00ca4c1b0d
116 changed files with 11569 additions and 2 deletions

580
spec/openapi.yaml Normal file
View File

@@ -0,0 +1,580 @@
openapi: 3.1.0
info:
title: BrowserBookmark API
version: 0.1.0
description: Internal bookmark manager API (Web + Extension)
servers:
- url: http://localhost:3001
tags:
- name: Health
- name: Auth
- name: Bookmarks
- name: Folders
- name: ImportExport
- name: Sync
- name: Admin
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
Error:
type: object
properties:
message:
type: string
required: [message]
User:
type: object
properties:
id:
type: string
format: uuid
email:
type: string
format: email
role:
type: string
enum: [user, admin]
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
required: [id, email, role, createdAt, updatedAt]
Folder:
type: object
properties:
id:
type: string
format: uuid
userId:
type: string
format: uuid
parentId:
anyOf:
- type: string
format: uuid
- type: 'null'
name:
type: string
visibility:
type: string
enum: [public, private]
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
required: [id, userId, parentId, name, visibility, createdAt, updatedAt]
Bookmark:
type: object
properties:
id:
type: string
format: uuid
userId:
type: string
format: uuid
folderId:
anyOf:
- type: string
format: uuid
- type: 'null'
title:
type: string
url:
type: string
urlNormalized:
type: string
urlHash:
type: string
visibility:
type: string
enum: [public, private]
source:
type: string
enum: [manual, import]
updatedAt:
type: string
format: date-time
deletedAt:
anyOf:
- type: string
format: date-time
- type: 'null'
required: [id, userId, folderId, title, url, urlNormalized, urlHash, visibility, source, updatedAt, deletedAt]
FolderPatch:
type: object
properties:
parentId:
anyOf:
- type: string
format: uuid
- type: 'null'
name:
type: string
visibility:
type: string
enum: [public, private]
BookmarkPatch:
type: object
properties:
folderId:
anyOf:
- type: string
format: uuid
- type: 'null'
title:
type: string
url:
type: string
visibility:
type: string
enum: [public, private]
security: []
paths:
/health:
get:
tags: [Health]
summary: Health check
operationId: healthCheck
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
required: [ok]
/auth/register:
post:
tags: [Auth]
summary: Register
operationId: register
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
format: email
password:
type: string
minLength: 8
required: [email, password]
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
token:
type: string
user:
$ref: '#/components/schemas/User'
required: [token, user]
/auth/login:
post:
tags: [Auth]
summary: Login
operationId: login
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
format: email
password:
type: string
required: [email, password]
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
token:
type: string
user:
$ref: '#/components/schemas/User'
required: [token, user]
/auth/me:
get:
tags: [Auth]
summary: Current user
operationId: me
security:
- bearerAuth: []
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/User'
/folders:
get:
tags: [Folders]
summary: List my folders
operationId: listFolders
security:
- bearerAuth: []
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Folder'
post:
tags: [Folders]
summary: Create folder
operationId: createFolder
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
parentId:
anyOf:
- type: string
format: uuid
- type: 'null'
name:
type: string
visibility:
type: string
enum: [public, private]
required: [parentId, name, visibility]
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Folder'
/folders/{id}:
patch:
tags: [Folders]
summary: Update folder
operationId: updateFolder
security:
- bearerAuth: []
parameters:
- in: path
name: id
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/FolderPatch'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Folder'
delete:
tags: [Folders]
summary: Delete folder
operationId: deleteFolder
security:
- bearerAuth: []
parameters:
- in: path
name: id
required: true
schema:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
required: [ok]
/bookmarks/public:
get:
tags: [Bookmarks]
summary: List public bookmarks (anonymous allowed)
operationId: listPublicBookmarks
parameters:
- in: query
name: q
schema:
type: string
required: false
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Bookmark'
/bookmarks:
get:
tags: [Bookmarks]
summary: List my bookmarks
operationId: listMyBookmarks
security:
- bearerAuth: []
parameters:
- in: query
name: q
schema:
type: string
required: false
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Bookmark'
post:
tags: [Bookmarks]
summary: Create bookmark (auto-dedupe)
operationId: createBookmark
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
folderId:
anyOf:
- type: string
format: uuid
- type: 'null'
title:
type: string
url:
type: string
visibility:
type: string
enum: [public, private]
required: [folderId, title, url, visibility]
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Bookmark'
/bookmarks/{id}:
patch:
tags: [Bookmarks]
summary: Update bookmark
operationId: updateBookmark
security:
- bearerAuth: []
parameters:
- in: path
name: id
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BookmarkPatch'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Bookmark'
delete:
tags: [Bookmarks]
summary: Soft delete bookmark
operationId: deleteBookmark
security:
- bearerAuth: []
parameters:
- in: path
name: id
required: true
schema:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Bookmark'
/bookmarks/import/html:
post:
tags: [ImportExport]
summary: Import bookmarks from Chrome/Edge HTML
operationId: importBookmarksHtml
security:
- bearerAuth: []
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
required: [file]
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
imported:
type: integer
merged:
type: integer
required: [imported, merged]
/bookmarks/export/html:
get:
tags: [ImportExport]
summary: Export my bookmarks as HTML
operationId: exportBookmarksHtml
security:
- bearerAuth: []
responses:
'200':
description: Netscape Bookmark HTML
content:
text/html:
schema:
type: string
/sync/push:
post:
tags: [Sync]
summary: Push local changes to cloud (LWW)
operationId: syncPush
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
bookmarks:
type: array
items:
$ref: '#/components/schemas/Bookmark'
folders:
type: array
items:
$ref: '#/components/schemas/Folder'
required: [bookmarks, folders]
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
required: [ok]
/sync/pull:
get:
tags: [Sync]
summary: Pull cloud changes since timestamp (LWW)
operationId: syncPull
security:
- bearerAuth: []
parameters:
- in: query
name: since
schema:
type: string
format: date-time
required: false
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
bookmarks:
type: array
items:
$ref: '#/components/schemas/Bookmark'
folders:
type: array
items:
$ref: '#/components/schemas/Folder'
serverTime:
type: string
format: date-time
required: [bookmarks, folders, serverTime]