letopis 0.13.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,64 +1,69 @@
1
1
  -- =============================================================================
2
2
  -- Сид таблицы Schema из schema.booking.v2.json (источник правды — JSON).
3
- -- Файл сгенерирован, не редактировать вручную. Идемпотентен (ON CONFLICT).
3
+ -- Файл сгенерирован: node lib/scripts/gen-seed.mjs — не редактировать вручную.
4
+ -- Идемпотентен (ON CONFLICT). Концы связей — Schema.links v2 (JSON-объекты в text[]).
4
5
  -- =============================================================================
5
6
 
6
7
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
7
- ('entity', 'Entity', 'Сущность', 'HUB', NULL, '{"id":"any"}'::jsonb, '{"abstract":true,"description":"Абстрактный корень всех сущностей"}'::jsonb, '{}'::text[], 100, '{"Entity"}'::text[])
8
+ ('entity', 'Entity', 'Сущность', 'HUB', NULL, '{"id":{"type":"uuid","generate":7}}'::jsonb, '{"abstract":true,"description":"Абстрактный корень всех сущностей"}'::jsonb, '[]'::jsonb, 100, ARRAY['Entity']::text[])
8
9
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
9
10
 
10
11
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
11
- ('entity', 'Org', 'Организация', 'HUB', 'Entity', '{"id":"uuid","name":"string","timezone":{"type":"string","default":"Europe/Moscow"},"address":"string|optional","phone":"string|optional","active":{"type":"boolean","default":true},"settings":{"type":"object","optional":true,"strict":true,"props":{"booking":{"type":"object","optional":true,"strict":true,"props":{"deposit":{"type":"object","optional":true,"strict":true,"props":{"amount":"number|integer|min:0|default:0","currency":{"type":"enum","values":["RUB","USD","EUR","AED"],"default":"RUB"}}},"autoconfirm":"boolean|default:false"}}}}}'::jsonb, '{"abstract":false,"description":"Организация / точка / филиал — владелец каталога и расписаний; settings — вложенные настройки (пример структуры глубины 4)"}'::jsonb, '{}'::text[], 200, '{"Org","Entity"}'::text[])
12
+ ('entity', 'Org', 'Организация', 'HUB', 'Entity', '{"name":"string","timezone":{"type":"string","default":"Europe/Moscow"},"address":"string|optional","phone":"string|optional","active":{"type":"boolean","default":true},"settings":{"type":"object","optional":true,"strict":true,"props":{"booking":{"type":"object","optional":true,"strict":true,"props":{"deposit":{"type":"object","optional":true,"strict":true,"props":{"amount":"number|integer|min:0|default:0","currency":{"type":"enum","values":["RUB","USD","EUR","AED"],"default":"RUB"}}},"autoconfirm":"boolean|default:false"}}}}}'::jsonb, '{"abstract":false,"description":"Организация / точка / филиал — владелец каталога и расписаний; settings — вложенные настройки (пример структуры глубины 4)"}'::jsonb, '[]'::jsonb, 200, ARRAY['Org', 'Entity']::text[])
12
13
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
13
14
 
14
15
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
15
- ('entity', 'Staff', 'Сотрудник', 'HUB', 'Entity', '{"id":"uuid","name":"string","roles":{"type":"array","items":{"type":"enum","values":["owner","administrator","manager","master"]},"default":["master"]},"active":{"type":"boolean","default":true}}'::jsonb, '{"abstract":false,"description":"Человек: роли совмещаются (owner+master). Бронируемый ⇔ master ∈ roles. Владелец = первый сотрудник с owner."}'::jsonb, '{"Org"}'::text[], 300, '{"Staff","Entity"}'::text[])
16
+ ('entity', 'Staff', 'Сотрудник', 'HUB', 'Entity', '{"name":"string","roles":{"type":"array","items":{"type":"enum","values":["owner","administrator","manager","master"]},"default":["master"]},"active":{"type":"boolean","default":true}}'::jsonb, '{"abstract":false,"description":"Человек: роли совмещаются (owner+master). Бронируемый ⇔ master ∈ roles. Владелец = первый сотрудник с owner."}'::jsonb, '[{"class":"Org","cardinality":1}]'::jsonb, 300, ARRAY['Staff', 'Entity']::text[])
16
17
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
17
18
 
18
19
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
19
- ('entity', 'Folder', 'Папка', 'HUB', 'Entity', '{"id":"uuid","name":"string","kind":{"type":"enum","values":["services","masters"],"default":"services"}}'::jsonb, '{"abstract":false,"description":"Папка-категория; вложенность — ссылкой на родительскую Папку в links"}'::jsonb, '{"Org","Folder"}'::text[], 400, '{"Folder","Entity"}'::text[])
20
+ ('entity', 'Folder', 'Папка', 'HUB', 'Entity', '{"name":"string","kind":{"type":"enum","values":["services","masters"],"default":"services"}}'::jsonb, '{"abstract":false,"description":"Папка-категория; вложенность — ссылкой на родительскую Папку в links"}'::jsonb, '[{"class":"Org","cardinality":1},{"class":"Folder","optional":true,"cardinality":1}]'::jsonb, 400, ARRAY['Folder', 'Entity']::text[])
20
21
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
21
22
 
22
23
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
23
- ('entity', 'Service', 'Услуга', 'HUB', 'Entity', '{"id":"uuid","name":"string","description":"string|optional","duration":"number|integer|positive","price":{"type":"record","key":{"type":"enum","values":["RUB","USD","EUR","AED"]},"value":"number|integer|min:0","default":{"RUB":0}},"active":{"type":"boolean","default":true}}'::jsonb, '{"abstract":false,"description":"Услуга: длительность (мин) + цена; занимает столько подряд окон, сколько покрывает duration"}'::jsonb, '{"Org","Folder"}'::text[], 500, '{"Service","Entity"}'::text[])
24
+ ('entity', 'Service', 'Услуга', 'HUB', 'Entity', '{"id":{"type":"uuid","generate":5,"from":["Org","name"]},"name":"string","description":"string|optional","duration":"number|integer|positive","price":{"type":"record","key":{"type":"enum","values":["RUB","USD","EUR","AED"]},"value":"number|integer|min:0","default":{"RUB":0}},"active":{"type":"boolean","default":true}}'::jsonb, '{"abstract":false,"description":"Услуга: длительность (мин) + цена; занимает столько подряд окон, сколько покрывает duration"}'::jsonb, '[{"class":"Org","cardinality":1},{"class":"Folder","optional":true,"cardinality":1}]'::jsonb, 500, ARRAY['Service', 'Entity']::text[])
24
25
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
25
26
 
26
27
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
27
- ('entity', 'Complex', 'Комплекс', 'HUB', 'Entity', '{"id":"uuid","name":"string","description":"string|optional","duration":"number|integer|positive","discount":"number|integer|default:0","price":{"type":"record","key":{"type":"enum","values":["RUB","USD","EUR","AED"]},"value":"number|integer|min:0","optional":true}}'::jsonb, '{"abstract":false,"description":"Комплекс: собственный duration; состав — позиция(Комплекс→Услуга); свободный текст цены — в description"}'::jsonb, '{"Org","Folder"}'::text[], 600, '{"Complex","Entity"}'::text[])
28
+ ('entity', 'Complex', 'Комплекс', 'HUB', 'Entity', '{"id":{"type":"uuid","generate":5,"from":["Org","name"]},"name":"string","description":"string|optional","duration":"number|integer|positive","discount":"number|integer|default:0","price":{"type":"record","key":{"type":"enum","values":["RUB","USD","EUR","AED"]},"value":"number|integer|min:0","optional":true}}'::jsonb, '{"abstract":false,"description":"Комплекс: собственный duration; состав — позиция(Комплекс→Услуга); свободный текст цены — в description"}'::jsonb, '[{"class":"Org","cardinality":1},{"class":"Folder","optional":true,"cardinality":1}]'::jsonb, 600, ARRAY['Complex', 'Entity']::text[])
28
29
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
29
30
 
30
31
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
31
- ('entity', 'Customer', 'Клиент', 'HUB', 'Entity', '{"id":"uuid","name":"string|optional","contact":"string|optional","language":{"type":"enum","values":["ru","en"],"default":"ru"},"active":{"type":"boolean","default":true}}'::jsonb, '{"abstract":false,"description":"Клиент — записывается на услуги"}'::jsonb, '{"Org"}'::text[], 700, '{"Customer","Entity"}'::text[])
32
+ ('entity', 'Customer', 'Клиент', 'HUB', 'Entity', '{"name":"string|optional","contact":"string|optional","language":{"type":"enum","values":["ru","en"],"default":"ru"},"active":{"type":"boolean","default":true}}'::jsonb, '{"abstract":false,"description":"Клиент — записывается на услуги"}'::jsonb, '[{"class":"Org","cardinality":1}]'::jsonb, 700, ARRAY['Customer', 'Entity']::text[])
32
33
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
33
34
 
34
35
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
35
- ('entity', 'Schedule', 'Расписание', 'HUB', 'Entity', '{"id":"uuid","start":{"type":"date","convert":true},"end":{"type":"date","convert":true},"active":{"type":"boolean","default":true}}'::jsonb, '{"abstract":false,"description":"Расписание — период организации, содержит непересекающиеся Окна (инвариант проверяет приложение)"}'::jsonb, '{"Org"}'::text[], 800, '{"Schedule","Entity"}'::text[])
36
+ ('entity', 'Schedule', 'Расписание', 'HUB', 'Entity', '{"start":{"type":"date","convert":true},"end":{"type":"date","convert":true},"active":{"type":"boolean","default":true}}'::jsonb, '{"abstract":false,"description":"Расписание — период организации, содержит непересекающиеся Окна (инвариант проверяет приложение)"}'::jsonb, '[{"class":"Org","cardinality":1}]'::jsonb, 800, ARRAY['Schedule', 'Entity']::text[])
36
37
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
37
38
 
38
39
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
39
- ('entity', 'Slot', 'Окно', 'HUB', 'Entity', '{"id":"uuid","start":{"type":"date","convert":true},"end":{"type":"date","convert":true}}'::jsonb, '{"abstract":false,"description":"Окно — общий таймлайн произвольной длины внутри Расписания; статуса нет — занятость мастера хранит LINK занятость"}'::jsonb, '{"Schedule"}'::text[], 900, '{"Slot","Entity"}'::text[])
40
+ ('entity', 'Slot', 'Окно', 'HUB', 'Entity', '{"id":{"type":"uuid","generate":5,"from":["Schedule","start"]},"start":{"type":"date","convert":true},"end":{"type":"date","convert":true}}'::jsonb, '{"abstract":false,"description":"Окно — общий таймлайн произвольной длины внутри Расписания; статуса нет — занятость мастера хранит LINK занятость"}'::jsonb, '[{"class":"Schedule","cardinality":1}]'::jsonb, 900, ARRAY['Slot', 'Entity']::text[])
40
41
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
41
42
 
42
43
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
43
- ('entity', 'Booking', 'Запись', 'HUB', 'Entity', '{"id":"uuid","status":{"type":"enum","values":["created","confirmed","completed","cancelled","no_show"],"default":"created"},"source":{"type":"enum","values":["online","web","admin","telegram"],"default":"online"},"comment":"string|optional","total":{"type":"record","key":{"type":"enum","values":["RUB","USD","EUR","AED"]},"value":"number|integer|min:0","default":{"RUB":0}}}'::jsonb, '{"abstract":false,"description":"Запись клиента. Без мастера (мульти-мастер): мастера — на занятости/позиции. Ручная бронь по имени: без Customer, имя в comment. Дата приёма = start первого окна брони. history: полный аудит версиями"}'::jsonb, '{"Customer"}'::text[], 1000, '{"Booking","Entity"}'::text[])
44
+ ('entity', 'Booking', 'Запись', 'HUB', 'Entity', '{"status":{"type":"enum","values":["created","confirmed","completed","cancelled","no_show"],"default":"created"},"source":{"type":"enum","values":["online","web","admin","telegram"],"default":"online"},"comment":"string|optional","total":{"type":"record","key":{"type":"enum","values":["RUB","USD","EUR","AED"]},"value":"number|integer|min:0","default":{"RUB":0}}}'::jsonb, '{"abstract":false,"description":"Запись клиента. Без мастера (мульти-мастер): мастера — на занятости/позиции. Ручная бронь по имени: без Customer, имя в comment. Дата приёма = start первого окна брони. history: полный аудит версиями"}'::jsonb, '[{"class":"Customer","optional":true,"cardinality":1}]'::jsonb, 1000, ARRAY['Booking', 'Entity']::text[])
44
45
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
45
46
 
46
47
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
47
- ('entity', 'link', 'связь', 'LINK', NULL, '{"id":"any"}'::jsonb, '{"abstract":true,"description":"Абстрактная связь; фактические концы — ключи Entity.links {Класс: id, …}"}'::jsonb, '{"Entity","Entity"}'::text[], 100, '{"link"}'::text[])
48
+ ('entity', 'link', 'связь', 'LINK', NULL, '{"id":{"type":"uuid","generate":7}}'::jsonb, '{"abstract":true,"description":"Абстрактная связь; концы объявляются потомками в links (Schema.links v2: объекты-концы)"}'::jsonb, '[]'::jsonb, 100, ARRAY['link']::text[])
48
49
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
49
50
 
50
51
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
51
- ('entity', 'item', 'позиция', 'LINK', 'link', '{"id":"any","qty":"number|integer|min:1|default:1","price":{"type":"record","key":{"type":"enum","values":["RUB","USD","EUR","AED"]},"value":"number|integer|min:0","optional":true}}'::jsonb, '{"abstract":false,"description":"Полиморфная позиция: {Запись,(Услуга|Комплекс),Сотрудник} — строка записи со снимком цены и исполнителем; {Комплекс,Услуга} — состав комплекса"}'::jsonb, '{"Entity","Entity"}'::text[], 200, '{"item","link"}'::text[])
52
+ ('entity', 'item', 'позиция', 'LINK', 'link', '{"qty":"number|integer|min:1|default:1","price":{"type":"record","key":{"type":"enum","values":["RUB","USD","EUR","AED"]},"value":"number|integer|min:0","optional":true}}'::jsonb, '{"abstract":false,"description":"Позиция заказа: Запись × предмет [Услуга|Комплекс] × Сотрудник?. Снимок цены в price. Состав комплекса — отдельный LINK «состав» (compo)"}'::jsonb, '[{"classes":["Booking"],"cardinality":1},{"classes":["Service","Complex"],"cardinality":1},{"class":"Staff","optional":true,"cardinality":1}]'::jsonb, 200, ARRAY['item', 'link']::text[])
52
53
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
53
54
 
54
55
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
55
- ('entity', 'skill', 'навык', 'LINK', 'link', '{"id":"any"}'::jsonb, '{"abstract":false,"description":"Навык: Сотрудник умеет (Услуга|Комплекс); при записи проверяется"}'::jsonb, '{"Staff","Entity"}'::text[], 300, '{"skill","link"}'::text[])
56
+ ('entity', 'compo', 'состав', 'LINK', 'link', '{"id":{"type":"uuid","generate":5,"from":["Complex","Service"]},"qty":"number|integer|min:1|default:1"}'::jsonb, '{"abstract":false,"description":"Состав комплекса: Комплекс ← Услуга (+qty). Раньше жил на позиции — вынесен отдельным классом"}'::jsonb, '[{"class":"Complex","cardinality":1},{"class":"Service","cardinality":1}]'::jsonb, 250, ARRAY['compo', 'link']::text[])
56
57
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
57
58
 
58
59
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
59
- ('entity', 'shift', 'смена', 'LINK', 'link', '{"id":"any"}'::jsonb, '{"abstract":false,"description":"Ростер: сотрудник работает в расписании ⇒ по умолчанию доступен во всех его окнах"}'::jsonb, '{"Schedule","Staff"}'::text[], 400, '{"shift","link"}'::text[])
60
+ ('entity', 'skill', 'навык', 'LINK', 'link', '{"id":{"type":"uuid","generate":5,"from":["Staff","Service|Complex"]}}'::jsonb, '{"abstract":false,"description":"Навык: Сотрудник умеет (Услуга|Комплекс); при записи проверяется"}'::jsonb, '[{"class":"Staff","cardinality":1},{"classes":["Service","Complex"],"cardinality":1}]'::jsonb, 300, ARRAY['skill', 'link']::text[])
60
61
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
61
62
 
62
63
  INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
63
- ('entity', 'busy', 'занятость', 'LINK', 'link', '{"id":"any","kind":{"type":"enum","values":["off","hold","booking"],"default":"booking"},"reason":"string|optional"}'::jsonb, '{"abstract":false,"description":"Негативная доступность: свободно = НЕТ живой занятости. off — мастер убран из окна; hold — оформление; booking — бронь (+ключ Запись в links). id = uuidv5(Сотрудник, Окно) — детерминирован против двойной брони"}'::jsonb, '{"Staff","Slot"}'::text[], 500, '{"busy","link"}'::text[])
64
+ ('entity', 'shift', 'смена', 'LINK', 'link', '{"id":{"type":"uuid","generate":5,"from":["Schedule","Staff"]}}'::jsonb, '{"abstract":false,"description":"Ростер: сотрудник работает в расписании ⇒ по умолчанию доступен во всех его окнах"}'::jsonb, '[{"class":"Schedule","cardinality":1},{"class":"Staff","cardinality":1}]'::jsonb, 400, ARRAY['shift', 'link']::text[])
65
+ ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;
66
+
67
+ INSERT INTO "<SCHEMA-NAME>"."Schema" (partition, id, alias, category, ancestor, attributes, meta, links, "order", ancestors) VALUES
68
+ ('entity', 'busy', 'занятость', 'LINK', 'link', '{"id":{"type":"uuid","generate":5,"from":["Slot","Staff"]},"kind":{"type":"enum","values":["off","hold","booking"],"default":"booking"},"reason":"string|optional"}'::jsonb, '{"abstract":false,"description":"Негативная доступность: свободно = НЕТ живой занятости. off — мастер убран из окна; hold — оформление; booking — бронь (+ключ Запись в links). id = uuidv5(Окно, Сотрудник) — считает схема (attributes.id) — детерминирован против двойной брони"}'::jsonb, '[{"class":"Staff","cardinality":1},{"class":"Slot","cardinality":1},{"class":"Booking","optional":true,"cardinality":1}]'::jsonb, 500, ARRAY['busy', 'link']::text[])
64
69
  ON CONFLICT (partition, id) DO UPDATE SET alias = EXCLUDED.alias, category = EXCLUDED.category, ancestor = EXCLUDED.ancestor, attributes = EXCLUDED.attributes, meta = EXCLUDED.meta, links = EXCLUDED.links, "order" = EXCLUDED."order", ancestors = EXCLUDED.ancestors;