Post

라이프 다이어리

일상 관리 및 개선 다이어리 웹사이트

라이프 다이어리

프로젝트 이름: Life Diary - 10분 단위 일상 관리 시스템

일상생활을 체계적으로 관리하고 싶지만, 기존의 시간 관리 도구들은 너무 복잡하거나 부담스러웠습니다. Life Diary는 이러한 문제를 해결하기 위해 개발한 웹 애플리케이션입니다. 하루를 10분 단위로 나누어 기록하고, 태그 기반으로 분류하여 시간 사용 패턴을 분석할 수 있게 설계되었습니다.

기술적으로는 Django 5.2.4와 Python을 기반으로 개발되었으며, SQLite를 개발용 데이터베이스로 사용하고 있습니다. 프론트엔드는 Django Templates와 Bootstrap을 활용하여 직관적인 사용자 인터페이스를 구현했습니다.

Life Diary를 왜 만들었나?

대학생 시절부터 시간 관리를 위해 다양한 도구들을 시도해봤지만, 항상 아쉬움이 남았습니다.

  • 너무 세밀한 계획: 30분, 1시간 단위로 계획을 세우면 실제로는 그렇게 되지 않아서 스트레스만 쌓임
  • 복잡한 인터페이스: 많은 기능들이 있지만 실제로는 사용하지 않는 기능들이 대부분
  • 분석 부족: 시간을 기록해도 “그래서 어쩨?”라는 질문에 답을 주지 못함

그러던 중 10분 단위 기록이라는 아이디어가 떠올랐습니다. 10분은 충분히 짧아서 부담스럽지 않으면서도, 하루 144개의 슬롯으로 세밀한 패턴을 파악할 수 있는 단위였습니다.

기술 스택

  • Backend: Django 5.2.4 (Python)
  • Frontend: Django Templates, Bootstrap 5, HTML/CSS/JavaScript
  • Database: SQLite (개발), PostgreSQL (프로덕션)
  • Deployment: Gunicorn, WhiteNoise
  • Data Processing: Django ORM, Python datetime

시스템 아키텍처

1. 프로젝트 구조

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
lifeDiary/
├── apps/                          # Django 앱들
│   ├── core/                      # 핵심 유틸리티
│   │   ├── static/core/           # 공통 정적 파일
│   │   │   ├── css/style.css      # 공통 스타일
│   │   │   ├── js/tag.js          # 태그 관련 JavaScript
│   │   │   └── js/utils.js        # 유틸리티 함수
│   │   └── utils.py               # 공통 유틸리티 함수
│   ├── dashboard/                 # 메인 대시보드
│   │   ├── models.py              # TimeBlock 모델
│   │   ├── views.py               # 대시보드 뷰
│   │   ├── api_urls.py            # API 엔드포인트
│   │   └── templates/dashboard/   # 대시보드 템플릿
│   ├── stats/                     # 통계 및 분석
│   │   ├── views.py               # 통계 뷰
│   │   ├── logic.py               # 통계 계산 로직
│   │   ├── feedback.py            # AI 피드백 생성
│   │   └── templates/stats/       # 통계 템플릿
│   ├── tags/                      # 태그 관리
│   │   ├── models.py              # Tag 모델
│   │   ├── views.py               # 태그 뷰
│   │   ├── api_urls.py            # API 엔드포인트
│   │   └── templates/tags/        # 태그 템플릿
│   └── users/                     # 사용자 관리
│       ├── models.py              # UserGoal, UserNote 모델
│       ├── views.py               # 사용자 뷰
│       ├── forms.py               # 폼 정의
│       └── templates/users/       # 사용자 템플릿
├── lifeDiary/                     # 프로젝트 설정
│   ├── settings/                  # 설정 파일들
│   │   ├── base.py                # 기본 설정
│   │   ├── dev.py                 # 개발 환경 설정
│   │   └── prod.py                # 프로덕션 환경 설정
│   ├── urls.py                    # 메인 URL 설정
│   └── wsgi.py                    # WSGI 설정
└── requirements.txt               # Python 의존성

2. 핵심 컴포넌트

TimeBlock 모델 설계

가장 중요한 설계 결정은 10분 단위 시간 블록을 어떻게 효율적으로 관리할 것인가였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# apps/dashboard/models.py
class TimeBlock(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateField()
    time_slot = models.IntegerField()  # 0-143 (10분 단위)
    tag = models.ForeignKey(Tag, on_delete=models.SET_NULL, null=True, blank=True)
    memo = models.TextField(max_length=500, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ['user', 'date', 'time_slot']
        indexes = [
            models.Index(fields=['user', 'date']),
            models.Index(fields=['user', 'tag']),
        ]

주요 특징:

  • time_slot: 0-143 (하루 144개 10분 슬롯)
  • unique_together: 같은 시간대 중복 방지
  • 인덱스 최적화: 사용자별 날짜, 태그별 조회 성능 향상

태그 시스템

사용자별 개인 태그와 공용 기본 태그를 구분하여 관리합니다.

1
2
3
4
5
6
7
8
9
# apps/tags/models.py
class Tag(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    name = models.CharField(max_length=50)
    color = models.CharField(max_length=7, default='#007bff')  # HEX 색상
    is_default = models.BooleanField(default=False)
    
    class Meta:
        unique_together = ['user', 'name']

특별한 처리 사항:

  • 개인 태그: user가 설정된 경우
  • 기본 태그: user가 null이고 is_default=True인 경우
  • 색상 커스터마이징: HEX 색상 코드로 시각적 구분

핵심 기능 구현

1. 시간 블록 관리 시스템

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# apps/dashboard/views.py
def update_timeblock(request):
    if request.method == 'POST':
        date = request.POST.get('date')
        time_slot = int(request.POST.get('time_slot'))
        tag_id = request.POST.get('tag_id')
        memo = request.POST.get('memo', '')
        
        # 기존 블록이 있으면 업데이트, 없으면 생성
        timeblock, created = TimeBlock.objects.get_or_create(
            user=request.user,
            date=date,
            time_slot=time_slot,
            defaults={'tag_id': tag_id, 'memo': memo}
        )
        
        if not created:
            timeblock.tag_id = tag_id
            timeblock.memo = memo
            timeblock.save()

2. 통계 분석 시스템

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
# apps/stats/logic.py
def calculate_tag_statistics(user, start_date, end_date):
    """태그별 시간 사용 통계 계산"""
    timeblocks = TimeBlock.objects.filter(
        user=user,
        date__range=[start_date, end_date],
        tag__isnull=False
    ).select_related('tag')
    
    stats = {}
    for timeblock in timeblocks:
        tag_name = timeblock.tag.name
        if tag_name not in stats:
            stats[tag_name] = {
                'total_minutes': 0,
                'color': timeblock.tag.color,
                'percentage': 0
            }
        stats[tag_name]['total_minutes'] += 10
    
    # 퍼센티지 계산
    total_minutes = sum(stat['total_minutes'] for stat in stats.values())
    for stat in stats.values():
        stat['percentage'] = (stat['total_minutes'] / total_minutes * 100) if total_minutes > 0 else 0
    
    return stats

3. AI 피드백 시스템

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# apps/stats/feedback.py
def generate_ai_feedback(user, stats_data):
    """시간 사용 패턴에 대한 AI 피드백 생성"""
    feedback = []
    
    # 가장 많은 시간을 사용한 태그 분석
    top_tag = max(stats_data.items(), key=lambda x: x[1]['total_minutes'])
    if top_tag[1]['percentage'] > 50:
        feedback.append(f"'{top_tag[0]}'에 하루의 절반 이상을 사용하고 있습니다. "
                       f"다른 활동과의 균형을 고려해보세요.")
    
    # 목표 대비 달성률 분석
    user_goals = UserGoal.objects.filter(user=user)
    for goal in user_goals:
        actual_time = stats_data.get(goal.tag.name, {}).get('total_minutes', 0)
        if actual_time < goal.target_minutes:
            feedback.append(f"'{goal.tag.name}' 목표 달성률: "
                           f"{actual_time/60:.1f}시간 / {goal.target_minutes/60:.1f}시간 "
                           f"({actual_time/goal.target_minutes*100:.1f}%)")
    
    return feedback

데이터 플로우

1
2
3
4
5
6
7
8
9
10
graph TD
    A[사용자 로그인] --> B[대시보드 접속]
    B --> C[날짜 선택]
    C --> D[시간 블록 표시]
    D --> E[태그 할당]
    E --> F[TimeBlock 저장]
    F --> G[통계 페이지]
    G --> H[시간 사용량 계산]
    H --> I[AI 피드백 생성]
    I --> J[결과 시각화]

개발 과정에서의 도전과 해결

1. 10분 단위 시간 관리의 효율성

문제: 144개의 시간 슬롯을 어떻게 직관적으로 표시할 것인가? 해결:

  • 시간대별로 그룹화하여 표시 (아침, 오후, 저녁, 밤)
  • 색상 코딩으로 태그별 구분
  • 드래그 앤 드롭으로 연속 시간 블록 선택

2. 실시간 데이터 동기화

문제: 여러 사용자가 동시에 접근할 때 데이터 일관성 해결:

  • Django ORM의 unique_together 제약 조건 활용
  • AJAX를 통한 비동기 업데이트
  • 낙관적 락킹 패턴 적용

3. 통계 계산 성능 최적화

문제: 대량의 TimeBlock 데이터에서 통계 계산 시 성능 저하 해결:

  • 데이터베이스 인덱스 최적화
  • select_related를 통한 N+1 쿼리 방지
  • 캐싱을 통한 반복 계산 최소화

결과 및 성과

주요 기능

  • 10분 단위 기록: 하루 144개 슬롯으로 세밀한 시간 관리
  • 태그 기반 분류: 사용자 정의 태그로 활동 분류
  • 실시간 통계: 시간 사용 패턴 즉시 분석
  • AI 피드백: 개인화된 시간 관리 조언

사용자 경험 개선

  • 기록 편의성: 클릭 한 번으로 10분 단위 기록
  • 시각적 피드백: 색상 코딩으로 한눈에 파악
  • 인사이트 제공: 시간 사용 패턴 분석 및 개선점 제시

향후 개선 계획

  1. 기능 확장
    • 모바일 앱 개발
    • 팀/그룹 시간 관리 기능
    • 캘린더 연동
  2. AI 기능 강화
    • 머신러닝 기반 시간 사용 패턴 예측
    • 개인화된 생산성 최적화 제안
  3. 데이터 분석
    • 주간/월간 리포트 생성
    • 목표 달성률 추적
    • 생산성 지표 대시보드

마무리

이 프로젝트를 통해 실제 사용자의 일상적 문제를 해결하는 웹 애플리케이션을 만드는 경험을 할 수 있었습니다. 특히 10분 단위라는 독특한 접근 방식으로 시간 관리의 새로운 패러다임을 제시할 수 있었다는 점이 가장 보람찼습니다.

가장 중요한 학습은 사용자 중심의 설계가 얼마나 중요한지 깨달은 것입니다. 복잡한 기능보다는 사용자가 실제로 필요로 하는 핵심 기능에 집중하는 것이 더 가치 있다는 것을 배웠습니다.


관련 링크


This post is licensed under CC BY 4.0 by the author.