원클릭으로
project-architecture
Guide for project structure and architectural decisions. Use when setting up new projects or organizing code structure.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Guide for project structure and architectural decisions. Use when setting up new projects or organizing code structure.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | project-architecture |
| description | Guide for project structure and architectural decisions. Use when setting up new projects or organizing code structure. |
Follow this guide for consistent project structure and architectural decisions:
src/
├── components/ # Reusable UI components
│ ├── Button/
│ │ ├── Button.tsx
│ │ ├── Button.test.tsx
│ │ └── Button.module.css
│ └── Card/
│ └── ...
├── features/ # Feature-based modules
│ ├── auth/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── services/
│ │ └── types.ts
│ └── dashboard/
│ └── ...
├── pages/ # Page-level components (routes)
│ ├── HomePage.tsx
│ ├── DashboardPage.tsx
│ └── ...
├── layouts/ # Layout components
│ ├── MainLayout.tsx
│ └── AuthLayout.tsx
├── hooks/ # Shared custom hooks
│ ├── useAuth.ts
│ └── useFetch.ts
├── services/ # API calls and external services
│ ├── api.ts
│ └── authService.ts
├── utils/ # Helper functions
│ ├── formatDate.ts
│ └── validation.ts
├── types/ # Shared TypeScript types
│ ├── user.ts
│ └── api.ts
├── constants/ # App-wide constants
│ └── config.ts
├── styles/ # Global styles
│ ├── globals.css
│ └── variables.css
└── assets/ # Static assets
├── images/
└── icons/
Button/
├── Button.tsx # Component logic
├── Button.test.tsx # Tests
├── Button.module.css # Styles
├── Button.stories.tsx # Storybook (optional)
└── index.ts # Re-export
components/
├── Button.tsx
├── ButtonStyles.css
├── ButtonTest.tsx # Inconsistent naming
└── Card.tsx
// CSP Violation! Allows XSS attacks
<div style={{ color: userInput }}>Content</div>
// Button.module.css
import styles from './Button.module.css';
<button className={styles.primary}>Click</button>
Why CSS Modules:
<button className="px-4 py-2 bg-blue-500 text-white rounded">
Click
</button>
Why Tailwind:
import styled from 'styled-components';
const Button = styled.button`
padding: 0.5rem 1rem;
background: blue;
`;
Only if: You configure CSP nonce correctly!
// OK: Truly dynamic value that can't be in CSS
<div style={{ width: `${percent}%` }}>Progress</div>
// Better: Use CSS variables
<div
className={styles.progress}
style={{ '--progress': `${percent}%` } as React.CSSProperties}
/>
Group by feature, not by file type:
features/
└── user-profile/
├── components/
│ ├── ProfileCard.tsx
│ └── EditProfileForm.tsx
├── hooks/
│ └── useUserProfile.ts
├── services/
│ └── profileApi.ts
└── types.ts
src/
├── components/ # 100+ files mixed together
├── hooks/ # Hard to find related code
└── services/
// 1. External dependencies
import React, { useState } from 'react';
import { useRouter } from 'next/router';
// 2. Internal absolute imports
import { Button } from '@/components/Button';
import { useAuth } from '@/hooks/useAuth';
// 3. Relative imports (same feature)
import { ProfileCard } from './ProfileCard';
import type { UserProfile } from './types';
// 4. Styles (last)
import styles from './Profile.module.css';
❌ DON'T: API calls in components
function UserProfile() {
const [user, setUser] = useState();
useEffect(() => {
fetch('/api/users/123').then(/* ... */); // ❌ Bad
}, []);
}
✅ DO: Separate service layer
// services/userService.ts
export async function getUserProfile(id: string): Promise<User> {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) throw new Error('Failed to fetch user');
return response.json();
}
// Component
function UserProfile() {
const { data, isLoading } = useQuery({
queryKey: ['user', id],
queryFn: () => getUserProfile(id),
});
}
// config/env.ts
export const config = {
apiUrl: import.meta.env.VITE_API_URL || 'http://localhost:3000',
isDev: import.meta.env.DEV,
isProd: import.meta.env.PROD,
} as const;
// ❌ DON'T: Hardcode URLs everywhere
// ✅ DO: Single source of truth
// types/user.ts - Domain types
export interface User {
id: string;
email: string;
}
// types/api.ts - API types
export interface ApiResponse<T> {
data: T;
error?: string;
}
// Component-specific types: Co-located
// Button/Button.tsx
interface ButtonProps { /* ... */ }
contexts/
├── AuthContext.tsx
└── ThemeContext.tsx
stores/
├── authStore.ts
└── cartStore.ts
store/
├── slices/
│ ├── authSlice.ts
│ └── userSlice.ts
└── store.ts
| Type | Convention | Example |
|---|---|---|
| Components | PascalCase | UserProfile.tsx |
| Hooks | camelCase + "use" | useAuth.ts |
| Utils | camelCase | formatDate.ts |
| Constants | UPPER_SNAKE_CASE | API_BASE_URL |
| Types | PascalCase | User, ApiResponse |
| CSS Modules | camelCase | styles.primaryButton |
| Files | kebab-case or PascalCase | user-profile.tsx |
// components/Button/index.ts
export { Button } from './Button';
export type { ButtonProps } from './Button';
// Now import like:
import { Button } from '@/components/Button';
When adding new code, ask:
Checklist for auditing and fixing accessibility issues (WCAG 2.1 AA compliance). Use when reviewing components or pages for accessibility.
Guide for creating RESTful API endpoints with validation and error handling. Use when implementing backend API routes.
Guide for implementing secure authentication with JWT and session management. Use when adding authentication to an application.
Guide for creating responsive layouts with CSS. Use when implementing responsive design or fixing layout issues.
Guide for designing database schemas with Prisma ORM. Use when creating or modifying database models.
Guide for consistent error handling across frontend and backend. Use when implementing error handling logic.