feat: TK 안전관리 플랫폼 초기 구현
위험성평가, 안전 RAG Q&A, 안전점검 체크리스트를 통합한 안전관리자 전용 웹 플랫폼 전체 구현. - Next.js 15 (App Router) + TypeScript + Tailwind + shadcn/ui - Drizzle ORM + PostgreSQL 16 (12개 테이블) - 위험성평가 CRUD + 5x5 위험성 매트릭스 + 인쇄 내보내기 - 체크리스트 템플릿/점검/NCR 추적 - RAG 문서 파이프라인 (Tika + bge-m3 + Qdrant) - SSE 스트리밍 RAG 채팅 (qwen3.5:35b-a3b) - AI 어시스트 (위험요인 추천, 감소대책, 점검항목 생성) - 대시보드 통계/차트 (recharts) - 단일 사용자 인증 (HMAC 쿠키 세션) - 다크모드 지원 - Docker 멀티스테이지 빌드 (standalone) - 프로젝트 가이드 문서 (docs/) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
64
src/components/dashboard/charts-loader.tsx
Normal file
64
src/components/dashboard/charts-loader.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { db } from "@/lib/db";
|
||||
import { riskAssessmentHazards, nonConformances } from "@/lib/db/schema";
|
||||
import { getRiskGrade } from "@/lib/constants";
|
||||
import { DashboardCharts } from "./charts";
|
||||
|
||||
export async function DashboardChartsLoader() {
|
||||
let riskDistribution = [
|
||||
{ name: "저위험", value: 0, color: "#22c55e" },
|
||||
{ name: "보통", value: 0, color: "#eab308" },
|
||||
{ name: "고위험", value: 0, color: "#f97316" },
|
||||
{ name: "매우위험", value: 0, color: "#ef4444" },
|
||||
];
|
||||
|
||||
let ncrByStatus = [
|
||||
{ name: "미조치", value: 0, color: "#ef4444" },
|
||||
{ name: "시정조치", value: 0, color: "#f97316" },
|
||||
{ name: "확인 중", value: 0, color: "#eab308" },
|
||||
{ name: "종결", value: 0, color: "#22c55e" },
|
||||
];
|
||||
|
||||
try {
|
||||
// Risk distribution
|
||||
const hazards = await db
|
||||
.select({ riskLevel: riskAssessmentHazards.riskLevel })
|
||||
.from(riskAssessmentHazards);
|
||||
|
||||
for (const h of hazards) {
|
||||
const grade = getRiskGrade(h.riskLevel);
|
||||
const idx = riskDistribution.findIndex(
|
||||
(d) =>
|
||||
d.name ===
|
||||
{ low: "저위험", medium: "보통", high: "고위험", critical: "매우위험" }[
|
||||
grade.grade
|
||||
]
|
||||
);
|
||||
if (idx >= 0) riskDistribution[idx].value++;
|
||||
}
|
||||
|
||||
// NCR distribution
|
||||
const ncrs = await db
|
||||
.select({ status: nonConformances.status })
|
||||
.from(nonConformances);
|
||||
|
||||
const ncrStatusMap: Record<string, number> = {
|
||||
open: 0,
|
||||
corrective_action: 1,
|
||||
verification: 2,
|
||||
closed: 3,
|
||||
};
|
||||
for (const n of ncrs) {
|
||||
const idx = ncrStatusMap[n.status];
|
||||
if (idx !== undefined) ncrByStatus[idx].value++;
|
||||
}
|
||||
} catch {
|
||||
// DB not connected yet
|
||||
}
|
||||
|
||||
return (
|
||||
<DashboardCharts
|
||||
riskDistribution={riskDistribution}
|
||||
ncrByStatus={ncrByStatus}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user