Науковий редактор

Науковий редактор Zemna.AI — це редактор форматованого тексту на базі Tiptap для академічного письма. Він підтримує формули LaTeX, автоматичне збереження, історію версій та збереження публікацій через шар бази даних Ring Platform.

Статус: Фаза 2 (спринти 2.1–2.3) завершені. Підтримка рисунків/таблиць та експорт заплановані в спринтах 2.4–2.5.


Огляд

МожливістьОпис
Форматований текстЗаголовки (H1–H6), жирний, курсив, підкреслення, списки, цитати, блоки коду, таблиці, посилання, зображення
LaTeXІнлайн та блокові формули через KaTeX; модальне вікно формул з попереднім переглядом та шаблонами
АвтозбереженняЗбереження з затримкою 30 с; перше збереження створює публікацію, далі оновлення через PUT
Історія версійЗнімки та відновлення версій; список версій з датами та опційними описами
ПублікаціїВміст зберігається як Tiptap JSON; завантаження за ?id=... або створення нового

Можливості редактора

Форматований текст (Tiptap)

Редактор використовує Tiptap з StarterKit та розширеннями для наукового письма:

  • Форматування: Жирний, курсив, підкреслення, закреслення, надрядковий, підрядковий, виділення
  • Структура: Заголовки H1–H6, нумеровані/марковані списки, блокові цитати
  • Блоки: Блоки коду (підсвітка через lowlight), таблиці (рядки, стовпці, заголовок)
  • Інлайн: Посилання, зображення (підтримка placeholder)
  • Типографіка: Розумні лапки та покращення типографіки

Вміст зберігається як Tiptap JSON у полі публікації content; редактор приймає початковий вміст як рядок HTML або JSON для завантаження збережених публікацій.

Формули LaTeX

  • Блокові формули: Вставка формул у режимі display через панель (іконка калькулятора) або модальне вікно формул.
  • Відображення: KaTeX рендерить формули в редакторі; клік для редагування відкриває модальне вікно.
  • Модальне вікно: Поле LaTeX, перемикач display/inline, попередній перегляд, кнопки шаблонів (дріб, сума, інтеграл, матриця), Вставити/Скасувати.

Формули зберігаються як власні вузли Tiptap (mathBlock) з атрибутами latex та display.

Автозбереження та публікації

  • Новий документ: Немає ?id= у URL; перше «Зберегти» або перше автозбереження створює публікацію через POST /api/publications і встановлює id публікації для подальших збережень.
  • Існуючий документ: Відкрити з ?id=<publicationId>; сторінка завантажує публікацію і встановлює заголовок та вміст (JSON). Автозбереження та ручне «Зберегти» використовують PUT /api/publications/:id.
  • Затримка: Зміни заголовка або вмісту запускають збереження з затримкою 30 с; ручне «Зберегти» виконує збереження одразу.
  • Індикатор збереження: На панелі відображається «Збережено» з часом останнього успішного збереження.

Історія версій

  • Панель: Кнопка «Історія версій» на панелі відкриває діалог зі списком версій (номер версії, дата, опційний опис).
  • Знімок: «Зберегти знімок» створює нову версію з поточним вмістом (опційний опис змін).
  • Відновити: «Відновити» для версії оновлює вміст публікації до цієї версії та перезавантажує редактор; панель закривається, редактор показує відновлений вміст.

Архітектура

Схема публікацій

Публікації та версії використовують абстракцію бази даних Ring Platform (PostgreSQL з JSONB):

  • publications: id, data (JSONB), created_at, updated_at.
    data містить: user_id, title, content (Tiptap JSON), status, template_id.
  • publication_versions: id, data (JSONB), created_at, updated_at.
    data містить: publication_id, version_number, content, change_summary, created_by.

Схема визначена в data/schema.sql; адаптер PostgreSQL має fieldMappings для обох колекцій.

Потік збереження

sequenceDiagram
  participant User
  participant Editor
  participant useAutoSave
  participant API
  participant DB

  User->>Editor: Edit content / title
  Editor->>useAutoSave: touch(publicationId, payload)
  useAutoSave->>useAutoSave: Debounce 30s
  Note over useAutoSave: Timer fires
  useAutoSave->>API: POST /api/publications (new) or PUT /api/publications/:id
  API->>DB: create() or update()
  DB-->>API: publication
  API-->>useAutoSave: 200 + publication
  useAutoSave->>Editor: onFirstSave(id) if new
  useAutoSave->>Editor: lastSaved updated

Потік історії версій

sequenceDiagram
  participant User
  participant Panel
  participant API
  participant DB

  User->>Panel: Open Version History
  Panel->>API: GET /api/publications/:id/versions
  API->>DB: findByField(publication_versions, publication_id, id)
  DB-->>API: versions[]
  API-->>Panel: versions

  User->>Panel: Restore version V
  Panel->>API: POST /api/publications/:id/versions { action: 'restore', versionId: V }
  API->>DB: updatePublication(id, content from V)
  DB-->>API: publication
  API-->>Panel: 200
  Panel->>User: onRestore() → refetch publication, set editor content

API-маршрути

МетодШляхОпис
GET/api/publicationsСписок публікацій поточного користувача
POST/api/publicationsСтворити публікацію (body: title, content, status, template_id)
GET/api/publications/[id]Отримати публікацію (перевірка власності)
PUT/api/publications/[id]Оновити публікацію (перевірка власності)
DELETE/api/publications/[id]Видалити публікацію (перевірка власності)
GET/api/publications/[id]/versionsСписок версій публікації
POST/api/publications/[id]/versionsЗнімок (action: snapshot) або відновлення (action: restore, versionId)

Усі маршрути потребують автентифікації; для get/update/delete та версій перевіряється власність.


Ключові файли

ОбластьШлях
Сторінка редактораapp/(authenticated)/[locale]/editor/page.tsx
Науковий редакторcomponents/editor/scientific-editor.tsx
Панель інструментівcomponents/editor/editor-toolbar.tsx
Розширення LaTeXcomponents/editor/extensions/latex-extension.tsx
Модальне вікно формулcomponents/editor/equation-editor.tsx
Панель історії версійcomponents/editor/version-history-panel.tsx
Хук автозбереженняhooks/use-auto-save.ts
Типи публікаційfeatures/publications/types/index.ts
Сервіс публікаційfeatures/publications/services/publication-service.ts
API-маршрутиapp/(public)/api/publications/
Схемаdata/schema.sql

Використання

Відкриття редактора

  • Нова публікація: Перейдіть на /editor (або /[locale]/editor). Редактор завантажується з типовим науковим шаблоном; id публікації встановлюється при першому збереженні.
  • Існуюча публікація: Перейдіть на /editor?id=<publicationId>. Сторінка отримує публікацію та встановлює заголовок і вміст (Tiptap JSON) в редакторі.

Збереження

  • Вручну: Натисніть Зберегти на панелі. Для нового документу це створює публікацію та встановлює id; для існуючого — оновлення через PUT.
  • Автозбереження: Через 30 секунд без змін поточний заголовок та вміст зберігаються автоматично (POST для нового, PUT для існуючого).

Історія версій

  1. Натисніть Історія версій (іконка історії) на панелі.
  2. Використовуйте Зберегти знімок, щоб створити нову версію з поточним вмістом.
  3. Використовуйте Відновити для версії, щоб встановити вміст публікації на цю версію та перезавантажити редактор.
Порада

Відновлення не видаляє версії; воно оновлює вміст публікації, історія версій залишається.


Дорожня карта (залишок фази 2)

  • Спринт 2.4: Компонент завантаження рисунків, покращення редактора таблиць, розширення перехресних посилань, інтеграція FileService для зображень.
  • Спринт 2.5: Сервіси експорту (PDF, Word, Markdown), діалог експорту, кнопка та скорочення експорту.

Детальний розклад спрингів: Фаза 2: Покращення наукового редактора.