openapi: 3.1.0 info: title: Gerege Drive API version: "1" description: | Гуравдагч талын системд зориулсан REST API. Нэвтрэх: `Authorization: Bearer gd_…` (вэб интерфейсийн «Холболтууд» хэсгээс API түлхүүр үүсгэнэ). Tenant бүр анх 5 MB-ын квоттой. **Платформ өөрөө холбогдох (Connect, OAuth 2.0 authorization code + PKCE S256):** 1. Хэрэглэгчийг `GET /connect?app=<нэр>&redirect_uri=&state=&code_challenge=[&webhook=]` руу илгээнэ. 2. Хэрэглэгч нэвтэрч зөвшөөрнө → `redirect_uri?code=&state=` (code 10 минут хүчинтэй, нэг удаагийн). 3. Сервер талаас `POST /api/v1/connect/token` → `api_key` (+ `webhook.secret`). Түлхүүр зөвхөн өөрийн webhook-уудыг удирдана, `DELETE /api/v1/connection`-оор өөрийгөө салгана. Webhook: файл/хавтас үүсэх, өөрчлөгдөх, устах үед бүртгэсэн URL руу JSON `{id, event, tenant, time, data}` POST хийнэ. Event: `folder.created`, `file.created`, `file.updated`, `file.deleted`. Header `X-Gerege-Signature: sha256=`. servers: [{ url: / }] security: [{ apiKey: [] }] components: securitySchemes: apiKey: { type: http, scheme: bearer } schemas: Node: type: object properties: id: { type: string } parent: { type: string, description: '"" = root' } name: { type: string } dir: { type: boolean } size: { type: integer } mime: { type: string } created: { type: integer, description: unix seconds } updated: { type: integer } shared: { type: boolean } Error: type: object properties: { error: { type: string } } parameters: id: { name: id, in: path, required: true, schema: { type: string } } paths: /api/v1/me: get: summary: Tenant болон ашиглалт/квот responses: "200": description: OK content: { application/json: { schema: { type: object, properties: { tenant: { type: string }, org: { type: string }, used: { type: integer }, quota: { type: integer } } } } } /api/v1/files: get: summary: Хавтасны агуулга parameters: [{ name: parent, in: query, schema: { type: string }, description: хоосон = root }] responses: "200": description: OK content: { application/json: { schema: { type: object, properties: { path: { type: array, items: { $ref: "#/components/schemas/Node" } }, items: { type: array, items: { $ref: "#/components/schemas/Node" } } } } } } post: summary: Файл оруулах (multipart, олон файл зөвшөөрнө; ижил нэртэй бол "нэр (2).ext") parameters: [{ name: parent, in: query, schema: { type: string } }] requestBody: content: { multipart/form-data: { schema: { type: object, properties: { file: { type: string, format: binary } } } } } responses: "201": { description: Created, content: { application/json: { schema: { type: array, items: { $ref: "#/components/schemas/Node" } } } } } "413": { description: Квот хүрэлцэхгүй, content: { application/json: { schema: { $ref: "#/components/schemas/Error" } } } } /api/v1/folders: post: summary: Хавтас үүсгэх requestBody: content: { application/json: { schema: { type: object, required: [name], properties: { parent: { type: string }, name: { type: string } } } } } responses: "201": { description: Created, content: { application/json: { schema: { $ref: "#/components/schemas/Node" } } } } "409": { description: Ийм нэр байна } /api/v1/files/{id}: parameters: [{ $ref: "#/components/parameters/id" }] get: summary: Мэдээлэл responses: { "200": { description: OK, content: { application/json: { schema: { $ref: "#/components/schemas/Node" } } } } } patch: summary: Нэр солих / зөөх requestBody: content: { application/json: { schema: { type: object, properties: { name: { type: string }, parent: { type: string } } } } } responses: { "200": { description: OK, content: { application/json: { schema: { $ref: "#/components/schemas/Node" } } } } } delete: summary: Устгах (хавтас бол доторх бүгд) responses: { "204": { description: Deleted } } /api/v1/files/{id}/content: parameters: [{ $ref: "#/components/parameters/id" }] get: summary: Татах (Range дэмжинэ) responses: { "200": { description: Файлын агуулга } } /api/v1/files/{id}/share: parameters: [{ $ref: "#/components/parameters/id" }] post: summary: Нийтийн холбоос үүсгэх responses: "200": { description: OK, content: { application/json: { schema: { type: object, properties: { token: { type: string }, url: { type: string } } } } } } delete: summary: Холбоосыг хаах responses: { "204": { description: Closed } } /api/v1/connect/token: post: summary: "Connect: code-ийг API түлхүүрээр солих (server-to-server, нэвтрэлтгүй)" security: [] requestBody: content: { application/json: { schema: { type: object, required: [code, code_verifier, redirect_uri], properties: { code: { type: string }, code_verifier: { type: string }, redirect_uri: { type: string, description: /connect-д өгсөнтэй яг ижил } } } } } responses: "200": description: OK content: { application/json: { schema: { type: object, properties: { api_key: { type: string }, key_id: { type: string }, tenant: { type: string }, org: { type: string }, webhook: { type: object, properties: { id: { type: string }, url: { type: string }, secret: { type: string } } } } } } } "400": { description: "invalid_grant — буруу/хугацаа дууссан/ашигласан code, verifier эсвэл redirect_uri таарахгүй" } /api/v1/connection: delete: summary: "Платформ өөрийгөө салгана: API түлхүүр болон түүний webhook-ууд устна" responses: { "204": { description: Disconnected } } /api/v1/webhooks: get: summary: Webhook-ууд (API түлхүүр зөвхөн өөрийн бүртгэснийг харна) responses: { "200": { description: OK } } post: summary: Webhook бүртгэх (хариунд `secret` нэг удаа ирнэ) requestBody: content: { application/json: { schema: { type: object, required: [url], properties: { url: { type: string } } } } } responses: { "201": { description: Created } } /api/v1/webhooks/{id}: parameters: [{ $ref: "#/components/parameters/id" }] delete: summary: Webhook устгах (API түлхүүр зөвхөн өөрийнхийг) responses: { "204": { description: Deleted } } /api/v1/admin/tenants: get: summary: "Оператор: бүх tenant, ашиглалт, квот (Bearer ADMIN_TOKEN)" responses: { "200": { description: OK } } /api/v1/admin/tenants/{id}: parameters: [{ $ref: "#/components/parameters/id" }] patch: summary: "Оператор: tenant-ийн квотыг өөрчлөх (байтаар)" requestBody: content: { application/json: { schema: { type: object, required: [quota], properties: { quota: { type: integer, example: 1073741824 } } } } } responses: { "200": { description: OK } }