184 lines
6.5 KiB
YAML
184 lines
6.5 KiB
YAML
openapi: 3.1.0
|
||
info:
|
||
title: Krona Staff API
|
||
version: 0.2.5
|
||
description: API посещаемости Krona Staff для кабинета сотрудника, терминала и табеля руководителя.
|
||
license:
|
||
name: Proprietary
|
||
url: https://git.ochenstarik.ru/ochenstarik/krona-staff/src/branch/main/LICENSE
|
||
servers:
|
||
- url: /api/v1/staff
|
||
security: []
|
||
paths:
|
||
/live:
|
||
get:
|
||
summary: Check process liveness
|
||
operationId: getLiveness
|
||
tags: [Operations]
|
||
responses:
|
||
'200':
|
||
description: Process is alive
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Health' }
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
/ready:
|
||
get:
|
||
summary: Check dependency readiness
|
||
operationId: getReadiness
|
||
tags: [Operations]
|
||
responses:
|
||
'200':
|
||
description: Required dependencies are ready
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Health' }
|
||
'503': { description: A required dependency is unavailable }
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
/version:
|
||
get:
|
||
summary: Read runtime build identity
|
||
operationId: getVersion
|
||
tags: [Operations]
|
||
responses:
|
||
'200':
|
||
description: Runtime build identity
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Version' }
|
||
'400': { $ref: '#/components/responses/BadRequest' }
|
||
/session:
|
||
post:
|
||
summary: Открыть защищённую сессию администратора
|
||
operationId: createStaffSession
|
||
tags: [Authentication]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [access_token]
|
||
properties:
|
||
access_token: { type: string, minLength: 32, maxLength: 4096, writeOnly: true }
|
||
responses:
|
||
'200':
|
||
description: Сессия открыта; токен перенесён в HttpOnly Secure cookie
|
||
'401': { description: Ключ недействителен }
|
||
'403': { description: Ключ не имеет прав администратора }
|
||
delete:
|
||
summary: Завершить сессию администратора
|
||
operationId: deleteStaffSession
|
||
tags: [Authentication]
|
||
responses:
|
||
'204': { description: Сессия завершена }
|
||
'403': { description: Запрос с постороннего сайта отклонён }
|
||
/portal:
|
||
get:
|
||
summary: Получить доступную пользователю сводку посещаемости и табеля
|
||
operationId: getStaffPortal
|
||
tags: [Attendance]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Сводка с автоматическим ограничением данными текущего сотрудника
|
||
content:
|
||
application/json:
|
||
schema: { type: object }
|
||
'403': { description: Недостаточно прав }
|
||
/attendance/events:
|
||
post:
|
||
summary: Принять идемпотентную отметку терминала
|
||
operationId: recordAttendanceEvent
|
||
tags: [Attendance]
|
||
security: [{ bearerAuth: [] }]
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [employee_id, event_type, occurred_at, source_event_id]
|
||
properties:
|
||
event_id: { $ref: '#/components/schemas/Ulid' }
|
||
employee_id: { $ref: '#/components/schemas/Ulid' }
|
||
event_type: { enum: [check_in, check_out] }
|
||
occurred_at: { type: string, format: date-time }
|
||
source_event_id: { type: string, minLength: 1, maxLength: 200 }
|
||
device_id: { $ref: '#/components/schemas/Ulid' }
|
||
responses:
|
||
'201': { description: Отметка принята }
|
||
'200': { description: Повтор уже принятой отметки }
|
||
'403': { description: Недостаточно прав }
|
||
/timesheets/{employeeId}/{workDate}:
|
||
put:
|
||
summary: Сохранить строку табеля
|
||
operationId: saveTimesheetEntry
|
||
tags: [Timesheet]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- in: path
|
||
name: employeeId
|
||
required: true
|
||
schema: { $ref: '#/components/schemas/Ulid' }
|
||
- in: path
|
||
name: workDate
|
||
required: true
|
||
schema: { type: string, format: date }
|
||
requestBody:
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [minutes_worked, status]
|
||
properties:
|
||
minutes_worked: { type: integer, minimum: 0, maximum: 1440 }
|
||
status: { enum: [draft, submitted, approved, rejected] }
|
||
note: { type: string, maxLength: 1000 }
|
||
responses:
|
||
'200': { description: Строка табеля сохранена }
|
||
'403': { description: Недостаточно прав }
|
||
components:
|
||
securitySchemes:
|
||
bearerAuth:
|
||
type: http
|
||
scheme: bearer
|
||
bearerFormat: JWT
|
||
responses:
|
||
BadRequest:
|
||
description: Invalid request
|
||
content:
|
||
application/json:
|
||
schema: { $ref: '#/components/schemas/Problem' }
|
||
schemas:
|
||
Ulid:
|
||
type: string
|
||
pattern: '^[0-9A-HJKMNP-TV-Z]{26}$'
|
||
examples: [01J00000000000000000000000]
|
||
Health:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [status]
|
||
properties:
|
||
status: { type: string }
|
||
Problem:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [type, title, status, trace_id]
|
||
properties:
|
||
type: { type: string, format: uri-reference }
|
||
title: { type: string }
|
||
status: { type: integer, minimum: 400, maximum: 599 }
|
||
trace_id: { $ref: '#/components/schemas/Ulid' }
|
||
Version:
|
||
type: object
|
||
additionalProperties: false
|
||
required: [name, version, mode]
|
||
properties:
|
||
name: { const: krona-staff }
|
||
version: { type: string }
|
||
mode: { enum: [standalone, platform] }
|