아이센스에프앤비
경력근거: 메시지 ·업무 ·프로젝트가 연결되는 협업플랫폼 기능 구현
※ 실제 산출물이 아닌 AI 예측 시안입니다.
아이센스에프앤비는 PC방 아이센스 블랙라벨 PC존, 만화카페 벌툰, 한식포차 생전포차의 프랜차이즈 본사로, 예비 창업자와 가맹점주에게 가맹 창업·인테리어 시공·물품 공급을 하고 매장 손님이 쓰는 벌툰 앱도 직접 운영해요. 이번 공고는 본사에서 메시지·업무·프로젝트가 연결되는 협업플랫폼을 만들 풀스택 개발자를 뽑아요.
공고는 이 자리가 할 일로 '메시지 ·업무 ·프로젝트가 연결되는 협업플랫폼 기능 구현'과 '사용자권한, 데이터접근, 알림 및 실시간상태 관리 기능개발'을 꼽아요. 한 업무를 두고 담당이 바뀌고, 담당자와 요청자가 메시지로 묻고 답하고, 사람이 프로젝트에 들고 나는 일은 서로 다른 때에 따로 일어나요. 그래서 지금 누가 움직일 차례인지는 어느 한 기록만 봐서는 알 수 없어요. 프로젝트 멤버만 그 프로젝트의 업무를 볼 수 있게 권한을 두면, 사람이 빠지는 순간 그 사람이 맡던 업무는 맡은 사람이 볼 수 없는 업무가 돼요.
공고는 담당업무로 메시지·업무·프로젝트가 연결되는 협업플랫폼 기능 구현을 꼽아요. 프론트엔드·백엔드·API·DB 설계까지 풀스택으로 개발하는 자리예요.
공고는 사용자 권한, 데이터 접근, 알림, 실시간 상태 관리 기능 개발을 담당업무로 적었어요. 자격요건에도 인증·권한·데이터 접근 같은 기본 보안 요구사항을 구현하는 역량을 넣었어요.
공고는 우대사항으로 실시간 메시징·동기화·검색·알림·문서편집 기능 개발 경험과, 서비스 장애 대응·성능 최적화·데이터 정합성 문제를 해결해 본 경험을 꼽아요.
프로젝트 리더가 협업플랫폼에서 업무 현황을 열 때 보는 관리자 페이지예요. 그 시각에 열려 있는 업무마다 담당자가 하고 있는지, 담당자가 요청자의 답을 기다리는지, 담당자가 프로젝트에서 빠져 업무를 볼 수 없는지, 한동안 아무도 손대지 않았는지 알려 주고, 같은 차례끼리 사람별로 모아 리더가 누구에게 먼저 말을 걸지 정하게 해 줘요. 받은 데이터를 담을 DB 설계와 기술·구조, 그리고 한동안 손대지 않았다고 볼 일수는 지원자가 정해요.
협업플랫폼에서 프로젝트를 맡아 여러 사람에게 업무를 나눠 준 프로젝트 리더예요. 업무마다 담당자가 바뀌고 메시지로 질문이 오가며 사람이 프로젝트에 들고 나서, 지금 누가 움직여야 하는지 알려면 업무마다 대화를 하나씩 열어 봐야 해요.
프로젝트 리더가 협업플랫폼에서 그 프로젝트의 업무 현황 화면을 연 기록이에요. 한 행이 한 번 연 것이고 view_id 가 키예요. project_id 는 연 프로젝트로, tasks.project_id·project_members.project_id 와 같은 프로젝트 코드예요. viewer_id 는 연 사람이고, 그 프로젝트의 project_members 에서 role 이 leader 인 사람이에요. viewed_at 은 화면을 연 시각이고, 이 기능이 '지금'으로 삼는 시각이에요 — 이 시각과 같거나 이른 기록만으로 업무마다 누구 차례인지 가려요. 다섯 표의 시각은 모두 협업플랫폼 서버가 그 일을 저장한 시각이라 같은 시계 기준으로 견줄 수 있어요. 리더는 프로젝트가 진행되는 평일마다 화면을 한두 번 열어요. 큰 데이터는 2026년 7월 1일부터 10월 28일까지 프로젝트 48개의 리더가 연 기록 전부이고, 시작용은 그 가운데 10월 28일 09:00~12:00 에 PJ-17·PJ-21 리더가 연 기록 전부를 같은 ID·같은 값으로 잘라 낸 것이에요.
전체 2행 가운데 앞 2행이에요.
| view_id | project_id | viewer_id | viewed_at |
|---|---|---|---|
| BV-02254 | PJ-21 | U-013 | 2026-10-28T09:20:00+09:00 |
| BV-02260 | PJ-17 | U-001 | 2026-10-28T10:00:00+09:00 |
2행 전부를 JSON 파일 하나로 받을 수 있어요.
같은 형식으로 만든 2,292행이에요. 위 데이터가 이 안에 그대로 들어 있어요(한 줄에 한 행, gzip 압축).
미리보기와 내려받는 데이터 모두 이 형식(JSON Schema)을 따라요.
{
"type": "object",
"description": "리더가 업무 현황 화면을 한 번 연 기록. 키는 view_id.",
"additionalProperties": false,
"required": [
"view_id",
"project_id",
"viewer_id",
"viewed_at"
],
"properties": {
"view_id": {
"type": "string",
"pattern": "^BV-[0-9]{5}$",
"description": "열람 번호. 이 표의 키예요."
},
"project_id": {
"type": "string",
"pattern": "^PJ-[0-9]{2}$",
"description": "연 프로젝트 코드(PJ-01~PJ-48). tasks.project_id·project_members.project_id 와 같은 코드예요."
},
"viewer_id": {
"type": "string",
"pattern": "^U-[0-9]{3}$",
"description": "화면을 연 사람 코드. 그 프로젝트의 project_members 에서 role 이 leader 인 사람이에요."
},
"viewed_at": {
"type": "string",
"format": "date-time",
"description": "화면을 연 시각. 협업플랫폼 서버가 기록한 한국 시간(+09:00) ISO 8601, 초 단위. 이 기능이 '지금'으로 삼는 시각이에요."
}
}
}프로젝트에 올라온 업무예요. 한 행이 업무 하나이고 task_id 가 키예요. project_id 는 업무가 속한 프로젝트로, 한 업무는 한 프로젝트에만 속하고 다른 프로젝트로 옮겨 가지 않아요. requester_id 는 업무를 요청한 사람이에요. 요청자는 업무가 열려 있는 동안 그 프로젝트 멤버로 남아 있고, 그 업무의 담당자가 되지는 않아요. created_at 은 업무를 올린 시각이고, 같은 시각에 task_assignments 에 첫 담당 기록이 있어요. completed_at 은 업무를 끝냄으로 바꾼 시각이고, 데이터 끝(2026-10-28T23:59:59+09:00)까지 끝내지 않았으면 null 이에요. 끝낸 업무를 다시 열지는 않아요. 리더가 화면을 열기 몇 분 전에 끝낸 업무와 몇 분 뒤에 끝낸 업무가 들어 있어요. 큰 데이터는 7월 1일부터 10월 28일까지 프로젝트 48개에 올라온 업무 전부이고, 시작용은 PJ-17·PJ-21 에서 10월 28일에 한 번이라도 열려 있던 업무 전부를 같은 ID·같은 값으로 잘라 낸 것이에요.
전체 19행 가운데 앞 5행이에요.
| task_id | project_id | title | requester_id | created_at | completed_at |
|---|---|---|---|---|---|
| T-01956 | PJ-17 | 알림 문구 정리 | U-002 | 2026-10-05T10:10:20+09:00 | — |
| T-02058 | PJ-17 | 정산 내역 화면 개선 | U-002 | 2026-10-07T09:40:12+09:00 | — |
| T-02130 | PJ-17 | 예약 오류 수정 | U-003 | 2026-10-08T11:00:05+09:00 | — |
| T-02189 | PJ-21 | 권한 요청 처리 | U-014 | 2026-10-09T11:40:03+09:00 | — |
| T-02213 | PJ-17 | 권한 설정 화면 정리 | U-002 | 2026-10-09T15:40:02+09:00 | — |
19행 전부를 JSON 파일 하나로 받을 수 있어요.
같은 형식으로 만든 3,045행이에요. 위 데이터가 이 안에 그대로 들어 있어요(한 줄에 한 행, gzip 압축).
미리보기와 내려받는 데이터 모두 이 형식(JSON Schema)을 따라요.
{
"type": "object",
"description": "업무 하나. 키는 task_id.",
"additionalProperties": false,
"required": [
"task_id",
"project_id",
"title",
"requester_id",
"created_at",
"completed_at"
],
"properties": {
"task_id": {
"type": "string",
"pattern": "^T-[0-9]{5}$",
"description": "업무 번호. 이 표의 키예요."
},
"project_id": {
"type": "string",
"pattern": "^PJ-[0-9]{2}$",
"description": "업무가 속한 프로젝트 코드. 한 업무는 한 프로젝트에만 속해요."
},
"title": {
"type": "string",
"minLength": 1,
"description": "업무 제목."
},
"requester_id": {
"type": "string",
"pattern": "^U-[0-9]{3}$",
"description": "업무를 요청한 사람 코드. project_members.user_id 와 같은 사람 코드이고, 업무가 열려 있는 동안 그 프로젝트 멤버예요. 이 업무의 담당자가 되지는 않아요."
},
"created_at": {
"type": "string",
"format": "date-time",
"description": "업무를 올린 시각. 협업플랫폼 서버가 기록한 한국 시간(+09:00) ISO 8601, 초 단위. 이 시각에 task_assignments 에 첫 담당 기록이 있어요."
},
"completed_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "업무를 끝냄으로 바꾼 시각. 협업플랫폼 서버가 기록한 한국 시간(+09:00) ISO 8601, 초 단위. 데이터 끝(2026-10-28T23:59:59+09:00)까지 끝내지 않았으면 null 이에요."
}
}
}업무의 담당자를 정하거나 바꾼 기록이에요. 한 행이 한 번 정한 것이고 assignment_id 가 키예요. task_id 는 tasks.task_id 를 가리켜요. assignee_id 는 그때부터 업무를 맡은 사람이고, 맡긴 시각에 그 프로젝트 멤버였어요. assigned_at 은 담당을 정한 시각이에요. 업무마다 올린 시각에 첫 기록이 있고 담당을 비우는 기록은 없어서, 열린 업무에는 늘 담당자가 한 명 있어요. 한 번도 담당이 바뀌지 않은 업무, 리더가 화면을 열기 하루 전쯤 다른 사람에게 다시 맡긴 업무가 섞여 있고, 메시지는 오래전에 끊겼는데 최근에 담당만 바뀐 업무도 있어요. 큰 데이터는 tasks 큰 데이터에 있는 업무 전부의 담당 기록이고, 시작용은 tasks 시작용에 든 업무의 담당 기록 전부를 같은 ID·같은 값으로 잘라 낸 것이에요.
전체 23행 가운데 앞 5행이에요.
| assignment_id | task_id | assignee_id | assigned_at |
|---|---|---|---|
| AS-002647 | T-01956 | U-007 | 2026-10-05T10:10:20+09:00 |
| AS-002778 | T-02058 | U-008 | 2026-10-07T09:40:12+09:00 |
| AS-002872 | T-02130 | U-007 | 2026-10-08T11:00:05+09:00 |
| AS-002877 | T-01956 | U-005 | 2026-10-08T11:20:45+09:00 |
| AS-002944 | T-02189 | U-018 | 2026-10-09T11:40:03+09:00 |
23행 전부를 JSON 파일 하나로 받을 수 있어요.
같은 형식으로 만든 4,170행이에요. 위 데이터가 이 안에 그대로 들어 있어요(한 줄에 한 행, gzip 압축).
미리보기와 내려받는 데이터 모두 이 형식(JSON Schema)을 따라요.
{
"type": "object",
"description": "업무 담당을 한 번 정한 기록. 키는 assignment_id.",
"additionalProperties": false,
"required": [
"assignment_id",
"task_id",
"assignee_id",
"assigned_at"
],
"properties": {
"assignment_id": {
"type": "string",
"pattern": "^AS-[0-9]{6}$",
"description": "담당 기록 번호. 이 표의 키예요."
},
"task_id": {
"type": "string",
"pattern": "^T-[0-9]{5}$",
"description": "담당을 정한 업무. tasks.task_id 를 가리켜요."
},
"assignee_id": {
"type": "string",
"pattern": "^U-[0-9]{3}$",
"description": "이때부터 업무를 맡은 사람 코드. project_members.user_id 와 같은 사람 코드이고, 맡긴 시각에 그 프로젝트 멤버였어요."
},
"assigned_at": {
"type": "string",
"format": "date-time",
"description": "담당을 정한 시각. 협업플랫폼 서버가 기록한 한국 시간(+09:00) ISO 8601, 초 단위. 업무의 첫 기록은 tasks.created_at 과 같은 시각이에요."
}
}
}업무에 남긴 메시지예요. 한 행이 메시지 하나이고 message_id 가 키예요. 메시지 본문은 담지 않았어요. task_id 는 tasks.task_id 를 가리켜요. author_id 는 쓴 사람이고, 쓴 시각에 그 프로젝트 멤버였어요. mention_ids 는 메시지에서 부른 사람 코드의 목록으로, 부른 사람이 없으면 빈 목록이고 쓴 사람 자신은 들어 있지 않아요. sent_at 은 메시지를 보낸 시각이에요. 담당자가 요청자를 불러 물었는데 답이 없는 업무, 물은 뒤 요청자가 답한 업무, 요청자와 다른 사람을 함께 부른 메시지, 리더가 화면을 연 몇 분 뒤에 온 답과 재촉, 며칠째 메시지가 없는 업무가 들어 있어요. 큰 데이터는 tasks 큰 데이터에 있는 업무 전부의 메시지이고, 시작용은 tasks 시작용에 든 업무의 메시지 전부(리더가 화면을 연 뒤의 메시지까지)를 같은 ID·같은 값으로 잘라 낸 것이에요.
전체 98행 가운데 앞 5행이에요.
| message_id | task_id | author_id | mention_ids | sent_at |
|---|---|---|---|---|
| MS-016113 | T-01956 | U-007 | [] | 2026-10-07T17:30:11+09:00 |
| MS-016646 | T-01956 | U-005 | ["U-002"] | 2026-10-09T09:24:32+09:00 |
| MS-016689 | T-01956 | U-002 | ["U-005"] | 2026-10-09T10:23:05+09:00 |
| MS-016931 | T-02058 | U-008 | ["U-002"] | 2026-10-09T16:25:41+09:00 |
| MS-016945 | T-02058 | U-002 | [] | 2026-10-09T16:41:13+09:00 |
98행 전부를 JSON 파일 하나로 받을 수 있어요.
같은 형식으로 만든 24,265행이에요. 위 데이터가 이 안에 그대로 들어 있어요(한 줄에 한 행, gzip 압축).
미리보기와 내려받는 데이터 모두 이 형식(JSON Schema)을 따라요.
{
"type": "object",
"description": "업무에 남긴 메시지 하나. 키는 message_id.",
"additionalProperties": false,
"required": [
"message_id",
"task_id",
"author_id",
"mention_ids",
"sent_at"
],
"properties": {
"message_id": {
"type": "string",
"pattern": "^MS-[0-9]{6}$",
"description": "메시지 번호. 이 표의 키예요."
},
"task_id": {
"type": "string",
"pattern": "^T-[0-9]{5}$",
"description": "메시지를 남긴 업무. tasks.task_id 를 가리켜요."
},
"author_id": {
"type": "string",
"pattern": "^U-[0-9]{3}$",
"description": "쓴 사람 코드. project_members.user_id 와 같은 사람 코드이고, 쓴 시각에 그 프로젝트 멤버였어요."
},
"mention_ids": {
"type": "array",
"items": {
"type": "string",
"pattern": "^U-[0-9]{3}$"
},
"uniqueItems": true,
"description": "이 메시지에서 부른 사람 코드 목록(project_members.user_id 와 같은 코드). 부른 사람이 없으면 빈 목록이고, 쓴 사람 자신은 들어 있지 않아요."
},
"sent_at": {
"type": "string",
"format": "date-time",
"description": "메시지를 보낸 시각. 협업플랫폼 서버가 기록한 한국 시간(+09:00) ISO 8601, 초 단위."
}
}
}사람이 프로젝트 멤버였던 기간이에요. 한 행이 한 사람이 한 프로젝트에 든 한 번의 기간이고, project_id·user_id·added_at 묶음이 키예요. 같은 사람이 빠졌다가 다시 들어오면 행이 하나 더 생겨요. 한 사람은 여러 프로젝트에 함께 들 수 있어요. user_id 는 사람 코드이고 tasks.requester_id·task_assignments.assignee_id·messages.author_id·messages.mention_ids·board_views.viewer_id 가 모두 이 코드를 써요. member_name 은 그 사람의 이름이고, 같은 user_id 는 어느 행에서나 같은 이름이에요. role 은 leader(프로젝트를 맡은 리더, 프로젝트마다 한 명이고 빠지지 않아요) 또는 member 예요. added_at 은 프로젝트에 넣은 시각, removed_at 은 프로젝트에서 뺀 시각이고, 데이터 끝(2026-10-28T23:59:59+09:00)까지 빠지지 않았으면 null 이에요. 이 데이터에서는 added_at 과 같거나 늦고 removed_at 보다 이른 동안에만 그 사람이 그 프로젝트의 업무를 볼 수 있어요. 업무를 맡은 채 프로젝트에서 빠진 사람, 빠졌다가 다시 들어온 사람, 리더가 화면을 열기 몇 분 전과 몇 분 뒤에 빠진 사람이 들어 있어요. 큰 데이터는 프로젝트 48개의 멤버 기간 전부이고, 시작용은 PJ-17·PJ-21 의 멤버 기간 전부를 같은 값으로 잘라 낸 것이에요.
전체 19행 가운데 앞 5행이에요.
| project_id | user_id | member_name | role | added_at | removed_at |
|---|---|---|---|---|---|
| PJ-17 | U-012 | 장수아 | member | 2026-08-24T09:05:52+09:00 | 2026-09-19T11:00:00+09:00 |
| PJ-17 | U-002 | 박서준 | member | 2026-08-24T09:06:53+09:00 | — |
| PJ-17 | U-008 | 문태오 | member | 2026-08-24T09:09:51+09:00 | — |
| PJ-17 | U-006 | 한지민 | member | 2026-08-24T09:19:00+09:00 | 2026-10-28T09:58:00+09:00 |
| PJ-17 | U-005 | 이도윤 | member | 2026-08-24T09:26:37+09:00 | 2026-10-20T14:10:00+09:00 |
19행 전부를 JSON 파일 하나로 받을 수 있어요.
같은 형식으로 만든 545행이에요. 위 데이터가 이 안에 그대로 들어 있어요(한 줄에 한 행, gzip 압축).
미리보기와 내려받는 데이터 모두 이 형식(JSON Schema)을 따라요.
{
"type": "object",
"description": "한 사람이 한 프로젝트에 든 한 번의 기간. 키는 (project_id, user_id, added_at) 묶음.",
"additionalProperties": false,
"required": [
"project_id",
"user_id",
"member_name",
"role",
"added_at",
"removed_at"
],
"properties": {
"project_id": {
"type": "string",
"pattern": "^PJ-[0-9]{2}$",
"description": "프로젝트 코드. tasks.project_id·board_views.project_id 와 같은 코드예요."
},
"user_id": {
"type": "string",
"pattern": "^U-[0-9]{3}$",
"description": "사람 코드(U-001~U-160)."
},
"member_name": {
"type": "string",
"minLength": 1,
"description": "사람 이름. 같은 user_id 는 어느 행에서나 같은 이름이고, 다른 사람과 이름이 겹치지 않아요."
},
"role": {
"type": "string",
"enum": [
"leader",
"member"
],
"description": "leader 는 프로젝트를 맡은 리더(프로젝트마다 한 명, 빠지지 않아요), member 는 그 밖의 멤버예요."
},
"added_at": {
"type": "string",
"format": "date-time",
"description": "프로젝트에 넣은 시각. 협업플랫폼 서버가 기록한 한국 시간(+09:00) ISO 8601, 초 단위."
},
"removed_at": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "프로젝트에서 뺀 시각. 협업플랫폼 서버가 기록한 한국 시간(+09:00) ISO 8601, 초 단위. 데이터 끝(2026-10-28T23:59:59+09:00)까지 빠지지 않았으면 null 이에요."
}
}
}