Skip to content

Commit

Permalink
merge: 서비스 소개글 업데이트
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeonjerry authored Nov 13, 2023
2 parents 060e51c + 3cf11bc commit 03b2180
Show file tree
Hide file tree
Showing 30 changed files with 424 additions and 217 deletions.
16 changes: 12 additions & 4 deletions .github/workflows/backend-dev-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
outputs:
current_timestamp: ${{ steps.timestamp.outputs.timestamp }}

steps:
- name: workflow_dispatch에서 지정한 branch로 checkout
Expand All @@ -29,6 +31,13 @@ jobs:
token: ${{ secrets.SUBMODULE_TOKEN }}
submodules: true

- name: unix 타임스탬프 얻기
id: timestamp
run: echo "::set-output name=timestamp::$(date +%s)"

- name: unix 타임스탬프 확인하기
run: echo ${{ steps.timestamp.outputs.timestamp }}

- name: JDK 11로 설정
uses: actions/setup-java@v3
with:
Expand Down Expand Up @@ -65,17 +74,16 @@ jobs:
file: backend/emm-sale/Dockerfile-dev
platforms: linux/arm64/v8
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/kerdy-dev:latest
tags: ${{ secrets.DOCKERHUB_USERNAME }}/kerdy-dev:${{ steps.timestamp.outputs.timestamp }}

deploy:
needs: build
name: 배포
runs-on: [ self-hosted, label-dev ]
steps:
- name: 도커 실행
run: |
docker stop kerdy && docker rm kerdy && docker rmi -f ${{ secrets.DOCKERHUB_USERNAME }}/kerdy-dev
docker run -d -p 8080:8080 --name kerdy -e TZ=Asia/Seoul --network host ${{ secrets.DOCKERHUB_USERNAME }}/kerdy-dev
run:
sudo /home/ubuntu/deploy.sh ${{ secrets.DOCKERHUB_USERNAME }} ${{ needs.build.outputs.current_timestamp }}

- name: 슬랙 메시지 보내기
uses: 8398a7/action-slack@v3
Expand Down
17 changes: 12 additions & 5 deletions .github/workflows/backend-prod-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,22 @@ jobs:
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

outputs:
current_timestamp: ${{ steps.timestamp.outputs.timestamp }}
steps:
- name: workflow_dispatch에서 지정한 branch로 checkout
uses: actions/checkout@v3
with:
token: ${{ secrets.SUBMODULE_TOKEN }}
submodules: true

- name: unix 타임스탬프 얻기
id: timestamp
run: echo "::set-output name=timestamp::$(date +%s)"

- name: unix 타임스탬프 확인하기
run: echo ${{ steps.timestamp.outputs.timestamp }}

- name: firebase key 생성
run: |
echo "${{ secrets.FIREBASE_KEY }}" > firebase-kerdy.json
Expand Down Expand Up @@ -72,17 +80,16 @@ jobs:
file: backend/emm-sale/Dockerfile-prod
platforms: linux/arm64/v8
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/kerdy:latest
tags: ${{ secrets.DOCKERHUB_USERNAME }}/kerdy:${{ steps.timestamp.outputs.timestamp }}

deploy:
needs: build
name: 배포
runs-on: [ self-hosted, label-prod ]
steps:
- name: 도커 실행
run: |
docker stop kerdy && docker rm kerdy && docker rmi -f ${{ secrets.DOCKERHUB_USERNAME }}/kerdy
docker run -d -p 8080:8080 -v /home/ubuntu/logs/:/logs/ -e TZ=Asia/Seoul --name kerdy ${{ secrets.DOCKERHUB_USERNAME }}/kerdy
run:
sudo /home/ubuntu/deploy.sh ${{ secrets.DOCKERHUB_USERNAME }} ${{ needs.build.outputs.current_timestamp }}

- name: 슬랙 메시지 보내기
uses: 8398a7/action-slack@v3
Expand Down
116 changes: 97 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,121 @@
# 📄 서비스 소개

### 여러분은 IT 컨퍼런스나 해커톤, 대회에 참여할 때 주로 어떤 목적을 가지고 참여하시나요?
## 이런 적 있지 않나요?

아마도 유익한 강연을 듣기 위해서일 수도 있고, 같은 관심사를 가진 동료 개발자들과 교류하려는 의도일 수도 있습니다. 하지만 이러한 행사에 참여하기 위해 동료를 찾거나 행사의 질에 대한 리뷰를 알아보려면 많은 노력이 필요했을 겁니다. 이런 고민을 해결하고자 **커디(KerDy)**가 탄생했습니다.
### **평소 IT 행사 정보를 찾아보기 어렵지 않으셨나요?**

커디는 개발자들의 특별한 인연을 만들어낼 수 있는 모바일 앱 서비스로써, 행사에 참여하려는 동료를 찾거나 행사의 리뷰를 확인하고 싶을 때 직접적인 도움을 줍니다. 커디의 주요 기능은 다음과 같습니다.
<p align="center">
<img src="https://velog.velcdn.com/images/kerdy-official/post/604e39a5-85b3-4d13-8538-8962966f23a1/image.png" alt="drawing" style="width:80%;"/>
</p>

IT 업계의 능력있는 사람들이 모여 지식을 공유하고, 네트워킹하며 지식의 뿌리를 넓힐 수 있는 컨퍼런스
자신의 역량을 시험하고 경험을 넓힐 수 있는 귀중한 기회인 공모전과 대회
여러분은 컨퍼런스나 대회를 찾을 때 어떻게 찾으시나요?

어쩌다가 생각나서 행사 모음 사이트를 검색하거나 지인에게 건너 듣진 않으신가요?

이런 IT 행사 정보를 간편하게 한 데 모아볼 수 있다면 좋지 않을까요?

<br/>

### **여러분의 관심사와 맞지 않는 행사가 너무 많지 않나요?**

<p align="center">
<img src="https://velog.velcdn.com/images/kerdy-official/post/c295c82a-30dd-46df-b318-6fe3a81e5242/image.png" alt="drawing" style="width:80%;"/>
</p>

사실, 이런 행사 정보를 모아둔 사이트는 이미 여럿 존재하고 있습니다.

하지만 막상 사이트를 둘러보면, 수많은 행사 중 자신의 관심 분야와 맞는 행사의 개수는 손에 꼽습니다.

> _백엔드, 프론트엔드, 안드로이드, 정보보안, AI, 빅데이터…_
그렇다고 사이트에 매일 접속해서 자신이 관심있는 분야의 행사가 올라왔는지 확인하는 것은 귀찮고 번거로운 작업입니다.

그냥 자신이 관심있는 분야의 행사 정보만 골라 볼 수 있다면 좋지 않을까요?

<br/>

### **행사를 함께할 친구를 찾기 힘들지 않았나요?**

<p align="center">
<img src="https://velog.velcdn.com/images/kerdy-official/post/a03911ad-2759-4463-bccb-6ae91e99f378/image.png" alt="drawing" style="width:80%;"/>
</p>

가고 싶은 행사가 생겼어도, 컨퍼런스를 가려고 하니 막상 컨퍼런스를 혼자 가기가 두렵진 않으셨나요?

혹은 팀으로 참여하는 대회 팀원을 구하는 데 어려움을 겪은 적이 있지 않았나요?

하나의 플랫폼에서 행사에 함께 참여할 사람을 구할 수 있다면 좋지 않을까요?

그런 여러분을 위해 Kerdy 서비스를 출시하게 되었습니다!

<br/>

## ✨ 핵심 기능

**1. 오프라인 네트워킹 활성화**
### 1. 행사 필터링 & 스크랩

| ![](https://velog.velcdn.com/images/kerdy-official/post/10c013bf-0e44-4a5b-8e4b-fb494e8dcbd0/image.png) | ![](https://velog.velcdn.com/images/kerdy-official/post/0fb37480-65bc-40aa-b4b0-b0ecb8befd13/image.png) | ![](https://velog.velcdn.com/images/kerdy-official/post/02c7c3d0-2dde-4ea1-a3b4-8664773805ff/image.png) |
| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |

원하는 행사, 쉽게 필터링하고 찾아보세요!

커디는 관심 분야별로 행사를 필터링할 수 있습니다.

만약 관심있는 행사가 있다면 스크랩 해보시는건 어떠신가요?

관심있는 행사는 스크랩해서 언제든지 다시 확인해보세요!

<br/>

### 2. 관심 태그를 설정해 알람을 받아보세요!

| ![](https://velog.velcdn.com/images/kerdy-official/post/c82091e5-b2ae-4ff0-9457-cdcb560229ca/image.png) | ![](https://velog.velcdn.com/images/kerdy-official/post/c681ce12-73ea-4c77-b540-6c8223116a85/image.png) |
| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |

<br>
관심 태그 설정을 통해 원하는 분야의 행사 알림을 쉽게 받아볼 수 있어요.
<br>
<br>

| ![](https://velog.velcdn.com/images/kerdy-official/post/cd47070e-5fda-41b6-91d6-2985b87b234b/image.png) | ![](https://velog.velcdn.com/images/kerdy-official/post/39b28b61-624b-4857-81ee-e3c55d5bc348/image.png) |
| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |

알림 보관함을 통해 나에게 온 알림을 모아볼 수 있어요!

커디를 통해 원하는 행사에 함께 참여하고 싶은 동료를 쉽게 찾을 수 있습니다. 요청을 보내고 상대방이 수락하면, 카카오톡 오픈 프로필로 연결되어 행사 참여에 관한 대화를 이어나갈 수 있습니다.
<br/>

**2. IT 행사 정보 제공**
### 3. 행사에 같이가요!

커디에서는 다양한 IT 행사의 정보를 한눈에 볼 수 있습니다. 관심 있는 행사의 태그를 설정하면 관련 행사 정보의 업데이트 알림을 받을 수 있습니다.
| ![](https://velog.velcdn.com/images/kerdy-official/post/439361f4-076a-4b0c-b32e-1f236e90874a/image.png) | ![](https://velog.velcdn.com/images/kerdy-official/post/eb500827-3deb-40d8-a020-44542f443140/image.png) |
| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |

**3. 커뮤니티**
<br>
상대방의 활동 이력과 관심사를 확인하고 마음이 맞으면 `함께하기 요청` 을 시도해보세요.
<br>
<br>

행사에 관한 후기나 의견을 자유롭게 공유할 수 있는 댓글 커뮤니티 기능을 제공합니다. 행사에 참여한 후기나 궁금한 점을 나누어보세요.
| ![](https://velog.velcdn.com/images/kerdy-official/post/0431e0bb-40f5-404a-b560-7c96309e1965/image.png) | ![](https://velog.velcdn.com/images/kerdy-official/post/0a8de7ee-99d6-4cbb-9282-bf9b073c15f2/image.png) |
| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |

## 🌈 기대 효과
약간의 채팅을 통해 상대방이 어떤 사람인지 알아보고, 만나고자 하는 시간과 장소를 정해보세요!

그럼 커디를 통해 어떤 변화를 가져올 수 있을까요?
간단한 소통만으로 `행사에 대한 두려움` 을 조금은 덜어냈네요!

첫째, **행사 참여의 장벽을 낮춥니다.** 주변에 같은 관심사를 가진 동료가 없어도 커디를 통해 쉽게 동료를 찾을 수 있습니다.
### 4. 행사 게시판을 통해 의견을 공유하세요!

둘째, **행사의 질을 향상시킵니다.** 다양한 참여자들의 리뷰와 의견을 통해 더 나은 행사를 기획하고 개선할 수 있습니다.
| ![](https://velog.velcdn.com/images/kerdy-official/post/7b0a19da-8adf-4995-8183-ede78039657f/image.png) | ![](https://velog.velcdn.com/images/kerdy-official/post/1594c6c2-4085-45cf-977f-fa1b4f893d5e/image.png) | ![](https://velog.velcdn.com/images/kerdy-official/post/dd995906-1ac5-4142-a978-4a67dd6f94b7/image.png) |
| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |

셋째, **활발한 행사 참여를 도모합니다.** 개발자들이 관심 있어 할 IT 행사 정보를 한 데 모아 제공함으로써, 많은 개발자들이 유익한 경험을 할 수 있도록 토대를 마련합니다.
커디의 행사 상세정보 페이지는 더욱 풍부한 상호작용과 소통을 위해 게시판 기능을 제공하고 있습니다.

커디는 단순한 정보 제공 서비스가 아닙니다. 사용자들 간의 연결과 커뮤니케이션을 중심으로 한 서비스로써 개발자 커뮤니티의 활성화에 기여하고자 합니다.
이 기능을 통해 참가자 간의 소통을 쉽게 할 수 있고, 다양한 정보를 공유하고 토론할 수 있어요.

지금 바로 커디를 통해 특별한 인연과 유익한 행사 정보를 얻어보세요!
게시판 탭에서 행사에 대한 후기, QNA 등 자유롭게 이야기를 나눠 보세요!

# 설치 URL
[Google PlayStore 설치 URL](https://play.google.com/store/apps/details?id=com.emmsale&hl=ko-KR)
# 팀원 소개

# 팀 구성
### Android

<table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import com.emmsale.activity.api.ActivityApi;
import com.emmsale.activity.application.dto.ActivityAddRequest;
import com.emmsale.activity.application.dto.ActivityResponse;
import com.emmsale.activity.application.dto.ActivityResponses;
import com.emmsale.activity.domain.ActivityType;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
Expand All @@ -36,68 +35,56 @@ class ActivityApiTest extends MockMvcTestHelper {
void findAll() throws Exception {
// given
final ResponseFieldsSnippet responseFields = PayloadDocumentation.responseFields(
PayloadDocumentation.fieldWithPath("[].activityType").type(JsonFieldType.STRING)
.description("activity 분류"),
PayloadDocumentation.fieldWithPath("[].activityResponses[].id").type(JsonFieldType.NUMBER)
.description("activity id"),
PayloadDocumentation.fieldWithPath("[].activityResponses[].name").type(JsonFieldType.STRING)
.description("activity 이름")
fieldWithPath("[].id").type(JsonFieldType.NUMBER).description("activity id"),
fieldWithPath("[].activityType").type(JsonFieldType.STRING).description("activity 분류"),
fieldWithPath("[].name").type(JsonFieldType.STRING).description("activity 이름")
);

final List<ActivityResponses> activityResponses = List.of(
new ActivityResponses("동아리",
List.of(
new ActivityResponse(1L, "YAPP"),
new ActivityResponse(2L, "DND"),
new ActivityResponse(3L, "nexters")
)),
new ActivityResponses("컨퍼런스",
List.of(
new ActivityResponse(4L, "인프콘")
)),
new ActivityResponses("교육",
List.of(
new ActivityResponse(5L, "우아한테크코스")
)),
new ActivityResponses("직무",
List.of(
new ActivityResponse(6L, "Backend")
))
final List<ActivityResponse> expected = List.of(
new ActivityResponse(1L, "동아리", "YAPP"),
new ActivityResponse(2L, "동아리", "DND"),
new ActivityResponse(3L, "동아리", "nexters"),
new ActivityResponse(4L, "컨퍼런스", "인프콘"),
new ActivityResponse(5L, "교육", "우아한테크코스"),
new ActivityResponse(6L, "직무", "Backend")
);

Mockito.when(activityQueryService.findAll()).thenReturn(activityResponses);
Mockito.when(activityQueryService.findAll()).thenReturn(expected);

// when & then

mockMvc.perform(MockMvcRequestBuilders.get("/activities"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcRestDocumentation.document("find-all-activities", responseFields));
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcRestDocumentation.document("find-all-activities", responseFields));
}

@Test
@DisplayName("새로운 활동을 생성할 수 있다.")
void addTag() throws Exception {
//given
final RequestFieldsSnippet requestFields = requestFields(
fieldWithPath("activityType").type(JsonFieldType.STRING).description("활동 유형"),
fieldWithPath("name").type(JsonFieldType.STRING).description("활동 이름")
fieldWithPath("activityType").type(JsonFieldType.STRING).description("활동 유형"),
fieldWithPath("name").type(JsonFieldType.STRING).description("활동 이름")
);

final ActivityAddRequest request = new ActivityAddRequest(ActivityType.CLUB, "DND");
final ActivityResponse response = new ActivityResponse(3L, "DND");
final ActivityResponse response = new ActivityResponse(3L,
ActivityType.CLUB.getValue(),
"DND"
);

when(activityCommandService.addActivity(any(ActivityAddRequest.class))).thenReturn(response);

final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("id").type(JsonFieldType.NUMBER).description("활동 식별자"),
fieldWithPath("name").type(JsonFieldType.STRING).description("활동 이름")
fieldWithPath("id").type(JsonFieldType.NUMBER).description("활동 식별자"),
fieldWithPath("activityType").type(JsonFieldType.STRING).description("활동 종류"),
fieldWithPath("name").type(JsonFieldType.STRING).description("활동 이름")
);

//when & then
mockMvc.perform(post("/activities")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isCreated())
.andDo(document("add-activity", requestFields, responseFields));
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isCreated())
.andDo(document("add-activity", requestFields, responseFields));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import com.emmsale.tag.TagFixture;
import com.emmsale.tag.application.dto.TagRequest;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -109,8 +108,8 @@ void findEvent() throws Exception {
void findEvents() throws Exception {
// given
final RequestParametersSnippet requestParameters = requestParameters(
RequestDocumentation.parameterWithName("category")
.description("행사 카테고리(CONFERENCE, COMPETITION)"),
RequestDocumentation.parameterWithName("category").optional()
.description("행사 카테고리(CONFERENCE, COMPETITION)(option)"),
RequestDocumentation.parameterWithName("start_date")
.description("필터링하려는 기간의 시작일(yyyy:mm:dd)(option)")
.optional(),
Expand Down Expand Up @@ -171,7 +170,7 @@ void findEvents() throws Exception {
);

Mockito.when(eventService.findEvents(any(EventType.class),
any(LocalDate.class), eq("2023-07-01"),
any(LocalDateTime.class), eq("2023-07-01"),
eq("2023-07-31"),
eq(null), any(), eq("컨퍼"))).thenReturn(eventResponses);

Expand Down Expand Up @@ -223,7 +222,7 @@ void updateEventTest() throws Exception {
request.getLocation(),
tags.stream().map(TagRequest::getName).collect(Collectors.toList()),
"image1.jpg", request.getType().toString(),
List.of("imageUrl1", "imageUrl2"), "행사기관", "유료","온라인");
List.of("imageUrl1", "imageUrl2"), "행사기관", "유료", "온라인");

Mockito.when(eventService.updateEvent(eq(eventId), any(EventDetailRequest.class), any()))
.thenReturn(response);
Expand Down Expand Up @@ -325,7 +324,7 @@ void addEventTest() throws Exception {
request.getLocation(),
tags.stream().map(TagRequest::getName).collect(Collectors.toList()),
"image1.jpg", request.getType().toString(),
List.of("imageUrl1", "imageUrl2"), "행사기관", "무료","오프라인");
List.of("imageUrl1", "imageUrl2"), "행사기관", "무료", "오프라인");

Mockito.when(eventService.addEvent(any(EventDetailRequest.class), any()))
.thenReturn(response);
Expand Down
Loading

0 comments on commit 03b2180

Please sign in to comment.