코드 주석을 이 저장소 기준으로 정리

This commit is contained in:
Sn-Kinos
2026-10-16 18:04:14 +09:00
parent 80b90aad4c
commit 4236d75fd1
89 changed files with 212 additions and 212 deletions
+13 -13
View File
@@ -86,12 +86,12 @@ export async function planetColorKeys(): Promise<string[]> {
/**
* 운영값 기본 — 🟡 `config/policy` 가 덮는다.
* - 성운 전환: 원장 B-10 「10명 이상 + 1,000 POP 이상 + 기본 목표 7일」.
* - 성운 전환: 정책 원장 B-10 「10명 이상 + 1,000 POP 이상 + 기본 목표 7일」.
* `nebulaConversionDeadlineEnforced` — 7일을 넘긴 성운의 전환을 막을지. B-10 「미달성 시 유지」와
* 「7일 이내 판정」이 갈려 발주사 확인 중이며, 회신 전에는 막지 않는다(false).
* - 대표 팬덤: 원장 C-15 「변경 무료 · 재변경까지 초기 30일 대기 · 운영자 조정 가능」.
* - 대표 팬덤: 정책 원장 C-15 「변경 무료 · 재변경까지 초기 30일 대기 · 운영자 조정 가능」.
* - `primaryOnLeave` — 대표 팬덤에서 탈퇴할 때 남은 가입 팬덤 가운데 무엇을 대표로 둘지.
* 원장 C-101 확정값은 `latest`(가장 최근 가입). `earliest` · `none` 은 확정 전 남겨 둔 운영 스위치.
* 정책 원장 C-101 확정값은 `latest`(가장 최근 가입). `earliest` · `none` 은 확정 전 남겨 둔 운영 스위치.
* 자동 지정은 C-15 대기에 세지 않는다.
*/
const FANDOM_DEFAULTS = {
@@ -122,7 +122,7 @@ function primaryOf(user: Data): string | null {
}
/**
* 대표 팬덤을 [fandomId] 로 바꾸는 필드 — 원장 C-15.
* 대표 팬덤을 [fandomId] 로 바꾸는 필드 — 정책 원장 C-15.
*
* 대표가 없던 계정의 첫 지정은 「변경」이 아니므로 대기를 걸지 않고 시각도 찍지 않는다.
* 이미 대표가 있으면 `primaryChangedAt + 대기일` 이 지나야 바뀐다. `patch` 가 null 이면
@@ -145,7 +145,7 @@ function primaryPatch(user: Data, fandomId: string, cooldownDays: number, now: n
/**
* 멤버십 한 건을 트랜잭션 안에서 쓴다. 호출 측이 「아직 멤버가 아님」을 확인한 뒤에만 부른다.
*
* - `fandoms/{id}/members/{uid}` — 가입 사실 · 가입 순번(`memberNo`, 원장 B-68 #001~ 기록).
* - `fandoms/{id}/members/{uid}` — 가입 사실 · 가입 순번(`memberNo`, 정책 원장 B-68 #001~ 기록).
* 순번은 탈퇴로 줄지 않는 `memberSeq` 에서 뽑아 재사용하지 않는다.
* - `users/{uid}/memberships/{id}` — 「가입 또는 생성한 행성/성운」 목록(명세 §2.58)의 원천.
* - `memberCount` 는 같은 트랜잭션에서 올린다 — 전환 조건(B-10)이 이 값을 읽는다.
@@ -183,7 +183,7 @@ function writeJoin(tx: Transaction, uid: string, fandomId: string, fandom: Data)
}
/**
* `fn-nebula-create` — 성운(Stage0) 생성. 원장 B-08 · B-09 · B-10 · C-15.
* `fn-nebula-create` — 성운(Stage0) 생성. 정책 원장 B-08 · B-09 · B-10 · C-15.
*
* 팬덤 문서 자체가 공용 성운/행성이다(팬덤 1 : 행성 1). 만든 사람은 창립 멤버 #001 이다.
* 확인 다이얼로그 「선택한 행성을 기본 행성으로 변경할까요?」대로 대표 팬덤을 바꾸되, C-15
@@ -237,7 +237,7 @@ export const fnNebulaCreate = onCall(async (req) => {
});
/**
* `fn-fandom-join` — 행성/성운 가입. 원장 C-15 「복수 팬덤 가입」.
* `fn-fandom-join` — 행성/성운 가입. 정책 원장 C-15 「복수 팬덤 가입」.
*
* 이미 멤버면 아무것도 쓰지 않는다(두 번 눌러도 `memberCount` 는 한 번만 오른다).
* 대표 팬덤이 없던 계정은 처음 가입한 팬덤이 대표가 된다 — 그 외에는 대표를 바꾸지 않는다.
@@ -276,10 +276,10 @@ export const fnFandomJoin = onCall(async (req) => {
* 과거 기여 · Passport 기록(원장 · growthEvents · popTransactions)은 지우지 않는다(C-15).
* 순번은 `memberSeq` 를 되돌리지 않으므로 다른 사용자에게 다시 주지 않는다(C-100 · B-68).
*
* - 성운(Stage0) 창립자도 탄생 전 떠날 수 있다(원장 C-100). 탄생 권한(`founderUid`)은 남은 멤버
* - 성운(Stage0) 창립자도 탄생 전 떠날 수 있다(정책 원장 C-100). 탄생 권한(`founderUid`)은 남은 멤버
* 가운데 `joinedAt` 이 가장 이른 사용자에게 넘기고 알림을 남긴다. 남은 멤버가 없으면 비워 두고
* 다음 가입자가 이어받는다(원장 S20 확인 전 유지 기준). `ownerUid`(행성 문서) 등 최초 생성자 기록은 그대로다.
* - 대표 팬덤을 떠나면 남은 팬덤 중 가장 최근 가입한 팬덤을 대표로 둔다(원장 C-101). 자동 지정이라
* - 대표 팬덤을 떠나면 남은 팬덤 중 가장 최근 가입한 팬덤을 대표로 둔다(정책 원장 C-101). 자동 지정이라
* `primaryChangedAt` 을 찍지 않는다 — 사용자의 다음 직접 변경을 30일 대기로 막지 않는다.
*/
export const fnFandomLeave = onCall(async (req) => {
@@ -343,7 +343,7 @@ export const fnFandomLeave = onCall(async (req) => {
});
/**
* `fn-primary-fandom-set` — 대표 팬덤 변경. 원장 C-15 · 명세 §2.56 「기본 행성 변경」.
* `fn-primary-fandom-set` — 대표 팬덤 변경. 정책 원장 C-15 · 명세 §2.56 「기본 행성 변경」.
*
* 가입한 팬덤만 대표가 될 수 있다. 변경은 무료이고, 재변경은 `primaryChangedAt + 30일`
* (운영값 `primaryCooldownDays`) 이 지나야 한다. 과거 기여 · Passport 는 건드리지 않는다.
@@ -369,11 +369,11 @@ export const fnPrimaryFandomSet = onCall(async (req) => {
});
/**
* `fn-planet-create` — 성운(Stage0) → 정식 행성(Stage1) 탄생. 원장 B-09 · B-10 · C-50.
* `fn-planet-create` — 성운(Stage0) → 정식 행성(Stage1) 탄생. 정책 원장 B-09 · B-10 · C-50.
*
* 형태(`planetType`)와 컬러(`colorKey`) 두 가지만 이때 한 번 고른다. 행성 문서 ID 는
* 팬덤 안에서 고정(`planet`)이라 팬덤당 1건이 문서 ID 충돌로 원자적으로 지켜진다
* (Firestore 설계서 §2.4 정정). 렌더링이 팬덤 문서 하나로 끝나도록 두 값을 팬덤 문서에도
* (Firestore 설계서 §2.4). 렌더링이 팬덤 문서 하나로 끝나도록 두 값을 팬덤 문서에도
* 싣는다. 생성 후 두 값을 바꾸는 경로는 없다(보안 규칙이 클라이언트 쓰기를 전부 닫음).
*
* 전환 조건(인원 · POP)은 **트랜잭션 안에서 읽은** 팬덤 문서로 판정한다 — 가입 · 탈퇴와
@@ -505,7 +505,7 @@ export async function hasLocationConsent(uid: string): Promise<boolean> {
export const SIGNUP_REQUIRED_TERMS = ['service', 'privacy', 'age'] as const;
/**
* `fn-signup-consent` — 가입 약관 동의를 한 번에 기록한다(FR-CMN-04 · 원장 C-134).
* `fn-signup-consent` — 가입 약관 동의를 한 번에 기록한다(FR-CMN-04 · 정책 원장 C-134).
*
* 항목마다 `consents` 에 append-only 행을 남기고(약관 버전 포함), 사용자 문서에 `termsAgreedAt` 을
* 찍는다. 앱은 이 값이 없으면 로그인 직후 온보딩(약관부터)으로 보낸다 — 「로그인」 버튼으로 처음