Управление доступом в модуле projects (IProjectAccess / ProjectAccess)

Документ описывает модель прав на проекты и доски: роли участников, ограничения, лимиты.

1. Порт IProjectAccess

Файл: modules/projects/application/port/IProjectAccess.php

interface IProjectAccess
{
    public function getUserProjectIds(int $userId): array;
    public function getProjectBoardIds(int $projectId): array;
    public function getProjectIdByBoardId(int $boardId): ?int;

    public function canViewProject(int $userId, int $projectId): bool;
    public function canViewBoard(int $userId, int $boardId): bool;
    public function canManageProject(int $userId, int $projectId): bool;
    public function canManageBoard(int $userId, int $boardId): bool;
    public function canManageUser(int $userId, int $targetUserId, int $projectId): bool;
    public function canAddMember(int $userId, int $targetUserId, int $projectId): bool;
    public function canInviteUser(int $userId, int $targetUserId, int $projectId): bool;
    public function canRemoveUser(int $userId, int $targetUserId, int $projectId): bool;
    public function canDeleteProject(int $userId, int $projectId): bool;
    public function canDeleteBoard(int $userId, int $boardId): bool;
    public function canCreateBoard(int $userId, int $projectId): bool;
    public function canCreateProject(int $userId): bool;
}

2. Реализация ProjectAccess

Файл: modules/projects/infrastructure/access/ProjectAccess.php

Константы-лимиты (захардкожены в коде!)

КонстантаЗначениеОписание
MAX_USER_PROJECTS10Максимум проектов, владельцем которых может быть пользователь
MAX_PROJECT_BOARDS4Максимум досок в одном проекте

⚠️ Эти лимиты заданы жёстко в коде (не в конфиге). Изменение — правка класса и, возможно, тестов.

3. Таблица прав

МетодВладелец (owner)Админ проектаУчастник (member)Не участник
canViewProject✅✅✅❌
canViewBoard✅✅✅❌
canManageProject✅✅❌❌
canManageBoard✅✅*; создатель доски тоже ✅❌❌
canManageUser✅✅ (см. оговорки)❌❌
canAddMember❌❌ (см. типы проектов)❌❌
canInviteUser✅✅❌❌
canRemoveUser✅✅ (оговорки)❌❌
canDeleteProject✅ (не personal)❌❌❌
canDeleteBoard✅❌❌❌
canCreateBoard✅✅ (лимит 4)❌❌
canCreateProjectпо лимиту 10по лимитупо лимитупо лимиту

* canManageBoard: админ проекта ✅; иначе — создатель доски (board.created_by == userId).

4. Особые правила

4.1. Управление участниками (canManageUser, canRemoveUser)

4.2. Типы проектов и добавление участников (canAddMember, canInviteUser)

Компания пользователя читается из UserAR::company_id (getUserCompanyId). TODO в коде: вынести в отдельный сервис / привязать проекты к компании (см. known-issues-and-roadmap).

4.3. Удаление

5. Использование модулем tasks

TaskAccess (модуль tasks) делегирует проверки прав на доску в IProjectAccess:

См. tasks/access.md.

6. Как пользоваться в хендлерах

if (!$this->projectAccess->canManageProject($userId, $projectId)) {
    throw new PermissionDeniedException('Недостаточно прав для управления проектом');
}

Хендлеры получают IProjectAccess через DI (реализация — ProjectAccess).