문서 / 기능 붙이기
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.groupsaeroon:group-applied—detail.groupId,detail.applicationsaeroon:group-marked—detail.targetMemberId,detail.mark
관련 문서
요약
회원들이 모임을 만들고 가입하는 구조입니다. 상회·팀·동아리처럼 이름은 달라도 필요한 것은 같습니다. 누가 개설할 수 있는지, 가입에 승인이 필요한지, 몇 명부터 정식으로 활동하는지, 그 안에 어떤 자리가 있는지.