AI 역문서 · 1D1S-client@ad5edf9 · 1D1S-admin@5dd0cfe · 1D1S-server-v2@23a5ca8 기준 · 코드에서 거꾸로 만든 초안입니다. 근거 링크로 확인하세요.
관련 소스 파일
이 페이지는 테스트 프로젝트의 세 저장소 중 코드 원문에서 확인되는 디렉터리·파일 경계를 정리합니다.
1D1S-client의 Next.js App Router 구조와 홈 화면, 공통 레이아웃, 오류 경계, 메타데이터 파일의 역할을 설명합니다.1D1S-admin의 Next.js 루트 레이아웃과 AppProviders 연결을 설명합니다.1D1S-server-v2의 Spring Boot 애플리케이션 진입점과 확인 가능한 HTTP 엔드포인트를 설명합니다.화면별 업무 흐름은 2.1 챌린지 탐색과 참여, 2.2 챌린지 만들기, 2.3 일지 작성과 조회에서 다룹니다. 클라이언트와 서버 사이의 REST·WebSocket 연결은 1.3 시스템 아키텍처, 요청 계층과 응답 형식은 3.2 API와 응답 구조, 서버의 세부 계층은 5.1 서버 도메인 계층과 연결됩니다. 관리자 화면의 상세 구성은 4.2 관리자 콘솔에서 다룹니다.
출처: layout.tsx:99-131, layout.tsx:12-23, OdosServerV2Application.java:1-16
현재 원문에서 확인되는 저장소 구성 요소는 다음과 같습니다.
| 저장소 | 확인되는 구성 요소 | 역할 |
|---|---|---|
1D1S-client | src/app | Next.js App Router의 루트 레이아웃, 홈, 오류·404, SEO 관련 라우트 파일을 둡니다. |
1D1S-client | @component, @feature, @module, @constants | 레이아웃 컴포넌트, 기능별 화면·컴포넌트, 공통 모듈, 상수를 가져오는 경로 별칭으로 사용됩니다. |
1D1S-admin | src/app/layout.tsx | 관리자 웹의 HTML 루트와 AppProviders를 구성합니다. |
1D1S-server-v2 | com.odos.odos_server_v2 | Spring Boot 애플리케이션 클래스와 확인 가능한 테스트 컨트롤러의 패키지 루트입니다. |
1D1S-server-v2 | src/main/resources/db/migration | SQL 형식의 데이터베이스 스키마 변경 파일을 둡니다. |
클라이언트 홈은 src/app/page.tsx가 진입점이며, HomeMobileHeader와 HomeScreen을 조합합니다. 홈의 비동기 표시 영역은 Suspense로 감싸고 HomeLoadingSkeleton을 대체 UI로 사용합니다. 기능 구현은 @feature/home, @feature/stories, @feature/challenge, @feature/guide처럼 기능별 별칭 경로에서 가져옵니다.
관리자 웹 원문에서는 기능별 페이지나 관리 도메인 컴포넌트가 직접 제시되지 않습니다. 따라서 1D1S-admin에 관리자 로그인·회원·챌린지 관리 화면이 실제로 어떤 하위 경로에 있는지는 현재 자료만으로 확정할 수 없습니다.
출처: page.tsx:1-11, layout.tsx:9-25, layout.tsx:1-23
1D1S-client/src/app은 Next.js의 App Router 파일 규칙을 사용합니다. 확인되는 파일과 연결은 다음과 같습니다.
| 파일 | 확인되는 역할 | 연결되는 코드 |
|---|---|---|
layout.tsx | 전체 문서의 HTML, 전역 스타일, 프로바이더, 공통 셸을 구성합니다. | AppProviders, ScrollToTop, AppLayoutShell |
page.tsx | / 홈 경로를 구성합니다. | HomeMobileHeader, HomeScreen |
error.tsx | 라우트 세그먼트의 렌더링 예외를 처리합니다. | reset(), window.location.replace('/') |
global-error.tsx | 루트 레이아웃까지 무너진 경우의 전역 예외 화면을 구성합니다. | reset(), window.location.replace('/') |
not-found.tsx | 찾을 수 없는 페이지의 404 화면을 구성합니다. | router.back(), router.push('/') |
manifest.ts | PWA 매니페스트를 반환합니다. | manifest() |
robots.ts | 크롤러 허용·차단 규칙과 사이트맵 위치를 반환합니다. | robots() |
sitemap.ts | 공개 경로와 공개 챌린지 URL을 사이트맵으로 반환합니다. | sitemap(), fetchAllPublicChallenges() |
홈 요청의 화면 조합은 다음 순서로 진행됩니다.
src/app/page.tsx의 MainPage()를 실행합니다.MainPage()가 buildOrganizationJsonLd()와 buildWebSiteJsonLd()의 결과를 JsonLd로 삽입합니다.HomeMobileHeader를 먼저 배치합니다.HomeScreen을 Suspense 경계 안에서 렌더링합니다.HomeScreen이 준비되지 않은 동안 HomeLoadingSkeleton이 StoryRingSkeleton과 세 개의 로딩 블록을 표시합니다.원문 주석에 따르면 홈의 랜덤 챌린지·일지 데이터는 useHomeRandomData로 클라이언트 React Query에 이관되어 있습니다. 다만 해당 훅의 구현과 실제 요청 URL은 제공되지 않았으므로, 이 페이지에서는 함수 존재와 홈에서 사용되는 데이터 계층의 설명까지만 확정합니다.
출처: page.tsx:1-59, sitemap.ts:1-53
RootLayout()은 클라이언트 웹의 모든 페이지를 감싸는 공통 진입점입니다. 먼저 globals.css와 pretendard-subset.css를 가져오고, <html lang="ko">와 <body>를 구성합니다. <body> 안에서는 다음 호출 구조를 사용합니다.
AppProviders가 children을 감쌉니다.ScrollToTop이 공통 스크롤 동작을 담당하는 컴포넌트로 배치됩니다.AppLayoutShell이 실제 페이지 콘텐츠인 children을 감쌉니다.SpeedInsights가 <body> 하위에 별도로 배치됩니다.루트 <head>에는 NATIVE_APP_INIT_SCRIPT와 THEME_INIT_SCRIPT가 인라인 스크립트로 삽입됩니다. <html>에는 초기값으로 data-native-app="false"와 suppressHydrationWarning이 설정되어 있습니다. 또한 metadata에는 SITE_TITLE, SITE_DESCRIPTION, SITE_URL, Open Graph 이미지 정보가 사용되고, viewport에는 모바일 화면 폭·확대·테마 색상이 정의되어 있습니다.
오류 처리는 두 단계입니다.
| 경계 | 컴포넌트 | 복구 동작 |
|---|---|---|
| 라우트 세그먼트 | Error | reset()으로 다시 시도하거나 /로 이동합니다. |
| 전역 루트 | GlobalError | 인라인 스타일만 사용해 오류 화면을 그린 뒤 reset() 또는 / 이동을 제공합니다. |
| 존재하지 않는 경로 | NotFound | router.back()으로 이전 페이지로 돌아가거나 router.push('/')로 홈으로 이동합니다. |
Error와 GlobalError는 각각 useEffect()에서 console.error()로 오류를 기록하지만, 사용자 화면에는 서버 오류 메시지를 직접 표시하지 않습니다. GlobalError는 디자인 시스템이나 전역 CSS가 원인일 가능성을 고려해 <html>과 <body>를 직접 그리고 인라인 스타일만 사용합니다.
출처: layout.tsx:1-25, layout.tsx:99-131, error.tsx:14-50, global-error.tsx:10-78, not-found.tsx:8-39
관리자 웹의 확인 가능한 Next.js 구조는 1D1S-admin/src/app/layout.tsx입니다. RootLayout()은 다음 순서로 관리자 문서를 구성합니다.
@/app.styles/globals.css를 가져옵니다.<html lang="ko">를 생성합니다.<body> 안에 AppProviders를 배치합니다.children을 AppProviders의 하위 콘텐츠로 전달합니다.관리자 메타데이터는 다음과 같이 고정되어 있습니다.
| 키 | 값 |
|---|---|
title | 1D1S Admin |
description | 1Day 1Streak 관리자 페이지 |
| HTML 언어 | ko |
클라이언트 레이아웃과 비교하면 관리자 레이아웃에는 원문에서 다음 요소가 확인되지 않습니다.
AppLayoutShellScrollToTopNATIVE_APP_INIT_SCRIPTTHEME_INIT_SCRIPTSpeedInsightsmanifest, robots, sitemap 파일이는 해당 기능이 관리자 웹에 없다는 뜻이 아니라, 제공된 원문에 나타나지 않는다는 뜻입니다. 관리자 로그인·관리자 API 호출·도메인별 관리 화면·조회 훅·폼·상세 모달의 실제 파일 경로는 추가 자료 확인이 필요합니다. 따라서 이 페이지에서 확정할 수 있는 관리자 구조는 공통 CSS와 AppProviders를 중심으로 한 루트 셸까지입니다.
출처: layout.tsx:1-23, layout.tsx:99-131
Spring Boot 서버의 애플리케이션 진입점은 OdosServerV2Application입니다. 클래스에는 @SpringBootApplication, @EnableJpaAuditing, @EnableScheduling이 붙어 있습니다.
| 설정 | 코드에서 확인되는 의미 |
|---|---|
@SpringBootApplication | OdosServerV2Application을 Spring Boot 애플리케이션 진입점으로 사용합니다. |
@EnableJpaAuditing | JPA auditing을 활성화합니다. |
@EnableScheduling | 스케줄링을 활성화합니다. |
SpringApplication.run() | main()에서 애플리케이션을 실행합니다. |
현재 제공된 서버 원문에는 도메인별 controller, service, repository, entity, dto 패키지와 클래스가 포함되어 있지 않습니다. 따라서 다음과 같은 계층 연결은 이 자료만으로 구체화할 수 없습니다.
확인 가능한 HTTP 진입점은 TestController 하나입니다.
GET /을 요청합니다.TestController.index()가 요청을 처리합니다."서버 정상 작동 중!" 문자열을 반환합니다.이 엔드포인트는 서버의 정상 실행 여부를 확인하는 단순 컨트롤러이며, 제공된 원문에서는 클라이언트의 특정 화면이 이 경로를 호출하는 연결은 확인되지 않습니다.
출처: OdosServerV2Application.java:1-16, TestController.java:1-12
서버의 스키마 변경 파일은 1D1S-server-v2/src/main/resources/db/migration 아래에 있습니다. 파일명은 V10__...sql부터 V17__...sql까지 확인되며, 각 파일은 특정 테이블·컬럼·제약 조건·인덱스를 추가하거나 변경합니다.
| 마이그레이션 | 변경 대상 | 확인되는 변경 |
|---|---|---|
V10__add_unique_nickname.sql | member | nickname에 uk_nickname 유일 제약을 추가합니다. |
V11__add_challenge_participant_type.sql | challenge | type을 goal_type으로 변경하고 participation_type을 추가합니다. 기존 값은 INDIVIDUAL 또는 GROUP으로 채웁니다. |
V12__add_challenge_deleted_at.sql | challenge | nullable deleted_at을 추가합니다. |
V13__add_friend_tables.sql | friend_request, friend, block_list | 회원 간 요청·친구·차단 목록 테이블과 유일 제약, 외래 키를 추가합니다. |
V14__add_comment_report.sql | comment_report | 댓글 신고 테이블과 member, comment 외래 키 및 인덱스를 추가합니다. |
V15__add_challenge_type.sql | challenge | challenge_type 기본값 PUBLIC과 nullable password를 추가합니다. |
V16__add_notification.sql | notification, notification_preference, diary_like_milestone_state | 알림, 알림 설정, 일지 좋아요 마일스톤 상태 테이블을 추가합니다. |
V17__add_notification_endpoint_table.sql | notification_endpoint | 회원별 푸시 엔드포인트와 활성 상태·최근 확인 시각을 저장합니다. |
주요 데이터 흐름을 마이그레이션 기준으로 표현하면 다음과 같습니다.
member가 챌린지·친구·알림 관련 데이터의 회원 기준이 됩니다.challenge에는 목표 유형인 goal_type, 참여 유형인 participation_type, 공개 유형인 challenge_type, 선택적 password, 삭제 시각인 deleted_at이 추가됩니다.friend_request는 from_member_id와 to_member_id로 요청 양쪽 회원을 참조하고, status로 상태를 저장합니다.friend와 block_list는 각각 member_id와 대상 회원 ID를 저장하며, 동일 조합의 중복을 막습니다.comment_report는 신고한 member_id와 대상 comment_id를 외래 키로 연결합니다.notification은 수신자 receiver_member_id, 선택적 행위자 actor_member_id, category, type, target_type, target_id, 읽음 여부와 만료 시각을 저장합니다.notification_endpoint는 회원별 endpoint_url, p256dh, auth_secret, is_active, last_seen_at을 저장합니다.이 SQL 파일들로 테이블의 관계와 일부 데이터 모델은 확인할 수 있지만, 이를 매핑하는 JPA 엔티티 클래스명과 리포지터리·서비스 호출 순서는 제공되지 않았습니다.
출처: V10__add_unique_nickname.sql:1-2, V11__add_challenge_participant_type.sql:1-13, V12__add_challenge_deleted_at.sql:1-2, V13__add_friend_tables.sql:4-34, V14__add_comment_report.sql:1-14, V15__add_challenge_type.sql:1-4, V16__add_notification.sql:1-43, V17__add_notification_endpoint_table.sql:1-15
클라이언트와 서버가 직접 연결되는 구체적인 API 목록은 제공되지 않았지만, 공개 콘텐츠를 사이트맵에 넣는 코드에서 하나의 연결 지점은 확인됩니다. sitemap()은 fetchAllPublicChallenges(CHALLENGE_PAGE_SIZE)를 호출하고, CHALLENGE_PAGE_SIZE는 100입니다. 원문 주석은 이 함수가 GET /challenges 응답을 사용하며 커서를 끝까지 따라가 공개 챌린지를 모두 수집한다고 설명합니다.
처리 흐름은 다음과 같습니다.
sitemap()을 실행합니다.sitemap()이 fetchAllPublicChallenges(100)을 호출합니다.challengeId를 꺼냅니다./challenge/${challengeId} URL로 변환합니다.MetadataRoute.Sitemap 결과로 반환합니다.정적 공개 경로에는 /, /explore, /challenge, /guide, /notice, /terms, /privacy 등이 포함됩니다. 반대로 robots()의 DISALLOW에는 /diary, /login, /signup, /mypage, /notification, /challenge/create 등이 포함되어 있습니다. ALLOW에는 /와 /api/og가 지정되어 있습니다.
따라서 현재 원문에서 확인 가능한 프론트엔드-백엔드 연결은 공개 챌린지 목록을 가져오는 fetchAllPublicChallenges()와 주석에 언급된 GET /challenges까지입니다. 상세 화면, 관리자 화면, 인증 화면이 어떤 API를 호출하는지는 관련 API 파일과 서버 컨트롤러 원문이 추가로 필요합니다.
출처: sitemap.ts:8-51, robots.ts:4-22
다음 항목은 제공된 코드만으로는 확정할 수 없습니다.
1D1S-client의 실제 App Router 하위 경로와 각 페이지 파일은 어디에 있습니까? 현재 원문에는 / 홈과 공통 파일만 제시되어 있습니다.AppProviders 안에 어떤 프로바이더가 있으며, useHomeRandomData가 어떤 QueryClient 또는 API 모듈을 사용하는지 확인할 수 있습니까?fetchAllPublicChallenges()가 호출하는 실제 URL, 요청 파라미터, 커서 응답 필드, 오류 처리 방식은 무엇입니까?1D1S-admin의 로그인 페이지, 관리자 셸, 도메인별 관리 화면, API 훅, 폼과 모달의 실제 경로는 어디입니까?1D1S-server-v2의 도메인별 controller·service·repository·entity·dto 패키지와 클래스 목록은 무엇입니까?V10 이전에 생성된 member, challenge, diary, comment 테이블의 최초 스키마와 JPA 엔티티는 어디에 정의되어 있습니까?@EnableJpaAuditing으로 자동 기록되는 시간 필드와 해당 엔티티의 매핑 방식은 무엇입니까?GET /challenges 외에 클라이언트와 관리자 웹이 호출하는 REST 엔드포인트, WebSocket 연결 경로, 인증 헤더 구조는 무엇입니까?notification_endpoint의 endpoint_url, p256dh, auth_secret을 사용하는 발송 서비스와 스케줄 작업의 클래스는 어디에 있습니까?출처: sitemap.ts:30-39, OdosServerV2Application.java:5-10, layout.tsx:3-20