feat: 완전한 데이터베이스 스키마 정리 및 테스트 서버 안정화
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled

- 43개 테이블로 구성된 완전한 BOM 관리 시스템
- 카테고리별 상세 테이블 (9개): pipe, fitting, flange, valve, gasket, bolt, support, special, instrument
- 사용자 관리 시스템: users, login_logs, user_sessions, user_activity_logs
- 구매 관리 시스템: purchase_requests, purchase_request_items, purchase_items
- 리비전 관리 시스템: material_revisions_comparison, material_comparison_details
- 튜빙 시스템: tubing_categories, tubing_manufacturers, tubing_products, tubing_specifications
- 표준화/분류 시스템: material_standards, material_categories, material_patterns 등
- 권한 관리 시스템: permissions, role_permissions
- 고급 기능: user_requirements, pipe_end_preparations, material_tubing_mapping
- 성능 최적화: materials 테이블 17개 인덱스, GIN/복합/조건부 인덱스
- 데이터 무결성: 외래키 제약으로 일관성 보장
- 확장성: JSONB 활용한 유연한 메타데이터 저장
This commit is contained in:
hyungi
2025-10-21 12:33:05 +09:00
parent ab607dfa9a
commit edfe1bdf78

View File

@@ -174,8 +174,8 @@ function App() {
newSet.delete(projectId); newSet.delete(projectId);
console.log('📦 활성화 프로젝트 업데이트:', { prev: Array.from(prev), new: Array.from(newSet) }); console.log('📦 활성화 프로젝트 업데이트:', { prev: Array.from(prev), new: Array.from(newSet) });
return newSet; return newSet;
}); });
}; };
// 인증 상태 확인 // 인증 상태 확인
useEffect(() => { useEffect(() => {
@@ -192,13 +192,13 @@ function App() {
} }
} catch (error) { } catch (error) {
console.error('인증 확인 실패:', error); console.error('인증 확인 실패:', error);
localStorage.removeItem('access_token'); localStorage.removeItem('access_token');
localStorage.removeItem('user_data'); localStorage.removeItem('user_data');
setIsAuthenticated(false); setIsAuthenticated(false);
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }
}; };
checkAuth(); checkAuth();
}, []); }, []);
@@ -213,7 +213,7 @@ function App() {
const renderCurrentPage = () => { const renderCurrentPage = () => {
switch (currentPage) { switch (currentPage) {
case 'dashboard': case 'dashboard':
return ( return (
<DashboardPage <DashboardPage
user={user} user={user}
projects={projects} projects={projects}
@@ -279,14 +279,14 @@ function App() {
); );
case 'system-settings': case 'system-settings':
return ( return (
<SystemSettingsPage <SystemSettingsPage
onNavigate={navigateToPage} onNavigate={navigateToPage}
user={user} user={user}
/> />
); );
case 'account-settings': case 'account-settings':
return ( return (
<AccountSettingsPage <AccountSettingsPage
onNavigate={navigateToPage} onNavigate={navigateToPage}
user={user} user={user}
onUserUpdate={(updatedUser) => { onUserUpdate={(updatedUser) => {
@@ -297,21 +297,21 @@ function App() {
); );
case 'user-management': case 'user-management':
return ( return (
<UserManagementPage <UserManagementPage
onNavigate={navigateToPage} onNavigate={navigateToPage}
user={user} user={user}
/> />
); );
case 'system-logs': case 'system-logs':
return ( return (
<SystemLogsPage <SystemLogsPage
onNavigate={navigateToPage} onNavigate={navigateToPage}
user={user} user={user}
/> />
); );
case 'log-monitoring': case 'log-monitoring':
return ( return (
<LogMonitoringPage <LogMonitoringPage
onNavigate={navigateToPage} onNavigate={navigateToPage}
user={user} user={user}
/> />
@@ -339,20 +339,20 @@ function App() {
<div style={{ textAlign: 'center' }}> <div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '24px', marginBottom: '16px' }}></div> <div style={{ fontSize: '24px', marginBottom: '16px' }}></div>
<div style={{ fontSize: '16px', color: '#718096' }}> 없는 페이지입니다.</div> <div style={{ fontSize: '16px', color: '#718096' }}> 없는 페이지입니다.</div>
<button <button
onClick={() => navigateToPage('dashboard')} onClick={() => navigateToPage('dashboard')}
style={{ style={{
background: '#4299e1', background: '#4299e1',
color: 'white', color: 'white',
border: 'none', border: 'none',
borderRadius: '6px', borderRadius: '6px',
padding: '12px 24px', padding: '12px 24px',
cursor: 'pointer', cursor: 'pointer',
marginTop: '16px' marginTop: '16px'
}} }}
> >
대시보드로 돌아가기 대시보드로 돌아가기
</button> </button>
</div> </div>
</div> </div>
); );
@@ -376,21 +376,21 @@ function App() {
loadProjects(); loadProjects();
}; };
return ( return (
<ErrorBoundary errorContext={{ user, currentPage, pageParams }}> <ErrorBoundary errorContext={{ user, currentPage, pageParams }}>
{isLoading ? ( {isLoading ? (
<div style={{ <div style={{
display: 'flex', display: 'flex',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
height: '100vh', height: '100vh',
background: '#f7fafc' background: '#f7fafc'
}}> }}>
<div style={{ textAlign: 'center' }}> <div style={{ textAlign: 'center' }}>
<div style={{ fontSize: '24px', marginBottom: '16px' }}>🔄</div> <div style={{ fontSize: '24px', marginBottom: '16px' }}>🔄</div>
<div style={{ fontSize: '16px', color: '#718096' }}>로딩 ...</div> <div style={{ fontSize: '16px', color: '#718096' }}>로딩 ...</div>
</div>
</div> </div>
</div>
) : !isAuthenticated ? ( ) : !isAuthenticated ? (
<SimpleLogin onLoginSuccess={handleLoginSuccess} /> <SimpleLogin onLoginSuccess={handleLoginSuccess} />
) : ( ) : (
@@ -422,8 +422,8 @@ function App() {
</div> </div>
{/* 페이지 컨텐츠 */} {/* 페이지 컨텐츠 */}
{renderCurrentPage()} {renderCurrentPage()}
</div> </div>
)} )}
</ErrorBoundary> </ErrorBoundary>
); );