Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8ca3b4b
chore: Prettier 설정 및 검사 스크립트 적용 (#1)
wjswlgh96 Jul 3, 2026
6812f8a
chore: 에이전트 개인 파일 gitignore 추가 (#1)
wjswlgh96 Jul 3, 2026
56d75ee
chore: 애니메이션 라이브러리 motion 추가 (#1)
wjswlgh96 Jul 3, 2026
75062f7
refactor: FSD 구조 도입 및 shared 레이어 이동 (#1)
wjswlgh96 Jul 3, 2026
a18eafd
feat: 브랜드 디자인 토큰 및 랜딩 views 골격 추가 (#1)
wjswlgh96 Jul 3, 2026
ea9b94e
chore: ESLint 코드 품질 및 FSD 경계 규칙 적용 (#1)
wjswlgh96 Jul 3, 2026
aeda616
design: 브랜드 보조 버튼 토큰 추가 (#1)
wjswlgh96 Jul 3, 2026
26cc1a2
feat: 공용 motion 애니메이션 상수 추가 (#1)
wjswlgh96 Jul 3, 2026
3500e3a
feat: 랜딩 페이지 위젯 및 애니메이션 구현 (#1)
wjswlgh96 Jul 3, 2026
d1cafb3
chore: 로컬 도구 설정 gitignore 추가 (#1)
wjswlgh96 Jul 3, 2026
8a15132
rename: 랜딩 위젯을 widgets/landing 그룹 폴더로 이동 (#1)
wjswlgh96 Jul 3, 2026
f42153b
design: Tailwind 프리셋 치환 및 모바일 레이아웃 Figma 정합 수정 (#1)
wjswlgh96 Jul 3, 2026
c4b77d7
design: 모바일 기능 카드 콘텐츠 중앙 정렬 (#1)
wjswlgh96 Jul 3, 2026
0d28ab5
design: Tailwind v4 gradient 네이밍 마이그레이션 및 푸터 연도 동적화 (#1)
wjswlgh96 Jul 3, 2026
91144f3
docs: README 스크립트 표 및 프로젝트 구조 갱신 (#1)
wjswlgh96 Jul 3, 2026
1a2ef65
design: 랜딩 페이지 신규 디자인 반영 (#1)
wjswlgh96 Jul 6, 2026
221ec76
design: 랜딩 페이지 디자인 보정 (#1)
wjswlgh96 Jul 6, 2026
09fc21e
fix: 캐러셀 탭 복귀 안정성·엣지 페이드 및 CodeRabbit 리뷰 반영 (#1)
wjswlgh96 Jul 6, 2026
052bffc
fix: 헤더 z-index 및 기능 캐러셀 full-bleed 정렬 수정 (#1)
wjswlgh96 Jul 6, 2026
e622131
feat: 기능 캐러셀 수동 일시정지 버튼 추가 (WCAG 2.2.2) (#1)
wjswlgh96 Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

language: "ko-KR"
language: 'ko-KR'

reviews:
profile: "assertive"
profile: 'assertive'
request_changes_workflow: false
high_level_summary: true
poem: false

# 리뷰 제외 대상 (노이즈 방지)
path_filters:
- "!node_modules/**"
- "!package-lock.json"
- "!.next/**"
- "!public/**"
- '!node_modules/**'
- '!package-lock.json'
- '!.next/**'
- '!public/**'

# 프로젝트 내 커스텀 컨벤션 파일 학습
knowledge_base:
code_guidelines:
enabled: true
filePatterns:
- "README.md"
- 'README.md'

chat:
auto_reply: true
Expand Down
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/issue_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@

<!-- 완료해야 할 작업을 체크리스트로 작성해주세요. -->

- [ ]
- [ ]

## 완료 기준

<!-- 이 이슈가 완료되었다고 판단할 수 있는 기준을 작성해주세요. -->

- [ ]
- [ ]

## 참고 자료

Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# agent files (개인 작업용)
AGENTS.md
.agents/
.claude/
15 changes: 8 additions & 7 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
node_modules
.next
out
build
coverage
public
package-lock.json
node_modules
.next
out
build
coverage
public
package-lock.json
next-env.d.ts
13 changes: 10 additions & 3 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
{
"plugins": ["prettier-plugin-tailwindcss"]
}
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2,
"arrowParens": "always",
"endOfLine": "lf",
"plugins": ["prettier-plugin-tailwindcss"]
}
92 changes: 50 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ Slack · Notion · Jira 같은 기존 협업툴은 강력하지만, 협업툴에

처음부터 워크스페이스 구조를 직접 설계하지 않아도, 목적별 템플릿을 선택하면 공지·업무·일정·회의록·자료·채팅을 **한 공간에서** 바로 관리할 수 있습니다.

| 기존 협업툴 | Syncly |
| --- | --- |
| 사용자가 직접 구조를 설계 | 목적별 템플릿으로 자동 구성 |
| 기능이 많아 처음 쓰기 어려움 | 필요한 기능만 정리된 화면 |
| 여러 툴을 조합해야 함 | 한 공간에서 모든 협업 |
| 기존 협업툴 | Syncly |
| ---------------------------- | --------------------------- |
| 사용자가 직접 구조를 설계 | 목적별 템플릿으로 자동 구성 |
| 기능이 많아 처음 쓰기 어려움 | 필요한 기능만 정리된 화면 |
| 여러 툴을 조합해야 함 | 한 공간에서 모든 협업 |

## 타겟 사용자

Expand All @@ -23,34 +23,34 @@ Slack · Notion · Jira 같은 기존 협업툴은 강력하지만, 협업툴에

## 주요 기능 (MVP)

| 기능 | 설명 |
| --- | --- |
| 로그인 | GitHub 소셜 로그인, 프로필 설정 |
| 템플릿 선택 | 팀플 / 프로젝트 / 매장 운영 템플릿 |
| 워크스페이스 생성 | 템플릿 기반 자동 구성, 생성자 = 관리자 |
| 프로젝트 관리 | 업무 생성, 담당자 지정, 상태(대기/진행중/완료), 마감일 |
| 캘린더 | 일정·마감일·회의 등록, 월간/주간 확인 |
| 공지 | 작성·수정·삭제, 중요 공지 고정 |
| 업무 회의록 | 회의 내용·참석자·결정사항·후속 업무 기록 |
| 자료실 | 파일 업로드, 링크 저장, 자료 목록 관리 |
| 채팅 | 워크스페이스 멤버 간 메시지 |
| 차트표 | 전체/완료 업무 개수, 진행률, 담당자별 통계 |
| 초대 | 초대 링크 생성, 멤버 목록 및 역할 관리 |
| 기능 | 설명 |
| ----------------- | ------------------------------------------------------ |
| 로그인 | GitHub 소셜 로그인, 프로필 설정 |
| 템플릿 선택 | 팀플 / 프로젝트 / 매장 운영 템플릿 |
| 워크스페이스 생성 | 템플릿 기반 자동 구성, 생성자 = 관리자 |
| 프로젝트 관리 | 업무 생성, 담당자 지정, 상태(대기/진행중/완료), 마감일 |
| 캘린더 | 일정·마감일·회의 등록, 월간/주간 확인 |
| 공지 | 작성·수정·삭제, 중요 공지 고정 |
| 업무 회의록 | 회의 내용·참석자·결정사항·후속 업무 기록 |
| 자료실 | 파일 업로드, 링크 저장, 자료 목록 관리 |
| 채팅 | 워크스페이스 멤버 간 메시지 |
| 차트표 | 전체/완료 업무 개수, 진행률, 담당자별 통계 |
| 초대 | 초대 링크 생성, 멤버 목록 및 역할 관리 |

자세한 내용은 PRD 문서를 참고하세요.

## 기술 스택

| 영역 | 사용 기술 |
| --- | --- |
| 프레임워크 | [Next.js 16](https://nextjs.org) (App Router), React 19, TypeScript |
| 백엔드 / 인증 | [Supabase](https://supabase.com) (`@supabase/ssr`, `supabase-js`) |
| 서버 상태 | [TanStack Query](https://tanstack.com/query) |
| 클라이언트 상태 | [Zustand](https://zustand-demo.pmnd.rs) |
| UI | [Tailwind CSS v4](https://tailwindcss.com), [shadcn/ui](https://ui.shadcn.com), Radix UI, lucide-react |
| 폼 / 검증 | [react-hook-form](https://react-hook-form.com), [zod](https://zod.dev) |
| 레이아웃 | [react-grid-layout](https://github.com/react-grid-layout/react-grid-layout) (워크스페이스 컴포넌트 배치) |
| 날짜 | [date-fns](https://date-fns.org) |
| 영역 | 사용 기술 |
| --------------- | -------------------------------------------------------------------------------------------------------- |
| 프레임워크 | [Next.js 16](https://nextjs.org) (App Router), React 19, TypeScript |
| 백엔드 / 인증 | [Supabase](https://supabase.com) (`@supabase/ssr`, `supabase-js`) |
| 서버 상태 | [TanStack Query](https://tanstack.com/query) |
| 클라이언트 상태 | [Zustand](https://zustand-demo.pmnd.rs) |
| UI | [Tailwind CSS v4](https://tailwindcss.com), [shadcn/ui](https://ui.shadcn.com), Radix UI, lucide-react |
| 폼 / 검증 | [react-hook-form](https://react-hook-form.com), [zod](https://zod.dev) |
| 레이아웃 | [react-grid-layout](https://github.com/react-grid-layout/react-grid-layout) (워크스페이스 컴포넌트 배치) |
| 날짜 | [date-fns](https://date-fns.org) |

## 시작하기

Expand Down Expand Up @@ -79,27 +79,35 @@ npm run dev

## 스크립트

| 명령어 | 설명 |
| --- | --- |
| `npm run dev` | 개발 서버 실행 |
| `npm run build` | 프로덕션 빌드 |
| `npm run start` | 프로덕션 서버 실행 |
| `npm run lint` | ESLint 검사 |
| 명령어 | 설명 |
| ---------------------- | ----------------------------------------- |
| `npm run dev` | 개발 서버 실행 |
| `npm run build` | 프로덕션 빌드 |
| `npm run start` | 프로덕션 서버 실행 |
| `npm run lint` | ESLint 검사 |
| `npm run typecheck` | TypeScript 타입 검사 |
| `npm run format` | Prettier 포맷 적용 |
| `npm run format:check` | Prettier 포맷 검사 |
| `npm run check` | lint + typecheck + format:check 일괄 검사 |

## 프로젝트 구조

FSD(Feature-Sliced Design) 구조를 따릅니다. Next.js Pages Router와의 폴더명 충돌을 피하기 위해 FSD의 `pages` 레이어는 `views`로 명명합니다.

```
src/
├── app/ # Next.js App Router (페이지, 레이아웃)
├── components/
│ └── ui/ # shadcn/ui 컴포넌트
── lib/
── client.ts # Supabase 브라우저 클라이언트
├── server.ts # Supabase 서버 클라이언트
├── middleware.ts # Supabase 세션 미들웨어
└── utils.ts # 공용 유틸 (cn 등)
├── app/ # Next.js App Router — 라우팅·전역 스타일 (화면은 views에서 import)
├── views/ # 페이지 단위 조합 (FSD pages 레이어)
│ └── landing/
── widgets/ # 페이지를 구성하는 독립 UI 블록
── landing/ # landing-header / hero / teams / features / cta
└── shared/ # 공통 코드
├── ui/ # shadcn/ui 컴포넌트
└── lib/ # Supabase 클라이언트, cn, motion 상수
```

레이어 import 방향은 `app → views → widgets → features → entities → shared` 이며, ESLint로 경계를 강제합니다.

## 향후 확장 (MVP 이후)

템플릿 공유 커뮤니티 · AI 회의록 정리 · 대화 → 업무 변환 · 외부 링크 연동(Figma/GitHub) · 알림 기능 · 모바일 앱
10 changes: 5 additions & 5 deletions components.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
"menuColor": "default",
"menuAccent": "subtle",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
"components": "@/shared/ui",
"utils": "@/shared/lib/utils",
"ui": "@/shared/ui",
"lib": "@/shared/lib",
"hooks": "@/shared/lib/hooks"
},
"registries": {
"@supabase": "https://supabase.com/ui/r/{name}.json"
Expand Down
48 changes: 24 additions & 24 deletions docs/conventions/code-convention.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ Syncly의 코드 구조, 네이밍, 품질 기준을 통일하기 위한 문서

## 1. Naming Convention

| 대상 | 규칙 | 예시 |
| --- | --- | --- |
| 변수 | camelCase | `userList`, `activeIndex` |
| 함수 | camelCase, 동사로 시작 | `fetchUser`, `createWorkspace` |
| boolean 변수 | `is`, `has`, `can`, `should` 접두사 | `isOpen`, `hasPermission` |
| 상수 | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT` |
| 객체/배열 상수 | camelCase | `moduleTypeMap` |
| 타입/인터페이스 | PascalCase | `WorkspaceModule`, `UserProfile` |
| React 컴포넌트 | PascalCase | `WorkspaceCard` |
| 커스텀 훅 | `use` 접두사 + camelCase | `useWorkspaceModules` |
| 이벤트 핸들러 | `handle` 접두사 | `handleSubmit` |
| 이벤트 핸들러 props | `on` 접두사 | `onSubmit`, `onClose` |
| 컴포넌트 파일 | PascalCase | `WorkspaceCard.tsx` |
| 유틸/훅/타입 파일 | kebab-case | `date-format.ts`, `use-auth.ts` |
| 폴더명 | kebab-case | `workspace-module` |
| URL 경로 | kebab-case | `/workspace-settings` |
| 대상 | 규칙 | 예시 |
| ------------------- | ----------------------------------- | -------------------------------- |
| 변수 | camelCase | `userList`, `activeIndex` |
| 함수 | camelCase, 동사로 시작 | `fetchUser`, `createWorkspace` |
| boolean 변수 | `is`, `has`, `can`, `should` 접두사 | `isOpen`, `hasPermission` |
| 상수 | UPPER_SNAKE_CASE | `MAX_RETRY_COUNT` |
| 객체/배열 상수 | camelCase | `moduleTypeMap` |
| 타입/인터페이스 | PascalCase | `WorkspaceModule`, `UserProfile` |
| React 컴포넌트 | PascalCase | `WorkspaceCard` |
| 커스텀 훅 | `use` 접두사 + camelCase | `useWorkspaceModules` |
| 이벤트 핸들러 | `handle` 접두사 | `handleSubmit` |
| 이벤트 핸들러 props | `on` 접두사 | `onSubmit`, `onClose` |
| 컴포넌트 파일 | PascalCase | `WorkspaceCard.tsx` |
| 유틸/훅/타입 파일 | kebab-case | `date-format.ts`, `use-auth.ts` |
| 폴더명 | kebab-case | `workspace-module` |
| URL 경로 | kebab-case | `/workspace-settings` |

## 2. TypeScript Convention

Expand Down Expand Up @@ -166,14 +166,14 @@ PR 생성 전 아래 항목을 확인합니다.

아래 규칙은 팀 합의 후 ESLint를 통해 자동 검사할 예정입니다.

| 규칙 | 목적 |
| --- | --- |
| `console.log` 금지 | 디버깅 코드가 배포 코드에 포함되는 것을 방지 |
| unused import / variable 금지 | 불필요한 코드 제거 |
| `any` 사용 제한 | 타입 안정성 유지 |
| React Hooks 규칙 강제 | Hooks 오사용 방지 |
| FSD layer import 규칙 강제 | 프로젝트 구조 일관성 유지 |
| 공통 UI 중복 구현 제한 | UI 컴포넌트 재사용성 유지 |
| 규칙 | 목적 |
| ----------------------------- | -------------------------------------------- |
| `console.log` 금지 | 디버깅 코드가 배포 코드에 포함되는 것을 방지 |
| unused import / variable 금지 | 불필요한 코드 제거 |
| `any` 사용 제한 | 타입 안정성 유지 |
| React Hooks 규칙 강제 | Hooks 오사용 방지 |
| FSD layer import 규칙 강제 | 프로젝트 구조 일관성 유지 |
| 공통 UI 중복 구현 제한 | UI 컴포넌트 재사용성 유지 |

## 9. Design Token Rule

Expand Down
20 changes: 10 additions & 10 deletions docs/conventions/prettier-convention.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ PR 전에는 반드시 포맷 검사를 통과해야 합니다.

## 3. 규칙 설명

| 옵션 | 값 | 설명 |
| --- | --- | --- |
| `semi` | `true` | 문장 끝에 세미콜론을 사용합니다. |
| `singleQuote` | `true` | 문자열은 작은따옴표를 사용합니다. |
| `trailingComma` | `all` | 가능한 곳에는 trailing comma를 사용합니다. |
| `printWidth` | `100` | 한 줄 최대 길이는 100자로 제한합니다. |
| `tabWidth` | `2` | 들여쓰기는 2칸을 사용합니다. |
| `arrowParens` | `always` | 화살표 함수 인자는 항상 괄호를 사용합니다. |
| `endOfLine` | `lf` | 운영체제별 줄바꿈 차이를 방지하기 위해 LF로 통일합니다. |
| `plugins` | `prettier-plugin-tailwindcss` | Tailwind class를 자동 정렬합니다. |
| 옵션 | 값 | 설명 |
| --------------- | ----------------------------- | ------------------------------------------------------- |
| `semi` | `true` | 문장 끝에 세미콜론을 사용합니다. |
| `singleQuote` | `true` | 문자열은 작은따옴표를 사용합니다. |
| `trailingComma` | `all` | 가능한 곳에는 trailing comma를 사용합니다. |
| `printWidth` | `100` | 한 줄 최대 길이는 100자로 제한합니다. |
| `tabWidth` | `2` | 들여쓰기는 2칸을 사용합니다. |
| `arrowParens` | `always` | 화살표 함수 인자는 항상 괄호를 사용합니다. |
| `endOfLine` | `lf` | 운영체제별 줄바꿈 차이를 방지하기 위해 LF로 통일합니다. |
| `plugins` | `prettier-plugin-tailwindcss` | Tailwind class를 자동 정렬합니다. |

## 4. Line Ending

Expand Down
63 changes: 56 additions & 7 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,17 +1,66 @@
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
import { defineConfig, globalIgnores } from 'eslint/config';
import nextVitals from 'eslint-config-next/core-web-vitals';
import nextTs from 'eslint-config-next/typescript';

// FSD 레이어 경계 — 하위 레이어가 상위 레이어를 import하지 못하도록 제한한다.
// 순서: app → views → widgets → features → entities → shared
const fsdLayerRules = [
{
layer: 'views',
forbidden: ['@/app/*'],
},
{
layer: 'widgets',
forbidden: ['@/app/*', '@/views/*'],
},
{
layer: 'features',
forbidden: ['@/app/*', '@/views/*', '@/widgets/*'],
},
{
layer: 'entities',
forbidden: ['@/app/*', '@/views/*', '@/widgets/*', '@/features/*'],
},
{
layer: 'shared',
forbidden: ['@/app/*', '@/views/*', '@/widgets/*', '@/features/*', '@/entities/*'],
},
].map(({ layer, forbidden }) => ({
files: [`src/${layer}/**/*.{ts,tsx}`],
rules: {
'no-restricted-imports': [
'error',
{
patterns: [
{
group: forbidden,
message: `FSD 규칙 위반: ${layer} 레이어는 상위 레이어를 import할 수 없습니다.`,
},
],
},
],
},
Comment thread
wjswlgh96 marked this conversation as resolved.
}));
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const eslintConfig = defineConfig([
...nextVitals,
...nextTs,
{
rules: {
// 디버깅 코드가 배포 코드에 포함되는 것을 방지 (개발자 로그는 warn/error만 허용)
'no-console': ['error', { allow: ['warn', 'error'] }],
// 타입 안정성 유지
'@typescript-eslint/no-explicit-any': 'error',
},
},
...fsdLayerRules,
// Override default ignores of eslint-config-next.
globalIgnores([
// Default ignores of eslint-config-next:
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
'.next/**',
'out/**',
'build/**',
'next-env.d.ts',
]),
]);

Expand Down
Loading