[Live 챌린지] 6주 완성! 개발 실무를 위한 고농축 바이브코딩 (Cursor AI, Figma)
공통 컴포넌트 부분의 프롬프트를 실행하던 중에 궁금한 점이 있어요. 아래와 같이 실행을 했는데, 1) input 버튼을 만들기 위해 파일 실행 - commons/components/input/prompts/prompt.101.ui.txt 2) 아래와 같은 답변이 나옴 (Claude-4.5-sonnet thinking model 사용): 🤔 룰 간 충돌 분석 prompt.101.ui.txt: variant 시스템 구현 요구 03-ui.mdc: 피그마 디자인 그대로만 구현하라고 요구 피그마 실제: 단일 Input만 존재 그리고 저 또한, AI가 돌린 코드를 분석하고 룰 재검토 및 실행을 몇 번 반복하는 과정에서 실질적으로 문제가 있을 수 있다고 보였어요. 1) Case 1 처음에 Button 컴포넌트를 위해서 프롬프트를 실행했을 때는 prompt.101.ui.txt 의 " 다음 조건을 모두 만족하는 완전한 variant 시스템을 구현할 것 ." 이 조건을 만족하기 위해서 노드ID 제공했는데도 불구하고, 계속해서 피그마의 모든 button을 다 찾아서 사이즈를 가져오는 것을 볼 수 있었습니다. 2) Case 2 그 다음에 Input 컴포넌트를 위해서 프롬프트를 실행했을 때는 03-ui.mdc 의 " 피그마 링크가 제공되면, 모든 사이즈는 제공된 피그마와 동일하게 처리할 것 " 이라는 룰을 검토하는 과정에서 문제가 있었습니다. 이 조건 때문에 반응형 웹은 고려하지 못하고 width를 진짜 있는 그대로 갖고 와서 상수로 넣어버리고, 유연성이 전혀 없게 만들었습니다. 몇 번 룰을 재검토하라고 시키고 원하는 코드와 비슷하게 만들긴 했지만, 혹시 이런 경우에 대한 해결 방법이 있을까요?
안녕하세요 제가 책보면서 공부중인데 코딩을 할 때 아래와 같이 코딩을 하다보니 에러가 뜨더라구요 result = df['차이'].min()에서 ['차이'] 이거를 빼고 하니까 되던데... 컬럼명을 넣고 안넣고에서 어떤 차이가 있는건가요..? import pandas as pd df = pd.read_csv("delivery_time.csv") # df.info() df['실제도착시간']=pd.to_datetime(df['실제도착시간']) df['주문시간']=pd.to_datetime(df['주문시간']) # df.info() df['차이']=(df['실제도착시간']-df['주문시간']).dt.total_seconds()/60 df = df.groupby('앱종류')['차이'].mean() df result = df['차이'].min() print(result)
안녕하십니까 코드빌런님. 이번 추석 연휴동안 레빗 엠큐 강의 잘 들었습니다. 다름이 아니라 강의에서 알려주신 여러 내용을 바탕으로 기존에 구현하였던 redis pub/sub 기반의 알림 기능에 레빗 엠큐를 적용해보고 있습니다. 그리고 구현 중 두가지 질문이 있어 질문을 작성하게 되었습니다. 1. 동적 큐 이름 설정 방식 우선 알림을 전송하는 과정에 대해 말씀드리면 다음과 같습니다. 알림 객체 저장 성공 시 알림 발송 sse 연결들을 ConcurrentMap으로 관리하여 대상 userId의 sse연결을 찾아 해당 연결로 알림 객체 전송 현재 메시지 큐 구조는 다음과 같습니다. 알림 저장 메시지 생성 (direct exchange, saveNotificationQueue) -> 메시지 저장 성공 시 알림 전달 메시지 생성 (fanout exchange, publishNotificationQueue), 메시지 저장 실패 시 데드레터 큐로 전달 현재 서비스는 3개의 인스턴스로 동작하고 있습니다. 이때 알림 저장 큐는 1개라서 복수 저장될 일이 없지만, 그 후에 진행되는 알림 전달의 경우 단일 큐로 작동하면 대상 sse 연결이 없는 인스턴스에서 해당 메시지를 소비하게 되면 전송이 실패합니다. 그래서 각 인스턴스마다 큐를 만들어주고 fanout exchange에 모두 바인딩하여 사용하는 방식으로 만들어야 할 것 같다고 생각하였습니다. 그래서 찾아보니 SpEL 기반 동적 큐 이름 지정 방식이 있다고 하여 해당 방식으로 구현해보았습니다. // RabbitMQConfig.java // 알림 발송 큐 @Bean public String dynamicPublishNotificationQueueName() { String randomString = UUID.randomUUID().toString(); return PUBLISH_NOTIFICATION_QUEUE + " : " + randomString; } @Bean public Queue publishNotificationQueue() { return new Queue(dynamicPublishNotificationQueueName(), false); } @Bean public FanoutExchange publishNotificationExchange() { return new FanoutExchange(PUBLISH_NOTIFICATION_EXCHANGE); } @Bean public Binding publishNotificationBinding() { return BindingBuilder.bind(publishNotificationQueue()).to(publishNotificationExchange()); } // NotificationSubscriber.java @RabbitListener(queues = "#{@dynamicPublishNotificationQueueName}") public void consumePublishNotificationMessage(Notification notification) { notificationService.publishNotification(notification); } 해당 방식으로 정상 작동은 확인하였는데, 혹시 해당 방식 외에 더 나은 방식이 있는지 궁금합니다. 2. SimpleRabbitListenerContainerFactory의 재정의에 따른 Retry 설정 미적용 강의 18강에서 application.yml에 retry 관련 프로퍼티를 설정하는 것만으로 자동으로 retry가 적용된다고 하여 해당 방식을 프로젝트에 적용해보았습니다. spring.rabbitmq.listener.simple.retry.enabled=true spring.rabbitmq.listener.simple.retry.initial-interval=1000 spring.rabbitmq.listener.simple.retry.max-attempts=3 spring.rabbitmq.listener.simple.retry.max-interval=1000 spring.rabbitmq.listener.simple.default-requeue-rejected=false 하지만 어떤 이유인지는 몰라도 retry가 작동하지 않았습니다. 실제로 실행되는 코드에 로그를 찍어봐도 한번만 시도하고 설정한 예외가 발생 후 바로 DLQ로 이동하였습니다. 그래서 원인을 찾던 도중 https://inf.run/bsxxr 에서 @RabbitListener를 사용하면 내부적으로 SimpleMessageListenerContainer 가 자동으로 생성되기 때문에 retry 설정을 읽어서 exception 이 발생할 경우 RetryTemplate을 사용해서 자동으로 설정된 속성에 해당하는 작업을 수행하게 됩니다. 라고 코드빌런님이 말씀하신 것을 보았습니다. 확인해보니 메시지큐에서 객체 자동 역직렬화를 위해 @Bean public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setMessageConverter(messageConverter()); return factory; } 이렇게 SimpleRabbitListenerContainerFactory를 정의하여 빈으로 등록해놓았는데, SimpleRabbitListenerContainerFactory를 살펴보니 public class SimpleRabbitListenerContainerFactory extends AbstractRabbitListenerContainerFactory<SimpleMessageListenerContainer> { ... 말씀하신 SimpleMessageListenerContainer 를 타입파라미터로 받아 상속받고 있는 형태였습니다. 이에 말씀하신 SimpleMessageListenerContainer 가 자동으로 생성되어 retry 설정이 적용안되는것인가? 라고 예상하여 application.properties에 정의하는 대신 @Bean public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setMessageConverter(messageConverter()); factory.setDefaultRequeueRejected(false); factory.setAdviceChain(RetryInterceptorBuilder.stateless() .maxAttempts(3) .backOffOptions(1000, 2.0, 10000) .build()); return factory; } 이렇게 직접 retry 설정을 넣어주니 그제야 재시도가 정상적으로 작동하였습니다. 해당 원인이 제가 생각한 직접 팩토리를 Bean으로 등록하면 application.properties 의 retry 설정이 무시되는 것이 맞는지 궁금합니다. 코드는 아래 url에서 보실 수 있습니다. https://github.com/Dockerel/4th-SC-TEAM1-BE/pull/15/files 강의 정말 잘 들었습니다! 이렇게 프로젝트에 바로 적용해볼 수 있어서 기분이 좋네요. 나중에 코드빌런님의 다른 기술 스택 강의도 들어보고 싶습니다. 감사합니다.
강의를 보다가 리뷰 입력 하는 부분..약 2분 정도 되는 시점에서 리뷰를 데이터 베이스에 입력 하기 위해서는 준비해야 할 것이 많다고 하셨는데.. 구체적으로 어떤 준비가 필요한가요?? supabase를 사용 하는 것이니까 테이블 만들고.. insert 함수 호출 해서 입력 하면 되는 것 외에 다른 준비를 해야 하는 것이 있나요??