-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path걷는 생각들 4771be484d4945d8bdafd02fcde418ab.html
719 lines (632 loc) · 30.4 KB
/
걷는 생각들 4771be484d4945d8bdafd02fcde418ab.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>걷는 생각들</title><style>
/* cspell:disable-file */
/* webkit printing magic: print all background colors */
html {
-webkit-print-color-adjust: exact;
}
* {
box-sizing: border-box;
-webkit-print-color-adjust: exact;
}
html,
body {
margin: 0;
padding: 0;
}
@media only screen {
body {
margin: 2em auto;
max-width: 900px;
color: rgb(55, 53, 47);
}
}
body {
line-height: 1.5;
white-space: pre-wrap;
}
a,
a.visited {
color: inherit;
text-decoration: underline;
}
.pdf-relative-link-path {
font-size: 80%;
color: #444;
}
h1,
h2,
h3 {
letter-spacing: -0.01em;
line-height: 1.2;
font-weight: 600;
margin-bottom: 0;
}
.page-title {
font-size: 2.5rem;
font-weight: 700;
margin-top: 0;
margin-bottom: 0.75em;
}
h1 {
font-size: 1.875rem;
margin-top: 1.875rem;
}
h2 {
font-size: 1.5rem;
margin-top: 1.5rem;
}
h3 {
font-size: 1.25rem;
margin-top: 1.25rem;
}
.source {
border: 1px solid #ddd;
border-radius: 3px;
padding: 1.5em;
word-break: break-all;
}
.callout {
border-radius: 3px;
padding: 1rem;
}
figure {
margin: 1.25em 0;
page-break-inside: avoid;
}
figcaption {
opacity: 0.5;
font-size: 85%;
margin-top: 0.5em;
}
mark {
background-color: transparent;
}
.indented {
padding-left: 1.5em;
}
hr {
background: transparent;
display: block;
width: 100%;
height: 1px;
visibility: visible;
border: none;
border-bottom: 1px solid rgba(55, 53, 47, 0.09);
}
img {
max-width: 100%;
}
@media only print {
img {
max-height: 100vh;
object-fit: contain;
}
}
@page {
margin: 1in;
}
.collection-content {
font-size: 0.875rem;
}
.column-list {
display: flex;
justify-content: space-between;
}
.column {
padding: 0 1em;
}
.column:first-child {
padding-left: 0;
}
.column:last-child {
padding-right: 0;
}
.table_of_contents-item {
display: block;
font-size: 0.875rem;
line-height: 1.3;
padding: 0.125rem;
}
.table_of_contents-indent-1 {
margin-left: 1.5rem;
}
.table_of_contents-indent-2 {
margin-left: 3rem;
}
.table_of_contents-indent-3 {
margin-left: 4.5rem;
}
.table_of_contents-link {
text-decoration: none;
opacity: 0.7;
border-bottom: 1px solid rgba(55, 53, 47, 0.18);
}
table,
th,
td {
border: 1px solid rgba(55, 53, 47, 0.09);
border-collapse: collapse;
}
table {
border-left: none;
border-right: none;
}
th,
td {
font-weight: normal;
padding: 0.25em 0.5em;
line-height: 1.5;
min-height: 1.5em;
text-align: left;
}
th {
color: rgba(55, 53, 47, 0.6);
}
ol,
ul {
margin: 0;
margin-block-start: 0.6em;
margin-block-end: 0.6em;
}
li > ol:first-child,
li > ul:first-child {
margin-block-start: 0.6em;
}
ul > li {
list-style: disc;
}
ul.to-do-list {
text-indent: -1.7em;
}
ul.to-do-list > li {
list-style: none;
}
.to-do-children-checked {
text-decoration: line-through;
opacity: 0.375;
}
ul.toggle > li {
list-style: none;
}
ul {
padding-inline-start: 1.7em;
}
ul > li {
padding-left: 0.1em;
}
ol {
padding-inline-start: 1.6em;
}
ol > li {
padding-left: 0.2em;
}
.mono ol {
padding-inline-start: 2em;
}
.mono ol > li {
text-indent: -0.4em;
}
.toggle {
padding-inline-start: 0em;
list-style-type: none;
}
/* Indent toggle children */
.toggle > li > details {
padding-left: 1.7em;
}
.toggle > li > details > summary {
margin-left: -1.1em;
}
.selected-value {
display: inline-block;
padding: 0 0.5em;
background: rgba(206, 205, 202, 0.5);
border-radius: 3px;
margin-right: 0.5em;
margin-top: 0.3em;
margin-bottom: 0.3em;
white-space: nowrap;
}
.collection-title {
display: inline-block;
margin-right: 1em;
}
.simple-table {
margin-top: 1em;
font-size: 0.875rem;
}
.simple-table-header {
background: rgb(247, 246, 243);
color: black;
font-weight: 500;
}
time {
opacity: 0.5;
}
.icon {
display: inline-block;
max-width: 1.2em;
max-height: 1.2em;
text-decoration: none;
vertical-align: text-bottom;
margin-right: 0.5em;
}
img.icon {
border-radius: 3px;
}
.user-icon {
width: 1.5em;
height: 1.5em;
border-radius: 100%;
margin-right: 0.5rem;
}
.user-icon-inner {
font-size: 0.8em;
}
.text-icon {
border: 1px solid #000;
text-align: center;
}
.page-cover-image {
display: block;
object-fit: cover;
width: 100%;
max-height: 30vh;
}
.page-header-icon {
font-size: 3rem;
margin-bottom: 1rem;
}
.page-header-icon-with-cover {
margin-top: -0.72em;
margin-left: 0.07em;
}
.page-header-icon img {
border-radius: 3px;
}
.link-to-page {
margin: 1em 0;
padding: 0;
border: none;
font-weight: 500;
}
p > .user {
opacity: 0.5;
}
td > .user,
td > time {
white-space: nowrap;
}
input[type="checkbox"] {
transform: scale(1.5);
margin-right: 0.6em;
vertical-align: middle;
}
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.image {
border: none;
margin: 1.5em 0;
padding: 0;
border-radius: 0;
text-align: center;
}
.code,
code {
background: rgba(135, 131, 120, 0.15);
border-radius: 3px;
padding: 0.2em 0.4em;
border-radius: 3px;
font-size: 85%;
tab-size: 2;
}
code {
color: #eb5757;
}
.code {
padding: 1.5em 1em;
}
.code-wrap {
white-space: pre-wrap;
word-break: break-all;
}
.code > code {
background: none;
padding: 0;
font-size: 100%;
color: inherit;
}
blockquote {
font-size: 1.25em;
margin: 1em 0;
padding-left: 1em;
border-left: 3px solid rgb(55, 53, 47);
}
.bookmark {
text-decoration: none;
max-height: 8em;
padding: 0;
display: flex;
width: 100%;
align-items: stretch;
}
.bookmark-title {
font-size: 0.85em;
overflow: hidden;
text-overflow: ellipsis;
height: 1.75em;
white-space: nowrap;
}
.bookmark-text {
display: flex;
flex-direction: column;
}
.bookmark-info {
flex: 4 1 180px;
padding: 12px 14px 14px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.bookmark-image {
width: 33%;
flex: 1 1 180px;
display: block;
position: relative;
object-fit: cover;
border-radius: 1px;
}
.bookmark-description {
color: rgba(55, 53, 47, 0.6);
font-size: 0.75em;
overflow: hidden;
max-height: 4.5em;
word-break: break-word;
}
.bookmark-href {
font-size: 0.75em;
margin-top: 0.25em;
}
.sans { font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; }
.code { font-family: "SFMono-Regular", Menlo, Consolas, "PT Mono", "Liberation Mono", Courier, monospace; }
.serif { font-family: Lyon-Text, Georgia, ui-serif, serif; }
.mono { font-family: iawriter-mono, Nitti, Menlo, Courier, monospace; }
.pdf .sans { font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol", 'Twemoji', 'Noto Color Emoji', 'Noto Sans CJK JP'; }
.pdf:lang(zh-CN) .sans { font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol", 'Twemoji', 'Noto Color Emoji', 'Noto Sans CJK SC'; }
.pdf:lang(zh-TW) .sans { font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol", 'Twemoji', 'Noto Color Emoji', 'Noto Sans CJK TC'; }
.pdf:lang(ko-KR) .sans { font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol", 'Twemoji', 'Noto Color Emoji', 'Noto Sans CJK KR'; }
.pdf .code { font-family: Source Code Pro, "SFMono-Regular", Menlo, Consolas, "PT Mono", "Liberation Mono", Courier, monospace, 'Twemoji', 'Noto Color Emoji', 'Noto Sans Mono CJK JP'; }
.pdf:lang(zh-CN) .code { font-family: Source Code Pro, "SFMono-Regular", Menlo, Consolas, "PT Mono", "Liberation Mono", Courier, monospace, 'Twemoji', 'Noto Color Emoji', 'Noto Sans Mono CJK SC'; }
.pdf:lang(zh-TW) .code { font-family: Source Code Pro, "SFMono-Regular", Menlo, Consolas, "PT Mono", "Liberation Mono", Courier, monospace, 'Twemoji', 'Noto Color Emoji', 'Noto Sans Mono CJK TC'; }
.pdf:lang(ko-KR) .code { font-family: Source Code Pro, "SFMono-Regular", Menlo, Consolas, "PT Mono", "Liberation Mono", Courier, monospace, 'Twemoji', 'Noto Color Emoji', 'Noto Sans Mono CJK KR'; }
.pdf .serif { font-family: PT Serif, Lyon-Text, Georgia, ui-serif, serif, 'Twemoji', 'Noto Color Emoji', 'Noto Serif CJK JP'; }
.pdf:lang(zh-CN) .serif { font-family: PT Serif, Lyon-Text, Georgia, ui-serif, serif, 'Twemoji', 'Noto Color Emoji', 'Noto Serif CJK SC'; }
.pdf:lang(zh-TW) .serif { font-family: PT Serif, Lyon-Text, Georgia, ui-serif, serif, 'Twemoji', 'Noto Color Emoji', 'Noto Serif CJK TC'; }
.pdf:lang(ko-KR) .serif { font-family: PT Serif, Lyon-Text, Georgia, ui-serif, serif, 'Twemoji', 'Noto Color Emoji', 'Noto Serif CJK KR'; }
.pdf .mono { font-family: PT Mono, iawriter-mono, Nitti, Menlo, Courier, monospace, 'Twemoji', 'Noto Color Emoji', 'Noto Sans Mono CJK JP'; }
.pdf:lang(zh-CN) .mono { font-family: PT Mono, iawriter-mono, Nitti, Menlo, Courier, monospace, 'Twemoji', 'Noto Color Emoji', 'Noto Sans Mono CJK SC'; }
.pdf:lang(zh-TW) .mono { font-family: PT Mono, iawriter-mono, Nitti, Menlo, Courier, monospace, 'Twemoji', 'Noto Color Emoji', 'Noto Sans Mono CJK TC'; }
.pdf:lang(ko-KR) .mono { font-family: PT Mono, iawriter-mono, Nitti, Menlo, Courier, monospace, 'Twemoji', 'Noto Color Emoji', 'Noto Sans Mono CJK KR'; }
.highlight-default {
color: rgba(55, 53, 47, 1);
}
.highlight-gray {
color: rgba(120, 119, 116, 1);
fill: rgba(145, 145, 142, 1);
}
.highlight-brown {
color: rgba(159, 107, 83, 1);
fill: rgba(187, 132, 108, 1);
}
.highlight-orange {
color: rgba(217, 115, 13, 1);
fill: rgba(215, 129, 58, 1);
}
.highlight-yellow {
color: rgba(203, 145, 47, 1);
fill: rgba(203, 148, 51, 1);
}
.highlight-teal {
color: rgba(68, 131, 97, 1);
fill: rgba(108, 155, 125, 1);
}
.highlight-blue {
color: rgba(51, 126, 169, 1);
fill: rgba(91, 151, 189, 1);
}
.highlight-purple {
color: rgba(144, 101, 176, 1);
fill: rgba(167, 130, 195, 1);
}
.highlight-pink {
color: rgba(193, 76, 138, 1);
fill: rgba(205, 116, 159, 1);
}
.highlight-red {
color: rgba(212, 76, 71, 1);
fill: rgba(225, 111, 100, 1);
}
.highlight-gray_background {
background: rgba(241, 241, 239, 1);
}
.highlight-brown_background {
background: rgba(244, 238, 238, 1);
}
.highlight-orange_background {
background: rgba(251, 236, 221, 1);
}
.highlight-yellow_background {
background: rgba(251, 243, 219, 1);
}
.highlight-teal_background {
background: rgba(237, 243, 236, 1);
}
.highlight-blue_background {
background: rgba(231, 243, 248, 1);
}
.highlight-purple_background {
background: rgba(244, 240, 247, 0.8);
}
.highlight-pink_background {
background: rgba(249, 238, 243, 0.8);
}
.highlight-red_background {
background: rgba(253, 235, 236, 1);
}
.block-color-default {
color: inherit;
fill: inherit;
}
.block-color-gray {
color: rgba(120, 119, 116, 1);
fill: rgba(145, 145, 142, 1);
}
.block-color-brown {
color: rgba(159, 107, 83, 1);
fill: rgba(187, 132, 108, 1);
}
.block-color-orange {
color: rgba(217, 115, 13, 1);
fill: rgba(215, 129, 58, 1);
}
.block-color-yellow {
color: rgba(203, 145, 47, 1);
fill: rgba(203, 148, 51, 1);
}
.block-color-teal {
color: rgba(68, 131, 97, 1);
fill: rgba(108, 155, 125, 1);
}
.block-color-blue {
color: rgba(51, 126, 169, 1);
fill: rgba(91, 151, 189, 1);
}
.block-color-purple {
color: rgba(144, 101, 176, 1);
fill: rgba(167, 130, 195, 1);
}
.block-color-pink {
color: rgba(193, 76, 138, 1);
fill: rgba(205, 116, 159, 1);
}
.block-color-red {
color: rgba(212, 76, 71, 1);
fill: rgba(225, 111, 100, 1);
}
.block-color-gray_background {
background: rgba(241, 241, 239, 1);
}
.block-color-brown_background {
background: rgba(244, 238, 238, 1);
}
.block-color-orange_background {
background: rgba(251, 236, 221, 1);
}
.block-color-yellow_background {
background: rgba(251, 243, 219, 1);
}
.block-color-teal_background {
background: rgba(237, 243, 236, 1);
}
.block-color-blue_background {
background: rgba(231, 243, 248, 1);
}
.block-color-purple_background {
background: rgba(244, 240, 247, 0.8);
}
.block-color-pink_background {
background: rgba(249, 238, 243, 0.8);
}
.block-color-red_background {
background: rgba(253, 235, 236, 1);
}
.select-value-color-pink { background-color: rgba(245, 224, 233, 1); }
.select-value-color-purple { background-color: rgba(232, 222, 238, 1); }
.select-value-color-green { background-color: rgba(219, 237, 219, 1); }
.select-value-color-gray { background-color: rgba(227, 226, 224, 1); }
.select-value-color-orange { background-color: rgba(250, 222, 201, 1); }
.select-value-color-brown { background-color: rgba(238, 224, 218, 1); }
.select-value-color-red { background-color: rgba(255, 226, 221, 1); }
.select-value-color-yellow { background-color: rgba(253, 236, 200, 1); }
.select-value-color-blue { background-color: rgba(211, 229, 239, 1); }
.checkbox {
display: inline-flex;
vertical-align: text-bottom;
width: 16;
height: 16;
background-size: 16px;
margin-left: 2px;
margin-right: 5px;
}
.checkbox-on {
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Crect%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22%2358A9D7%22%2F%3E%0A%3Cpath%20d%3D%22M6.71429%2012.2852L14%204.9995L12.7143%203.71436L6.71429%209.71378L3.28571%206.2831L2%207.57092L6.71429%2012.2852Z%22%20fill%3D%22white%22%2F%3E%0A%3C%2Fsvg%3E");
}
.checkbox-off {
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Crect%20x%3D%220.75%22%20y%3D%220.75%22%20width%3D%2214.5%22%20height%3D%2214.5%22%20fill%3D%22white%22%20stroke%3D%22%2336352F%22%20stroke-width%3D%221.5%22%2F%3E%0A%3C%2Fsvg%3E");
}
</style></head><body><article id="4771be48-4d49-45d8-bdaf-d02fcde418ab" class="page sans"><header><h1 class="page-title">걷는 생각들</h1></header><div class="page-body"><p id="27860517-5bc9-4450-a0ee-294c15da847a" class="">
</p><p id="28737044-0db4-470e-89a9-754075eded73" class="">
</p><p id="83c345b2-aedd-4d2a-98aa-01caf14a6f85" class="">
</p><p id="c2ca0583-08f6-475a-8d6a-ec4d30542dac" class="">
</p><h2 id="857ac5d3-4551-4b0e-b194-a18aba443246" class="">쓰임과 주요기능</h2><p id="1b80032f-182c-4faf-9eea-624bb97fd7aa" class="">
</p><ul id="c560a847-3020-4c47-9ec9-72e506a2e861" class="bulleted-list"><li style="list-style-type:disc">매일, 그날 어떤 생각들을 했는지 돌아보고 기록</li></ul><ul id="48616a6d-8ca5-4fe7-b8b0-efc00f401ea2" class="bulleted-list"><li style="list-style-type:disc">매일의 기록이 쌓여 월말이 되면 지난 한 달 간 어떤 생각을 하며 보냈는지 모아보고, 계속 가져가고 싶은 생각들을 선택하여 리뷰를 기록</li></ul><ul id="2b6b1fd4-7fd7-464d-a335-8803571c8dcf" class="bulleted-list"><li style="list-style-type:disc">12개월의 기록을 모아 실물 책 제작</li></ul><p id="c44e7ddf-8b7c-4473-aa03-3c5f2b383ac7" class="">
</p><p id="e668d348-49b7-47ba-83c7-81671f818a24" class="">
</p><h2 id="a05bfe1b-4a65-477f-9223-eda6d7d7a07d" class="">팀원 소개와 역할</h2><p id="a58fcaea-54a2-45b7-986e-05be99f9e0f3" class="">
</p><p id="5fa26069-6fa6-4fab-aec7-0d0a67b19a39" class="">김상연</p><ul id="2078d04e-815c-4594-8758-e272e84bea3c" class="bulleted-list"><li style="list-style-type:disc">웹 어플리케이션 개발/배포/운영</li></ul><p id="5d375156-9784-4a59-a4c0-eec2f617305e" class="">정찬</p><ul id="a9a1bf46-088e-4283-942b-5c037e685e90" class="bulleted-list"><li style="list-style-type:disc">슈퍼맨</li></ul><ul id="f0898181-b3a7-4421-94f1-4935305ff670" class="bulleted-list"><li style="list-style-type:disc">히어로</li></ul><ul id="a3621cfa-fa72-4721-9578-013e39aa8bdd" class="bulleted-list"><li style="list-style-type:disc">선생님</li></ul><p id="9a6ea0b2-de28-4eb2-a915-5a7cadcf566a" class="">
</p><h2 id="c63417a1-3929-4cf5-88dc-fdb66e3766aa" class="">개발 배경</h2><p id="0ba2831b-093a-4d90-b5fa-0102fe4e3c20" class="">
</p><p id="1eb86a74-8782-4a76-941f-d4fd35e1b311" class="">그동안은 나의 삶을 따로 기록 해 두지 않았는데, 항상 갈증은 있었다. 유난히 고민이 많았던 나의 삶, 망망대해에 빠질 때마다 길잡이가 되었던 가장 핵심적인 질문들을 기록 해 두고 싶었다. 적절한 방법이 떠오르지 않아서, 시도하고 실패해서 지쳐 있었다.</p><p id="3bec660f-783c-4e8f-8171-f0f54e26d166" class="">
</p><p id="2586ec4c-7402-4ae8-adf4-cb14f9e336b6" class="">그러다가,</p><p id="c6b0faf4-2ef8-4e3b-8fa4-293bad3f52b9" class="">5년 일기라는 제품을 소개 받았다. 한 권의 일기장으로 5년을 기록하는데, 한 페이지에 5년치의 그 날을 기록하는 방식이다. 애써 쓴 일기도 다시 읽히는 경우는 드문데, 이 제품은 따로 찾아 읽지 않더라도 오늘을 기록하면서 지난날의 나를 돌아볼 수 있다. 같은 날짜가 순서대로 한 페이지-에 나열되니 달라지는 나의 모습을 발견하기도 쉽다.</p><p id="b63959e1-069a-4925-894b-85f48a438002" class="">
</p><p id="93d2020b-0e46-4a8f-94e5-41fa7063d65b" class="">컴퓨터로 만들면 5년이 아니라 평생 쓸 수 있고, 기록물의 재사용성도 좋고, 훨씬 편리하게 쓸 수 있겠다는 생각을 했다.</p><p id="20e5b969-2d20-4021-85ea-e33ee7c7f79f" class="">
</p><p id="46958f73-5e46-4c62-b4ac-01698fb2ef97" class="">
</p><p id="f286de9c-af73-453c-9bf1-0c2af844d55f" class="">
</p><p id="600bbc12-3e51-43b3-9768-08181f556378" class="">
</p><p id="262ecccb-90bf-48d1-a350-3f9a490eaca9" class="">
</p><p id="5fe6a5fe-9a18-4420-9ab7-9f650676dc90" class="">
</p><h2 id="b4e32113-3449-47c8-aa2e-be5c8a975298" class="">코드베이스</h2><p id="faa68666-30d1-487f-8979-330d6363b50c" class="">
</p><h2 id="b3a0af83-7a49-4b50-965d-4ed9fd55d3fe" class="">코드컨벤션</h2><p id="6f7497ad-73de-4170-ba52-d6032335e04e" class="">
</p><h2 id="b918ea0e-b1c0-4719-97f4-f75d7b3cecb2" class="">인프라</h2><p id="b7b54824-0860-4703-9b56-193814e9fef5" class="">node.js</p><p id="73298e2f-660e-46bc-b9d6-27dd152abcef" class="">ejs</p><p id="e66c4c83-a2f3-4c52-87d1-e9aa1e068559" class="">mariadb</p><p id="7243c8a4-5fd4-4d27-9588-dbddaaf72c3f" class="">docker</p><p id="3b75a983-992a-4d47-8c11-ef5a72d18217" class="">rasberry pi 4 server</p><p id="fc1b556e-309a-4e93-be45-b3a8da7a9888" class="">
</p><h2 id="ddcd7904-db5c-4acb-ab31-a30702f13b85" class="">파일구조</h2><p id="92e7f3a6-15b4-4676-8b5a-91201f88e7ca" class="">
</p><h2 id="fcdff465-c450-4b3d-a8a1-71a2cdee356e" class="">리팩토링</h2><ul id="a3ae7579-f1fe-444e-b69e-dc6863a44d9e" class="toggle"><li><details open=""><summary>MVC 패턴 완성하기</summary><p id="f4650702-a181-4825-9efe-ce7d2a0c1124" class="">현재 이 프로그램은 나 혼자 만든 것이 아니다. 손이 닿지 않은 곳이 거의 없지만, 아무런 디자인 패턴 없이 만들어가던 것을 찬씨가 합류하며 어느 정도 구조를 잡아 주신 것이다. 당시에도 mvc를 언급하셨지만 내가 워낙 기초가 없어서 부분적으로만 그 필요성을 납득했다. 개발을 해 갈수록 이리저리 꼬이고, 어떤 변수들은 어느 디렉토리에 둘지 알쏭달쏭 해 지는 경험을 하다보니 왜 필요한지 알겠더라. 그래서 디자인 패턴을 제대로 정비하길 원했지만, 빨리 배포하고 싶은 마음에 미루고 미뤘다.</p><p id="8cb19eb6-2bc3-44c3-a224-860db87f7624" class="">
</p><p id="86e795bc-3295-4f82-a010-b0c6ec519e36" class="">현재 구조에서는 model, view, controller의 역할 구분이 명확하지 않고 controller가 model의 모든 역할을 전부 맡고 있다. 그러니까 나는 m/v/c가 각각 어떤 역할을 맡도록 할지 결정하는 것부터 시작해야 한다.</p><p id="d83c91e0-6a0d-4edf-8029-87300f0708eb" class="">
</p><ul id="7e01e3b0-56df-47da-9645-44301f5de89b" class="toggle"><li><details open=""><summary>21.12.11 user파트 전체</summary><p id="85068cf7-02f3-4f1c-afd3-3e8f2f5dec80" class="">데이터를 model에서 준비하고, controller는 무엇을 가져와서 어떻게 사용 할지만 결정하도록 수정. 처음으로 클래스를 사용 해 봤는데, 기능이 좀 더 복잡 해 지면 유용함을 더 많이 느낄 수 있을 것 같다. 어쨌건 그냥 객체 리터럴을 정의해서 사용하는 것과는 개념적으로 구분이 되어서 전체 소스코드의 구조를 파악하는 것에도 도움이 된다.</p></details></li></ul><ul id="e19b21b5-a1a2-4bbb-8662-dd3d16d56f1d" class="toggle"><li><details open=""><summary>21.12.12 diary파트 중 daily </summary><p id="f3fa7f86-8ab0-4d9f-88ec-10b36915a3d1" class="">데이터를 model에서 준비하고, controller는 무엇을 가져와서 어떻게 사용 할지만 결정하도록 수정. 그 외 controller에서 데이터를 손 보는 것(사람이 읽기 쉬운 형태로 수정하는 등)을 더 효율적으로 만들고 중복을 없앴다. 처음엔 엄두가 안 났는데 사용되지 않는 것 지워버리고 더 단순한 코드로 바꾸니까 보기보다 간단한 놈이었다. 한 줄 한 줄 모두 처음 만들어내던 때가 떠올랐다. 지금은 당연한 것들이 그땐 왜 그렇게 어려웠을까 ㅎㅎ</p></details></li></ul><ul id="26d2a2c8-22d1-4e29-92da-85962914c417" class="toggle"><li><details open=""><summary>21.12.13 diary 파트 중 read_monthly</summary><p id="a1b85bdc-7bb1-47c5-8fbf-656faecde905" class="">데이터를 model에서 준비하고, controller는 무엇을 가져와서 어떻게 사용 할지만 결정하도록 수정. controller내부 비효율적 코드 개선. 변수 명 일관성 있게 변경.</p><p id="9b6860e6-bd42-472d-8f84-6efc7d1affba" class="">같은 기능을 하는 부분은 최대한 일관성 있게 진행하고 있는데, 리팩토링도 빠르고 나중에 코드 파악하기에도 빠를 것이 확실해 보인다.</p></details></li></ul><ul id="4c2084c6-ab19-4530-902b-8cb368961a54" class="toggle"><li><details open=""><summary>21.12.11 복수의 쿠키에 대응</summary><p id="7263b011-fcfc-45d3-bb7b-f0c495089523" class="">복수의 쿠키가 대응하기 위해 npm 내장모듈인 cookie를 사용했다. 그러나 cookie.parse 메서드는 첫 번째 인자로 string타입이 와야 한다는 오류가 계속 떴다. 모바일에서만 확인되는 오류인 것을 근거로 삼아 원인을 찾아봤다. 결론은 단지 쿠키가 없을 때(로그아웃 하거나 새로운 기기에서 접속하는 등) undefined를 인자로 전달하기 때문에 오류가 발생했던 것이었다. </p><p id="46011460-3287-458a-b24b-240dcb12384a" class="">
</p><p id="a5cff96b-5872-461f-9dc6-474a052c463d" class="">인자로 string 타입을 받지 못할 때의 대처도 내장 모듈인 cookie에서 마련해 둘 만 한 것 아닌가? 그래서 해당 메서드의 코드를 살펴봤는데, 아직은 봐도 그 뜻을 잘 모르겠다 ^^</p><p id="b6a5a221-d8bb-4cd9-8377-e3e1f4d1b537" class="">
</p><pre id="3344e9ca-834f-4dfd-b0eb-0d7404236d55" class="code"><code>function get_token(req) {
] let cookies = {};
cookies = cookie.parse(req.headers.cookie);
}
if(cookies != undefined){
//token = token.split("=")[1]; legacy: there could be more than 2 cookies. req.headers.cookie will return single string no matter how many of cookies are being.
return cookies.login_access_token;
} else{
console.log('cookies are undefined. aka no token is being')
return false;
}
}</code></pre><p id="60240738-c873-4eb4-b952-1e246e49d5d9" class="">
</p><pre id="22796a29-89e6-4bc8-9594-0ddad8b6d6cf" class="code"><code>function get_token(req) {
let cookies = {};
if(req.headers.cookie == undefined){
cookies = undefined;
}else{
cookies = cookie.parse(req.headers.cookie);
}
if(cookies != undefined){
//token = token.split("=")[1]; legacy: there could be more than 2 cookies. req.headers.cookie will return single string no matter how many of cookies are being.
return cookies.login_access_token;
} else{
console.log('cookies are undefined. aka no token is being')
return false;
}
}</code></pre><p id="21fe0457-fa97-433d-8eef-7007834c38f1" class="">
</p></details></li></ul><ul id="598231b2-b87a-40e4-8894-77fc7d5ab3e0" class="toggle"><li><details open=""><summary>21.12.14 diary 파트 중 pickup_game_monthly</summary><p id="ab4169de-caf8-4c76-8674-eebdcb10b84e" class="">역시 마찬가지로 model과 controller로 분리했다. controller에서 데이터 마련하는 부분을 model로 옮기는 작업을 며칠 하다 보니 느끼는 것이, 최소한의 데이터 가공은 모델에서 해 줘야 한다는 거다. </p><p id="930b34fd-1148-4313-8ec2-3364a9d82800" class="">
</p><p id="60803d21-02ce-4ab6-8295-bc664dcbbb51" class="">요리에 비유하자면, model이 할 역할이 그냥 밭에서 캐온 감자 고구마를 주방에 휙 집어 던지는 것이 아니라 잔 뿌리도 제거 하고 흙도 털어내고 상처 난 곳은 베어내서 딱 쓰기 좋은 재료로 만든 뒤에 건네줘야 한다는 거다. controller가 그 감자를 반으로 자르든 갈아버리든 찜을 찌던 튀김을 하던 간에 말이다. 일단 재료 자체를 바로 갖다 쓸 수 있게 기본 손질을 해 줘야 역할 분리가 되고 구분을 할 수 있겠다. </p><p id="7c84e0ba-fb6f-4538-b213-6dbc8241fccc" class="">
</p><p id="6f606eb3-cb88-4e47-af43-22f86d9fcaa8" class="">물론 나의 경우, 이 프로젝트의 경우에 그런 것이고 이런 역할 정의는 프로젝트마다 달라지는 것이 당연하겠다. MVC를 설명하는 사람들이 왜 각각의 역할 구분을 모호하게 표현하거나 서로 말이 다른 것인지 이제는 알겠다.</p></details></li></ul><ul id="2c015caa-fc67-497d-ad41-dd83c3edeb55" class="toggle"><li><details open=""><summary>21.12.15 diary 파트 중 post D, M</summary><p id="39052424-ce6b-478a-b2bc-0f42eab069a2" class="">역시 model과 controller를 분리하는 작업이었다. controller에서는 client에서 받아온것을 model로 전달만 해 주고, model이 db에 post한 결과에 따라 res.redirect만 해 주는 것으로 역할을 나누었다. </p><p id="47338099-0b68-4c19-8c77-5efa6a5b61c2" class="">
</p><p id="7448b237-7341-42e8-96bc-9a90660ce703" class="">이 과정에서 1,2,3일에 쓴 월간일기가 1달 전의 월간 일기가 되도록 간단한 로직을 추가헀다.</p></details></li></ul></details></li></ul><ul id="26340e20-ffd1-45cf-a5f2-97a0de5c2507" class="toggle"><li><details open=""><summary></summary></details></li></ul><h2 id="2a9dd442-28a8-440c-bdb4-1068dcd7246a" class="">버그 수정 등</h2><ul id="a28d7fba-cdba-48d2-b6ce-b61725f05afc" class="toggle"><li><details open=""><summary>21.12.12 특정 테이블만 복구</summary><p id="e5b77d05-2451-423f-8219-b7aa193b6fb4" class="">변수로 둬야 할 것을 상수로 둬서 잘못된 data가 삭제된 적이 있다.베타테스터분들이 실시간으로 이용 중이라 전날 백업한 schema를 통째로 덮어 씌울 수는 없었다. </p><p id="0fae086c-0b5e-445c-94d2-6663a496426c" class="">
</p><p id="c196f621-a1d8-4c99-a397-d7a55295cab0" class="">특정 테이블만 복구하는 방법이 있더라.</p><p id="e6ff535a-155d-472d-9b60-81f2ff0bc3db" class="">일단 schema 통째로 백업</p><figure class="block-color-gray_background callout" style="white-space:pre-wrap;display:flex" id="a5e24ba4-16ef-4435-908e-154fd70e6f64"><div style="font-size:1.5em"><span class="icon">💡</span></div><div style="width:100%">mysqldump -u [user] -p[pw] [schema] > [backup file name.sql]</div></figure><p id="6abf57f9-97c2-4057-b4bf-55025653117d" class="">그 다음에 백업해둔 .sql파일에서 필요한 테이블만 추출</p><figure class="block-color-gray_background callout" style="white-space:pre-wrap;display:flex" id="d37bd950-ce65-46b1-a2b1-f8fb1bbbc8ce"><div style="font-size:1.5em"><span class="icon">💡</span></div><div style="width:100%">sed -n -e '/DROP TABLE.*[table name]/,/UNLOCK TABLES/p' [backuped file name.sql] > [backuped table file name.sql]</div></figure><p id="029b13f4-cc6e-4640-a58b-2c7568b63670" class="">그다음 해당 schema에 넣어주면 알아서 제자리를 찾아 간다.</p><figure class="block-color-gray_background callout" style="white-space:pre-wrap;display:flex" id="d4b0c791-e355-414d-b045-b0aecd809641"><div style="font-size:1.5em"><span class="icon">💡</span></div><div style="width:100%">mysql -u [user] -p[pw] [schema] < [backuped table file name.sql]</div></figure><p id="8706af59-b532-4bbc-91a3-78aba0552500" class="">
</p></details></li></ul><ul id="16d5b118-a2d6-4049-9b6a-ea71c8e41abc" class="toggle"><li><details open=""><summary></summary></details></li></ul><p id="87a80769-8b28-4b89-953a-faffb2756d05" class="">
</p><h2 id="44a4c3df-e9aa-4e92-bb1c-e72f7ecc495c" class="">버전 정보</h2><p id="e99db01a-2eab-4d85-9418-30c2413fdee5" class="">도커 이미지별로 어떤 차이점이 있는지 기록한다. 이게 git에도 버전정보가 있긴 하지만 그냥 commit만 나와있는 것 아닌가? 내가 버전별로 git branch를 새로 파는 것도 아니고.</p><p id="c40ce718-0e89-45f1-925a-bc6acb2913a7" class="">
</p><p id="637b4944-a162-4a59-a6bc-cb865b90274d" class="">업데이트를 할 때마다 어차피 도커 이미지를 만들고 버전 정보를 태그 해 둔다. 그러니까 그 상세 업데이트 내용을 여기에 적어본다.</p><p id="5f94feba-0f54-4b44-9441-7ed64d537dd0" class="">
</p><ul id="38901db9-8657-44f6-82a4-2b1abd40ea0a" class="toggle"><li><details open=""><summary>21.12.13 wt:betatest_v4.08</summary><ol type="1" id="74ea95ec-ec8f-41f5-bd4a-4a515dd4205b" class="numbered-list" start="1"><li>11월 월간일기 작성 시점에 버그 발견으로 아무도 일기를 작성할 수 없었다. 내가 버그를 잡은 시점은 원래 오픈 된 일기 작성 기간을 훨씬 지났기 때문에 임시로 지나간 11월 월간 일기를 쓸 수 있게 오픈 해 줬었다.<p id="d31ebf59-1f97-4ddc-8746-44781e6bc03a" class="">임시로 오픈 한 기간을 공지 했었는데, 그 기간이 끝남에 따라 다시 조건부로 월간일기를 쓸 수있게 만들었다.(매달 마지막날~익월 03일까지)</p></li></ol><p id="638d50f3-0d01-4af1-a3ec-1c0c46a89b16" class="">
</p><ol type="1" id="a823304e-368c-4885-9814-666fe4491861" class="numbered-list" start="2"><li>베타테스터들은 매달 월간 일기를 쓰고 나면 설문 조사를 하게 되어있다. /diary로 접근하면 설문조사 페이지로 이동 되도록 만들었다.</li></ol></details></li></ul><p id="15feb819-6c06-478d-982f-41a77bf3107e" class="">
</p></div></article></body></html>