새로온 개발자 센터
11단계 시작하기22단계 연결· 내 현황문서

이 문서의 큐

  1. 두 평면을 먼저 구분하세요
  2. 정책 정의하기
  3. 운영 규칙
  4. 직위와 서열
  5. 권한은 대부분 강제되지 않습니다
  6. 정책 조회
  7. 정리
  8. 회원 쪽 화면 붙이기
  9. 관련 문서

개요

시작하기

Quickstart

기능 붙이기

FormsMembersBoardsShopCatalogsGroupsHoldings

앱 붙이기

앱 백엔드 붙이기

레퍼런스

속성 계약 (data-saeroon-*)CLI 레퍼런스 (@saeroon/cli)APIMCP

마켓플레이스

Marketplace

문서 / 기능 붙이기

이 문서의 큐
  1. 두 평면을 먼저 구분하세요
  2. 정책 정의하기
  3. 운영 규칙
  4. 직위와 서열
  5. 권한은 대부분 강제되지 않습니다
  6. 정책 조회
  7. 정리
  8. 회원 쪽 화면 붙이기
  9. 관련 문서

Groups

회원들이 모임을 만들고 가입하는 구조입니다. 상회·팀·동아리처럼 이름은 달라도 필요한 것은 같습니다. 누가 개설할 수 있는지, 가입에 승인이 필요한지, 몇 명부터 정식으로 활동하는지, 그 안에 어떤 자리가 있는지.

새로온은 그 규칙을 코드가 아니라 데이터로 다룹니다. 사이트가 정책을 정의하면 회원들은 그 안에서 스스로 움직입니다.

두 평면을 먼저 구분하세요

이 기능은 주체가 둘이고, 어느 통로를 쓸지가 거기서 갈립니다.

하는 일통로
운영자그룹의 종류와 규칙, 직위 어휘를 정한다CLI group · MCP saeroon_define_group_policy
회원그룹을 만들고, 가입하고, 직위를 주고받는다data-saeroon-group-* 속성 (회원 세션)

운영자 키로 회원의 가입을 대신 처리하는 경로는 없습니다. 그래서 CLI 에는 "그룹 만들기" 커맨드가 없습니다 — 그것은 회원이 자기 세션으로 하는 일입니다. 운영자가 정하는 것은 회원들이 딛고 설 규칙입니다.

정책 정의하기

npx @saeroon/cli group apply ./policies.json --site <siteId>
{
  "policies": [
    {
      "key": "guilds",
      "name": "상회",
      "requiresApproval": true,
      "activationMinMembers": 3,
      "allowMemberCreatedGroups": true,
      "maxMembers": 30,
      "roles": [
        { "roleKey": "leader", "label": "회장", "rankLevel": 10,
          "isExclusive": true, "isLeadership": true, "isRequiredForActivation": true,
          "defaultPermissions": ["group.edit", "members.approve", "members.manage-roles"] },
        { "roleKey": "vice", "label": "부회장", "rankLevel": 5,
          "isLeadership": true, "defaultPermissions": ["members.approve"] },
        { "roleKey": "member", "label": "회원", "rankLevel": 0, "isDefault": true }
      ]
    }
  ]
}

key 는 사이트 안에서 유일하며 한 번 정하면 바꿀 수 없습니다.

운영 규칙

필드뜻
requiresApproval가입에 임원 승인이 필요한가
activationMinMembers결성 중인 그룹이 정식 활동을 시작하는 최소 인원
maxMembers인원 상한
allowMultipleMemberships한 회원이 여러 그룹에 동시에 속할 수 있는가
allowMemberCreatedGroups일반 회원이 그룹을 개설할 수 있는가 (아니면 운영자만)
requireInviteWhileForming결성 중에는 초대로만 들어올 수 있는가
actingLeaderEnabled대표 자리가 비었을 때 권한대행을 둘 수 있는가

activationMinMembers 가 maxMembers 보다 크면 그룹이 영원히 활성화되지 못합니다. CLI 가 요청 전에 거절합니다.

직위와 서열

직위는 이름·서열·기본 권한을 가집니다. 여기서 가장 중요한 것이 서열(rankLevel)입니다.

그룹 해산과 배타 직위 배정은 권한이 아니라 서열로 판정합니다. 권한 위임으로 자기보다 높은 자리를 만들어 내는 통로를 막기 위해서입니다. 회장이 부회장에게 권한을 넘겨도, 부회장이 회장 자리를 자기에게 배정할 수는 없습니다.

플래그뜻
rankLevel서열. 높을수록 상위
isExclusive그룹당 한 명만 앉는 자리 (회장 등)
isLeadership임원. 카탈로그의 GroupLeader 쓰기 정책을 만족시킨다
isRequiredForActivation이 직위를 가진 사람이 있어야 그룹이 활성화된다
canCreateGroup이 직위 보유자가 새 그룹을 열 수 있다
isDefault새로 들어온 사람이 받는 직위. 정책당 하나

isExclusive 는 부분 유니크 인덱스로 강제되지만 기존 멤버십에 소급되지 않습니다. 값을 바꾼 시점 이후의 재배정부터 적용됩니다.

isDefault 를 둘 이상에 켜면 CLI 가 거절합니다. 서버는 마지막에 처리한 것만 남기므로, 배열 순서에 따라 결과가 달라지는 상태를 만들지 않기 위해서입니다.

권한은 대부분 강제되지 않습니다

직위의 defaultPermissions 에는 아무 문자열이나 넣을 수 있고 플랫폼은 그것을 저장하고 돌려줍니다. 사이트가 자기 화면에서 쓸 권한을 자유롭게 정의하라는 뜻입니다.

다만 서버가 실제로 막아 주는 권한은 여섯 개뿐입니다.

키서버가 막는 것
group.edit그룹 이름·설명·속성 변경
members.manage-roles그룹원 직위 변경
members.approve가입 신청 수락·반려, 초대 코드 발급
members.remove그룹원 내보내기
members.delegate권한 위임 (자기가 가진 것만 넘길 수 있음)
marks.manage조율 표식 편집

이 목록 밖의 문자열, 예를 들어 posts.write 는 사이트 프론트가 스스로 해석하는 값이지 백엔드 보호가 아닙니다. 그것을 서버가 지켜 준다고 믿으면 값은 있는데 판정이 없는 게이트가 생깁니다. CLI 는 목록 밖 키를 거절하지 않고 경고로 알려 줍니다.

정책 조회

npx @saeroon/cli group list --site <siteId>
npx @saeroon/cli group get guilds --site <siteId>     # 규칙 + 직위 + 속성 스키마
npx @saeroon/cli group export --site <siteId> -o policies.json

정리

정책은 삭제가 아니라 보관입니다.

npx @saeroon/cli group archive guilds --site <siteId>

보관하면 신규 그룹 개설만 막히고 기존 그룹은 계속 돕니다. 되돌리려면 group unarchive 를 씁니다.

직위 정의 삭제는 그 직위를 가진 활성 그룹원이 없을 때만 됩니다. 있으면 서버가 거절합니다 — 정의를 지우면 그 소속이 서열 0인 미아가 되기 때문입니다.

npx @saeroon/cli group role-delete guilds vice --site <siteId>

group apply 는 매니페스트에 없는 정책과 직위를 건드리지 않습니다. 정리하려면 --prune 을 붙이세요. 그때도 보유자가 있는 직위는 건너뛰고 결과에 따로 보고합니다.

회원 쪽 화면 붙이기

여기서부터는 회원 세션으로 도는 표면입니다. 회원 인증이 먼저 배선되어 있어야 합니다.

<!-- 정책 아래 그룹 목록 (공개 읽기) -->
<div data-saeroon-group-list data-policy="guilds">
  <template>
    <li>
      <span data-saeroon-field="name"></span>
      <small data-saeroon-field="memberCount"></small>
    </li>
  </template>
  <p data-saeroon-empty>아직 개설된 그룹이 없습니다.</p>
</div>

<!-- 개설 (정책의 allowMemberCreatedGroups 가 켜져 있어야 함) -->
<form data-saeroon-group-create data-policy="guilds">
  <input name="name" required />
  <input name="description" />
  <button type="submit">개설</button>
</form>

<!-- 가입 신청 · 명부 -->
<button data-saeroon-group-apply data-group-id="<groupId>">가입 신청</button>

<div data-saeroon-group-members data-group-id="<groupId>">
  <template>
    <li>
      <span data-saeroon-field="displayName"></span>
      <em data-saeroon-field="roleLabel"></em>
    </li>
  </template>
</div>

명부는 서열 내림차순으로 그려집니다. 승인제 정책이면 group-apply 가 신청을 남기고, 아니면 서버가 즉시 가입으로 처리합니다.

동작이 끝나면 이벤트가 올라옵니다. 사이트 코드가 이어받아 화면을 갱신할 수 있습니다.

  • saeroon:group-created — detail.group
  • saeroon:group-applied — detail.groupId, detail.application
  • saeroon:group-marked — detail.targetMemberId, detail.mark

관련 문서

  • Catalogs — 그룹 기준 쓰기 권한이 걸리는 대상
  • Holdings — 그룹 안에서 서로의 보유를 보고 표식을 남기기
  • Members — 회원 인증 (그룹 기능의 선행 조건)

요약

회원들이 모임을 만들고 가입하는 구조입니다. 상회·팀·동아리처럼 이름은 달라도 필요한 것은 같습니다. 누가 개설할 수 있는지, 가입에 승인이 필요한지, 몇 명부터 정식으로 활동하는지, 그 안에 어떤 자리가 있는지.

마크다운 원문/docs/groups.md