{"id":51436840,"url":"https://github.com/claude-code-expert/todo-app","last_synced_at":"2026-07-05T07:07:33.251Z","repository":{"id":336044226,"uuid":"1147104287","full_name":"claude-code-expert/todo-app","owner":"claude-code-expert","description":"Ticket+Kanban Style TODO App","archived":false,"fork":false,"pushed_at":"2026-04-05T08:03:25.000Z","size":2205,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-05T10:05:52.675Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://tika-app.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/claude-code-expert.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-01T07:40:10.000Z","updated_at":"2026-04-05T08:03:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"1769654a-dff1-4e9a-9eaa-76fb7b21be69","html_url":"https://github.com/claude-code-expert/todo-app","commit_stats":null,"previous_names":["claude-code-expert/todo-app"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/claude-code-expert/todo-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claude-code-expert%2Ftodo-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claude-code-expert%2Ftodo-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claude-code-expert%2Ftodo-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claude-code-expert%2Ftodo-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/claude-code-expert","download_url":"https://codeload.github.com/claude-code-expert/todo-app/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claude-code-expert%2Ftodo-app/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35146126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-05T07:07:30.227Z","updated_at":"2026-07-05T07:07:33.167Z","avatar_url":"https://github.com/claude-code-expert.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TODO App - Ticket-based Kanban Board\n\n\u003e 티켓 기반 칸반 보드 할 일 관리 애플리케이션 (MVP)\n\u003e https://ticket-kanban.vercel.app \n\n![스크린샷](https://github.com/claude-code-expert/todo-app/blob/main/reference/image/scrshot.png?raw=true)\n\n클로드 코드 마스터 책 예제로 6장에 해당 하는 예제 사이트 이다. \n\n단일 사용자 환경에서 티켓을 생성하고, 4개 칼럼(Backlog, TODO, In Progress, Done) 간 드래그앤드롭으로 상태를 관리하는 칸반 보드 앱이다.\n\n---\n\n## 주요 기능\n\n| ID | 기능 | 설명 |\n|----|------|------|\n| FR-001 | 티켓 생성 | 제목, 설명, 우선순위, 시작예정일, 종료예정일 입력. Backlog 맨 위에 배치 |\n| FR-002 | 보드 조회 | 4개 칼럼별 그룹화, position 오름차순 정렬 |\n| FR-003 | 티켓 상세 | 카드 클릭 시 모달로 전체 정보 표시 |\n| FR-004 | 티켓 수정 | 제목, 설명, 우선순위, 시작예정일, 종료예정일 수정 |\n| FR-005 | 티켓 완료 | Done 이동 시 completedAt 자동 설정, 24시간 경과 시 보드에서 제외 |\n| FR-006 | 티켓 삭제 | 확인 다이얼로그 후 영구 삭제 |\n| FR-007 | 드래그앤드롭 | 칼럼 간/내 이동, startedAt/completedAt 자동 관리 |\n| FR-008 | 오버듀 판정 | 종료예정일 초과 + 미완료 티켓에 시각적 경고 |\n\n## 기술 스택\n\n### 프런트엔드\n\n| 기술 | 버전 | 용도 |\n|------|------|------|\n| Next.js | 15.x | 풀스택 프레임워크 (App Router) |\n| React | 19.x | UI 렌더링 |\n| TypeScript | 5.x | 타입 안전성 (strict mode) |\n| Tailwind CSS | 4.x | 유틸리티 기반 스타일링 |\n| @dnd-kit | core 6.x / sortable 8.x | 드래그앤드롭 |\n\n### 백엔드\n\n| 기술 | 버전 | 용도 |\n|------|------|------|\n| Drizzle ORM | 0.38.x | DB 쿼리, 스키마 관리 |\n| @vercel/postgres | latest | Vercel Postgres 연결 드라이버 |\n| Zod | 3.x | 요청/폼 데이터 검증 (프론트/백엔드 공유) |\n\n### 개발 도구\n\n| 기술 | 용도 |\n|------|------|\n| Jest + React Testing Library | TDD 테스트 |\n| ESLint | 린트 |\n| Prettier | 코드 포맷팅 |\n| Drizzle Kit | DB 마이그레이션 |\n\n---\n\n## 구현 현황\n\n### 백엔드 (7/7 API 완료)\n| 엔드포인트 | 테스트 | 상태 |\n|-----------|--------|------|\n| POST /api/tickets | 11 passed | ✅ |\n| GET /api/tickets | 8 passed | ✅ |\n| GET /api/tickets/:id | 3 passed | ✅ |\n| PATCH /api/tickets/:id | 8 passed | ✅ |\n| PATCH /api/tickets/:id/complete | 5 passed | ✅ |\n| DELETE /api/tickets/:id | 2 passed | ✅ |\n| PATCH /api/tickets/reorder | 10 passed | ✅ |\n\n### 프런트엔드 (16/16 컴포넌트 완료)\n| Phase | 컴포넌트 | 테스트 | 상태 |\n|-------|---------|--------|------|\n| 1 | Button, Badge, Modal, ConfirmDialog | 22 passed | ✅ |\n| 2 | TicketCard, ColumnHeader, Column, Board | 25 passed | ✅ |\n| 3 | TicketDetailView, TicketForm, TicketModal | 17 passed | ✅ |\n| 4 | ticketApi, useTickets | 21 passed | ✅ |\n| 5 | BoardHeader, FilterBar, BoardContainer, page.tsx | 16 passed | ✅ |\n\n**전체: 26 test suites, 169 tests passed**\n\n---\n\n## 프로젝트 구조\n\n```\ntika/\n├── app/                              # Next.js App Router\n│   ├── api/                          # 백엔드: API Route Handlers\n│   │   └── tickets/\n│   │       ├── route.ts              # GET /api/tickets, POST /api/tickets\n│   │       ├── [id]/\n│   │       │   ├── route.ts          # GET, PATCH, DELETE /api/tickets/:id\n│   │       │   └── complete/\n│   │       │       └── route.ts      # PATCH /api/tickets/:id/complete\n│   │       └── reorder/\n│   │           └── route.ts          # PATCH /api/tickets/reorder\n│   │\n│   ├── page.tsx                      # 메인 페이지 (서버 컴포넌트)\n│   ├── layout.tsx                    # 루트 레이아웃\n│   └── globals.css                   # 디자인 시스템 + CSS 변수\n│\n├── src/\n│   ├── server/                       # 백엔드 로직 (서버에서만 실행)\n│   │   ├── services/\n│   │   │   ├── ticketService.ts      # 비즈니스 로직\n│   │   │   └── index.ts              # 서비스 export\n│   │   └── db/\n│   │       ├── index.ts              # Drizzle 클라이언트 초기화\n│   │       ├── schema.ts             # DB 스키마 정의\n│   │       └── seed.ts               # 시드 데이터\n│   │\n│   ├── client/                       # 프런트엔드 로직 (브라우저에서 실행)\n│   │   ├── components/\n│   │   │   ├── board/                # BoardContainer, Board, Column, ColumnHeader\n│   │   │   │   ├── BoardContainer.tsx  # 메인 컨테이너 (필터, 모달, CRUD)\n│   │   │   │   ├── BoardHeader.tsx     # 상단 헤더 (타이틀, 새 업무 버튼)\n│   │   │   │   ├── FilterBar.tsx       # 필터 바 (이번주 업무, 일정 초과)\n│   │   │   │   ├── Board.tsx           # 4칼럼 보드 레이아웃\n│   │   │   │   ├── Column.tsx          # 단일 칼럼 (DnD 드롭 영역)\n│   │   │   │   └── ColumnHeader.tsx    # 칼럼 헤더 (이름 + 카드 수)\n│   │   │   ├── ticket/               # TicketCard, TicketModal, TicketForm\n│   │   │   │   ├── TicketCard.tsx      # 개별 카드 (DnD 드래그 소스)\n│   │   │   │   ├── TicketModal.tsx     # 상세/수정 모달\n│   │   │   │   ├── TicketForm.tsx      # 생성/수정 폼\n│   │   │   │   └── TicketDetailView.tsx # 읽기 전용 필드\n│   │   │   └── ui/                   # 공통 UI 컴포넌트\n│   │   │       ├── Button.tsx          # variant, size, isLoading\n│   │   │       ├── Modal.tsx           # ESC 닫기, 바깥 클릭, 스크롤 잠금\n│   │   │       ├── Badge.tsx           # PriorityBadge, DueDateBadge\n│   │   │       └── ConfirmDialog.tsx   # 삭제 확인 다이얼로그\n│   │   ├── hooks/\n│   │   │   └── useTickets.ts         # 티켓 CRUD + 보드 상태 관리\n│   │   └── api/\n│   │       └── ticketApi.ts          # API 호출 함수 (fetch 래퍼)\n│   │\n│   └── shared/                       # 프론트/백엔드 공유 코드\n│       ├── types/\n│       │   └── index.ts              # Ticket, BoardData, API 타입\n│       ├── validations/\n│       │   └── ticket.ts             # Zod 스키마 (폼 + API 검증)\n│       └── errors/\n│           └── index.ts              # TicketNotFoundError 등\n│\n├── __tests__/                        # 테스트 코드 (169 tests)\n│   ├── api/                          # API Route + ticketApi 테스트\n│   ├── services/                     # 서비스 통합 테스트 (@jest-environment node)\n│   ├── components/                   # 컴포넌트 테스트 (jsdom)\n│   └── hooks/                        # Hook 테스트\n│\n├── docs/                             # 프로젝트 명세 문서\n├── drizzle/                          # Drizzle 마이그레이션\n├── CLAUDE.md                         # Claude Code 프로젝트 설정\n├── CHANGELOG.md                      # 개발 히스토리\n├── jest.config.ts                    # Jest 설정 (jsdom + runInBand)\n└── package.json\n```\n\n### 계층 간 경계 규칙\n\n| 규칙 | 설명 |\n|------|------|\n| `src/server/` → `src/client/` import 금지 | 백엔드에서 프런트엔드 코드 참조 불가 |\n| `src/client/` → `src/server/` import 금지 | 프런트엔드에서 백엔드 코드 직접 참조 불가 |\n| `src/shared/`만 양쪽에서 참조 가능 | 타입, Zod 스키마, 상수만 공유 |\n| `app/page.tsx`만 `src/server/` 직접 참조 | 서버 컴포넌트에서 initialData 전달 |\n\n---\n\n## API 엔드포인트\n\n| # | 메서드 | 경로 | 설명 |\n|---|--------|------|------|\n| 1 | POST | /api/tickets | 티켓 생성 |\n| 2 | GET | /api/tickets | 전체 보드 조회 |\n| 3 | GET | /api/tickets/:id | 티켓 상세 조회 |\n| 4 | PATCH | /api/tickets/:id | 티켓 수정 |\n| 5 | PATCH | /api/tickets/:id/complete | 티켓 완료 |\n| 6 | DELETE | /api/tickets/:id | 티켓 삭제 |\n| 7 | PATCH | /api/tickets/reorder | 상태/순서 변경 (DnD) |\n\n\u003e Done으로의 이동은 `/complete`, 그 외 모든 이동은 `/reorder`를 사용한다.\n\n---\n\n## 시작하기\n\n### 1. 의존성 설치\n\n```bash\nnpm install\n```\n\n### 2. 환경 변수 설정\n\n```bash\ncp .env.example .env.local\n```\n\n`.env.local` 파일에 `DATABASE_URL` 값을 설정한다.\n\n**로컬 PostgreSQL 사용 시:**\n```\nDATABASE_URL=postgresql://username:password@localhost:5432/tika\n```\n\n**Vercel Postgres 사용 시:**\n```bash\nvercel env pull .env.local\n```\n\n### 3. DB 마이그레이션\n\n```bash\nnpm run db:generate   # 마이그레이션 파일 생성\nnpm run db:migrate    # 마이그레이션 적용\n```\n\n### 4. (선택) 시드 데이터\n\n```bash\nnpm run db:seed\n```\n\n### 5. 개발 서버 실행\n\n```bash\nnpm run dev\n```\n\n[http://localhost:3000](http://localhost:3000) 에서 확인\n\n---\n\n## 주요 명령어\n\n| 명령어 | 설명 |\n|--------|------|\n| `npm run dev` | 개발 서버 실행 |\n| `npm run build` | 프로덕션 빌드 |\n| `npm run test` | 전체 테스트 실행 (169 tests, --runInBand) |\n| `npm run test:components` | 컴포넌트 테스트만 (80 tests) |\n| `npm run test:watch` | 테스트 감시 모드 |\n| `npx tsc --noEmit` | 타입 체크 |\n| `npm run db:generate` | DB 마이그레이션 생성 |\n| `npm run db:migrate` | DB 마이그레이션 적용 |\n| `npm run db:studio` | Drizzle Studio (DB GUI) |\n| `npm run db:seed` | 시드 데이터 삽입 |\n| `npm run lint` | ESLint 검사 |\n\n---\n\n## 프로젝트 문서\n\n| 문서 | 설명 |\n|------|------|\n| [PRD.md](docs/PRD.md) | 제품 요구사항 (시나리오, 와이어프레임, FR/NFR) |\n| [TRD.md](docs/TRD.md) | 기술 요구사항 (아키텍처, 기술 스택, 디렉토리 구조) |\n| [REQUIREMENTS.md](docs/REQUIREMENTS.md) | 상세 요구사항 (FR, NFR, US, 추적 매트릭스) |\n| [API_SPEC.md](docs/API_SPEC.md) | 7개 REST API 엔드포인트 명세 |\n| [DATA_MODEL.md](docs/DATA_MODEL.md) | DB 스키마, Drizzle 정의, 비즈니스 규칙 |\n| [COMPONENT_SPEC.md](docs/COMPONENT_SPEC.md) | 컴포넌트 계층, Props, 이벤트 흐름, Hook 명세 |\n| [TEST_CASES.md](docs/TEST_CASES.md) | TDD용 테스트 케이스 (API + 컴포넌트 + 통합) |\n| [FRONTEND_TASKS.md](docs/FRONTEND_TASKS.md) | 프런트엔드 구현 순서 + TDD 체크리스트 |\n\n---\n\n## 테스트 구조\n\n```\n__tests__/\n├── api/                    # API 테스트\n│   ├── tickets.test.ts       # POST /api/tickets Route (@jest-environment node)\n│   ├── tickets-detail.test.ts  # GET/PATCH/DELETE Route (@jest-environment node)\n│   ├── tickets-reorder.test.ts # PATCH /api/tickets/reorder (@jest-environment node)\n│   └── ticketApi.test.ts     # fetch 래퍼 테스트 (jsdom)\n├── services/               # 서비스 통합 테스트 (@jest-environment node)\n│   ├── ticketService.test.ts   # 생성 (TC-API-001)\n│   ├── ticketService.board.test.ts  # 보드 조회 (TC-API-002)\n│   └── ...                 # getById, update, complete, delete, reorder, overdue\n├── components/             # 컴포넌트 테스트 (jsdom)\n│   ├── Button.test.tsx       # Phase 1\n│   ├── TicketCard.test.tsx   # Phase 2\n│   ├── TicketForm.test.tsx   # Phase 3\n│   ├── BoardContainer.test.tsx # Phase 5\n│   └── ...\n└── hooks/\n    └── useTickets.test.ts    # Phase 4\n```\n\n- **서비스/API Route 테스트**: 실제 DB 연결 필요 → `@jest-environment node` + `--runInBand`\n- **컴포넌트/Hook 테스트**: mock 기반 → `jsdom` 환경 (기본값)\n\n---\n\n## 개발 방식\n\n이 프로젝트는 Claude Code와 함께 **SDD(Specification-Driven Development) + TDD** 방식으로 개발되었다.\n\n```bash\n# Claude Code 실행\nclaude\n\n# CLAUDE.md를 참고하도록 요청\n\u003e CLAUDE.md를 읽고 프로젝트 컨텍스트를 파악해줘\n```\n\n개발 순서:\n1. **명세 작성**: PRD → TRD → REQUIREMENTS → API_SPEC → DATA_MODEL → COMPONENT_SPEC → TEST_CASES\n2. **백엔드 TDD**: TEST_CASES.md의 TC-API 기반으로 Red → Green → Refactor\n3. **프런트엔드 TDD**: FRONTEND_TASKS.md 순서대로 Bottom-up 구현 (UI → Board → Ticket → Data → Container)\n\n---\n\n## 라이선스\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclaude-code-expert%2Ftodo-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclaude-code-expert%2Ftodo-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclaude-code-expert%2Ftodo-app/lists"}