⚓ DATT 12 - Anchor 시스템 설계와 지역 기반 자동 큐레이션 구조
개요
현재 DATT는 다음 기능들을 지원한다.
1
2
3
4
5
장소 검색
Nearby Search
Place Detail API
JWT 인증
Bookmark 기능
하지만 이것만으로는 단순:
1
"장소 검색 서비스"
에 가깝다.
DATT가 진짜로 만들고 싶은 것은:
1
2
3
4
데이트
약속
여행
로컬 탐색
등의 경험을 빠르게 탐색할 수 있는 플랫폼이다.
따라서 이번 단계에서는:
1
Anchor 시스템
을 구축하였다.
Anchor란 무엇인가
DATT의 Anchor는 단순 저장 기능이 아니다.
Anchor는:
1
2
"특정 지역에 닻을 내리고
그 주변 경험을 자동 큐레이션하는 기능"
이다.
예를 들어 사용자가:
1
2
3
4
성수
을지로
강릉
홍대
등 특정 지역을 지정하고:
1
닻 버튼 클릭
만 하면:
1
2
3
4
5
맛집
카페
술집
숙소
놀거리
등을 자동 추천받는다.
즉 Anchor는:
1
지역 기반 경험 큐레이션
시스템이다.
왜 장소가 아닌 경험을 추천하는가
기존 장소 서비스 대부분은:
1
장소 단위 검색
에 집중한다.
예:
1
2
3
맛집 검색
카페 검색
술집 검색
하지만 실제 사용자는:
1
"어디 갈까?"
보다:
1
"오늘 어떻게 놀까?"
를 더 많이 고민한다.
즉 사용자가 원하는 것은:
1
장소 하나
가 아니라:
1
지역 기반 경험 흐름
이다.
예:
1
2
3
성수에서 데이트
강릉에서 1박2일
홍대에서 친구 모임
등.
Anchor는 바로 이 문제를 해결하기 위한 구조다.
Anchor 시스템 핵심 구조
Anchor는 다음 구조를 가진다.
1
2
3
4
5
Anchor
↕
AnchorPlace
↕
PlaceMaster
즉:
1
2
3
4
5
Anchor
= 기준 지역
AnchorPlace
= 기준 지역 주변 자동 추천 결과
이다.
Anchor Entity 설계
Anchor는:
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
@Entity
@Table(name = "anchor")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class Anchor extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "member_id", nullable = false)
private Member member;
private String title;
private String basePlaceName;
private String baseAddress;
private Double baseLon;
private Double baseLat;
private Double radiusKm;
private boolean isPublic;
private long viewCount;
}
핵심은:
1
기준 좌표
를 저장한다는 점이다.
왜 좌표 기반으로 설계했는가
처음에는:
1
장소 여러 개 저장
방식도 고려했다.
하지만 DATT의 핵심은:
1
"지역 기반 탐색"
이다.
따라서:
1
2
3
성수역
홍대입구역
강릉 중앙시장
같은:
1
기준 좌표
를 중심으로 자동 추천하는 구조가 더 자연스럽다.
AnchorPlace 설계
AnchorPlace는:
1
Anchor 생성 당시 추천된 장소 스냅샷
이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Entity
@Table(name = "anchor_place")
public class AnchorPlace extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
private Anchor anchor;
@ManyToOne(fetch = FetchType.LAZY)
private PlaceMaster placeMaster;
@Enumerated(EnumType.STRING)
private AnchorPlaceCategory category;
private Double distanceKm;
private int recommendOrder;
}
왜 추천 결과를 스냅샷으로 저장했는가
중요한 이유가 있다.
만약 매번 실시간 Nearby Search만 수행하면:
1
시간이 지나면서 추천 결과가 계속 바뀐다.
예:
1
2
3
공공데이터 변경
폐업
신규 장소 추가
등.
하지만 공유된 Anchor는:
1
"그 당시의 경험"
을 유지해야 한다.
따라서:
1
Anchor 생성 당시 추천 결과
를 별도 저장하는 구조로 설계했다.
Nearby Search와의 연동
Anchor의 핵심은:
1
Nearby Search 재사용
이다.
Anchor 생성 시 다음 흐름이 수행된다.
1
2
3
4
5
Anchor 생성
→ 기준 좌표 설정
→ Nearby Search 수행
→ 카테고리별 추천
→ AnchorPlace 저장
즉 기존 Nearby Search를:
1
재사용 가능한 추천 엔진
처럼 활용한다.
카테고리별 추천 구조
Anchor는 다음 카테고리 기준으로 자동 추천한다.
1
2
3
4
5
FOOD
CAFE
BAR
STAY
PLAY
즉:
1
2
3
4
5
맛집
카페
술집
숙소
놀거리
기반이다.
업종 코드 기반 추천
추천은 공공데이터 업종 중분류 코드 기반으로 수행한다.
예:
1
2
3
4
5
6
FOOD("맛집", List.of(
"I201",
"I202",
"I203",
"I204"
))
즉:
1
2
3
업종 코드
→ 카테고리 매핑
→ Nearby Search 수행
구조다.
Anchor 추천 흐름
최종 흐름은 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
사용자
→ 지역 지정
→ Anchor 생성
Anchor 생성
→ Nearby Search 수행
Nearby 결과
→ FOOD / CAFE / BAR / STAY / PLAY 분리
분리된 결과
→ AnchorPlace 저장
최종
→ AnchorDetailResponse 반환
왜 Anchor를 독립 도메인으로 봤는가
중요한 설계 포인트다.
처음에는 단순:
1
장소 저장 기능
처럼 보일 수 있다.
하지만 실제로는:
1
2
3
4
5
추천
공유
랭킹
개인화
큐레이션
등으로 확장된다.
즉 Anchor는 단순 기능이 아니라:
1
DATT 핵심 경험 도메인
이다.
Anchor 공유 구조
Anchor는:
1
공개/비공개
구조를 가진다.
1
private boolean isPublic;
즉:
1
2
3
4
5
공개 Anchor
→ 누구나 조회 가능
비공개 Anchor
→ 작성자만 조회 가능
이다.
Anchor 조회수 구조
Anchor는 공유 콘텐츠 성격을 가지기 때문에:
1
조회수
도 저장한다.
1
private long viewCount;
조회수는:
1
상세 조회 성공 시 증가
한다.
향후:
1
2
인기 Anchor
추천 랭킹
등으로 확장 가능하다.
Anchor 목록 조회 구조
Anchor는:
1
2
최신순
인기순
정렬을 지원한다.
1
2
3
4
5
public enum AnchorSortType {
LATEST,
POPULAR
}
즉:
1
2
createdAt DESC
viewCount DESC
기반 조회가 가능하다.
Anchor와 Bookmark의 관계
처음에는 Bookmark와 Anchor를 직접 연결할지 고민했다.
하지만 최종적으로는:
1
2
3
Bookmark
≠
Anchor
로 분리했다.
Bookmark는:
1
저장 행위
이고,
Anchor는:
1
지역 기반 경험 큐레이션
이다.
즉 역할이 다르다.
대신 어떻게 연동했는가
Bookmark는:
1
Anchor 생성 진입점
으로 사용한다.
예:
1
2
3
내가 저장한 장소
→ 기준점으로 선택
→ Anchor 생성
즉:
1
2
Bookmark는 입력 데이터
Anchor는 결과 콘텐츠
구조다.
경험 탐색 플랫폼 모델링
DATT는 단순:
1
장소 검색 플랫폼
이 아니다.
최종적으로는:
1
"어디서 무엇을 경험할 것인가"
를 탐색하는 플랫폼이다.
Anchor는 바로 이 철학을 기반으로 설계되었다.
현재 구조의 장점
현재 구조는 다음 장점을 가진다.
1
2
3
4
5
Nearby Search 재사용 가능
카테고리별 추천 가능
공유 가능
확장 가능
개인화 가능
특히:
1
2
Anchor
→ 경험 단위 콘텐츠
로 설계한 것이 핵심이다.
향후 확장 방향
현재는 MVP 수준이다.
하지만 이후 다음 기능들로 확장 가능하다.
1. AI 기반 추천
예:
1
사용자 취향 기반 장소 추천
2. 실시간 인기 지역
예:
1
현재 가장 인기 있는 Anchor
3. Gamification
예:
1
2
3
Anchor 생성 경험치
랭킹
칭호
4. 공유 기능 강화
예:
1
2
3
친구 공유
링크 공유
비공개 공유 링크
마무리
이번 단계에서는:
1
Anchor 시스템
을 구축하며:
1
지역 기반 자동 큐레이션 구조
를 완성하였다.
핵심은:
1
2
장소를 검색하는 것이 아니라
경험을 탐색하게 만드는 것
이다.
DATT는 앞으로:
1
2
3
4
데이트
여행
약속
로컬 탐색
등 실제 사용자 경험 중심 플랫폼으로 확장될 예정이다.