사람함께에이전트▾
사람 — 직접 정하고 책임지는 비즈니스 규칙과 흐름. 직접 읽어보세요.
함께 — 개념은 알아두고, 세부 규칙은 에이전트가 따릅니다.
에이전트 — 에이전트가 따르는 규칙과 레퍼런스. 필요할 때 찾아보세요.
앱 & 라이브러리▾
도메인▾
스칼라▾
scalar.abstract.md
scalar마다
lib/__scalar/<scalar>/<scalar>.abstract.md 파일이 하나 있습니다. scalar는 대개 모델의 field처럼 다른 무언가가 들고 있는 값이라서, 이 파일은 값이 무엇인지보다 그 값에 대해 무엇을 가정해도 되는지를 몇 줄의 markdown으로 답합니다.무엇을 가정해도 되는가
libs/util의 coordinate를 보면, constant 파일과 abstract가 같은 배열에 대해 서로 다른 것을 말합니다.constant 파일이 보여 주는 것
coordinates는 실수 두 개를 담는 배열입니다.coordinates: field([Float], { default: [0, 0] })abstract만 말하는 것
longitude가 먼저입니다. 거의 모든 사람이 위치를 입으로 말하는 순서와 반대입니다.
[127.114367, 37.497114] → [longitude, latitude]세 부분
scalar abstract는 세 부분으로 되어 있고, 넷째 부분은 없습니다:
apps/koyo/lib/__scalar/price/price.abstract.md
부분설명
# <scalar> Abstract
폴더 이름에 쓴 그대로의 scalar 이름을 담은 제목 한 줄입니다.
한 문장
이 값이 무엇을 나타내는지, 그리고 중요하다면 누가 들고 있는지를 소제목 없이 적습니다.
## Rules
두 개에서 다섯 개의 항목입니다. 고정된 값, field 순서, 단위, 유효 기간, static이 계산하는 것을 적습니다.
- workflow 절은 없습니다. Akan.js 저장소의 scalar abstract 17개가 모두 이 세 부분으로 되어 있고, workflow를 가진 것은 하나도 없습니다. 선택 항목으로
## Workflow를 두는model.abstract.md와 다른 점입니다. - 값에는 자기만의 수명 주기가 없습니다. 다른 것 안에 담기는 값이라, 따로 설명할 흐름이 없습니다.
- 상태 변화가 있어도 규칙 한 줄이면 됩니다.
oauthRequest처럼 보관되는 값이 상태를 오가더라도 절을 따로 만들지 않고,## Rules항목 하나에pending -> approved | denied이며 되돌아가지 않는다고 적습니다.
Rules 쓰기
Rules에는 적혀 있지 않으면 호출자가 틀리게 될 것만 적습니다. 실제 abstract 하나를 보면 어떤 모습인지 알 수 있습니다.
실제 예시
coordinate.abstract.md의 전문입니다. static helper가 열네 개인 class이지만 abstract는 여덟 줄입니다:libs/util/lib/__scalar/coordinate/coordinate.abstract.md
항목은 넷이고, 모두 적혀 있지 않으면 호출자가 틀리게 될 것들입니다:
| 규칙이 말하는 것 |
|---|
| ↳ 없으면 호출자가 하는 착각 |
type은 항상 Point입니다. |
type이 열려 있어 다른 GeoJSON 모양도 담을 수 있다고 여깁니다. |
coordinates는 longitude, latitude 순서입니다. |
| 입으로 말하는 순서대로 latitude가 먼저라고 여깁니다. |
| 거리는 구면 거리이고, 3D 계산은 altitude 차이를 함께 반영합니다. |
| 평면 거리이거나, altitude를 무시한 거리라고 여깁니다. |
| bounds, center, zoom 계산에는 좌표 목록이 있어야 합니다. |
빈 목록도 된다고 여기지만, computeCenterAndZoomFromLocations는 null을 돌려줍니다. |
- 선언이 이미 하는 말은 없습니다. field나 type을 나열하는 항목은 하나도 없고, 모두
coordinate.constant.ts가 말하지 못하는 것만 적습니다. - 파일 하나에 언어 하나. 이 저장소에는 한국어와 영어 abstract가 함께 있지만(
oauth*scalar는 영어입니다), 한 파일 안에서 언어를 바꾸지는 않습니다.
항목이 될 자격
이 저장소의 scalar에서 가져온 예시를 Rules에 적을지 여부로 나눴습니다:
내용
적는다
적지 않는다
타입이 담지 못하는 것
단위
✓
미터가 아니라 킬로미터 같은 것입니다.
getDistanceKm과 getDistanceM은 단위만 다릅니다.순서
✓
coordinate에서 latitude보다 앞서는 longitude 같은 것입니다.위치로 맞물리는 배열
✓
fileMeta 하나하나는 같은 순서에 있는 업로드 파일과 짝을 이룹니다.유효 기간이나 소비 규칙
✓
보관되는 값일 때 적습니다.
oauthGrant는 60초를 살고, 첫 교환에서 성공 여부와 관계없이 소비됩니다.static이 계산하는 것
✓
평면 거리처럼 호출자가 다른 것을 기대할 만할 때만 적습니다.
코드가 이미 말하는 것
field 목록
✓
constant 파일이 이미 모든 field를 나열합니다.
type
✓
field(...) 선언마다 type이 이미 적혀 있습니다.재사용 가능하다는 말
✓
모든 scalar가 재사용 가능하므로, 적어도 알려 주는 것이 없습니다.
✓이렇게 합니다하지 않습니다
스캐폴드 채우기
akan create-scalar는 첫 abstract를 대신 만들어 줍니다. 이 초안을 스캐폴드라고 부르며, 제목, 자리표시 문장 하나, 자리표시 규칙 두 개로 이미 정해진 모양을 갖췄습니다. 꺾쇠괄호로 된 줄은 모두 질문이라서, 처음 제대로 고칠 때 하나도 남지 않습니다.akan create-scalar price가 만드는 파일입니다:apps/koyo/lib/__scalar/price/price.abstract.md
줄마다 바뀌는 모습:
| 스캐폴드 |
|---|
| ↳ 바뀌는 모습 |
| # price Abstract |
| 폴더 이름으로 미리 적혀 있습니다. 그대로 둡니다. |
| <One sentence …> |
| 이 scalar가 담는 값과 그 값을 담는 곳을 사실로 적은 문장으로 바꿉니다. |
| ## Rules |
| 그대로 둡니다. 자리표시 항목 두 개를 호출자가 값에 대해 가정해도 되는 것 2~5개로 바꿉니다. |
| field의 의미 |
여기가 아니라 price.constant.ts에서 해당 field 옆의 꼬리 주석으로 씁니다. |
| workflow |
| 없습니다. 다른 것 안에 담기는 값에는 따로 설명할 수명 주기가 없습니다. |
- field의 의미는 field 옆에 둡니다. 그 field를 다음에 읽는 사람이 보는 곳이 꼬리 주석이기 때문입니다.
oauthGrant.constant.ts가 이렇게 씁니다:codeHash: field(String), // sha256 of the code; the code itself travels once, in the redirect
최신으로 유지하기
scalar를 고치기 전에 먼저 읽고, 갱신은 호출자가 기대는 것이 바뀔 때만 합니다:
변경
갱신
그대로
호출자가 기대는 것이 바뀔 때
검증 의미
✓
leaveInfo의 만족도가 1부터 5까지인 것처럼, 어떤 값이 유효한지입니다.공개 동작
✓
static이 무엇을 돌려주는지처럼, 쓰는 쪽에서 관찰할 수 있는 동작입니다.
재사용 규칙
✓
accessLog가 위치를 coordinate로 담는 것처럼, 다른 scalar와 어떻게 함께 쓰는지입니다.코드 모양만 바뀔 때
포맷팅
✓
포매터가 정하는 공백과 줄바꿈입니다.
import
✓
import를 추가하거나 지우거나 정렬하는 일입니다.
스타일
✓
동작을 바꾸지 않는 코드 스타일 변경입니다.
✓이렇게 합니다하지 않습니다