feat(architecture): add complete technical architecture for SimpleNote
- ARCHITECTURE.md: main architecture document - api-spec.yaml: full OpenAPI 3.0 spec - folder-structure.md: detailed folder layout - data-format.md: JSON schemas for .meta.json, .library.json, .tag-index.json - env-template.md: environment variables documentation - cli-protocol.md: CLI-to-API communication protocol
This commit is contained in:
877
api-spec.yaml
Normal file
877
api-spec.yaml
Normal file
@@ -0,0 +1,877 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: SimpleNote API
|
||||
description: REST API for SimpleNote document management system
|
||||
version: 1.0.0
|
||||
contact:
|
||||
name: SimpleNote Team
|
||||
|
||||
servers:
|
||||
- url: http://localhost:3000/api/v1
|
||||
description: Local development server
|
||||
|
||||
tags:
|
||||
- name: Auth
|
||||
description: Authentication and token management
|
||||
- name: Documents
|
||||
description: Document CRUD operations
|
||||
- name: Libraries
|
||||
description: Library (folder) management
|
||||
- name: Tags
|
||||
description: Tag-based search and management
|
||||
|
||||
paths:
|
||||
# ============ AUTH ============
|
||||
/auth/token:
|
||||
post:
|
||||
tags: [Auth]
|
||||
summary: Generate a new API token
|
||||
description: Admin-only endpoint to generate a new bearer token
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [label]
|
||||
properties:
|
||||
label:
|
||||
type: string
|
||||
description: Human-readable label for the token
|
||||
example: "cli-default"
|
||||
responses:
|
||||
'200':
|
||||
description: Token generated successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
example: "snk_a1b2c3d4e5f6..."
|
||||
label:
|
||||
type: string
|
||||
example: "cli-default"
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
'401':
|
||||
description: Unauthorized - invalid admin token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'400':
|
||||
description: Missing required fields
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/auth/verify:
|
||||
get:
|
||||
tags: [Auth]
|
||||
summary: Verify current token is valid
|
||||
security:
|
||||
- BearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: Token is valid
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
valid:
|
||||
type: boolean
|
||||
example: true
|
||||
token:
|
||||
type: string
|
||||
example: "snk_a1b2c3d4e5f6..."
|
||||
'401':
|
||||
description: Token is invalid or missing
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
# ============ DOCUMENTS ============
|
||||
/documents:
|
||||
get:
|
||||
tags: [Documents]
|
||||
summary: List all documents
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: tag
|
||||
in: query
|
||||
description: Filter by tag
|
||||
schema:
|
||||
type: string
|
||||
example: "backend"
|
||||
- name: library
|
||||
in: query
|
||||
description: Filter by library ID
|
||||
schema:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
- name: type
|
||||
in: query
|
||||
description: Filter by document type
|
||||
schema:
|
||||
type: string
|
||||
enum: [requirement, note, spec, general]
|
||||
example: "requirement"
|
||||
- name: status
|
||||
in: query
|
||||
description: Filter by status
|
||||
schema:
|
||||
type: string
|
||||
enum: [draft, approved, implemented]
|
||||
example: "draft"
|
||||
- name: limit
|
||||
in: query
|
||||
description: Max results to return
|
||||
schema:
|
||||
type: integer
|
||||
default: 50
|
||||
example: 20
|
||||
- name: offset
|
||||
in: query
|
||||
description: Skip first N results
|
||||
schema:
|
||||
type: integer
|
||||
default: 0
|
||||
example: 0
|
||||
responses:
|
||||
'200':
|
||||
description: List of documents
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
documents:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Document'
|
||||
total:
|
||||
type: integer
|
||||
example: 42
|
||||
limit:
|
||||
type: integer
|
||||
example: 20
|
||||
offset:
|
||||
type: integer
|
||||
example: 0
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
post:
|
||||
tags: [Documents]
|
||||
summary: Create a new document
|
||||
security:
|
||||
- BearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [title, libraryId]
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
description: Document title
|
||||
example: "API Authentication Design"
|
||||
libraryId:
|
||||
type: string
|
||||
description: Target library ID
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
content:
|
||||
type: string
|
||||
description: Markdown content (optional, defaults to template)
|
||||
example: "# API Authentication\n\n## Description\n..."
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: ["backend", "api", "auth"]
|
||||
type:
|
||||
type: string
|
||||
enum: [requirement, note, spec, general]
|
||||
default: general
|
||||
priority:
|
||||
type: string
|
||||
enum: [high, medium, low]
|
||||
default: medium
|
||||
status:
|
||||
type: string
|
||||
enum: [draft, approved, implemented]
|
||||
default: draft
|
||||
responses:
|
||||
'201':
|
||||
description: Document created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Document'
|
||||
'400':
|
||||
description: Invalid request body
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
description: Library not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/documents/{id}:
|
||||
get:
|
||||
tags: [Documents]
|
||||
summary: Get a document by ID
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Document UUID
|
||||
schema:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440001"
|
||||
responses:
|
||||
'200':
|
||||
description: Document found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Document'
|
||||
'404':
|
||||
description: Document not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
put:
|
||||
tags: [Documents]
|
||||
summary: Update a document
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Document UUID
|
||||
schema:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440001"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
example: "Updated Title"
|
||||
content:
|
||||
type: string
|
||||
example: "# Updated Content\n\nNew markdown..."
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: ["backend", "api"]
|
||||
type:
|
||||
type: string
|
||||
enum: [requirement, note, spec, general]
|
||||
priority:
|
||||
type: string
|
||||
enum: [high, medium, low]
|
||||
status:
|
||||
type: string
|
||||
enum: [draft, approved, implemented]
|
||||
responses:
|
||||
'200':
|
||||
description: Document updated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Document'
|
||||
'400':
|
||||
description: Invalid request body
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
description: Document not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
delete:
|
||||
tags: [Documents]
|
||||
summary: Delete a document
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Document UUID
|
||||
schema:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440001"
|
||||
responses:
|
||||
'200':
|
||||
description: Document deleted
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
deleted:
|
||||
type: boolean
|
||||
example: true
|
||||
id:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440001"
|
||||
'404':
|
||||
description: Document not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/documents/{id}/export:
|
||||
get:
|
||||
tags: [Documents]
|
||||
summary: Export document as raw Markdown
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Document UUID
|
||||
schema:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440001"
|
||||
responses:
|
||||
'200':
|
||||
description: Raw Markdown file
|
||||
content:
|
||||
text/markdown:
|
||||
schema:
|
||||
type: string
|
||||
example: |
|
||||
---
|
||||
id: REQ-001
|
||||
title: API Authentication
|
||||
---
|
||||
# API Authentication
|
||||
|
||||
## Description
|
||||
...
|
||||
'404':
|
||||
description: Document not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/documents/{id}/tags:
|
||||
post:
|
||||
tags: [Tags]
|
||||
summary: Add tags to a document
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Document UUID
|
||||
schema:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440001"
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [tags]
|
||||
properties:
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: ["new-tag", "another-tag"]
|
||||
responses:
|
||||
'200':
|
||||
description: Tags added
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Document'
|
||||
'400':
|
||||
description: Invalid tags array
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
description: Document not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
# ============ LIBRARIES ============
|
||||
/libraries:
|
||||
get:
|
||||
tags: [Libraries]
|
||||
summary: List root-level libraries
|
||||
security:
|
||||
- BearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: List of root libraries
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
libraries:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Library'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
post:
|
||||
tags: [Libraries]
|
||||
summary: Create a new library
|
||||
security:
|
||||
- BearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [name]
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: Library name
|
||||
example: "Backend Requirements"
|
||||
parentId:
|
||||
type: string
|
||||
nullable: true
|
||||
description: Parent library ID for nesting (null for root)
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
responses:
|
||||
'201':
|
||||
description: Library created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Library'
|
||||
'400':
|
||||
description: Invalid request body
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'404':
|
||||
description: Parent library not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/libraries/{id}:
|
||||
get:
|
||||
tags: [Libraries]
|
||||
summary: Get library contents (documents and sub-libraries)
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Library UUID
|
||||
schema:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
responses:
|
||||
'200':
|
||||
description: Library contents
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
library:
|
||||
$ref: '#/components/schemas/Library'
|
||||
documents:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Document'
|
||||
subLibraries:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Library'
|
||||
'404':
|
||||
description: Library not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/libraries/{id}/tree:
|
||||
get:
|
||||
tags: [Libraries]
|
||||
summary: Get full subtree of a library
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Library UUID
|
||||
schema:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
responses:
|
||||
'200':
|
||||
description: Full library tree
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/LibraryTree'
|
||||
'404':
|
||||
description: Library not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/libraries/{id}/documents:
|
||||
get:
|
||||
tags: [Documents]
|
||||
summary: List documents in a specific library
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
description: Library UUID
|
||||
schema:
|
||||
type: string
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
responses:
|
||||
'200':
|
||||
description: List of documents in library
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
libraryId:
|
||||
type: string
|
||||
documents:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Document'
|
||||
'404':
|
||||
description: Library not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
# ============ TAGS ============
|
||||
/tags:
|
||||
get:
|
||||
tags: [Tags]
|
||||
summary: List all tags with document counts
|
||||
security:
|
||||
- BearerAuth: []
|
||||
responses:
|
||||
'200':
|
||||
description: All tags with counts
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
example: "backend"
|
||||
count:
|
||||
type: integer
|
||||
example: 5
|
||||
total:
|
||||
type: integer
|
||||
example: 15
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
/tags/{tag}:
|
||||
get:
|
||||
tags: [Tags]
|
||||
summary: Get all documents with a specific tag
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
- name: tag
|
||||
in: path
|
||||
required: true
|
||||
description: Tag name
|
||||
schema:
|
||||
type: string
|
||||
example: "backend"
|
||||
responses:
|
||||
'200':
|
||||
description: Documents with tag
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
tag:
|
||||
type: string
|
||||
example: "backend"
|
||||
documents:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Document'
|
||||
count:
|
||||
type: integer
|
||||
example: 5
|
||||
'404':
|
||||
description: Tag not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
'401':
|
||||
description: Unauthorized
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
BearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: API token with `snk_` prefix
|
||||
|
||||
schemas:
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
example: "Document not found"
|
||||
code:
|
||||
type: string
|
||||
example: "NOT_FOUND"
|
||||
|
||||
Document:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "550e8400-e29b-41d4-a716-446655440001"
|
||||
title:
|
||||
type: string
|
||||
example: "API Authentication Design"
|
||||
path:
|
||||
type: string
|
||||
example: "/libraries/550e8400/.../documents/550e8401/index.md"
|
||||
content:
|
||||
type: string
|
||||
description: Raw markdown content
|
||||
example: "# API Authentication\n\n## Description\n..."
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: ["backend", "api", "auth"]
|
||||
type:
|
||||
type: string
|
||||
enum: [requirement, note, spec, general]
|
||||
example: "requirement"
|
||||
status:
|
||||
type: string
|
||||
enum: [draft, approved, implemented]
|
||||
example: "draft"
|
||||
priority:
|
||||
type: string
|
||||
enum: [high, medium, low]
|
||||
example: "high"
|
||||
libraryId:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
createdBy:
|
||||
type: string
|
||||
description: Agent or user ID who created the document
|
||||
example: "agent-001"
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2026-03-28T10:00:00Z"
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2026-03-28T12:30:00Z"
|
||||
|
||||
Library:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
example: "550e8400-e29b-41d4-a716-446655440000"
|
||||
name:
|
||||
type: string
|
||||
example: "Backend Requirements"
|
||||
parentId:
|
||||
type: string
|
||||
nullable: true
|
||||
format: uuid
|
||||
description: Parent library ID, null for root
|
||||
example: null
|
||||
path:
|
||||
type: string
|
||||
description: Absolute path to library folder
|
||||
example: "/data/libraries/550e8400"
|
||||
documentCount:
|
||||
type: integer
|
||||
description: Total documents in this library (excludes sub-libraries)
|
||||
example: 12
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2026-03-28T09:00:00Z"
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
example: "2026-03-28T09:00:00Z"
|
||||
|
||||
LibraryTree:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
name:
|
||||
type: string
|
||||
documents:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
subLibraries:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/LibraryTree'
|
||||
Reference in New Issue
Block a user