fix(review): address PR #101 review findings (dead DI, docs)
Some checks failed
Test / test (pull_request) Has been cancelled

- ai-chat: drop the unused pagePermissionRepo injection from
  PublicShareChatToolsService (its only use moved into
  ShareService.resolveReadableSharePage); update all 5 positional
  test construction sites to match the 3-arg constructor.
- env: correct the anonymous share-AI per-workspace cap comment —
  the limiter FAILS CLOSED on Redis failure (#62), not open.
- docs: sync README.ru.md with README.md — move "Page templates"
  from Planned to Done and drop the dead plan-doc link.

Remaining test-coverage gaps tracked as #102, #103, #104, #105, #106.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
claude_code
2026-06-21 05:24:13 +03:00
parent a20f4c3876
commit bc0c49db05
5 changed files with 4 additions and 11 deletions

View File

@@ -140,6 +140,7 @@ MCP_DOCMOST_PASSWORD=
# Backstop: a cluster-wide, sliding-window cap per workspace (IP-independent,
# keyed by the server-resolved workspace id) bounds the owner's bill even if the
# per-IP limit is fully evaded. It is a COST backstop, not an access control,
# and FAILS OPEN if Redis is unavailable. Override the hourly cap below
# and FAILS CLOSED if Redis is unavailable (the assistant is temporarily
# denied rather than serving unmetered calls). Override the hourly cap below
# (default: 300 calls per workspace per rolling hour).
# SHARE_AI_WORKSPACE_MAX_PER_HOUR=300

View File

@@ -102,6 +102,7 @@ real-time-коллаборации Docmost, поэтому запись нико
-**Приложение для macOS** — нативное приложение для macOS ([gitmost-app](https://github.com/vvzvlad/gitmost-app)), встраивающее UI с вкладками для нескольких серверов.
-**AI-чат** — встроенный чат с AI-агентом по содержимому вики (чтение + запись, RAG-поиск, настраиваемый провайдер, опциональный доступ в интернет через внешние MCP).
-**Голосовая диктовка** — кнопка-микрофон в чате AI-агента и в редакторе страниц; аудио распознаётся на сервере (Whisper / OpenAI-совместимый STT) через AI-провайдер воркспейса, с тумблером админа для показа/скрытия.
-**Шаблоны страниц** — пометить страницу шаблоном и вставлять её содержимое живой ссылкой в другие страницы; правки шаблона распространяются на все места вставки (whole-page-транслюзия поверх существующих synced-блоков).
### В процессе
@@ -109,7 +110,6 @@ real-time-коллаборации Docmost, поэтому запись нико
### В планах
- 🔭 **Шаблоны страниц** — пометить страницу шаблоном и вставлять её содержимое живой ссылкой в другие страницы; правки шаблона распространяются на все места вставки (whole-page-транслюзия поверх существующих synced-блоков). См. [docs/page-templates-plan.md](docs/page-templates-plan.md).
- 🔭 **Комментарии зрителей** — возможность комментировать для пользователей с доступом только на чтение.
- 🔭 **AI-ассистент на публичных шарах** — возможность анонимному зрителю расшаренной страницы спросить AI-агента, который ищет строго по дереву этой шары (read-only, share-scoped поиск), за тумблером воркспейса. См. [docs/public-share-assistant-plan.md](docs/public-share-assistant-plan.md).
- 🔭 **Защищённые паролем страницы** — защита отдельных страниц / шар паролем.

View File

@@ -533,7 +533,6 @@ describe('PublicShareChatToolsService share scoping', () => {
shareService as never,
{} as never,
{} as never,
{} as never,
);
const tools = svc.forShare('THIS-SHARE', 'ws-1');
@@ -566,7 +565,6 @@ describe('PublicShareChatToolsService share scoping', () => {
shareService as never,
{} as never,
{} as never,
{} as never,
);
const tools = svc.forShare('THIS-SHARE', 'ws-1');
@@ -591,7 +589,6 @@ describe('PublicShareChatToolsService share scoping', () => {
{} as never,
searchService as never,
{} as never,
{} as never,
);
const tools = svc.forShare('THIS-SHARE', 'ws-1');
const searchSharePages = tools.searchSharePages as {
@@ -732,7 +729,6 @@ describe('public-share assistant boundary locks (red-team regression guards)', (
shareService as never,
{} as never,
{} as never,
{} as never,
);
const tools = svc.forShare('FORGED-SHARE', 'ws-1');
const getSharePage = tools.getSharePage as {

View File

@@ -24,14 +24,12 @@ describe('PublicShareChatToolsService.forShare', () => {
};
const searchService = { searchPage: over.searchPage ?? jest.fn() };
const pageRepo = { findById: over.findById ?? jest.fn() };
const pagePermissionRepo = { hasRestrictedAncestor: jest.fn() };
const svc = new PublicShareChatToolsService(
shareService as never,
searchService as never,
pageRepo as never,
pagePermissionRepo as never,
);
return { svc, shareService, searchService, pageRepo, pagePermissionRepo };
return { svc, shareService, searchService, pageRepo };
}
describe('listSharePages', () => {

View File

@@ -4,7 +4,6 @@ import { z } from 'zod';
import { ShareService } from '../../share/share.service';
import { SearchService } from '../../search/search.service';
import { PageRepo } from '@docmost/db/repos/page/page.repo';
import { PagePermissionRepo } from '@docmost/db/repos/page/page-permission.repo';
import { jsonToMarkdown } from '../../../collaboration/collaboration.util';
/**
@@ -35,7 +34,6 @@ export class PublicShareChatToolsService {
private readonly shareService: ShareService,
private readonly searchService: SearchService,
private readonly pageRepo: PageRepo,
private readonly pagePermissionRepo: PagePermissionRepo,
) {}
/**