feat: 자료실 기능 및 워크스페이스 목업 확장 (#21) - #22
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough자료실 화면이 추가되어 타입, 목업 데이터, 상태 훅, 다이얼로그, 목록, 뷰, 라우트가 연결되었습니다. 워크스페이스 목업 조회가 보강되었고, 헤더 버튼 스타일이 변경되었습니다. Changes자료실 기능
워크스페이스 보조 변경
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant ResourcesView
participant useResourceLibraryState
participant ResourceAddDialog
participant ResourceList
User->>ResourcesView: "링크 저장" / "파일 업로드" 클릭
ResourcesView->>useResourceLibraryState: openDialog(resourceType)
ResourcesView->>ResourceAddDialog: isOpen, initialResourceType 전달
User->>ResourceAddDialog: 폼 입력 후 저장
ResourceAddDialog->>useResourceLibraryState: addResource(formValues)
useResourceLibraryState->>useResourceLibraryState: 검증, ID/createdAt 생성, 목록 갱신
useResourceLibraryState-->>ResourceList: resources 전달
ResourceList-->>User: 카드 목록 렌더링
Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/entities/resource/model/mock-resources.ts`:
- Around line 110-119: The mock resource in mock-resources.ts uses an invalid
createdAt date value for resource-11, so update that fixture to a real calendar
date. Keep the fix localized to the resource-11 object in the mock data and
ensure the createdAt string remains in the same format as the other resource
entries so functions like sortResources and any future Date parsing continue to
work with valid input.
- Around line 112-124: The user-facing description strings in the mock resource
data contain typos: update the `resource-11` and `resource-12` entries in
`mock-resources.ts` so the `description` values read correctly, since they are
rendered directly by `ResourceList`. Keep the fix limited to those mock text
fields and verify the displayed labels now match the intended Korean wording.
In `@src/entities/workspace/model/mock-workspace.ts`:
- Around line 21-30: The mock workspace entries in mockWorkspaceData use the
same display name for both store-test and store-workspace, which makes them
indistinguishable in sidebar/list tests. Update the name field for one of these
entries so each workspace has a unique, clearly different label while keeping
the existing ids and purpose values unchanged. Use the mockWorkspaceData object
and the store-test/store-workspace entries to locate the duplicates.
In `@src/features/manage-resources/model/use-resource-library-state.ts`:
- Around line 34-38: `use-resource-library-state`의 `resources` 상태가
`useState(workspaceResources)` 초기값에만 의존해서 `workspaceId`가 바뀌어도 이전 워크스페이스 데이터가 남는
문제를 수정하세요. `workspaceResources`를 만드는 `useMemo`와 `setResources`를 사용하는
`useResourceLibraryState`에서 `workspaceId` 또는 `initialResources` 변경을 감지하는
`useEffect`를 추가해 `resources`를 다시 동기화하도록 하세요. `workspaceResources`, `resources`,
`setResources` 식별자를 기준으로 상태 초기화 로직을 찾아 반영하면 됩니다.
In `@src/features/manage-resources/ui/ResourceAddDialog.tsx`:
- Around line 16-25: The linkProviders mapping in ResourceAddDialog currently
assigns the same Link icon to link, notion, and figma, so update that array to
use distinct icons for each provider. Use the existing ResourceAddDialog
component and linkProviders symbols to swap in different lucide-react icons
where available, ensuring the label/value/icon combinations are visually
distinguishable while keeping GitBranch for github.
- Around line 135-156: ResourceAddDialog’s URL input, title input, and
description textarea rely only on placeholders, so add accessible names for each
field by wiring in explicit <label> elements or aria-labels. Update the inputs
in ResourceAddDialog to give the URL field, the title field, and the description
textarea clear screen-reader labels, keeping the existing layout and
placeholders intact.
- Around line 61-178: The modal rendered by ResourceAddDialog is missing dialog
accessibility behavior, so update the outer modal container to use the dialog
semantics by adding role="dialog" and aria-modal="true" in the ResourceAddDialog
return markup. Also add ESC-to-close handling in ResourceAddDialog with a
useEffect keydown listener that calls onClose when Escape is pressed, and
include focus management or a focus trap so keyboard users stay within the modal
while it is open.
- Around line 40-59: The ResourceAddDialog state is not reset when the dialog is
closed, so reopening it can show stale title/description/URL/file values. In
ResourceAddDialog, add a useEffect that watches isOpen (and, if needed,
resourceType) and clears the local form state whenever the dialog closes, rather
than relying on onSubmit alone. Make sure to import useEffect from react and
keep the reset logic alongside the existing submitResource, canSubmit, and
isOpen handling.
In `@src/features/manage-resources/ui/ResourceList.tsx`:
- Around line 65-71: The ResourceList item action button is decorative only
because it has an aria-label but no click behavior. Update the button in
ResourceList to wire an onClick handler that opens resource.url in a new tab for
link resources, and routes file resources to the appropriate download/preview
action; use the existing resource object and the ChevronRight button markup to
locate the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3bb401fe-baeb-49c0-ac1c-8095567d6a39
📒 Files selected for processing (13)
src/app/workspaces/[workspaceId]/files/page.tsxsrc/entities/resource/index.tssrc/entities/resource/model/mock-resources.tssrc/entities/resource/model/resource.types.tssrc/entities/workspace/index.tssrc/entities/workspace/model/mock-workspace.tssrc/features/manage-resources/index.tssrc/features/manage-resources/model/use-resource-library-state.tssrc/features/manage-resources/ui/ResourceAddDialog.tsxsrc/features/manage-resources/ui/ResourceList.tsxsrc/views/store-operation/resources/index.tssrc/views/store-operation/resources/ui/ResourcesView.tsxsrc/widgets/workspace-shell/ui/WorkspaceHeader.tsx
| id: 'resource-11', | ||
| workspaceId: 'side-workspace', | ||
| title: 'Github Repository', | ||
| description: '매인 코드 저장소', | ||
| resourceType: 'link', | ||
| linkProvider: 'github', | ||
| url: 'https://github.com', | ||
| uploadedBy: '이하은', | ||
| createdAt: '2025-06-31', | ||
| }, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
존재하지 않는 날짜 값 (2025-06-31).
resource-11의 createdAt이 '2025-06-31'인데, 6월은 30일까지만 존재합니다. sortResources가 localeCompare로 문자열 비교만 하므로 크래시는 나지 않지만, 실제로는 유효하지 않은 날짜라 향후 Date 파싱이나 표시 로직에서 문제가 될 수 있습니다.
🛠️ 제안 수정
resourceType: 'link',
linkProvider: 'github',
url: 'https://github.com',
uploadedBy: '이하은',
- createdAt: '2025-06-31',
+ createdAt: '2025-06-30',
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| id: 'resource-11', | |
| workspaceId: 'side-workspace', | |
| title: 'Github Repository', | |
| description: '매인 코드 저장소', | |
| resourceType: 'link', | |
| linkProvider: 'github', | |
| url: 'https://github.com', | |
| uploadedBy: '이하은', | |
| createdAt: '2025-06-31', | |
| }, | |
| id: 'resource-11', | |
| workspaceId: 'side-workspace', | |
| title: 'Github Repository', | |
| description: '매인 코드 저장소', | |
| resourceType: 'link', | |
| linkProvider: 'github', | |
| url: 'https://github.com', | |
| uploadedBy: '이하은', | |
| createdAt: '2025-06-30', | |
| }, |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/entities/resource/model/mock-resources.ts` around lines 110 - 119, The
mock resource in mock-resources.ts uses an invalid createdAt date value for
resource-11, so update that fixture to a real calendar date. Keep the fix
localized to the resource-11 object in the mock data and ensure the createdAt
string remains in the same format as the other resource entries so functions
like sortResources and any future Date parsing continue to work with valid
input.
| const linkProviders: Array<{ | ||
| label: string; | ||
| value: ResourceLinkProvider; | ||
| icon: typeof Link; | ||
| }> = [ | ||
| { label: '링크', value: 'link', icon: Link }, | ||
| { label: '노션', value: 'notion', icon: Link }, | ||
| { label: '피그마', value: 'figma', icon: Link }, | ||
| { label: '깃허브', value: 'github', icon: GitBranch }, | ||
| ]; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
link/notion/figma 아이콘이 모두 동일합니다.
Link 아이콘이 link/notion/figma 세 항목에 공통으로 사용되어 시각적으로 구분되지 않습니다. lucide-react에 브랜드 전용 아이콘이 없다면, 최소한 서로 다른 일반 아이콘(예: FileText, Figma 유사 아이콘 등)을 배정해 구분성을 높이는 것을 고려해보세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/manage-resources/ui/ResourceAddDialog.tsx` around lines 16 - 25,
The linkProviders mapping in ResourceAddDialog currently assigns the same Link
icon to link, notion, and figma, so update that array to use distinct icons for
each provider. Use the existing ResourceAddDialog component and linkProviders
symbols to swap in different lucide-react icons where available, ensuring the
label/value/icon combinations are visually distinguishable while keeping
GitBranch for github.
| if (!isOpen) { | ||
| return null; | ||
| } | ||
|
|
||
| const canSubmit = resourceType === 'file' ? fileName.trim().length > 0 : url.trim().length > 0; | ||
|
|
||
| const submitResource = () => { | ||
| onSubmit({ | ||
| resourceType, | ||
| linkProvider, | ||
| url, | ||
| fileName, | ||
| title, | ||
| description, | ||
| }); | ||
| setUrl(''); | ||
| setFileName(''); | ||
| setTitle(''); | ||
| setDescription(''); | ||
| }; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
취소 후 재오픈 시 이전 입력값이 남습니다.
isOpen=false일 때 컴포넌트가 언마운트되지 않고 null만 렌더링하므로, 취소(onClose) 시 폼 state가 초기화되지 않습니다. ResourcesView에서 key={dialogResourceType}을 사용하지만 같은 타입으로 다시 열면 리마운트되지 않아, 이전에 입력했던 제목/설명/URL/파일명이 그대로 남은 채 다시 표시됩니다.
🐛 제안 수정
+ useEffect(() => {
+ if (!isOpen) {
+ setUrl('');
+ setFileName('');
+ setTitle('');
+ setDescription('');
+ }
+ }, [isOpen]);
+
if (!isOpen) {
return null;
}(useEffect를 react에서 import 해야 합니다.)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/manage-resources/ui/ResourceAddDialog.tsx` around lines 40 - 59,
The ResourceAddDialog state is not reset when the dialog is closed, so reopening
it can show stale title/description/URL/file values. In ResourceAddDialog, add a
useEffect that watches isOpen (and, if needed, resourceType) and clears the
local form state whenever the dialog closes, rather than relying on onSubmit
alone. Make sure to import useEffect from react and keep the reset logic
alongside the existing submitResource, canSubmit, and isOpen handling.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/manage-resources/ui/ResourceAddDialog.tsx`:
- Around line 122-131: This is an optional improvement, not a required change:
keep the current custom dialog implementation in ResourceAddDialog and do not
migrate it to a native <dialog>. The existing role="dialog" structure with
dialogRef, keepFocusInsideDialog, and the ESC/focus handling is sufficient here,
so leave this block as-is and address only the separate effect bug elsewhere.
- Around line 97-115: The ResourceAddDialog useEffect is re-running on every
render because it has no dependency array, which keeps refocusing the dialog and
steals input focus while typing. Update the useEffect in ResourceAddDialog to
depend on the open state so the focus/keydown listener logic only runs when
isOpen changes, and keep the Escape handler cleanup tied to that effect.
In `@src/features/manage-resources/ui/ResourceList.tsx`:
- Around line 24-39: In openResource, the fallback download path is saving plain
text Blob contents with the original resource.fileName, which can mislead users
into thinking it is a real binary file. Update the download naming logic so
mock/text exports use a .txt filename (for example by normalizing
resource.fileName in openResource or when setting downloadLink.download), while
keeping the existing link handling for resourceType === 'link'.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 4ca052c1-4070-4965-8f20-b35d8381de34
📒 Files selected for processing (3)
src/features/manage-resources/model/use-resource-library-state.tssrc/features/manage-resources/ui/ResourceAddDialog.tsxsrc/features/manage-resources/ui/ResourceList.tsx
| function openResource(resource: ResourceItem) { | ||
| if (resource.resourceType === 'link' && resource.url) { | ||
| window.open(resource.url, '_blank', 'noopener,noreferrer'); | ||
| return; | ||
| } | ||
|
|
||
| const fileContents = `${resource.title}\n\n${resource.description}`; | ||
| const file = new Blob([fileContents], { type: 'text/plain;charset=utf-8' }); | ||
| const fileUrl = URL.createObjectURL(file); | ||
| const downloadLink = document.createElement('a'); | ||
|
|
||
| downloadLink.href = fileUrl; | ||
| downloadLink.download = resource.fileName ?? `${resource.title}.txt`; | ||
| downloadLink.click(); | ||
| URL.revokeObjectURL(fileUrl); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
다운로드 파일명과 실제 내용이 불일치합니다.
resource.fileName을 그대로 다운로드 파일명으로 사용하지만, 실제 Blob 내용은 title+description으로 만든 일반 텍스트입니다. 원본 확장자(.xlsx, .pdf 등)를 유지한 채 저장되면 사용자가 파일을 열었을 때 손상된 파일로 오인할 수 있습니다. 실제 파일 저장이 불가능한 목업 환경이라면, 다운로드 파일명에 .txt 확장자를 강제하는 편이 안전합니다.
🐛 제안 수정
const fileContents = `${resource.title}\n\n${resource.description}`;
const file = new Blob([fileContents], { type: 'text/plain;charset=utf-8' });
const fileUrl = URL.createObjectURL(file);
const downloadLink = document.createElement('a');
downloadLink.href = fileUrl;
- downloadLink.download = resource.fileName ?? `${resource.title}.txt`;
+ downloadLink.download = `${(resource.fileName ?? resource.title).replace(/\.[^./]+$/, '')}.txt`;
downloadLink.click();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function openResource(resource: ResourceItem) { | |
| if (resource.resourceType === 'link' && resource.url) { | |
| window.open(resource.url, '_blank', 'noopener,noreferrer'); | |
| return; | |
| } | |
| const fileContents = `${resource.title}\n\n${resource.description}`; | |
| const file = new Blob([fileContents], { type: 'text/plain;charset=utf-8' }); | |
| const fileUrl = URL.createObjectURL(file); | |
| const downloadLink = document.createElement('a'); | |
| downloadLink.href = fileUrl; | |
| downloadLink.download = resource.fileName ?? `${resource.title}.txt`; | |
| downloadLink.click(); | |
| URL.revokeObjectURL(fileUrl); | |
| } | |
| function openResource(resource: ResourceItem) { | |
| if (resource.resourceType === 'link' && resource.url) { | |
| window.open(resource.url, '_blank', 'noopener,noreferrer'); | |
| return; | |
| } | |
| const fileContents = `${resource.title}\n\n${resource.description}`; | |
| const file = new Blob([fileContents], { type: 'text/plain;charset=utf-8' }); | |
| const fileUrl = URL.createObjectURL(file); | |
| const downloadLink = document.createElement('a'); | |
| downloadLink.href = fileUrl; | |
| downloadLink.download = `${(resource.fileName ?? resource.title).replace(/\.[^./]+$/, '')}.txt`; | |
| downloadLink.click(); | |
| URL.revokeObjectURL(fileUrl); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/manage-resources/ui/ResourceList.tsx` around lines 24 - 39, In
openResource, the fallback download path is saving plain text Blob contents with
the original resource.fileName, which can mislead users into thinking it is a
real binary file. Update the download naming logic so mock/text exports use a
.txt filename (for example by normalizing resource.fileName in openResource or
when setting downloadLink.download), while keeping the existing link handling
for resourceType === 'link'.
bd9f457 to
5ee4095
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (2)
src/features/manage-resources/ui/ResourceAddDialog.tsx (1)
97-115: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
useEffect에 의존성 배열이 없어 입력 중 포커스가 계속 빼앗깁니다.Line 115의
});에 의존성 배열이 없어,title/url/descriptionstate가 바뀔 때마다(즉 매 keystroke마다) 이펙트가 재실행되고dialogRef.current?.focus()(Line 102)가 다이얼로그 컨테이너로 포커스를 되돌립니다. 결과적으로 입력 필드에 연속으로 타이핑할 수 없습니다. 이 문제는 이전 리뷰에서 Critical로 지적되었으나 현재 코드에도 여전히 존재합니다.🐛 제안 수정
return () => { document.removeEventListener('keydown', closeOnEscape); }; - }); + }, [isOpen]);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/manage-resources/ui/ResourceAddDialog.tsx` around lines 97 - 115, The ResourceAddDialog useEffect is missing a dependency array, so it reruns on every render and keeps calling dialogRef.current?.focus(), stealing focus from the form inputs while typing. Update the effect tied to isOpen/closeDialog so it only runs when the dialog opens or the close handler changes, and keep the Escape key listener cleanup intact. Locate this in ResourceAddDialog around the useEffect that sets up closeOnEscape and focuses dialogRef.src/features/manage-resources/ui/ResourceList.tsx (1)
24-39: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win다운로드 파일명과 실제 내용이 불일치합니다 (미해결).
resource.fileName(예:6월 매출 정산.xls)을 그대로 다운로드 파일명으로 사용하지만 실제 Blob 내용은 일반 텍스트입니다. 원본 확장자를 유지한 채 저장되면 사용자가 손상된 파일로 오인할 수 있습니다. 이전 리뷰에서 지적되었으나 현재 코드에도 그대로 남아 있습니다.🐛 제안 수정
downloadLink.href = fileUrl; - downloadLink.download = resource.fileName ?? `${resource.title}.txt`; + downloadLink.download = `${(resource.fileName ?? resource.title).replace(/\.[^./]+$/, '')}.txt`;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/features/manage-resources/ui/ResourceList.tsx` around lines 24 - 39, The `openResource` download path is still using `resource.fileName` as-is even though it creates a plain text Blob, so the saved filename can misleadingly keep an original extension. Update the download logic in `openResource` to derive a safe text filename for generated content (for example, base it on `resource.title` and ensure a `.txt` extension) instead of reusing `resource.fileName` when the content is synthesized. Keep the existing link-handling branch unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@src/features/manage-resources/ui/ResourceAddDialog.tsx`:
- Around line 97-115: The ResourceAddDialog useEffect is missing a dependency
array, so it reruns on every render and keeps calling
dialogRef.current?.focus(), stealing focus from the form inputs while typing.
Update the effect tied to isOpen/closeDialog so it only runs when the dialog
opens or the close handler changes, and keep the Escape key listener cleanup
intact. Locate this in ResourceAddDialog around the useEffect that sets up
closeOnEscape and focuses dialogRef.
In `@src/features/manage-resources/ui/ResourceList.tsx`:
- Around line 24-39: The `openResource` download path is still using
`resource.fileName` as-is even though it creates a plain text Blob, so the saved
filename can misleadingly keep an original extension. Update the download logic
in `openResource` to derive a safe text filename for generated content (for
example, base it on `resource.title` and ensure a `.txt` extension) instead of
reusing `resource.fileName` when the content is synthesized. Keep the existing
link-handling branch unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d663510e-d969-4ce3-9983-9cc3afb98202
📒 Files selected for processing (12)
src/app/workspaces/[workspaceId]/files/page.tsxsrc/entities/resource/index.tssrc/entities/resource/model/mock-resources.tssrc/entities/resource/model/resource.types.tssrc/entities/workspace/model/mock-workspace.tssrc/features/manage-resources/index.tssrc/features/manage-resources/model/use-resource-library-state.tssrc/features/manage-resources/ui/ResourceAddDialog.tsxsrc/features/manage-resources/ui/ResourceList.tsxsrc/views/store-operation/resources/index.tssrc/views/store-operation/resources/ui/ResourcesView.tsxsrc/widgets/workspace-shell/ui/WorkspaceHeader.tsx
Pull Request
작업 내용
entities/resource,features/manage-resources,views/store-operation/resources로 분리했습니다.작업 결과
/workspaces/[workspaceId]/files에서 자료실 목록을 확인할 수 있습니다.링크 저장,파일 업로드버튼으로 자료 추가 모달을 열 수 있습니다.링크,파일순서의 탭을 제공합니다.workspaceId기준으로 필터링됩니다.변경 사항
Added
src/app/workspaces/[workspaceId]/files/page.tsxsrc/entities/resourcesrc/features/manage-resourcessrc/views/store-operation/resourcesChanged
team-workspace,side-workspace,store-workspace케이스를 추가했습니다.var(--color-brand)기준으로 정리했습니다.Fixed
실행화면
테스트
검증 명령:
npm run lintnpm run typechecknpm run buildcurl -I http://localhost:3000/workspaces/store-workspace/files리뷰 체크리스트
feature/*->develop, 배포 시develop또는release/*->main)Type/#issue-number/description형식을 따릅니다.console.log, 주석, 임시 코드를 제거했습니다.리뷰 요청사항
views/<domain>/resources -> features/manage-resources -> entities/resourceentities/resource는RESOURCES테이블 row/mapper,features/manage-resources는 저장/업로드 액션 연결 지점으로 확장하면 됩니다.관련 이슈
Closes #21
ref #2
Summary by CodeRabbit
Summary by CodeRabbit