티스토리챌린지 11

팀플) 캘린더 DB 저장.

우선은 리포지토리와 엔티티를 생성하고 그에 맞게끔 연결은 했는데.DB를 추가 한 이유가 사용자 UI 개선의 목적도 있지만 결국 결론은이제 DB저장을 하면 고유한 ID 번호가 생김 -> 복잡한 형태의 고유 ID를 입력하기 싫음.이거임.그래서 지금 작성한 로직을 DB ID 번호로 돌아가게끔 해야됨. 지금은 googleEventId를 내가 입력을 해줘야지 찾는데, 그게 아니고 고유 번호를 따라서 googleEventId를 찾아서 캘린더까지 접근해서 수정 삭제 읽기가 가능하게끔. 현재 코드는@Service@RequiredArgsConstructorpublic class PublicCalendarEventService { private final CalendarEventManager calendarEvent..

팀플) Google Calendar API 연결

우선 API 연결을 위해서 다시 구글 콘솔로 진입.추가해줬음.우선 약간의 문제가 있다면 나는 데이터를 보여줄 캘린더 하나, 그리고 사용자가 천체 관측 일정을 관리할 수 있는 캘린더 하나를 이 구글 캘린더로 제공을 하고 싶었는데, 이게 내 공용 캘린더를 읽기전용으로 전환해서밖에 보여줄 수 없다는 결론에 도달함.그게 아니라면 데이터를 보여줄 캘린더 따로 구축, 또 사용자는 구글 캘린더를 사용해야되는데, 이 과정에서 공용 데이터 캘린더 -> 사용자 캘린더로의 일정 복사도 복잡해질 것 같고.. 그래서 일관성 있게 그냥 내 구글 계정에 캘린더를 희생하기로 함.여튼 결론이 뭐냐?공용 캘린더에 이벤트 추가 및 공유: 천문 이벤트와 관련된 정보를 하나의 공용 캘린더에 추가하고, 이 캘린더를 사용자들에게 읽기 전용으로 ..

팀플) 유성우 가시성 데이터 로직 수정 및 API 재배포

그니까 뭐가 맘에 안들었냐 하면 지금 로직은 UTC 시각 기준으로 하루만 요청을 하는데 이러면 24시간중 UTC 시간 기준으로 0시만 요청하게 되어서 데이터의 의미가 없어짐.이게 이유를 설명하자면지구는 자전중임. -> UTC기준 0시만 검증함. -> 위도 경도 값을 받는 이유가 없어짐. -> 왜? 애진작 UTC 기준으로 0시만 요청하면 위도 경도를 받아봤자 가시성에 대한 평가는 명확하게 처리를 못함. -> 그래서 로직 자체를 UTC 기준 24시간을 1시간 단위로 나눠서 하기로 함.일단 이게 결론인데, 또 다른 문제는 피크타임의 start_date에서만 이 계산을 했다는거.그래서 피크타임의 시작점과 끝점을 순회하면서 고도와 달의 위상을 비교해서 Best_time을 뽑아내고 그 결과를 포함한 결과를 보여주도..

팀플) 유성우 데이터 통신 로직

이제 유성우 데이터 통신 로직을 짜면 됨.뭐 기존에 했던 별자리, 행성과 같음.MeteorShowerController와 MeteorShowerService생성하고 기반 다져놓고..이제 또 다 프론트에서 처리해야됨.그전에 시큐리티에 등록해두자.징글징글하구만여튼 백엔드 로직은 이제 준비 다 됐음. 추후에 DB에 저장해놓고 꺼내쓸거라 이건 일단 나중에 하자. (유성우는 주기가 많이 일정해서 이렇게 써도 됨.)간만에 Postman 한번써볼까?이렇게 요청 보내보자구굳 이럼 이제 프론트 로직을 짜면 되는데 그전에 이걸 DB에 어떻게 집어넣을지 고민 좀 해보자.아 내가 지금 내가 만든 API 명세서를 다시 보고 왔는데 저것도 로우데이터였음 ㅋㅋmeteor_shower_visibility라는 경로로 위도 경도값으로 ..

팀플) SQLAlchemy 세션 트랜잭션 관리 오류로 인해 다중 요청 환경에서 발생하는 충돌 문제 (오라클 서버 재배포)

나는 몰랐는데 팀원들이 내 코드를 받아서 요청보낼 때 행성 하나씩 오류가 나는걸 발견함.지금 문제는 ->동시에 다수의 행성 데이터를 요청할 때, SQLAlchemy 세션이 동일 트랜잭션 상태를 공유하거나 적절히 초기화되지 않아 Can't reconnect until invalid transaction is rolled back 에러가 발생함. 이로 인해 트랜잭션 충돌이나 데이터베이스 연결 문제가 간헐적으로 나타남.으로 정리할 수 있음.그래서 이걸 근본적으로 해결하기 위해서는SQLAlchemy 세션 관리 최적화retry_query 개선데이터베이스 연결 풀 확인 및 최적화캐싱 도입이정도?순차적으로 해보자.우선은 app/__init__.py에 # scoped_session 설정Session = scoped_s..

팀플) OpenWeather API 연결

처음 계획은 백엔드로 통신하고 값까지 검증해서 관측 가능한 상태랑 불가능한 상태로 나눌까 했었는데, 가만 생각해보니까 비효율적이라는 것을 깨닫고 오직 프론트에서만 돌아가도 된다고 결론이 났음.왜? 데이터는 데이터대로 보여주고 마지막에 요청 위치의 날씨를 확인하고 그날 기후는 뭐 흐리니 관측이 어려울 수 있음. 만 말해주면 끝날 문제라 프론트에서 충분히 처리 가능함.기존에 학원 과제 때문에 약식으로 만든 Weather API 프로젝트가 있어서 거기서 API KEY 가져와서 재사용하면 됨.여튼 .env KEY 값 저장하고 시작하자.useUserLocation훅을 사용해서 요청을 보낼거고, WeatherPage.js에서 mainPage접근시에 알아서 요청되게 했음.그래서 일단 요청에는 성공했음.여기 비회원이면..

팀플) 행성데이터 연결 및 로그인 로그아웃 UI 처리

이거 컨트롤러랑 서비스 준비는 해둠 사실.근데 캐싱은 안만져놔서 해놓자고@Cacheable(value = "planetVisibility", key = "#planetName + '-' + #latitude + '-' + #longitude + '-' + #startDate + '-' + #rangeDays")@Retryable(value = {RestClientException.class}, maxAttempts = 3, backoff = @Backoff(delay = 1000))캐싱 설정도 했고, @Retryable은 재시도 로직인데 Spring Retry의존성 주입해서 사용함. 이런게 있길래 넣어둠.여튼 백엔드 준비는 끝남.그래서 이제 프론트 작성하고 요청 해봤는데이게 백엔드 로직이 파라미터가 da..

팀플) 별자리 데이터 캐싱 구현 (Redis)

지금 어느정도 설계는 다 완료 되었는데 캐싱 시스템이 있으면 좋을 것 같음.과도한 요청이 사용자 경험에 영향을 끼치니까 만약 사용자가 자주 요청하는 것들은 기억해두고 처리하면 아주 좋을 것 같으니까 구현해두면 경험적으로도 비용적으로도 유리하다는 생각.그래서 이걸 Redis로 처리할거고 먼저 로컬에서 설치하고 나중에 배포할 때는 Docker로 할지 고민인데..지금 개발 단계긴하지만 하고 있는게 팀플이기 때문에 Docker로 처리하는게 접근성면에서 조금 더 유리할 것 같다. 나중에 배포할 때도 한번 더 안거쳐도 되고..근데 그냥 잘 생각해보니까 스프링 리액트에다가 도커까지 엮어서 뭐 하기 귀찮다 지금 그게 중요한게 아니니까 나는 우선 로컬에서 설치해서 진행하자.brew install redis정상 작동 확인..

팀플) 달의 위상 로직수정 및 오라클 서버 재배포

오늘 집 가다가 하늘을 보니까 겁나 땡그란 보름달이였다.이건 못참지 하고 지금 레슨 잠깐 비는 시간동안 API 요청을 오늘 날짜로 해봤는데,고쳐야겠지? 아 ㅋㅋ조명률은 거의 근접한 결과인데 위상이 엉망이다.뭐 고쳐야지 어떡하냐,,그래서 다시 코드를 좀 살펴보니까illumination은 자정과 정오 두 시점의 평균을 사용하고 있고, moon_phase는 정오만 사용하고 있었다.moon_phase도 평균 값인줄...이래서 한꺼번에 하다가 한번 떨어져서 체크 해봐야되는구나 싶다.그럼 내가 해야할 일은 달의 위상값도 자정과 정오의 평균 값을 사용하게 로직을 짜보고 테스트 해본 이후에, 값이 조명률과 차이가 크다고 생각되면 걍 버리고 조명률만 사용하게끔 하고 재배포 하지 않으면 되고, 값이 신뢰성이 높아진다면 수..

팀플) 회원의 별자리 데이터 요청 로직

이제 즐겨찾기 기능을 완성했으니까, 별자리 데이터 요청을 회원도 할 수 있게 됨. (자동으로 되는거긴 하지만)그에 대한 하드코딩을 지우고 이제 제대로 백엔드와 통신후에 요청이 되도록 수정하면 될듯.function StarMap() { const [constellationData, setConstellationData] = useState(null); const [error, setError] = useState(null); const { location, isLoading } = useUserLocation(); // 사용자 위치와 로딩 상태를 가져옴 const { isAuthenticated } = useAuth(); // 로그인 상태 확인 const { userId } = ..