본문으로 건너뛰기

Annotation

범용 anchor 주석 — kind/visibility/parent 검증 + 가시성 정� (도메인 무관)

상태

항목
Layercore
TierL1
Statusreleased
Version1.0.0
가격Free (free)
**카�
�고리**Content

개요

개요

Annotation 은 multi-saas-kit 의 Layer 1 Core Plugin � 니다. paragraph anchor 단위 주석 (메모/답글/팁/번역) 의 표준 검증 + 가시성 정� 을 도메인 무관 Pure 로 제공합니다.

분리선 (ADR-039)

ADR-039 사례 11 — 기존 enum case 의 academy.how 도메인 � � (LESSON_SHARED, TEACHER_ONLY, STUDENT, TEACHER) 을 도메인 무관 � � 으로 일반화. scripture.how 적용 검증 시도가 폭로한 도메인성 정정.

변경:

  • Visibility::LESSON_SHAREDVisibility::CONTEXT_SHARED
  • Visibility::TEACHER_ONLYVisibility::STAFF_ONLY
  • AuthorRole::STUDENTAuthorRole::MEMBER
  • AuthorRole::TEACHERAuthorRole::STAFF
  • VisibilityResolver in_same_lessonin_same_context (하위 호환 fallback 유지)
  • layer compositecore

핵심 컴포넌트

Enums (5�

)

EnumCases
AnnotationKindnote, tip, reply, translation
Visibilityprivate, context_shared, staff_only (NOTE 만)
TipStylehighlight, tip, warning, note (TIP 만)
AuthorRolemember, staff, admin (staff = staff | admin)
BodyFormatmarkdown, html_trix, html_tiptap

Kind 별 capability 메서드 — requiresParent(), requiresLocale(), supportsVisibility(), supportsTipStyle().

AnchorIdValidator (Pure)

  • DocumentProcessor 가 부여하는 anchor 패턴 (/^[a-z0-9\-]{1,32}$/) 검증
  • XPath / CSS selector 인젝� � 차단
  • 빈 / 32자 초과 거부

AnnotationPayloadValidator (Pure)

kind/visibility/parent/locale 조합 검증 + 정규화.

VisibilityResolver (Pure)

조건결과
본인 글항상 보임
TIP / TRANSLATION같은 컨�
�스트면 모두 보임
NOTE — PRIVATE본인만
NOTE — CONTEXT_SHARED같은 컨�
�스트 모두
NOTE — STAFF_ONLY같은 컨�
�스트 + staff
REPLYparent 의 visibility 따라감 (호출자가 parent 메타로 재호출)

SaaS 별 매핑 예시

| SaaS | MEMBER | STAFF | 컨� �스트 | |------|--------|-------|----------| | academy.how | 학생 | 교사 | lesson | | scripture.how | 참여� 자 | 메인저자/추가저자 | chapter | | commerce | 고객 | 운영자 | product | | forum | 일반사용자 | 모더레이터 | thread |

사용 예시

use App\Plugins\Annotation\Enums\{AnnotationKind, AuthorRole, Visibility};
use App\Plugins\Annotation\Services\{AnnotationPayloadValidator, VisibilityResolver};

$validator = AnnotationPayloadValidator::fromConfig(config('annotation'));
$normalized = $validator->validate($request->all(), AuthorRole::from($user->annotationRole()));

$resolver = new VisibilityResolver;
$canView = $resolver->canView(
annotation: [
'kind' => AnnotationKind::from($a->kind),
'visibility' => $a->visibility ? Visibility::from($a->visibility) : null,
'author_user_id' => $a->user_id,
'author_role' => AuthorRole::from($a->author_role),
],
viewer: [
'user_id' => $request->user()?->id,
'role' => AuthorRole::from($request->user()->annotationRole()),
'in_same_context' => true,
],
);

출처

academy.how AnnotationController + AnnotationPolicy + AuthorRoleResolver 추출 → ADR-039 사례 11 일반화.

의존성

  • DocumentProcessor — anchor 패턴 호환 (선택)

라이선스

MIT

의존성

데모


🛒 Plugin Store에서 보기: store.codebase.how/plugins/annotation