docs: define platform boundaries and contracts
This commit is contained in:
parent
fcf014cf71
commit
10968eacf7
17 changed files with 373 additions and 0 deletions
25
AGENTS.md
Normal file
25
AGENTS.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# AGENTS.md
|
||||
|
||||
## Назначение
|
||||
|
||||
Krona Staff — автономно развёртываемый блок Krona Business Platform, а не отдельный конкурирующий продукт. Предметные функции добавляются только по подтверждённым требованиям владельца.
|
||||
|
||||
## Неизменяемые инварианты
|
||||
|
||||
- Core владеет Tenant, User, Role, Permission, SSO, platform settings, files, notifications и event bus. Staff владеет Employee и HR-доменом. `User != Employee`.
|
||||
- Все tenant-данные имеют `tenant_id`; запросы идут через tenant-scoped transaction; новые таблицы включают и форсируют PostgreSQL RLS. Добавляйте тест утечки между двумя tenant.
|
||||
- ID — ULID в `VARCHAR(26)`. Деньги — `BIGINT` minor units + ISO 4217 currency. Временные метки — UTC; локальная интерпретация — IANA timezone tenant.
|
||||
- Межмодульные вызовы только через публичные порты/platform gateway или versioned events. Прямые импорты и запись в чужие таблицы запрещены.
|
||||
- События имеют version, tenant, subject, actor, correlation/causation; публикация через transactional outbox; consumer через inbox и идемпотентность.
|
||||
- Локальный диск не является постоянным хранилищем. Вложения — через `FileStoragePort`/platform Files/S3.
|
||||
- Standalone adapters совместимы, мигрируемы и отключаемы; они не становятся вторым постоянным source of truth.
|
||||
|
||||
## Перед изменением
|
||||
|
||||
Прочитайте `docs/109-PLATFORM-BLOCK-CONTRACT.md` и связанные актуальные контракты в `ochenstarik/business-platform`. Если контракт изменился, сначала синхронизируйте manifest/ADR и тесты. Не копируйте архитектуру Omnichannel механически.
|
||||
|
||||
## Проверка
|
||||
|
||||
Запускайте `npm run check`. Для изменений БД дополнительно проверьте up/down на чистой PostgreSQL и tenant isolation. Не объявляйте Docker/restore/CI проверенными, если соответствующая среда реально не запускалась.
|
||||
|
||||
Файлы UTF-8 без BOM, LF. Коммиты небольшие, объясняют причину. Ветка задачи: `codex/bootstrap-platform-foundation` или отдельная ASCII feature-ветка.
|
||||
5
LICENSE
Normal file
5
LICENSE
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Copyright (c) 2026 Krona. All rights reserved.
|
||||
|
||||
This software and its documentation are proprietary. No permission is granted to use, copy,
|
||||
modify, distribute, sublicense, or disclose them except under a separate written agreement
|
||||
with the copyright holder.
|
||||
25
README.md
Normal file
25
README.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# Krona Staff
|
||||
|
||||
Архитектурная основа блока сотрудников для Krona Business Platform. Это не готовая HRM: предметные правила табеля, графиков, отпусков, расчёта зарплаты, кадровых документов и отчётности намеренно не реализованы до требований владельца.
|
||||
|
||||
Сейчас репозиторий содержит совместимое техническое ядро: два runtime-режима, порты платформы, PostgreSQL/RLS, инфраструктуру outbox/inbox/idempotency/audit, проверяемые OpenAPI и module manifest, health endpoints, контейнеризацию и CI.
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
docker compose --profile tools run --rm migrate
|
||||
docker compose up --build app postgres redis
|
||||
```
|
||||
|
||||
Открыть: shell `http://localhost:8080/`, OpenAPI JSON `/openapi.json`, проверки `/live`, `/ready`, `/version`.
|
||||
|
||||
Без Docker: Node.js 22+, PostgreSQL 17 и Redis 7; затем `npm ci`, `npm run db:migrate`, `npm run dev`.
|
||||
|
||||
## Команды
|
||||
|
||||
- `npm run check` — lint, typecheck, tests, миграции, контракты и build.
|
||||
- `npm run db:migrate` / `npm run db:migrate:down` — применить/откатить миграции.
|
||||
- `npm run check:contracts` — проверить manifest/settings/OpenAPI.
|
||||
|
||||
Архитектурные решения: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md), интеграция: [docs/PLATFORM-INTEGRATION.md](docs/PLATFORM-INTEGRATION.md), будущий объём: [docs/ROADMAP.md](docs/ROADMAP.md).
|
||||
11
SECURITY.md
Normal file
11
SECURITY.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Security Policy
|
||||
|
||||
Сообщайте об уязвимостях приватно владельцу Forgejo, не создавая публичный issue и не прикладывая персональные/зарплатные данные.
|
||||
|
||||
## Baseline
|
||||
|
||||
Core SSO/JWT и RBAC в platform mode; fail-closed adapters; tenant scope + forced PostgreSQL RLS; least privilege permissions; audit trail; TLS; security headers; rate limits на будущих write endpoints; idempotency; validation; parameterized SQL; encrypted backups; S3 outside webroot; secrets только env/secret store.
|
||||
|
||||
PII и payroll относятся к особо чувствительным данным. До их появления должны быть утверждены classification, field-level permissions, masking, encryption/key rotation, audit access, retention/deletion и incident response. Логи не содержат токены, зарплатные значения или полные персональные payload.
|
||||
|
||||
Dependencies проверяются `npm audit` в CI; container и SBOM/image scan должны быть подключены к доступному registry scanner перед production release.
|
||||
84
api/openapi.yaml
Normal file
84
api/openapi.yaml
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
openapi: 3.1.0
|
||||
info:
|
||||
title: Krona Staff API
|
||||
version: 0.1.0
|
||||
description: Operational API for the Krona Staff foundation. HR domain endpoints are intentionally absent until owner requirements are approved.
|
||||
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' }
|
||||
components:
|
||||
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] }
|
||||
22
docs/ARCHITECTURE.md
Normal file
22
docs/ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Архитектура
|
||||
|
||||
Krona Staff — deployable modular service с hexagonal boundaries. HTTP и workers вызывают application layer; domain contexts зависят только от ports; adapters обеспечивают standalone либо platform integration; PostgreSQL, Redis/BullMQ и object storage находятся на внешнем краю.
|
||||
|
||||
```text
|
||||
HTTP / worker -> application -> bounded-context contracts
|
||||
|-> Identity / Authorization / Settings / Files / Notifications / EventBus ports
|
||||
|-> tenant-scoped PostgreSQL repositories + transactional outbox
|
||||
ports <- standalone adapters | platform-gateway adapters
|
||||
```
|
||||
|
||||
Текущий код — foundation: health/version, конфигурация, ULID/event contracts, tenant transaction и инфраструктурная миграция. Доменный API отсутствует намеренно.
|
||||
|
||||
## Контексты
|
||||
|
||||
Предусмотрены границы: Employee Directory, Employment, Organization Structure, Scheduling, Time & Attendance, Leave, Payroll, Documents, Audit/Reporting. Между ними допускаются команды/события и стабильные ID, но не общий «богатый» HR-aggregate. Пакеты будут созданы по мере утверждения требований, чтобы пустые интерфейсы не стали ложным контрактом.
|
||||
|
||||
## Данные и надёжность
|
||||
|
||||
Shared database/shared schema, `tenant_id` в каждой tenant-таблице, application scope и forced RLS. Запись доменного состояния и outbox должна быть одной транзакцией. Inbox `(tenant_id,event_id)` подавляет повторную обработку; HTTP idempotency хранит request hash и результат. Сервис stateless, поэтому scale-out позже не требует переноса локальных файлов.
|
||||
|
||||
См. [ADR-001](adr/ADR-001-technology-and-runtime-modes.md).
|
||||
9
docs/BACKUP-RESTORE.md
Normal file
9
docs/BACKUP-RESTORE.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Backup и restore
|
||||
|
||||
Production baseline: ежедневный `pg_dump` custom format, непрерывный WAL/PITR когда RPO этого требует, versioned S3 object copies и отдельный экспорт manifest/checksums. Копии шифруются recipient-based ключом вне сервера; retention задаётся политикой владельца. Секреты и ключ расшифрования в архив не входят.
|
||||
|
||||
Restore runbook: остановить записи, проверить checksum/decrypt, восстановить в новую БД, применить только необходимые миграции, сверить tenant counts/outbox/inbox/audit, проверить `/ready`, выполнить выборочную сверку вложений, переключить connection string, сохранить audit evidence. Никогда не восстанавливать поверх единственной production БД.
|
||||
|
||||
Тест восстановления обязателен по расписанию в изолированной среде. До принятия RPO/RTO и retention документ является архитектурным шаблоном, а не обещанием показателей.
|
||||
|
||||
Tenant export/import использует versioned archive, ULID, schema version, object references и checksum. Import идемпотентен и не может перезаписать другой tenant.
|
||||
9
docs/DATA-OWNERSHIP.md
Normal file
9
docs/DATA-OWNERSHIP.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Владение данными
|
||||
|
||||
Core — system of record для tenants, user accounts, roles, permissions, platform settings, file metadata/storage access, notifications и event bus. Staff хранит только ссылки-ULID на Core records и не применяет foreign key через границу автономного deployment.
|
||||
|
||||
Staff станет system of record для Employee, Employment и утверждённых HR aggregates. Scheduling/attendance/leave/payroll ownership уточняется с владельцем до схемы. Внешние кадровые/бухгалтерские системы подключаются через adapters; authority и направление sync фиксируются отдельным ADR.
|
||||
|
||||
Каждая tenant-таблица: `tenant_id VARCHAR(26) NOT NULL`, составные unique/index keys с tenant, application scoping и forced RLS. Cross-tenant операции запрещены; системный export выполняется отдельной привилегированной ролью с audit.
|
||||
|
||||
PII/payroll fields получают classification, field-level permissions, шифрование и retention после определения состава. Секреты не являются settings и поступают из secret store/env.
|
||||
9
docs/DEPLOYMENT.md
Normal file
9
docs/DEPLOYMENT.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Развёртывание
|
||||
|
||||
Одна команда локально: скопировать `.env.example` в `.env`, затем `docker compose --profile tools run --rm migrate` и `docker compose up --build`. Compose поднимает приложение, PostgreSQL и Redis. Object storage не включён, пока нет файлового сценария; production использует Platform Files или S3-compatible adapter.
|
||||
|
||||
Production: один stateless app container/process, отдельные PostgreSQL и Redis, TLS/reverse proxy, secret manager, external object storage, централизованные logs/metrics/traces. `/live` проверяет процесс, `/ready` — обязательные зависимости, `/version` — release и runtime mode. Container работает non-root, read-only filesystem.
|
||||
|
||||
HA сейчас не требуется. Для будущего scale-out: общий PostgreSQL/Redis/S3, несколько API/worker nodes, leader election для scheduler, outbox relay и идемпотентные consumers. Локальные вложения запрещены. Linux и Windows deployment сохраняют паритет на уровне Node/container contract.
|
||||
|
||||
Миграции запускаются отдельным one-shot job до rollout. Down migration существует, но удаление данных требует отдельного backup и явного решения оператора.
|
||||
17
docs/DOMAIN-BOUNDARIES.md
Normal file
17
docs/DOMAIN-BOUNDARIES.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Доменные границы
|
||||
|
||||
| Контекст | Будущее владение Staff | Сейчас |
|
||||
|---|---|---|
|
||||
| Employee Directory | Карточка сотрудника и связь с Core User по nullable reference | Только manifest |
|
||||
| Employment | Трудовые отношения и их жизненный цикл | Ожидает требований |
|
||||
| Organization Structure | HR-представление подразделений/позиций | Ожидает решения о source of truth |
|
||||
| Scheduling | Плановые смены/графики | Ожидает требований |
|
||||
| Time & Attendance | Факты времени/явки и корректировки | Ожидает требований |
|
||||
| Leave | Заявки и остатки отпусков/отсутствий | Ожидает требований |
|
||||
| Payroll | Расчётные входы/результаты и защищённый доступ | Ожидает требований и юрисдикции |
|
||||
| Documents | HR-документы и ссылки на Platform Files | Ожидает требований |
|
||||
| Audit/Reporting | HR audit projections и разрешённые отчёты | Базовый audit transport |
|
||||
|
||||
Core User — учётная запись для входа и прав. Employee — предметная карточка человека в трудовом контексте. Они могут быть связаны, но ни один не является другим: сотрудник может не иметь аккаунта, аккаунт может не быть сотрудником.
|
||||
|
||||
Запрещено до требований: придумывать ставки, формулы зарплаты, нормы времени, статусы кадровых процессов, юридические реквизиты, виды отпусков или фиктивные CRUD endpoints.
|
||||
11
docs/PLATFORM-INTEGRATION.md
Normal file
11
docs/PLATFORM-INTEGRATION.md
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Интеграция с Business Platform
|
||||
|
||||
Основание: актуальная ветка `main` `ochenstarik/business-platform`, прежде всего Platform Block Contract 109, Module System 34, Lifecycle 54, Configuration Engine 51, Field Types 52, Integration 15 и deployment 93/97.
|
||||
|
||||
В `platform` режиме gateway/JWT adapter получает tenant, actor и permissions из Core SSO; Staff не создаёт tenant/user/role. Settings, Files, Notifications и Event Bus доступны через отдельные порты. Реализация JWT намеренно fail-closed до публикации точного Core gateway/JWKS runtime contract.
|
||||
|
||||
В `standalone` режиме совместимый adapter выдаёт один явно настроенный tenant/actor для разработки. Он не содержит таблиц пользователей и ролей и должен отключаться сменой `STAFF_RUNTIME_MODE=platform`. Миграция в platform означает сопоставление standalone ULID с Core references, проверку владения и отключение adapter.
|
||||
|
||||
Манифест `module.json` объявляет hard dependency только на `ru.krona.core`, permissions, entity ownership, settings schema, configurable entities и UI slots. События пока пусты: имена и payload нельзя утверждать до бизнес-требований. API versioned; будущие события также versioned и используют platform envelope.
|
||||
|
||||
Omnichannel использован только как существующий пример. Здесь заранее исключены его риски: параллельная identity/tenant модель, неоднозначный tenant-to-project mapping, доменные настройки вне platform schema и локально-незаменимое файловое состояние.
|
||||
16
docs/ROADMAP.md
Normal file
16
docs/ROADMAP.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# Roadmap
|
||||
|
||||
## Готово: foundation
|
||||
|
||||
Runtime modes and ports, ULID/event envelope, PostgreSQL RLS infrastructure, outbox/inbox/idempotency/audit, manifest/settings/OpenAPI validation, health/version, Docker/Compose, CI and documentation.
|
||||
|
||||
## Следующий этап — только после требований владельца
|
||||
|
||||
1. Уточнить jurisdiction, terminology, data classification and ownership.
|
||||
2. Согласовать Employee Directory и Employment workflows, затем создать первую vertical slice.
|
||||
3. Отдельно описать Organization Structure, Scheduling, Time & Attendance, Leave, Payroll, Documents, Audit/Reporting.
|
||||
4. Получить фактический Core gateway/JWT, Module SDK, Settings/Files/Notifications/Event Bus runtime contracts и реализовать platform adapters/conformance tests.
|
||||
5. Утвердить event catalog/OpenAPI changes до публикации.
|
||||
6. Утвердить backup RPO/RTO/retention и провести documented restore drill.
|
||||
|
||||
Никакой пункт не означает автоматически готовую бизнес-функцию или срок.
|
||||
20
docs/adr/ADR-001-technology-and-runtime-modes.md
Normal file
20
docs/adr/ADR-001-technology-and-runtime-modes.md
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# ADR-001: TypeScript service and runtime adapters
|
||||
|
||||
- Status: Accepted for foundation
|
||||
- Date: 2026-09-10
|
||||
|
||||
## Context
|
||||
|
||||
Platform contracts are TypeScript, baseline API is REST/OpenAPI 3.1, PostgreSQL/Redis/BullMQ are normative, blocks need independent deployment without duplicating Core identity. Staff business rules are unknown.
|
||||
|
||||
## Decision
|
||||
|
||||
Use Node.js 22 + strict TypeScript, Fastify, PostgreSQL 17, Redis/BullMQ, Zod, Vitest and a single stateless container. Keep domain code behind ports. Select either standalone adapters or platform-gateway adapters through configuration. Use ULID `VARCHAR(26)`, UTC, `BIGINT` minor money, transactional outbox/inbox and S3 abstraction.
|
||||
|
||||
Standalone provides only explicit development tenant/actor references; no durable user/role source. Platform mode fails closed until verified Core JWT/gateway contracts are implemented.
|
||||
|
||||
## Consequences
|
||||
|
||||
The module can deploy separately and share platform contract types with minimal translation. PostgreSQL RLS gives defense in depth. Runtime integration remains explicit work rather than a mocked claim. Fastify adds a different web runtime from Omnichannel, but platform compatibility is contractual, not framework inheritance.
|
||||
|
||||
Rejected: copy Omnichannel/Python mechanically; embed inside platform monolith; invent a local identity service; implement HR endpoints before requirements.
|
||||
30
module.json
Normal file
30
module.json
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"$schema": "./schemas/module.schema.json",
|
||||
"id": "ru.krona.staff",
|
||||
"name": "Krona Staff",
|
||||
"version": "0.1.0",
|
||||
"min_platform_version": "3.2.0",
|
||||
"dependencies": ["ru.krona.core"],
|
||||
"optional_dependencies": [],
|
||||
"permissions": [
|
||||
"staff:employee:read",
|
||||
"staff:employee:write",
|
||||
"staff:employment:read",
|
||||
"staff:employment:write",
|
||||
"staff:sensitive:read",
|
||||
"staff:sensitive:write",
|
||||
"staff:audit:read"
|
||||
],
|
||||
"entities": ["Employee", "Employment", "OrganizationUnit"],
|
||||
"events_emitted": [],
|
||||
"events_consumed": [],
|
||||
"settings_schema": "settings.schema.json",
|
||||
"configurable_entities": ["Employee", "Employment", "OrganizationUnit"],
|
||||
"promote_targets": [],
|
||||
"api_prefix": "/api/v1/staff",
|
||||
"routes": ["/staff"],
|
||||
"ui_extensions": [
|
||||
{ "slot": "navigation", "component": "StaffNavigation" },
|
||||
{ "slot": "settings.module", "component": "PlatformGeneratedSettings" }
|
||||
]
|
||||
}
|
||||
26
schemas/module.schema.json
Normal file
26
schemas/module.schema.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://krona.example/schemas/module.schema.json",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "name", "version", "min_platform_version", "dependencies", "permissions", "entities", "events_emitted", "events_consumed", "settings_schema", "configurable_entities", "ui_extensions"],
|
||||
"properties": {
|
||||
"$schema": { "type": "string" },
|
||||
"id": { "const": "ru.krona.staff" },
|
||||
"name": { "type": "string", "minLength": 1 },
|
||||
"version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
|
||||
"min_platform_version": { "type": "string" },
|
||||
"dependencies": { "type": "array", "contains": { "const": "ru.krona.core" }, "items": { "type": "string" }, "uniqueItems": true },
|
||||
"optional_dependencies": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
|
||||
"permissions": { "type": "array", "items": { "type": "string", "pattern": "^staff:[a-z_]+:(read|write)$" }, "uniqueItems": true },
|
||||
"entities": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
|
||||
"events_emitted": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
|
||||
"events_consumed": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
|
||||
"settings_schema": { "type": "string" },
|
||||
"configurable_entities": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
|
||||
"promote_targets": { "type": "array", "items": { "type": "object" } },
|
||||
"api_prefix": { "const": "/api/v1/staff" },
|
||||
"routes": { "type": "array", "items": { "type": "string" } },
|
||||
"ui_extensions": { "type": "array", "items": { "type": "object", "required": ["slot", "component"], "properties": { "slot": { "type": "string" }, "component": { "type": "string" } }, "additionalProperties": false } }
|
||||
}
|
||||
}
|
||||
36
schemas/settings.schema.schema.json
Normal file
36
schemas/settings.schema.schema.json
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["groups"],
|
||||
"properties": {
|
||||
"$schema": { "type": "string" },
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["key", "label", "fields"],
|
||||
"properties": {
|
||||
"key": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" },
|
||||
"label": { "type": "string" },
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["key", "type", "label"],
|
||||
"properties": {
|
||||
"key": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" },
|
||||
"type": { "enum": ["text", "number", "boolean", "date", "datetime", "money", "select", "multiselect", "relation", "email", "phone", "url", "json"] },
|
||||
"label": { "type": "string" },
|
||||
"required": { "type": "boolean" },
|
||||
"description": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
settings.schema.json
Normal file
18
settings.schema.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "./schemas/settings.schema.schema.json",
|
||||
"groups": [
|
||||
{
|
||||
"key": "localization",
|
||||
"label": "Локализация",
|
||||
"fields": [
|
||||
{
|
||||
"key": "business_timezone",
|
||||
"type": "text",
|
||||
"label": "Часовой пояс организации",
|
||||
"required": true,
|
||||
"description": "IANA timezone; timestamps are persisted in UTC and interpreted using this tenant setting."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in a new issue