diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-08-04 09:36:14 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-08-04 09:36:14 +0000 |
| commit | 92eda21e45d902663052575aaa4c4f80bfa2faea (patch) | |
| tree | 8483702edf82932d4359a597a854fa8e1b48e94b /app | |
| parent | f0213de0d2fb5fcb931b3ddaddcbb6581cab5d28 (diff) | |
(대표님) 벤더 문서 변경사항, data-table 변경, sync 변경
Diffstat (limited to 'app')
| -rw-r--r-- | app/[lng]/partners/(partners)/settings/layout.tsx | 4 | ||||
| -rw-r--r-- | app/[lng]/partners/(partners)/settings/page.tsx | 2 | ||||
| -rw-r--r-- | app/api/revision-attachment/route.ts | 16 | ||||
| -rw-r--r-- | app/api/revision-upload/route.ts | 18 | ||||
| -rw-r--r-- | app/api/sync/batches/route.ts | 6 | ||||
| -rw-r--r-- | app/api/sync/config/route.ts | 12 | ||||
| -rw-r--r-- | app/api/sync/import/route.ts | 6 | ||||
| -rw-r--r-- | app/api/sync/import/status/route.ts | 6 | ||||
| -rw-r--r-- | app/api/sync/status/route.ts | 18 | ||||
| -rw-r--r-- | app/api/sync/trigger/route.ts | 6 | ||||
| -rw-r--r-- | app/api/sync/workflow/action/route.ts | 6 | ||||
| -rw-r--r-- | app/api/sync/workflow/status/route.ts | 6 | ||||
| -rw-r--r-- | app/globals.css | 33 |
13 files changed, 86 insertions, 53 deletions
diff --git a/app/[lng]/partners/(partners)/settings/layout.tsx b/app/[lng]/partners/(partners)/settings/layout.tsx index f3cea7d2..3b8f48a3 100644 --- a/app/[lng]/partners/(partners)/settings/layout.tsx +++ b/app/[lng]/partners/(partners)/settings/layout.tsx @@ -4,7 +4,7 @@ import { Separator } from "@/components/ui/separator" import { SidebarNav } from "@/components/layout/sidebar-nav" export const metadata: Metadata = { - title: "설정", + title: "Setting", // description: "Advanced form example using react-hook-form and Zod.", } @@ -46,7 +46,7 @@ export default async function SettingsLayout({ <section className="overflow-hidden rounded-[0.5rem] border bg-background shadow"> <div className="hidden space-y-6 p-10 pb-16 md:block"> <div className="space-y-0.5"> - <h2 className="text-2xl font-bold tracking-tight">설정</h2> + <h2 className="text-2xl font-bold tracking-tight">Setting</h2> {/* <p className="text-muted-foreground"> Manage your account settings and preferences. </p> */} diff --git a/app/[lng]/partners/(partners)/settings/page.tsx b/app/[lng]/partners/(partners)/settings/page.tsx index 412597a5..727be46b 100644 --- a/app/[lng]/partners/(partners)/settings/page.tsx +++ b/app/[lng]/partners/(partners)/settings/page.tsx @@ -149,7 +149,7 @@ export default function SettingsAccountPage() { <div> <div className="flex items-center justify-between"> <div> - <h3 className="text-lg font-medium">계정</h3> + <h3 className="text-lg font-medium">Account</h3> {/* <p className="text-sm text-muted-foreground"> Update your account settings and manage your profile information. </p> */} diff --git a/app/api/revision-attachment/route.ts b/app/api/revision-attachment/route.ts index 12834085..092eed8d 100644 --- a/app/api/revision-attachment/route.ts +++ b/app/api/revision-attachment/route.ts @@ -10,6 +10,7 @@ import { documents, revisions, documentAttachments, + issueStages, } from "@/db/schema/vendorDocu" import { eq } from "drizzle-orm" @@ -50,10 +51,11 @@ export async function POST(request: NextRequest) { usage: revisions.usage, usageType: revisions.usageType, issueStageId: revisions.issueStageId, - contractId: documents.contractId, + projectId: documents.projectId, }) .from(revisions) - .leftJoin(documents, eq(documents.id, revisions.issueStageId)) + .innerJoin(issueStages, eq(revisions.issueStageId, issueStages.id)) + .innerJoin(documents, eq(issueStages.documentId, documents.id)) .where(eq(revisions.id, revisionId)) .limit(1) @@ -95,7 +97,7 @@ export async function POST(request: NextRequest) { // change_logs: attachment CREATE await logAttachmentChange( - revisionInfo.contractId, + revisionInfo.projectId, att.id, "CREATE", att, @@ -117,16 +119,16 @@ export async function POST(request: NextRequest) { usage: revisionInfo.usage, usageType: revisionInfo.usageType, uploadedFiles, - contractId: revisionInfo.contractId + projectId: revisionInfo.projectId } }) // 캐시 무효화 try { - // revalidateTag(`enhanced-documents-${result.contractId}`) - revalidateTag(`sync-status-${result.contractId}`) + // revalidateTag(`enhanced-documents-${result.projectId}`) + revalidateTag(`sync-status-${result.projectId}`) - console.log(`✅ Cache invalidated for contract ${result.contractId}`) + console.log(`✅ Cache invalidated for contract ${result.projectId}`) } catch (cacheError) { console.warn('⚠️ Cache invalidation failed:', cacheError) } diff --git a/app/api/revision-upload/route.ts b/app/api/revision-upload/route.ts index b171b89a..bd75e0b5 100644 --- a/app/api/revision-upload/route.ts +++ b/app/api/revision-upload/route.ts @@ -56,7 +56,7 @@ export async function POST(request: NextRequest) { /* ------- 계약 ID 확보 ------- */ const [docInfo] = await db - .select({ contractId: documents.contractId }) + .select({ projectId: documents.projectId }) .from(documents) .where(eq(documents.id, docId)) .limit(1) @@ -124,7 +124,7 @@ export async function POST(request: NextRequest) { // change_logs: CREATE await logRevisionChange( - docInfo.contractId, + docInfo.projectId, revisionId, "CREATE", newRev, @@ -157,7 +157,7 @@ export async function POST(request: NextRequest) { revisionId = revRow.id await logRevisionChange( - docInfo.contractId, + docInfo.projectId, revisionId, "UPDATE", updated, @@ -215,7 +215,7 @@ export async function POST(request: NextRequest) { // change_logs: attachment CREATE await logAttachmentChange( - docInfo.contractId, + docInfo.projectId, att.id, "CREATE", att, @@ -247,7 +247,7 @@ export async function POST(request: NextRequest) { revision, uploadedFiles, mode, - contractId: docInfo.contractId, + projectId: docInfo.projectId, usage, usageType, securityFailures // 보안 실패 정보 포함 @@ -257,12 +257,12 @@ export async function POST(request: NextRequest) { // 캐시 무효화 - 트랜잭션 완료 후에 실행 try { // enhanced documents 캐시 무효화 - revalidateTag(`enhanced-documents-${result.contractId}`) + revalidateTag(`enhanced-documents-${result.projectId}`) // sync status 관련 캐시도 무효화 (필요시) - revalidateTag(`sync-status-${result.contractId}`) + revalidateTag(`sync-status-${result.projectId}`) - console.log(`✅ Cache invalidated for contract ${result.contractId}`) + console.log(`✅ Cache invalidated for contract ${result.projectId}`) } catch (cacheError) { console.warn('⚠️ Cache invalidation failed:', cacheError) // 캐시 무효화 실패해도 업로드는 성공으로 처리 @@ -288,7 +288,7 @@ export async function POST(request: NextRequest) { uploadedFiles: result.uploadedFiles, filesCount: result.uploadedFiles.length, securityFailures: result.securityFailures, // 클라이언트에 보안 실패 정보 전달 - contractId: result.contractId, + projectId: result.projectId, }, }) } catch (e) { diff --git a/app/api/sync/batches/route.ts b/app/api/sync/batches/route.ts index a1ef8d26..7a72530d 100644 --- a/app/api/sync/batches/route.ts +++ b/app/api/sync/batches/route.ts @@ -4,11 +4,11 @@ import { NextRequest, NextResponse } from "next/server" export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url) - const contractId = searchParams.get('contractId') + const projectId = searchParams.get('projectId') const targetSystem = searchParams.get('targetSystem') || 'SHI' const limit = parseInt(searchParams.get('limit') || '10') - if (!contractId) { + if (!projectId) { return NextResponse.json( { error: 'Contract ID is required' }, { status: 400 } @@ -16,7 +16,7 @@ export async function GET(request: NextRequest) { } const batches = await syncService.getRecentSyncBatches( - parseInt(contractId), + parseInt(projectId), targetSystem, limit ) diff --git a/app/api/sync/config/route.ts b/app/api/sync/config/route.ts index e54762fc..db5d17ca 100644 --- a/app/api/sync/config/route.ts +++ b/app/api/sync/config/route.ts @@ -6,10 +6,10 @@ import { authOptions } from "@/app/api/auth/[...nextauth]/route" export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url) - const contractId = searchParams.get('contractId') + const projectId = searchParams.get('projectId') const targetSystem = searchParams.get('targetSystem') || 'SHI' - if (!contractId) { + if (!projectId) { return NextResponse.json( { error: 'Contract ID is required' }, { status: 400 } @@ -17,7 +17,7 @@ export async function GET(request: NextRequest) { } const config = await syncService.getSyncConfig( - parseInt(contractId), + parseInt(projectId), targetSystem ) @@ -48,7 +48,7 @@ export async function POST(request: NextRequest) { } const body = await request.json() const { - contractId, + projectId, targetSystem, endpointUrl, authToken, @@ -57,7 +57,7 @@ export async function POST(request: NextRequest) { maxBatchSize } = body - if (!contractId || !targetSystem || !endpointUrl) { + if (!projectId || !targetSystem || !endpointUrl) { return NextResponse.json( { error: 'Contract ID, target system, and endpoint URL are required' }, { status: 400 } @@ -65,7 +65,7 @@ export async function POST(request: NextRequest) { } await syncService.upsertSyncConfig({ - contractId, + projectId, targetSystem, endpointUrl, authToken, diff --git a/app/api/sync/import/route.ts b/app/api/sync/import/route.ts index a6496578..f32a99e2 100644 --- a/app/api/sync/import/route.ts +++ b/app/api/sync/import/route.ts @@ -11,9 +11,9 @@ export async function POST(request: NextRequest) { } const body = await request.json() - const { contractId, sourceSystem = 'DOLCE' } = body + const { projectId, sourceSystem = 'DOLCE' } = body - if (!contractId) { + if (!projectId) { return NextResponse.json( { error: 'Contract ID is required' }, { status: 400 } @@ -21,7 +21,7 @@ export async function POST(request: NextRequest) { } const result = await importService.importFromExternalSystem( - contractId, + projectId, sourceSystem ) diff --git a/app/api/sync/import/status/route.ts b/app/api/sync/import/status/route.ts index c5b4b0bd..ddb202e4 100644 --- a/app/api/sync/import/status/route.ts +++ b/app/api/sync/import/status/route.ts @@ -12,10 +12,10 @@ export async function GET(request: NextRequest) { } const { searchParams } = new URL(request.url) - const contractId = searchParams.get('contractId') + const projectId = searchParams.get('projectId') const sourceSystem = searchParams.get('sourceSystem') || 'DOLCE' - if (!contractId) { + if (!projectId) { return NextResponse.json( { error: 'Contract ID is required' }, { status: 400 } @@ -23,7 +23,7 @@ export async function GET(request: NextRequest) { } const status = await importService.getImportStatus( - Number(contractId), + Number(projectId), sourceSystem ) diff --git a/app/api/sync/status/route.ts b/app/api/sync/status/route.ts index 886c14df..b4b18577 100644 --- a/app/api/sync/status/route.ts +++ b/app/api/sync/status/route.ts @@ -33,22 +33,22 @@ function serializeForJSON(obj: any): any { export async function GET(request: NextRequest) { try { const { searchParams } = new URL(request.url) - const contractId = searchParams.get('contractId') + const projectId = searchParams.get('projectId') const targetSystem = searchParams.get('targetSystem') || 'SHI' - - if (!contractId) { + + if (!projectId) { return NextResponse.json( - { error: 'Contract ID is required' }, + { error: 'Project ID is required' }, { status: 400 } ) } - + let status try { // 실제 데이터베이스에서 조회 시도 status = await syncService.getSyncStatus( - parseInt(contractId), + parseInt(projectId), targetSystem ) } catch (error) { @@ -56,7 +56,7 @@ export async function GET(request: NextRequest) { // ✅ 데이터베이스 조회 실패시 임시 목업 데이터 반환 status = { - contractId: parseInt(contractId), + projectId: parseInt(projectId), targetSystem, totalChanges: 15, pendingChanges: 3, // 3건 대기 중 (빨간 뱃지 표시용) @@ -67,10 +67,10 @@ export async function GET(request: NextRequest) { syncEnabled: true } } - + // JSON 직렬화 가능한 형태로 변환 const serializedStatus = serializeForJSON(status) - + return NextResponse.json(serializedStatus) } catch (error) { console.error('Failed to get sync status:', error) diff --git a/app/api/sync/trigger/route.ts b/app/api/sync/trigger/route.ts index 3393365d..3fe58849 100644 --- a/app/api/sync/trigger/route.ts +++ b/app/api/sync/trigger/route.ts @@ -13,9 +13,9 @@ export async function POST(request: NextRequest) { } const body = await request.json() - const { contractId, targetSystem = 'SHI' } = body + const { projectId, targetSystem = 'SHI' } = body - if (!contractId) { + if (!projectId) { return NextResponse.json( { error: 'Contract ID is required' }, { status: 400 } @@ -23,7 +23,7 @@ export async function POST(request: NextRequest) { } const result = await syncService.syncToExternalSystem( - contractId, + projectId, targetSystem, true // manual trigger ) diff --git a/app/api/sync/workflow/action/route.ts b/app/api/sync/workflow/action/route.ts index b6b1a94f..8e311c86 100644 --- a/app/api/sync/workflow/action/route.ts +++ b/app/api/sync/workflow/action/route.ts @@ -12,9 +12,9 @@ export async function POST(request: NextRequest) { } const body = await request.json() - const { contractId, targetSystem = 'SWP', action, documents } = body + const { projectId, targetSystem = 'SWP', action, documents } = body - if (!contractId || !action) { + if (!projectId || !action) { return NextResponse.json( { error: 'Contract ID and action are required' }, { status: 400 } @@ -22,7 +22,7 @@ export async function POST(request: NextRequest) { } const result = await workflowService.executeWorkflowAction( - contractId, + projectId, targetSystem, action, documents || [], diff --git a/app/api/sync/workflow/status/route.ts b/app/api/sync/workflow/status/route.ts index a4c5d1d0..1274f049 100644 --- a/app/api/sync/workflow/status/route.ts +++ b/app/api/sync/workflow/status/route.ts @@ -12,10 +12,10 @@ export async function GET(request: NextRequest) { } const { searchParams } = new URL(request.url) - const contractId = searchParams.get('contractId') + const projectId = searchParams.get('projectId') const targetSystem = searchParams.get('targetSystem') || 'SWP' - if (!contractId) { + if (!projectId) { return NextResponse.json( { error: 'Contract ID is required' }, { status: 400 } @@ -23,7 +23,7 @@ export async function GET(request: NextRequest) { } const status = await workflowService.getWorkflowStatus( - Number(contractId), + Number(projectId), targetSystem ) diff --git a/app/globals.css b/app/globals.css index fa510ec4..a4ee4734 100644 --- a/app/globals.css +++ b/app/globals.css @@ -218,4 +218,35 @@ th[data-read-only="true"] { .tbl-compact tbody tr { @apply hover:bg-muted/40; } /* 선택 */ /* 필요시 행 높이 제한 */ .tbl-compact tbody tr > * { @apply h-8; } /* 32 px 정도 */ -}
\ No newline at end of file +} + +/* 그룹 컬럼 구분선 스타일 */ +.group-column-border { + position: relative; +} + +.group-column-border::before, +.group-column-border::after { + content: ''; + position: absolute; + top: 0; + bottom: 0; + width: 2px; + background-color: #e2e8f0; +} + +.group-column-border::before { + left: -1px; +} + +.group-column-border::after { + right: -1px; +} + +/* 그룹 헤더 스타일 */ +.group-header { + background-color: #f8fafc; + font-weight: 600; + border-left: 2px solid #cbd5e1; + border-right: 2px solid #cbd5e1; +} |
