이 글은 Today I Learn 시리즈의 97번째 기록입니다. (총 125개)

앞날의 일을 미리 당겨 할 수 있게 만들고 첫 피드백 셋을 반영했다. 이어서 마감을 붙이고, 지운 것이 되살아나던 문제와 자정을 넘기면 날이 갈라지던 문제를 잡았다.


당겨서 한 일이 그날이 오자 미완료로 다시 떴다

앞날의 일을 당겨 하면 원래 날에서 빼야 한다. 처음엔 「아직 오지 않은 날에서 옮긴 것은 뺀다」로 갈랐다.

금요일 일을 목요일로 당긴 상황을 따라가 보니, 목요일에는 잘 뜬다. 그런데 금요일이 실제로 오면 그 날은 더 이상 「아직 오지 않은 날」이 아니다. 조건이 반대로 걸리면서, 목요일에 이미 한 일이 금요일에 미완료로 다시 뜬다.

코드는 한 줄도 안 바뀌었는데 판정이 바뀌었다. 조건이 오늘 날짜를 보고 있었기 때문이다.

같은 구분을 방향으로 다시 썼다. 「오늘보다 뒤인 날에서 옮겼나」가 아니라 「간 날짜가 원래 날보다 앞인가」를 본다. 앞으로 갔으면 당긴 것이니 원래 날에서 빼고, 뒤로 갔으면 민 것이니 남긴다.

비교하는 두 값이 모두 저장된 날짜라 시간이 지나도 안 변한다. 오늘이 언제든 같은 답이 나온다.

  • 조건에 「지금」이 들어가면 그 코드는 만들 때 맞고 나중에 틀린다. 고친 사람이 없는데 답이 달라진다
  • 지금이 꼭 필요한 게 아니라면 저장된 것끼리 비교하는 길이 있는지 먼저 본다
  • 이런 버그는 테스트로도 잘 안 잡힌다. 테스트를 쓰는 날에는 통과하기 때문이다

앞으로 당긴 것과 뒤로 민 것은 남길 것이 다르다

같은 「옮기기」인데 방향에 따라 원래 날에 남길 것이 달랐다.

  • 뒤로 민 것 — 남긴다. 오늘 못 했다는 사실이 사라지면 안 된다
  • 앞으로 당긴 것 — 뺀다. 그날이 오기 전에 이미 한 일이라 미완료로 뜨면 거짓말이 된다

데이터 구조는 하나로 충분했다(어디서 어디로). 화면에 보여줄 때만 갈라야 했다. 저장 구조가 같으면 같은 것이라고 여기기 쉬운데, 그건 저장하는 쪽 사정일 뿐이다.


두 자국이 겹친 날 무엇을 먼저 볼까

옮기기는 두 날에 자국을 남긴다. 옮긴 날에 「어디로 보냈다」, 받는 날에 「어디서 왔다」.

목요일로 당겨 놓고 목요일에도 못 하면 이월이 그 일을 금요일로 되돌려 보낸다. 그러면 금요일 하나가 두 자국을 동시에 들고 있게 된다 — 「목요일로 보냈다」와 「어딘가에서 왔다」.

배치를 짜는 코드가 위에서부터 조건을 보므로, 먼저 보는 쪽이 이긴다. 보냈다는 자국을 먼저 보면 그 일이 화면에서 통째로 사라진다.

  • 조건을 위에서부터 보는 코드는 순서 자체가 규칙이다. 처음 쓸 때는 하나씩 떠올리며 쓰니 겹칠 일을 생각 안 하는데, 나중에 겹치는 경우가 오면 순서가 답을 정해 버린다
  • 무엇을 앞에 둘지는 「어느 것이 더 나중 이야기인가」로 정했다. 기기 합치기에서는 시각을 찍어 같은 판단을 했다. 표현이 다를 뿐 규칙은 같다
  • 한 사실을 두 곳에 적기로 했으면 「둘이 동시에 있을 때 무엇이 맞나」를 처음부터 정해 두는 게 낫다. 나중에 만나면 이미 만들어 둔 코드 사이에서 찾아야 한다

기록실에서 앞날 업무를 옮겼는데 화면이 안 바뀌었다

저장은 됐는데 화면만 그대로였다.

기록실은 그 달 기록을 한 번 읽어 들고 있고, 다시 읽는 조건이 「달이 바뀌거나, 읽는 함수가 바뀌거나, 오늘 기록이 바뀌면」이었다. 앞날 기록을 고친 건 셋 중 아무것도 아니었다.

  • 다시 그릴 조건을 정해 놓는 건 성능 설정처럼 보이지만, 실은 「이것 말고는 안 본다」는 선언이다
  • 저장소를 고칠 길을 새로 냈으면 보는 것도 같이 넓혀야 한다. 길을 낸 쪽만 보고 읽는 쪽을 안 보면 이런 게 남는다
  • 빠뜨리면 낡은 화면이 남고, 필요 없는 걸 넣으면 쓸데없이 다시 한다. 뒤엣것은 느려질 뿐 틀리지는 않으므로 확신이 없으면 넣는 쪽으로 기운다

창고와 기록실이 스크롤을 다르게 다루고 있었다

「기록실에서 업무가 많으면 마지막 줄이 화면 아래에 딱 붙어 끝나서 더 없는 줄 안다」는 피드백을 받았다.

화면 이야기로 들렸는데 원인은 그 화면이 스크롤을 다루는 방식이었다. 창고는 패널 안에 스크롤 상자가 따로 있어 패널의 아래 여백이 밖에 남고, 기록실은 패널 자체가 스크롤 상자라 그 여백이 끝에 안 나타난다.

화면만 보면 둘은 같은 종류다. 목록이 있고 스크롤된다. 만들어진 방식이 달랐을 뿐이다.

  • 같은 일을 하는 곳이 두 방식으로 만들어져 있으면, 한쪽에서만 나는 문제가 반드시 생긴다. 그리고 그 문제는 화면을 봐서는 원인이 안 보인다
  • 쓰는 사람은 자기가 본 것을 말한다. 그 말을 그대로 고치려 들면 그 자리만 덧대게 된다. 「왜 여기서만 이런가」를 물으면 대개 다르게 만든 지점이 나온다
  • 여백을 상자의 성질에 맡기지 않고 내용 안에 넣으니, 같은 구조를 쓰는 다른 두 화면도 한 번에 고쳐졌다

지운 업무가 잠시 뒤 되살아난다는 말을 들었다

창고에서 업무를 지웠는데 잠시 뒤 다시 나타난다는 말을 들었다.

지우기는 배열에서 빼는 일이고, 두 기기를 합치는 규칙은 양쪽 id의 합집합이다. 지우면 이쪽 배열에서 빠지고, 3초 뒤 자동으로 합칠 때 드라이브에 남아 있는 쪽이 이겨서 되살아난다. 그리고 그 결과가 다시 올라가 굳는다.

지움이 지는 이유는 명확하다. 합치기는 「무엇이 있나」를 비교하는데 지움은 「없다」이므로 비교에 낄 자격이 없다. 나중에 지웠든 아니든 늘 진다.

배열에서 빼는 대신 「지웠다」는 시각을 찍었다. 그러면 그건 다른 값과 다를 게 없어서, 이미 있는 「나중에 고친 것이 이긴다」 규칙에 그대로 태워진다.

  • 값이 있어야 규칙에 태워진다. 표현하고 싶은 것이 「없음」이면 먼저 그걸 값으로 바꿔야 한다
  • 새 규칙을 만들지 않고 기존 규칙에 태울 수 있으면 그쪽이 늘 낫다

「피해가 작다」고 적어 둔 근거를 다시 쟀다

이건 동기화를 만들 때 이미 알고 넘어간 한계였다. 문서에 이렇게 적어 뒀었다.

지움은 표현하지 못한다. 다만 이력이 있는 업무는 완전 삭제가 아니라 보관이라 정상적으로 합쳐지고, 되살아나는 건 한 번도 안 쓴 것뿐이라 피해가 작다.

논리는 맞았다. 틀린 건 「한 번도 안 쓴 것뿐」의 무게였다. 한 번도 안 쓴 업무가 바로 제일 자주 지우는 것이다 — 만들어 보고 아니다 싶어 지우는 게 그거니까.

  • 한계를 알고 넘어갈 때 「어떤 경우에 문제가 되나」까지는 대개 맞힌다. 놓치는 건 「그 경우가 얼마나 자주 오나」다
  • 빈도는 만들 때가 아니라 써 봐야 안다. 그래서 「피해가 작다」로 넘긴 것은 사람 손에 들어간 뒤에 다시 재야 한다

지운 것을 배열에 남기는 게 비용이 아니었다

지운 것을 배열에 남겨 두는 게 어쩔 수 없이 치르는 값처럼 보였는데, 따져 보니 원래 그래야 했다.

하루 기록은 업무 제목을 복사하지 않고 가리키기만 한다. 그래야 이름을 고쳐도 지난 기록이 따라온다. 그런데 업무를 배열에서 빼 버리면 옛 기록이 가리킬 곳을 잃어 제목이 빈칸이 된다.

  • 고치고 나서 「이건 비용인가 원래 필요한 것인가」를 한 번 되물으면, 억지로 참고 있던 게 아니었다는 걸 알게 되는 경우가 있다
  • 대신 보이는 목록과 저장된 목록이 갈라진다. 어디서 거를지는 자리마다 다르다 — 배치와 창고 목록은 걸러야 하고, 지난 기록의 제목 찾기는 전체를 봐야 한다. 「전부 거르기」도 「아무 데서도 안 거르기」도 답이 아니었다

반복과 마감을 시켰더니 종류가 둘로 나뉘어 돌아왔다

반복 일정과 마감을 만들라고 했다. 돌아온 것은 일정 종류가 둘로 늘어난 모양이었다 — 「반복」 옆에 「마감까지」가 하나 더 생겼다. 나눈 근거도 분명해 보였다. 반복은 완료해도 다음 회차에 또 뜨고, 마감은 하면 끝난다.

화면에서 둘을 나란히 보다가 되물었다. 이걸 일 단위 반복으로 해 두고 언제까지를 지정하면 되는 거 아니냐고. 그게 맞았고, 종류 하나가 옵션 하나로 줄었다.

이 일로 확인 절차가 하나 생겼다. 하나로 시킨 것이 둘로 나뉘어 돌아오면 나눈 근거를 묻는다. 물을 질문은 이 둘이다.

  • 기존 것으로 표현할 수 있나 — 표현되면 특수한 경우다
  • 표현하고 나서 남는 차이가 몇 개인가 — 하나면 옵션, 여럿이면 개념

마감은 「N일마다 + 언제까지」로 표현되고 남는 차이가 하나였다. 옵션이 맞았다. 앞서 만든 「일회성」은 다르다 — 반복으로 표현하려면 「그날 하루만 반복」이라는 말이 안 되는 규칙이 필요하고, 남는 차이도 여럿이다.

  • 눈에 띄는 차이가 있으면 그게 구조를 가르는 선처럼 보인다. 실제로는 선이 아니라 옵션일 때가 더 많다
  • 합치면 공짜로 생기는 것이 있다. 나눠 뒀을 때 마감은 매일로 고정이었는데, 합치니 「9월 1일까지, 3일마다 상기」가 그냥 됐다. 만들려고 한 게 아니라 구조가 그래서 따라온 것이다
  • 합치면서 잃는 것은 대개 「찾는 문제」다. 「마감까지」라는 이름이 사라지면 처음 쓰는 사람이 못 찾는다. 그건 구조를 되돌릴 이유가 아니라 입구를 하나 두면 되는 일이다

안에서 만들면 나뉘어 보이고 밖에서 보면 한 덩어리다

나뉜 게 이상한 일은 아니었다. 마감을 붙이려고 시작하면 마감이 중심에 오고 반복은 옆에 있는 다른 것이 된다. 만드는 동안에는 그 순서가 그대로 구조가 된다.

화면에서 둘을 나란히 놓고 보면 다르다. 둘 다 「언제 뜨는가」를 정하는 칸이고, 쓰는 사람이 고를 때는 그게 한 덩어리다.

  • 만드는 순서와 쓰는 순서가 다르면 구조는 만드는 순서를 따라가기 쉽다. 밖에서 한 번 보는 것이 그걸 잡는다
  • 그래서 화면이 나온 다음에 물어보는 게 값이 싸다. 설계만 보고 있을 때는 나도 만드는 순서로 보게 된다

문서에서 「마감은 일정 종류다」를 지우지 않고 취소선을 그어 왜 되돌렸는지 적었다. 두 번째로 이렇게 해 보니 값어치가 더 보인다 — 지워 버리면 다음에 같은 자리에서 「마감을 종류로 만들까?」가 또 떠오르는데, 한 번 가 보고 아니었다는 게 적혀 있으면 그 자리에서 멈춘다.


반복 주기 프리셋을 없애고 숫자와 단위로 바꿨다

반복 주기를 「매주·격주·매월·3개월마다·매년·직접 정하기」로 고르게 해 뒀었다. 자주 쓰는 것을 앞에 두면 편할 거라고 봤다.

그런데 목록에 없는 것(2일마다, 5주마다)을 만들려면 「직접 정하기」로 한 번 더 들어가야 한다. 이름표가 편한 길이 아니라 갈림길을 만든 셈이었다.

숫자 칸과 단위 고르개 둘로 바꾸니 갈림길이 사라졌다.

[ 1 ] [일마다 ▾]     ← 「매일」
[ 2 ] [주마다 ▾]     ← 「격주」
[ 3 ] [개월마다 ▾]   ← 「분기」

이름표로 부르던 것이 전부 이 조합 안에 있고, 목록에 없던 「2일마다」·「5주마다」도 같은 자리에서 그냥 만들어진다.

  • 이름은 사람이 붙이는 것이지 목록에 있어야 하는 게 아니다. 「격주」는 「2 + 주마다」의 별명일 뿐이다
  • 프리셋은 목록에 있는 것만 만들 수 있게 만든다. 편의로 넣었는데 못 하는 게 생기면 그건 편의가 아니다

이걸 없애니 전날 고친 버그가 원인째 사라졌다. 그 버그는 지금 무엇이 켜져 있는지를 값에서 거꾸로 계산하다 사용자의 선택이 덮이던 것이었는데, 이름표가 없으면 되짚을 것도 없다.

  • 되짚어야 하는 상황 자체를 안 만들 수 있으면 그게 고치는 것보다 낫다
  • 버그를 고치고 나서 「이 버그가 날 수 있었던 이유」를 한 겹 더 보면 가끔 이런 게 나온다

마감에 딸린 옵션 셋을 하나로 묶었다

마감에는 정할 것이 셋이었다. 완료하면 그다음 날부터 안 뜬다, 종료일이 지나도 계속 뜬다, 뱃지가 주기 대신 남은 날이 된다.

셋을 따로 물으면 화면이 지저분해지고 말이 안 되는 조합도 생긴다. 그런데 셋이 사실은 하나의 뜻이었다 — 「이 종료일을 마감으로 다룬다」.

  • 옵션이 여럿 나오면 먼저 세지 말고 묶이는지를 본다. 묶이면 물을 것이 하나가 된다
  • 화면에서는 「이때까지 못 하면 경고 표시」라고 묻고 데이터에는 「마감으로 다룬다」로 적었다. 쓰는 사람에게는 눈에 보이는 결과가 또렷하고 코드에는 무슨 뜻인지가 중요하다. 둘을 억지로 같게 만들면 한쪽이 어색해진다
  • 이름 하나로 다 담을 수 없으면 이름을 늘리는 것보다 주석이 낫다

「완료하면 끝」을 항상 켤 수 없었던 반례

「완료하면 그다음 날부터 안 뜬다」는 물어볼 것도 없이 당연하니 옵션으로 두지 말라고 했다. 마감이 있는 일은 하면 끝나는 게 맞으니까.

그런데 반례가 하나 나왔다. 「매주 월요일 회의, 12월까지」는 종료일이 있지만 첫 월요일에 끝나면 안 된다.

  • 종료일이 있다고 다 마감은 아니었다. 「당연하다」고 말한 쪽이 나였는데 반례 하나에 뒤집혔다
  • 반례가 하나라도 있으면 그건 기본값이 아니라 선택이어야 한다. 「대개 그렇다」와 「늘 그렇다」는 다르고, 옵션을 없앨 수 있는 건 뒤쪽뿐이다

자정을 넘겨 찍은 도장이 어제 기록에 들어갔다

자정이 지나 도장을 찍었더니 자정 전에 있던 업무들이 사라지고, 도장은 어제 기록에 들어갔다.

보드에 세우는 업무 목록은 그릴 때마다 오늘 날짜를 다시 계산했고, 하루 기록은 화면을 열 때 한 번 읽은 것을 들고 있었다. 이 둘이 같은 날을 가리킨다는 보장이 어디에도 없었다. 자정 전에는 우연히 같았고, 자정을 넘기는 순간 갈라졌다.

  • 「지금」에서 나오는 값을 그릴 때마다 계산하면 시간이 지나며 조용히 바뀐다. 그 값에 기대는 다른 것이 같이 안 바뀌면 어긋난다
  • 날짜를 상태로 두면 언제 바뀌는지를 우리가 정하게 된다. 그러면 「날이 바뀔 때 같이 돌아야 하는 것」을 찾아 이을 자리가 생긴다
  • 앞서 「다시 그릴 조건에 없는 변화는 못 본다」를 배웠는데, 이건 반대쪽이었다. 새 신호를 만들었으면 그 신호를 봐야 할 것들을 찾아 이어야 한다

자정 타이머 대신 30초마다 확인하기로 한 이유

자정까지 남은 시간을 재서 한 번만 울리게 할 수도 있었다. 더 정확하고 덜 도는데, 컴퓨터가 자면 그 시각이 그냥 지나가고 깨어나서도 다음 자정까지 안 울린다.

일정 간격으로 확인하는 쪽은 자고 일어나도 다음 확인 때 따라잡는다. 정확하지 않은 대신 놓치지 않는다.

한 번만 울리는 것과 계속 확인하는 것 중에 고를 때, 정확도보다 놓쳤을 때 어떻게 되는지를 먼저 본다.

어제 셔터를 대신 내려 주지 않기로 했다

날이 바뀔 때 어제 셔터를 대신 내려 줄 수도 있었다. 안 했다.

하루를 매듭짓는 건 사람이 하는 일이다. 셔터를 내리면 그날 요약이 뜨는데, 자는 사이에 앱이 대신 닫으면 그걸 못 본다. 기록은 맞아도 하려던 것을 못 하게 된다.

대신 해 주려는 동작에 사람이 볼 것이 붙어 있으면, 대신 해 주는 게 뺏는 것이 된다.


업무 이름을 비웠더니 누를 것이 사라졌다

일회성 업무 이름을 눌러서 고치게 해 뒀다. 이름을 잠깐 빈칸으로 뒀더니 그 뒤로 손댈 수가 없었다.

누르는 것이 이름이 적힌 버튼이고, 버튼의 내용이 이름 그 자체다. 이름이 비면 버튼에 글자가 없어 폭이 0이 된다. 누를 것이 사라진 것이다.

  • 값이 곧 조작 대상이면, 값이 빌 수 있는지 반드시 따져야 한다
  • 고치는 동안에는 초안으로 들고 있다가 떠날 때 정리한다. 같은 방식이 숫자 칸에서도 나왔으니 규칙으로 굳힐 때가 됐다 — 화면에서 고치는 값은 다 이렇게 다룬다

막는 것과 되살리는 것은 따로 필요하다

앞으로 안 생기게 막는 것만으로는 이미 빈 이름으로 저장된 업무가 안 고쳐진다. 빈 이름일 때 대신 보여줄 글자를 두고서야 누를 것이 생겼다.

같은 얘기가 지움 문제에서도 나왔다. 지움을 고쳤어도 이미 되살아나 드라이브에 굳은 것들은 그대로다. 코드가 고쳐졌을 뿐 데이터는 그전 규칙으로 쓰인 것이라 한 번 더 지워야 한다.

  • 버그를 고칠 때는 두 가지를 나눠 본다. 앞으로 안 나게 하는 것과, 이미 난 것을 되돌리는 것
  • 고쳤다고 알릴 때 뒤엣것을 같이 말해야 한다. 안 그러면 「고쳤다는데 왜 그대로냐」가 된다

그밖에 정한 것들

  • 무언가를 화면에서 빼면 그 자리에 뭐가 있었는지 본다. 상시 업무를 옮기기 대상에서 뺐더니 그 자리에 원래 있던 「미완료」 글자가 드러났다. 뺀 것뿐 아니라 그 자리에 남는 것까지가 변경이다
  • 답하기 어려운 질문이 여럿 나오면, 질문을 잘 답하는 것보다 질문이 안 생기게 만드는 쪽을 먼저 본다. 업무 순서를 두 벌 두려다 「지난 기록은 그때 순서로 보이나」까지 딸려 나와서, 한 벌만 두는 것으로 통째로 없앴다
  • 요청 한 줄에 결정이 넷 딸려 오는 일이 있다. 정하지 않고 만들면 넷을 코드로 아무렇게나 정해 버리고, 나중에 왜 그렇게 됐는지 아무도 모른다
  • 그래서 미룰 때는 무엇을 정해야 하는지와 함께 가장 작게 시작하는 길을 같이 적는다. 구상만 적어 두면 다음에 열었을 때 「정할 게 넷이네」에서 또 멈춘다

Series: Today I Learn

1 C++ 자료형(Data Type) 2 MD5 vs pHash 3 C++에서 함수의 선언과 정의 4 Tkinter padx, pady 5 메모리와 포인터 변수 6 Call by Value, Call by Reference, Call by Pointer 비교 7 const 8 Gemfile — Jekyll 프로젝트의 의존성 파일 9 kramdown-parser-gfm — Jekyll의 GFM 파서 10 파서(Parser) 11 AHU vs OHU 12 I might try it vs I'll try it 뉘앙스 차이 13 SESSION_EXPIRE_AT_BROWSER_CLOSE=True 14 configuration key 15 Git stash vs discard 16 subprocess.Popen으로 Windows 탐색기에 명령어를 전달 17 Post 잔디 분석하기 18 Google Sheets Sync 최적화 19 DSL (Domain Specific Language)과 GPL (General Purpose Language) 20 마크다운 표 그리는 방법 21 쿼리 파라미터(Query Parameter). 기존 QR코드 재활용 22 Django 보안 취약점 점검 및 수정 23 OOP Object-Oriented Programming 객체 지향 프로그래밍 24 Fernet 대칭 암호화 25 Jekyll 코드블록 안의 Liquid 태그 26 insertOnConflictUpdate vs DoUpdate(target) 27 세션 필터 28 아코디언(Accordiaon) UI를 펼친상태로 만들기 29 input의 step 30 Word Cloud 31 Google Sheets를 데이터 버스로(with AppSheet) 32 Django 모델 텍스트 필드 자동 수집 패턴 33 localStorage로 섹션 토글 상태 유지 34 순차 ID 생성(`select_for_update()` + `max()` 조합) 35 역참조 검색과 distinct() 36 xlsx 다운로드와 로딩 오버레이 충돌 37 Android 파일 공유 MIME 타입 38 AssetManifest — Flutter 빌드 타임 asset 목록 런타임 조회 39 UTF-8 BOM과 PowerShell 파일 쓰기 40 소리꽃 KeyBloom TIL 1 41 소리꽃 KeyBloom TIL 2 42 소리꽃 KeyBloom TIL 3 43 메트로놈 Simple Metronome TIL 1 44 소리꽃 KeyBloom TIL 4 45 메트로놈 Simple Metronome TIL 2 46 소리꽃 KeyBloom TIL 5 47 메트로놈 Simple Metronome TIL 3 48 정적 블로그 SEO 정비와 Pagefind 검색 도입 49 메트로놈 Simple Metronome TIL 4 50 안드로이드 AudioTrack 연속 재생, 실측 피커 정렬, 카메라 토치 플래시 51 메트로놈 Simple Metronome TIL 5 52 모래게임 Sandrop TIL 1 53 메트로놈 Simple Metronome TIL 6 54 모래게임 Sandrop TIL 2 55 모래게임 Sandrop TIL 3 56 메트로놈 Simple Metronome TIL 7 57 모래게임 Sandrop TIL 4 58 모래게임 Sandrop TIL 5 59 모래게임 Sandrop TIL 6 60 소리꽃 KeyBloom TIL 6 61 모래게임 Sandrop TIL 7 62 모래게임 Sandrop TIL 8 63 소리꽃 KeyBloom TIL 7 64 모래게임 Sandrop TIL 9 65 소리꽃 KeyBloom TIL 8 66 모래게임 Sandrop TIL 10 67 소리꽃 KeyBloom TIL 9 68 소리꽃 KeyBloom TIL 10 69 소리꽃 KeyBloom TIL 11 70 소리꽃 KeyBloom TIL 12 71 소리꽃 KeyBloom TIL 13 72 온실 GreenHouse TIL 1 73 소리꽃 KeyBloom TIL 14 74 온실 GreenHouse TIL 2 75 소리꽃 KeyBloom TIL 15 76 소리꽃 KeyBloom TIL 16 77 소리꽃 KeyBloom TIL 17 78 소리꽃 KeyBloom TIL 18 79 소리꽃 KeyBloom TIL 19 80 소리꽃 KeyBloom TIL 20 81 로그스톤 상표 셀프 출원 TIL 1 82 소리꽃 KeyBloom TIL 21 83 소리꽃 KeyBloom TIL 22 84 소리꽃 KeyBloom TIL 23 85 소리꽃 KeyBloom TIL 24 86 MiniMacro TIL 1 87 Astro가 무엇인지, 왜 옮기는지 88 MiniMacro TIL 2 89 메트로놈 Simple Metronome TIL 8 90 메트로놈 Simple Metronome TIL 9 91 블로그 Astro 이관 TIL 92 오픈데이 Openday TIL 1 93 오픈데이 Openday TIL 2 94 Unreal Engine MCP TIL 1 95 콘티온 Conti On TIL 11 96 오픈데이 Openday TIL 3 97 오픈데이 Openday TIL 4 읽는 중 98 오픈데이 Openday TIL 5 99 ScorePlayer TIL 1 100 BuildingHub TIL 1 101 ScorePlayer TIL 2 102 BuildingHub TIL 2 103 ScorePlayer TIL 3 104 Unreal Engine MCP TIL 2 105 궁 미로 PalaceMaze TIL 1 106 메트로놈 Simple Metronome TIL 10 107 메트로놈 Simple Metronome TIL 11 108 오픈데이 Openday TIL 6 109 BuildingHub TIL 3 110 Obsidian vault에서 코드만 빼기 — directory junction 111 ScorePlayer TIL 4 112 오픈데이 Openday TIL 7 113 URL은 바뀔 수 있는 것에 묶지 않는다 114 도구는 기능이 아니라 내 일에 맞는지로 고른다 115 돌이키기 힘든 변경은 작게 먼저 확인한다 116 궁 미로 PalaceMaze TIL 3 117 궁 미로 PalaceMaze TIL 2 118 소리꽃 KeyBloom TIL 29 119 오픈데이 Openday TIL 8 120 BuildingHub TIL 4 121 ScorePlayer TIL 5 122 BuildingHub TIL 5 123 MiniMacro TIL 3 124 소리꽃 KeyBloom TIL 30 125 궁 미로 PalaceMaze TIL 4