feat: [interview] SAM Knowledge Base(SKB) 지식 기반 AI 인터뷰 시스템
SKB 지식 파일 (25개): - system_prompt_base.md: AI 역할 + SAM 개요 + 응답 형식 - modules/ 12개: 테넌트/품목/BOM/단가/견적/생산/품질/재고/회계/인사/결재/바로빌 - presets/ 6개: 블라인드/금속가공/기계조립/식품/건설/범용 업종 프리셋 - mapping_rules/ 3개: 답변→테이블 매핑, 크로스체크 규칙, 검증 규칙 PHP 서비스: - InterviewKnowledgeLoader: 도메인별 프롬프트 동적 조립 - InterviewCrossChecker: 도메인 간 정합성 검증 (CC-01~CC-07) - AiInterviewService: buildSystemPrompt → SKB 기반으로 교체
This commit is contained in:
@@ -524,50 +524,28 @@ private function callGemini(array $contents): array
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* 시스템 프롬프트 생성
|
||||
* 시스템 프롬프트 생성 (SKB 기반)
|
||||
*
|
||||
* InterviewKnowledgeLoader를 사용하여 SAM 시스템 지식 +
|
||||
* 업종 프리셋 + 매핑 규칙을 포함한 고품질 프롬프트를 생성한다.
|
||||
*/
|
||||
private function buildSystemPrompt(string $domain, ?InterviewCategory $category, array $questions): string
|
||||
{
|
||||
$domainName = $category?->name ?? $domain;
|
||||
$domainDescription = $category?->description ?? "{$domain} 도메인 관련 업무 파악";
|
||||
$loader = new InterviewKnowledgeLoader;
|
||||
$projectId = null;
|
||||
|
||||
$questionList = '';
|
||||
foreach ($questions as $index => $question) {
|
||||
$hint = $question->ai_hint ? " (힌트: {$question->ai_hint})" : '';
|
||||
$required = $question->is_required ? ' [필수]' : '';
|
||||
$type = $question->question_type ?? 'text';
|
||||
$questionList .= ($index + 1).". [{$type}]{$required} {$question->question_text}{$hint}\n";
|
||||
// 프로젝트에서 업종 프리셋 가져오기
|
||||
$preset = null;
|
||||
if ($category && $category->interview_project_id) {
|
||||
$projectId = $category->interview_project_id;
|
||||
$project = \App\Models\Interview\InterviewProject::find($projectId);
|
||||
$preset = $project?->company_type;
|
||||
}
|
||||
|
||||
if (empty($questionList)) {
|
||||
$questionList = "- 해당 도메인의 전반적인 업무 프로세스와 요구사항을 파악합니다.\n";
|
||||
}
|
||||
// 이전 도메인 결과 (크로스체크용)
|
||||
$previousResults = $projectId ? $loader->buildCrossCheckContext($projectId) : [];
|
||||
|
||||
return <<<PROMPT
|
||||
당신은 제조업 ERP/MES 시스템 구축을 위한 전문 인터뷰어입니다.
|
||||
|
||||
현재 도메인: {$domainName}
|
||||
수집 목표: {$domainDescription}
|
||||
|
||||
아래는 이 도메인에서 수집해야 할 핵심 질문 목록입니다:
|
||||
{$questionList}
|
||||
|
||||
지침:
|
||||
1. 자연스러운 대화체로 한 번에 1-2개 질문을 합니다
|
||||
2. 답변이 불충분하면 구체적인 예시를 요청합니다
|
||||
3. 답변에서 구조화 가능한 데이터를 발견하면 JSON으로 추출합니다
|
||||
4. 모든 핵심 질문이 커버될 때까지 대화를 이어갑니다
|
||||
5. 응답 마지막에 반드시 아래 형식의 JSON 블록을 포함합니다:
|
||||
|
||||
```json
|
||||
{
|
||||
"extracted_data": {},
|
||||
"covered_questions": [],
|
||||
"coverage_percent": 0,
|
||||
"next_focus": "다음에 물어볼 영역"
|
||||
}
|
||||
```
|
||||
PROMPT;
|
||||
return $loader->buildPrompt($domain, $preset, $previousResults, $questions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
349
app/Services/Sales/InterviewCrossChecker.php
Normal file
349
app/Services/Sales/InterviewCrossChecker.php
Normal file
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Sales;
|
||||
|
||||
use App\Models\Interview\InterviewAiConversation;
|
||||
use App\Models\Interview\InterviewKnowledge;
|
||||
|
||||
/**
|
||||
* 도메인 간 크로스체크 서비스
|
||||
*
|
||||
* 여러 도메인에서 수집된 데이터의 정합성을 검증한다.
|
||||
* BOM 부품 ⊂ 품목마스터, 단가 품목 = BOM 품목 등.
|
||||
*/
|
||||
class InterviewCrossChecker
|
||||
{
|
||||
/**
|
||||
* 프로젝트 전체 크로스체크 실행
|
||||
*/
|
||||
public function validate(int $projectId): array
|
||||
{
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
$data = $this->collectAllData($projectId, $tenantId);
|
||||
$issues = [];
|
||||
|
||||
// CC-01: BOM 부품 ⊂ 품목
|
||||
$issues = array_merge($issues, $this->checkBomVsItems($data));
|
||||
|
||||
// CC-02: 단가 품목 = BOM 품목
|
||||
$issues = array_merge($issues, $this->checkPricingVsBom($data));
|
||||
|
||||
// CC-03: 수식 변수 = 치수 변수
|
||||
$issues = array_merge($issues, $this->checkFormulaVsDimension($data));
|
||||
|
||||
// CC-04: 공정 부품 ⊂ BOM
|
||||
$issues = array_merge($issues, $this->checkProcessVsBom($data));
|
||||
|
||||
// CC-05: 견적 항목 = 단가 항목
|
||||
$issues = array_merge($issues, $this->checkQuoteVsPricing($data));
|
||||
|
||||
// CC-06: 부서 = 공정 담당
|
||||
$issues = array_merge($issues, $this->checkDepartmentVsProcess($data));
|
||||
|
||||
// 심각도별 정렬 (CRITICAL > HIGH > MEDIUM > LOW)
|
||||
usort($issues, function ($a, $b) {
|
||||
$order = ['CRITICAL' => 0, 'HIGH' => 1, 'MEDIUM' => 2, 'LOW' => 3];
|
||||
|
||||
return ($order[$a['severity']] ?? 4) <=> ($order[$b['severity']] ?? 4);
|
||||
});
|
||||
|
||||
return [
|
||||
'total_issues' => count($issues),
|
||||
'critical' => count(array_filter($issues, fn ($i) => $i['severity'] === 'CRITICAL')),
|
||||
'high' => count(array_filter($issues, fn ($i) => $i['severity'] === 'HIGH')),
|
||||
'medium' => count(array_filter($issues, fn ($i) => $i['severity'] === 'MEDIUM')),
|
||||
'low' => count(array_filter($issues, fn ($i) => $i['severity'] === 'LOW')),
|
||||
'issues' => $issues,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 모든 도메인 데이터 수집
|
||||
*/
|
||||
private function collectAllData(int $projectId, int $tenantId): array
|
||||
{
|
||||
$data = [
|
||||
'items' => [], // 품목명 목록
|
||||
'bom_parts' => [], // BOM에 사용된 부품명
|
||||
'priced_items' => [], // 단가가 정의된 품목명
|
||||
'formula_vars' => [], // 수식에 사용된 변수
|
||||
'dimension_vars' => [], // 치수에 정의된 변수
|
||||
'process_parts' => [], // 공정에서 투입하는 부품
|
||||
'quote_groups' => [], // 견적 항목 그룹
|
||||
'pricing_groups' => [], // 단가 구성요소
|
||||
'departments' => [], // 부서 목록
|
||||
'process_depts' => [], // 공정 담당 부서
|
||||
];
|
||||
|
||||
// AI 대화에서 structured_data 수집
|
||||
$conversations = InterviewAiConversation::where('interview_project_id', $projectId)
|
||||
->where('tenant_id', $tenantId)
|
||||
->where('role', 'assistant')
|
||||
->whereNotNull('structured_data')
|
||||
->get(['domain', 'structured_data']);
|
||||
|
||||
foreach ($conversations as $conv) {
|
||||
$sd = $conv->structured_data;
|
||||
if (! is_array($sd)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->extractFromStructuredData($conv->domain, $sd, $data);
|
||||
}
|
||||
|
||||
// knowledge에서도 수집
|
||||
$knowledge = InterviewKnowledge::on('codebridge')
|
||||
->where('interview_project_id', $projectId)
|
||||
->where('tenant_id', $tenantId)
|
||||
->get(['domain', 'title', 'content']);
|
||||
|
||||
foreach ($knowledge as $k) {
|
||||
$this->extractFromKnowledge($k->domain, $k->content, $data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* structured_data에서 항목 추출
|
||||
*/
|
||||
private function extractFromStructuredData(?string $domain, array $sd, array &$data): void
|
||||
{
|
||||
// sam_mapping에서 테이블별 데이터 추출
|
||||
if (isset($sd['sam_mapping']['table'])) {
|
||||
$table = $sd['sam_mapping']['table'];
|
||||
$mappingData = $sd['sam_mapping']['data'] ?? [];
|
||||
|
||||
foreach ($mappingData as $row) {
|
||||
$name = $row['name'] ?? $row['component'] ?? $row['item'] ?? null;
|
||||
if (! $name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
match ($table) {
|
||||
'categories', 'products' => $data['items'][] = $name,
|
||||
'bom_template_items' => $data['bom_parts'][] = $name,
|
||||
'price_histories' => $data['priced_items'][] = $name,
|
||||
'processes' => $data['process_depts'][] = $row['department'] ?? null,
|
||||
'departments' => $data['departments'][] = $name,
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// extracted_data에서도 추출
|
||||
if (isset($sd['extracted_data'])) {
|
||||
$ed = $sd['extracted_data'];
|
||||
|
||||
// 품목 목록
|
||||
foreach ($ed['categories'] ?? $ed['products'] ?? $ed['items'] ?? [] as $item) {
|
||||
$data['items'][] = is_array($item) ? ($item['name'] ?? '') : $item;
|
||||
}
|
||||
|
||||
// BOM 부품
|
||||
foreach ($ed['bom_items'] ?? $ed['components'] ?? [] as $item) {
|
||||
$data['bom_parts'][] = is_array($item) ? ($item['name'] ?? $item['component'] ?? '') : $item;
|
||||
}
|
||||
|
||||
// 수식 변수
|
||||
foreach ($ed['formulas'] ?? $ed['variables'] ?? [] as $item) {
|
||||
if (is_array($item) && isset($item['code'])) {
|
||||
$data['formula_vars'][] = $item['code'];
|
||||
}
|
||||
}
|
||||
|
||||
// 치수 변수
|
||||
foreach ($ed['parameters'] ?? $ed['dimensions'] ?? [] as $item) {
|
||||
if (is_array($item) && isset($item['code'])) {
|
||||
$data['dimension_vars'][] = $item['code'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* knowledge에서 항목 추출
|
||||
*/
|
||||
private function extractFromKnowledge(?string $domain, $content, array &$data): void
|
||||
{
|
||||
if (! is_array($content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
match ($domain) {
|
||||
'product_classification' => $data['items'] = array_merge($data['items'], $this->extractNames($content)),
|
||||
'bom_structure' => $data['bom_parts'] = array_merge($data['bom_parts'], $this->extractNames($content)),
|
||||
'pricing_structure' => $data['priced_items'] = array_merge($data['priced_items'], $this->extractNames($content)),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 배열에서 name/item/component 키 추출
|
||||
*/
|
||||
private function extractNames(array $content): array
|
||||
{
|
||||
$names = [];
|
||||
foreach ($content as $key => $value) {
|
||||
if (in_array($key, ['name', 'item', 'component', 'product'])) {
|
||||
$names[] = $value;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
$names = array_merge($names, $this->extractNames($value));
|
||||
}
|
||||
}
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
// ─── 크로스체크 규칙 구현 ───
|
||||
|
||||
private function checkBomVsItems(array $data): array
|
||||
{
|
||||
$issues = [];
|
||||
$items = array_map('mb_strtolower', array_filter(array_unique($data['items'])));
|
||||
foreach (array_unique($data['bom_parts']) as $part) {
|
||||
if (empty($part)) {
|
||||
continue;
|
||||
}
|
||||
$found = false;
|
||||
foreach ($items as $item) {
|
||||
if (str_contains($item, mb_strtolower($part)) || str_contains(mb_strtolower($part), $item)) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! $found && ! empty($items)) {
|
||||
$issues[] = [
|
||||
'rule' => 'CC-01',
|
||||
'severity' => 'HIGH',
|
||||
'source' => 'bom_structure',
|
||||
'target' => 'product_classification',
|
||||
'message' => "BOM에 '{$part}'이(가) 있는데 품목 분류에 없습니다",
|
||||
'suggestion' => "'{$part}'을(를) 품목 분류에 추가하시겠습니까?",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
private function checkPricingVsBom(array $data): array
|
||||
{
|
||||
$issues = [];
|
||||
$priced = array_map('mb_strtolower', array_filter(array_unique($data['priced_items'])));
|
||||
foreach (array_unique($data['bom_parts']) as $part) {
|
||||
if (empty($part)) {
|
||||
continue;
|
||||
}
|
||||
$found = false;
|
||||
foreach ($priced as $p) {
|
||||
if (str_contains($p, mb_strtolower($part)) || str_contains(mb_strtolower($part), $p)) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! $found && ! empty($priced)) {
|
||||
$issues[] = [
|
||||
'rule' => 'CC-02',
|
||||
'severity' => 'HIGH',
|
||||
'source' => 'pricing_structure',
|
||||
'target' => 'bom_structure',
|
||||
'message' => "BOM의 '{$part}'에 단가가 설정되지 않았습니다",
|
||||
'suggestion' => "'{$part}'의 단가를 알려주세요",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
private function checkFormulaVsDimension(array $data): array
|
||||
{
|
||||
$issues = [];
|
||||
$dims = array_map('strtolower', array_filter(array_unique($data['dimension_vars'])));
|
||||
foreach (array_unique($data['formula_vars']) as $var) {
|
||||
if (empty($var)) {
|
||||
continue;
|
||||
}
|
||||
if (! in_array(strtolower($var), $dims) && ! empty($dims)) {
|
||||
$issues[] = [
|
||||
'rule' => 'CC-03',
|
||||
'severity' => 'CRITICAL',
|
||||
'source' => 'quantity_formula',
|
||||
'target' => 'dimension_formula',
|
||||
'message' => "수량 공식에 '{$var}'를 사용하지만 치수 변수에 정의되지 않았습니다",
|
||||
'suggestion' => "'{$var}'는 무엇인가요? 치수 변수에 추가해주세요",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
private function checkProcessVsBom(array $data): array
|
||||
{
|
||||
$issues = [];
|
||||
$bomParts = array_map('mb_strtolower', array_filter(array_unique($data['bom_parts'])));
|
||||
foreach (array_unique($data['process_parts']) as $part) {
|
||||
if (empty($part)) {
|
||||
continue;
|
||||
}
|
||||
$found = false;
|
||||
foreach ($bomParts as $bp) {
|
||||
if (str_contains($bp, mb_strtolower($part)) || str_contains(mb_strtolower($part), $bp)) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! $found && ! empty($bomParts)) {
|
||||
$issues[] = [
|
||||
'rule' => 'CC-04',
|
||||
'severity' => 'MEDIUM',
|
||||
'source' => 'production_process',
|
||||
'target' => 'bom_structure',
|
||||
'message' => "공정에서 '{$part}'를 사용하지만 BOM에 없습니다",
|
||||
'suggestion' => "'{$part}'를 BOM에 추가하거나 확인해주세요",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
|
||||
private function checkQuoteVsPricing(array $data): array
|
||||
{
|
||||
// 견적 그룹과 단가 그룹의 일치 여부 (데이터 충분 시)
|
||||
return [];
|
||||
}
|
||||
|
||||
private function checkDepartmentVsProcess(array $data): array
|
||||
{
|
||||
$issues = [];
|
||||
$depts = array_map('mb_strtolower', array_filter(array_unique($data['departments'])));
|
||||
foreach (array_unique(array_filter($data['process_depts'])) as $procDept) {
|
||||
if (empty($procDept)) {
|
||||
continue;
|
||||
}
|
||||
$found = false;
|
||||
foreach ($depts as $d) {
|
||||
if (str_contains($d, mb_strtolower($procDept)) || str_contains(mb_strtolower($procDept), $d)) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! $found && ! empty($depts)) {
|
||||
$issues[] = [
|
||||
'rule' => 'CC-07',
|
||||
'severity' => 'LOW',
|
||||
'source' => 'production_process',
|
||||
'target' => 'tenant_setup',
|
||||
'message' => "공정 담당 '{$procDept}'이(가) 부서 목록에 없습니다",
|
||||
'suggestion' => "'{$procDept}'를 부서로 추가하시겠습니까?",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $issues;
|
||||
}
|
||||
}
|
||||
252
app/Services/Sales/InterviewKnowledgeLoader.php
Normal file
252
app/Services/Sales/InterviewKnowledgeLoader.php
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Sales;
|
||||
|
||||
use App\Models\Interview\InterviewAiConversation;
|
||||
use App\Models\Interview\InterviewKnowledge;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* SAM Knowledge Base(SKB) 프롬프트 로더
|
||||
*
|
||||
* 현재 인터뷰 도메인에 필요한 지식만 선별하여
|
||||
* AI 시스템 프롬프트를 동적으로 조립한다.
|
||||
*/
|
||||
class InterviewKnowledgeLoader
|
||||
{
|
||||
private string $basePath;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->basePath = config_path('interview_knowledge');
|
||||
}
|
||||
|
||||
/**
|
||||
* 도메인별 시스템 프롬프트 조립
|
||||
*
|
||||
* @param string $domain 현재 도메인 (예: 'pricing_structure')
|
||||
* @param string|null $preset 업종 프리셋 코드 (예: 'blinds')
|
||||
* @param array $previousResults 이전 도메인 수집 결과 요약
|
||||
* @param array $questions 현재 도메인 질문 목록
|
||||
*/
|
||||
public function buildPrompt(string $domain, ?string $preset, array $previousResults = [], array $questions = []): string
|
||||
{
|
||||
$parts = [];
|
||||
|
||||
// 1. 기본 시스템 프롬프트 (항상)
|
||||
$parts[] = $this->loadFile('system_prompt_base.md');
|
||||
|
||||
// 2. 업종 프리셋 (해당 시)
|
||||
if ($preset) {
|
||||
$presetContent = $this->loadPreset($preset);
|
||||
if ($presetContent) {
|
||||
$parts[] = "\n\n## 업종 프리셋: {$preset}\n\n".$presetContent;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 현재 도메인 모듈 지식
|
||||
$moduleContent = $this->loadModule($domain);
|
||||
if ($moduleContent) {
|
||||
$parts[] = "\n\n## 현재 도메인 지식\n\n".$moduleContent;
|
||||
}
|
||||
|
||||
// 4. 현재 도메인 질문 목록
|
||||
if (! empty($questions)) {
|
||||
$parts[] = "\n\n## 수집해야 할 질문 목록\n\n".$this->formatQuestions($questions);
|
||||
}
|
||||
|
||||
// 5. 이전 도메인 수집 결과 (크로스체크용)
|
||||
if (! empty($previousResults)) {
|
||||
$parts[] = "\n\n## 이전 도메인 수집 결과 (크로스체크 참고)\n\n".$this->formatPreviousResults($previousResults);
|
||||
}
|
||||
|
||||
// 6. 매핑 규칙 (답변→테이블)
|
||||
$mappingRules = $this->loadFile('mapping_rules/answer_to_table.md');
|
||||
if ($mappingRules) {
|
||||
$parts[] = "\n\n## 답변→SAM 매핑 규칙\n\n".$mappingRules;
|
||||
}
|
||||
|
||||
// 7. 크로스체크 규칙
|
||||
$crossCheckRules = $this->loadFile('mapping_rules/cross_check_rules.md');
|
||||
if ($crossCheckRules) {
|
||||
$parts[] = "\n\n## 도메인 간 크로스체크 규칙\n\n".$crossCheckRules;
|
||||
}
|
||||
|
||||
return implode('', $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 이전 도메인 결과를 요약하여 크로스체크 컨텍스트 생성
|
||||
*/
|
||||
public function buildCrossCheckContext(int $projectId): array
|
||||
{
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
|
||||
// 프로젝트의 모든 AI 대화에서 extracted_data 수집
|
||||
$conversations = InterviewAiConversation::where('interview_project_id', $projectId)
|
||||
->where('tenant_id', $tenantId)
|
||||
->where('role', 'assistant')
|
||||
->whereNotNull('structured_data')
|
||||
->orderBy('id')
|
||||
->get(['domain', 'structured_data']);
|
||||
|
||||
$domainResults = [];
|
||||
foreach ($conversations as $conv) {
|
||||
$domain = $conv->domain;
|
||||
if (! $domain) {
|
||||
continue;
|
||||
}
|
||||
if (! isset($domainResults[$domain])) {
|
||||
$domainResults[$domain] = [];
|
||||
}
|
||||
if (is_array($conv->structured_data)) {
|
||||
$domainResults[$domain][] = $conv->structured_data;
|
||||
}
|
||||
}
|
||||
|
||||
// 프로젝트의 검증된 지식도 포함
|
||||
$knowledge = InterviewKnowledge::on('codebridge')
|
||||
->where('interview_project_id', $projectId)
|
||||
->where('tenant_id', $tenantId)
|
||||
->get(['domain', 'title', 'content', 'knowledge_type']);
|
||||
|
||||
foreach ($knowledge as $k) {
|
||||
$domain = $k->domain;
|
||||
if (! isset($domainResults[$domain])) {
|
||||
$domainResults[$domain] = [];
|
||||
}
|
||||
$domainResults[$domain][] = [
|
||||
'knowledge' => $k->title,
|
||||
'type' => $k->knowledge_type,
|
||||
'content' => $k->content,
|
||||
];
|
||||
}
|
||||
|
||||
return $domainResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* 업종 프리셋 로딩
|
||||
*/
|
||||
public function loadPreset(string $presetCode): ?string
|
||||
{
|
||||
$presetMap = [
|
||||
'blinds' => 'blinds',
|
||||
'블라인드' => 'blinds',
|
||||
'스크린' => 'blinds',
|
||||
'방화' => 'blinds',
|
||||
'metal' => 'metal_fabrication',
|
||||
'금속' => 'metal_fabrication',
|
||||
'금속가공' => 'metal_fabrication',
|
||||
'machine' => 'machine_assembly',
|
||||
'기계' => 'machine_assembly',
|
||||
'기계조립' => 'machine_assembly',
|
||||
'food' => 'food_manufacturing',
|
||||
'식품' => 'food_manufacturing',
|
||||
'construction' => 'construction',
|
||||
'건설' => 'construction',
|
||||
'시공' => 'construction',
|
||||
'general' => 'general_manufacturing',
|
||||
'범용' => 'general_manufacturing',
|
||||
'제조' => 'general_manufacturing',
|
||||
];
|
||||
|
||||
$fileName = $presetMap[mb_strtolower($presetCode)] ?? $presetCode;
|
||||
|
||||
return $this->loadFile("presets/{$fileName}.md");
|
||||
}
|
||||
|
||||
/**
|
||||
* 도메인 코드로 모듈 번호 매핑
|
||||
*/
|
||||
public function getDomainModuleNumber(string $domain): string
|
||||
{
|
||||
$map = [
|
||||
'tenant_setup' => '01',
|
||||
'product_classification' => '02',
|
||||
'bom_structure' => '03',
|
||||
'dimension_formula' => '03',
|
||||
'component_config' => '03',
|
||||
'pricing_structure' => '04',
|
||||
'quantity_formula' => '04',
|
||||
'conditional_logic' => '04',
|
||||
'quote_format' => '05',
|
||||
'production_process' => '06',
|
||||
'quality_control' => '07',
|
||||
'logistics_inventory' => '08',
|
||||
'sales_customer' => '05',
|
||||
'finance' => '09',
|
||||
'hr' => '10',
|
||||
'approval' => '11',
|
||||
'barobill' => '12',
|
||||
];
|
||||
|
||||
return $map[$domain] ?? '01';
|
||||
}
|
||||
|
||||
/**
|
||||
* 모듈 지식 파일 로딩
|
||||
*/
|
||||
private function loadModule(string $domain): ?string
|
||||
{
|
||||
$moduleNumber = $this->getDomainModuleNumber($domain);
|
||||
$files = glob("{$this->basePath}/modules/{$moduleNumber}_*.md");
|
||||
|
||||
if (empty($files)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return file_get_contents($files[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 파일 로딩 (공통)
|
||||
*/
|
||||
private function loadFile(string $relativePath): ?string
|
||||
{
|
||||
$path = "{$this->basePath}/{$relativePath}";
|
||||
if (! file_exists($path)) {
|
||||
Log::debug("SKB file not found: {$path}");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return file_get_contents($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 질문 목록 포맷팅
|
||||
*/
|
||||
private function formatQuestions(array $questions): string
|
||||
{
|
||||
$lines = [];
|
||||
foreach ($questions as $i => $q) {
|
||||
$num = $i + 1;
|
||||
$required = ($q->is_required ?? false) ? ' [필수]' : '';
|
||||
$type = $q->question_type ?? 'text';
|
||||
$hint = ! empty($q->ai_hint) ? " (힌트: {$q->ai_hint})" : '';
|
||||
$lines[] = "{$num}. [{$type}]{$required} {$q->question_text}{$hint}";
|
||||
}
|
||||
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* 이전 도메인 결과 포맷팅
|
||||
*/
|
||||
private function formatPreviousResults(array $results): string
|
||||
{
|
||||
$text = '';
|
||||
foreach ($results as $domain => $items) {
|
||||
$text .= "### {$domain}\n";
|
||||
foreach ($items as $item) {
|
||||
if (is_array($item)) {
|
||||
$text .= '- '.json_encode($item, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)."\n";
|
||||
}
|
||||
}
|
||||
$text .= "\n";
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
75
config/interview_knowledge/mapping_rules/answer_to_table.md
Normal file
75
config/interview_knowledge/mapping_rules/answer_to_table.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 답변 → SAM 테이블 매핑 규칙
|
||||
|
||||
## 매핑 원칙
|
||||
|
||||
1. 고객 답변에서 SAM 테이블/필드로 직접 변환 가능한 데이터를 즉시 추출한다
|
||||
2. 매핑 불가능한 답변은 추가 질문으로 구체화한다
|
||||
3. 하나의 답변이 여러 테이블에 매핑될 수 있다
|
||||
4. 매핑 결과는 `sam_mapping` JSON 블록에 포함한다
|
||||
|
||||
## 테이블별 매핑 패턴
|
||||
|
||||
### categories (품목 분류)
|
||||
| 답변 패턴 | 매핑 | 추가 질문 |
|
||||
|---------|------|---------|
|
||||
| "제품은 A, B, C 3종류" | INSERT categories 3건 (type=PRODUCT) | "각 제품의 하위 모델은?" |
|
||||
| "원자재는 강판, 알루미늄" | INSERT categories 2건 (type=MATERIAL) | "규격은 어떻게 구분?" |
|
||||
| "분류는 용도별로 합니다" | category_fields: '용도' 필드 추가 | "용도 종류는?" |
|
||||
|
||||
### products (품목 마스터)
|
||||
| 답변 패턴 | 매핑 | 추가 질문 |
|
||||
|---------|------|---------|
|
||||
| "코드는 SC-01 형식" | code 패턴 = '{prefix}-{순번}' | "prefix가 제품군을 의미?" |
|
||||
| "단위는 EA로 관리" | unit = 'EA' | — |
|
||||
| "색상, 마감재 옵션 있음" | attributes에 추가 | "선택지 목록은?" |
|
||||
|
||||
### bom_template_items (BOM 항목)
|
||||
| 답변 패턴 | 매핑 | 추가 질문 |
|
||||
|---------|------|---------|
|
||||
| "모터 1개 고정" | quantity=1, quantity_formula=null | — |
|
||||
| "가이드레일은 높이 나누기 1219" | quantity_formula='CEIL(H1/1219)*2' | "올림 처리?" |
|
||||
| "LOSS 5% 적용" | waste_rate=5.0 | — |
|
||||
| "방화제품에만 연기차단재" | is_optional=true | "적용 조건 상세?" |
|
||||
|
||||
### price_histories (단가)
|
||||
| 답변 패턴 | 매핑 | 추가 질문 |
|
||||
|---------|------|---------|
|
||||
| "m당 15,000원" | price=15000, unit='m' | "VAT 포함?" |
|
||||
| "㎡당 45,000원" | price=45000, unit='㎡' | — |
|
||||
| "개당 125,000원" | price=125000, unit='EA' | — |
|
||||
| "분기마다 단가 변경" | effective_to 3개월 주기 | "다음 변경 예정일?" |
|
||||
|
||||
### clients (거래처)
|
||||
| 답변 패턴 | 매핑 | 추가 질문 |
|
||||
|---------|------|---------|
|
||||
| "A건설, B시공, C기업" | INSERT clients 3건 | "고객/공급업체 구분?" |
|
||||
| "월말 정산, 30일 이내 입금" | payment_terms='NET30' | — |
|
||||
| "A급/B급/C급 거래처" | grade 필드 설정 | "등급 기준은?" |
|
||||
|
||||
### tenants.options (시스템 설정)
|
||||
| 답변 패턴 | 매핑 키 |
|
||||
|---------|---------|
|
||||
| "견적번호 Q-2026-001" | quote_numbering: 'Q-{YYYY}-{NNN}' |
|
||||
| "부가세 별도 표시" | vat_display: 'separate' |
|
||||
| "FIFO로 재고 관리" | inventory_method: 'FIFO' |
|
||||
| "바코드 사용" | barcode_enabled: true |
|
||||
| "주 5일 9시~6시" | work_hours: {start:'09:00', end:'18:00', days:5} |
|
||||
|
||||
## JSON 출력 형식
|
||||
|
||||
```json
|
||||
{
|
||||
"sam_mapping": {
|
||||
"table": "categories",
|
||||
"action": "INSERT",
|
||||
"data": [
|
||||
{"name": "방화스크린", "type": "PRODUCT", "code": "SC"},
|
||||
{"name": "방화셔터", "type": "PRODUCT", "code": "SH"}
|
||||
],
|
||||
"confidence": 0.9,
|
||||
"needs_confirmation": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
confidence가 0.7 미만이면 needs_confirmation=true로 설정하고 확인 질문을 한다.
|
||||
@@ -0,0 +1,92 @@
|
||||
# 도메인 간 크로스체크 규칙
|
||||
|
||||
## 실행 시점
|
||||
|
||||
크로스체크는 다음 상황에서 자동 실행한다:
|
||||
1. 도메인 전환 시 (이전 도메인 결과 vs 현재 도메인)
|
||||
2. 인터뷰 완료 후 전체 검증
|
||||
3. AI가 모순을 감지했을 때 즉시
|
||||
|
||||
## 체크 규칙
|
||||
|
||||
### CC-01: BOM 부품 ⊂ 품목마스터
|
||||
```
|
||||
조건: bom_structure 수집 완료 AND product_classification 수집 완료
|
||||
검사: BOM에 있는 모든 부품이 품목 분류에 존재하는지
|
||||
경고: "BOM에 '{부품명}'이 있는데 품목 분류에 등록되지 않았습니다. 새로 추가할까요?"
|
||||
심각도: HIGH
|
||||
```
|
||||
|
||||
### CC-02: 단가 품목 = BOM 품목
|
||||
```
|
||||
조건: pricing_structure 수집 완료 AND bom_structure 수집 완료
|
||||
검사: 단가가 정의된 품목이 BOM에서 사용되는지 / BOM 품목에 단가가 있는지
|
||||
경고(미사용): "단가표에 '{품목}'이 있는데 BOM에서 사용되지 않습니다. 예비 단가인가요?"
|
||||
경고(미정가): "BOM의 '{부품}'에 단가가 설정되지 않았습니다. 단가를 알려주세요."
|
||||
심각도: HIGH (미정가), LOW (미사용)
|
||||
```
|
||||
|
||||
### CC-03: 수식 변수 = 치수 변수
|
||||
```
|
||||
조건: quantity_formula 수집 완료 AND dimension_formula 수집 완료
|
||||
검사: 수량 공식에서 사용하는 변수(W1, H1, area 등)가 치수 모듈에서 정의되어 있는지
|
||||
경고: "수량 공식에 'H2'를 사용하지만 치수 변수에 정의되지 않았습니다. H2는 무엇인가요?"
|
||||
심각도: CRITICAL
|
||||
```
|
||||
|
||||
### CC-04: 공정 부품 ⊂ BOM
|
||||
```
|
||||
조건: production_process 수집 완료 AND bom_structure 수집 완료
|
||||
검사: 각 공정에서 투입하는 부품이 BOM에 존재하는지
|
||||
경고: "'{공정명}' 공정에서 '{부품}'을 사용한다고 하셨는데 BOM에 없습니다."
|
||||
심각도: MEDIUM
|
||||
```
|
||||
|
||||
### CC-05: 검사 대상 ⊂ 품목
|
||||
```
|
||||
조건: quality_control 수집 완료 AND product_classification 수집 완료
|
||||
검사: 수입검사 대상 품목이 품목 마스터에 있는지
|
||||
경고: "수입검사 대상 '{품목}'이 품목 분류에 없습니다."
|
||||
심각도: MEDIUM
|
||||
```
|
||||
|
||||
### CC-06: 견적 항목 = 단가 항목
|
||||
```
|
||||
조건: quote_format 수집 완료 AND pricing_structure 수집 완료
|
||||
검사: 견적서 항목 그룹의 단가가 모두 정의되어 있는지
|
||||
경고: "견적서에 '운반비' 항목이 있는데 단가 기준이 수집되지 않았습니다."
|
||||
심각도: HIGH
|
||||
```
|
||||
|
||||
### CC-07: 부서 = 공정 담당
|
||||
```
|
||||
조건: tenant_setup 수집 완료 AND production_process 수집 완료
|
||||
검사: 공정 담당 부서가 조직도에 존재하는지
|
||||
경고: "'절단반'이 공정 담당인데 부서 목록에 없습니다. 부서를 추가할까요?"
|
||||
심각도: LOW
|
||||
```
|
||||
|
||||
### CC-08: 거래처 = 재무 거래처
|
||||
```
|
||||
조건: sales_customer 수집 완료 AND finance 수집 완료
|
||||
검사: 거래처 정보가 매출/매입 처리와 일치하는지
|
||||
경고: "매입 거래처 '{업체}'의 결제 조건이 설정되지 않았습니다."
|
||||
심각도: MEDIUM
|
||||
```
|
||||
|
||||
## JSON 출력 형식
|
||||
|
||||
```json
|
||||
{
|
||||
"cross_check_results": [
|
||||
{
|
||||
"rule": "CC-02",
|
||||
"severity": "HIGH",
|
||||
"source_domain": "pricing_structure",
|
||||
"target_domain": "bom_structure",
|
||||
"message": "BOM의 '연기차단재'에 단가가 설정되지 않았습니다.",
|
||||
"suggestion": "연기차단재의 단가를 알려주세요."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
75
config/interview_knowledge/mapping_rules/validation_rules.md
Normal file
75
config/interview_knowledge/mapping_rules/validation_rules.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 답변 검증 규칙
|
||||
|
||||
## 실행 시점
|
||||
모든 답변을 받을 때마다 즉시 검증한다.
|
||||
|
||||
## 필수값 검증
|
||||
|
||||
### CRITICAL (미수집 시 시스템 구축 불가)
|
||||
- □ 제품 분류 체계 (최소 1개 제품군)
|
||||
- □ 대표 제품 BOM 트리 (최소 1개)
|
||||
- □ 치수→제작 변환 공식 (치수 기반 견적 시)
|
||||
- □ 주요 부품 단가 (최소 BOM 부품 전체)
|
||||
- □ 견적서 양식 (파일 또는 상세 설명)
|
||||
|
||||
### HIGH (미수집 시 기능 제한)
|
||||
- □ 공정 순서 (생산 관리 시)
|
||||
- □ 단가 변경 주기
|
||||
- □ 거래처 결제 조건
|
||||
- □ 직급/권한 체계
|
||||
|
||||
### MEDIUM (미수집 시 수동 설정 필요)
|
||||
- □ 공통 코드/분류 (드롭다운 선택지)
|
||||
- □ 검사 항목/기준
|
||||
- □ LOT 번호 체계
|
||||
- □ 결재선 구성
|
||||
|
||||
## 데이터 형식 검증
|
||||
|
||||
| 항목 | 형식 | 오류 시 |
|
||||
|------|------|--------|
|
||||
| 사업자등록번호 | 10자리 숫자 | "사업자등록번호 형식을 확인해주세요" |
|
||||
| 단가 | 양수 | "단가가 0원 이하입니다. 확인해주세요" |
|
||||
| LOSS율 | 0~100% | "LOSS율이 100%를 초과합니다" |
|
||||
| 마진율 | 0~100% | — |
|
||||
| 수량 | 양의 정수 | "수량은 1 이상이어야 합니다" |
|
||||
| 공식 변수 | 영문+숫자 | "변수명은 영문으로 입력해주세요 (예: W1, H1)" |
|
||||
| 날짜 | YYYY-MM-DD | — |
|
||||
|
||||
## 논리적 검증
|
||||
|
||||
| 규칙 | 검사 | 메시지 |
|
||||
|------|------|--------|
|
||||
| V-01 | LOSS율 > 20% | "LOSS율이 높습니다. 실제 현장 기준인가요?" |
|
||||
| V-02 | 마진율 + LOSS율 > 30% | "원가 대비 부가 비율이 높습니다. 확인해주세요" |
|
||||
| V-03 | BOM 깊이 > 3 | "BOM이 4단계 이상입니다. SAM은 3단계를 권장합니다" |
|
||||
| V-04 | 카테고리 깊이 > 3 | "분류가 4단계 이상입니다" |
|
||||
| V-05 | 단가 0원 품목이 BOM에 존재 | "단가 미설정 품목이 BOM에 있습니다" |
|
||||
| V-06 | 공정 수 > 15 | "공정이 많습니다. 그룹화를 검토하세요" |
|
||||
| V-07 | 결재 단계 > 5 | "결재 단계가 많습니다. 간소화를 검토하세요" |
|
||||
| V-08 | 안전재고 0인 핵심 부품 | "핵심 부품의 안전재고가 0입니다" |
|
||||
|
||||
## 완료도 판정
|
||||
|
||||
### 도메인별 최소 수집 항목
|
||||
|
||||
| 도메인 | 필수 항목 수 | 최소 완료 기준 |
|
||||
|--------|:----------:|:-----------:|
|
||||
| 테넌트 기초 | 8 | 6개 이상 (75%) |
|
||||
| 품목 분류 | 10 | 7개 이상 (70%) |
|
||||
| BOM 구조 | 8 | 6개 이상 (75%) |
|
||||
| 단가 체계 | 10 | 8개 이상 (80%) |
|
||||
| 견적/수주 | 8 | 6개 이상 (75%) |
|
||||
| 생산 공정 | 8 | 5개 이상 (63%) |
|
||||
| 품질 관리 | 6 | 4개 이상 (67%) |
|
||||
| 재고/물류 | 6 | 4개 이상 (67%) |
|
||||
| 회계/재무 | 6 | 4개 이상 (67%) |
|
||||
| 인사 | 4 | 3개 이상 (75%) |
|
||||
| 결재 | 4 | 3개 이상 (75%) |
|
||||
| 바로빌 | 4 | 2개 이상 (50%) |
|
||||
|
||||
### 전체 완료 판정
|
||||
- 80% 이상: "인터뷰 완료. SAM 설정 생성 가능합니다."
|
||||
- 60~79%: "주요 정보 수집 완료. 일부 항목 보충이 필요합니다."
|
||||
- 40~59%: "기본 정보 수집 중. 추가 인터뷰가 필요합니다."
|
||||
- 40% 미만: "초기 단계. 핵심 도메인부터 집중해주세요."
|
||||
60
config/interview_knowledge/modules/01_tenant_setup.md
Normal file
60
config/interview_knowledge/modules/01_tenant_setup.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# 모듈 01: 테넌트 기초 설정
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### tenants (회사 정보)
|
||||
- name, business_number, representative, business_type, business_category
|
||||
- address, phone, fax, email, logo_path
|
||||
- subscription_plan, is_active, options(json)
|
||||
|
||||
### departments (부서)
|
||||
- tenant_id, parent_id, name, code, sort_order, is_active, head_user_id
|
||||
|
||||
### users + user_tenants (사용자)
|
||||
- name, email, phone, employee_number
|
||||
- user_tenants: role, is_active, is_default, department_id
|
||||
|
||||
### roles + permissions (역할/권한)
|
||||
- roles: tenant_id, name, guard_name
|
||||
- permissions: tenant_id, name, menu_id
|
||||
- permission_overrides: user_id, menu_id, allow/deny
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 회사 기본 정보 (tenants)
|
||||
- □ 회사명 (법인명과 상호 구분)
|
||||
- □ 사업자등록번호
|
||||
- □ 대표자명
|
||||
- □ 업태/업종
|
||||
- □ 주소 (본사 + 공장/사업장)
|
||||
- □ 연락처 (전화, 팩스, 이메일)
|
||||
- □ 직원 수 (규모 파악)
|
||||
- □ 연매출 규모 (구독 플랜 결정)
|
||||
|
||||
### 조직 구조 (departments)
|
||||
- □ 부서 목록 + 계층 구조 (예: 경영지원실 > 인사팀, 총무팀)
|
||||
- □ 각 부서 인원 수
|
||||
- □ 부서장/팀장 직급 체계
|
||||
- □ 공장/사업장이 여러 곳인 경우 구분
|
||||
|
||||
### 사용자 역할 (roles)
|
||||
- □ 직급 체계 (대표, 이사, 부장, 과장, 대리, 사원 등)
|
||||
- □ 역할별 시스템 접근 범위 (경영진/관리자/현장/외부)
|
||||
- □ 특수 권한이 필요한 사용자 (예: 단가 열람 제한)
|
||||
- □ 초기 등록 사용자 수
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "직원이 45명이고 본사와 공장이 있어요" | tenants.options.employee_count=45, departments에 본사/공장 생성 |
|
||||
| "영업부, 생산부, 관리부 3개 부서" | departments INSERT 3건 |
|
||||
| "부장급 이상만 단가 볼 수 있어요" | permission_overrides: 단가 메뉴 부장 이상만 allow |
|
||||
| "공장장은 생산 관련만 사용" | roles: '공장장' 역할 생성 + 생산 메뉴만 권한 |
|
||||
|
||||
## 검증 규칙
|
||||
|
||||
- 사업자등록번호 10자리 형식 체크
|
||||
- 부서 계층이 3단계 초과 시 확인 질문 (SAM 권장 2~3단계)
|
||||
- 초기 사용자 수가 구독 플랜 한도 초과 시 안내
|
||||
- 직급 체계 미수집 시 → 역할 기반 권한 설정 불가 경고
|
||||
74
config/interview_knowledge/modules/02_item_classification.md
Normal file
74
config/interview_knowledge/modules/02_item_classification.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# 모듈 02: 품목 분류 체계
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### categories (품목 카테고리)
|
||||
- tenant_id, parent_id, name, code, type(PRODUCT|MATERIAL|PART|SUBASSEMBLY)
|
||||
- description, sort_order, is_active, options(json)
|
||||
- 계층 구조: 대분류 > 중분류 > 소분류 (최대 3단계)
|
||||
|
||||
### category_fields (카테고리별 동적 필드)
|
||||
- category_id, field_name, field_type(text|number|select|checkbox|date)
|
||||
- options(json: choices, default, unit 등), is_required, sort_order
|
||||
|
||||
### category_templates (카테고리 양식 스냅샷)
|
||||
- category_id, version, fields_snapshot(json)
|
||||
|
||||
### products (제품/품목 마스터)
|
||||
- tenant_id, category_id, name, code, type(PRODUCT|PART|SUBASSEMBLY)
|
||||
- specification, unit, is_active, attributes(json)
|
||||
|
||||
### classifications (분류 코드)
|
||||
- tenant_id, group, code, name, sort_order
|
||||
- groups: product_type, material_type, finish_type 등
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 제품 분류 (categories)
|
||||
- □ 주요 제품군 목록 (대분류)
|
||||
- □ 각 제품군의 하위 분류 (중분류, 소분류)
|
||||
- □ 분류 기준 (소재별? 용도별? 크기별? 인증여부별?)
|
||||
- □ 제품 코드 체계 (예: SC-01 = 스크린 1번 모델)
|
||||
- □ 제품 수 (카테고리별 대략적 품목 수)
|
||||
|
||||
### 자재/부품 분류
|
||||
- □ 원자재 분류 (강판, 알루미늄, 수지 등)
|
||||
- □ 구매 부품 분류 (모터, 제어기, 센서 등)
|
||||
- □ 소모품/부자재 분류 (볼트, 너트, 패킹 등)
|
||||
- □ 반제품 구분 여부 (절곡품, 서브어셈블리 등)
|
||||
|
||||
### 품목 속성 (category_fields)
|
||||
- □ 제품별 고유 속성 (규격, 색상, 마감재 등)
|
||||
- □ 필수 속성 vs 선택 속성
|
||||
- □ 속성의 선택지 목록 (드롭다운 항목)
|
||||
- □ 단위 (mm, kg, EA, m, ㎡ 등)
|
||||
|
||||
### 인증/규격
|
||||
- □ 인증 제품 구분 (KC, 방화, KS 등)
|
||||
- □ 인증 제품의 구성 고정 여부
|
||||
- □ 인증서 번호 관리 필요성
|
||||
- □ 시험성적서 관리 필요성
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "방화스크린, 방화셔터, 일반블라인드" | categories INSERT 3건 (type=PRODUCT) |
|
||||
| "방화스크린 밑에 KSS01, KSS02 모델" | categories INSERT 2건 (parent_id=방화스크린) |
|
||||
| "코드는 SC-01 형식, SC가 스크린" | products.code 패턴 = '{카테고리코드}-{순번}' |
|
||||
| "색상은 흰색/아이보리/회색/브라운" | category_fields: field_name='색상', type='select', options=['흰색','아이보리','회색','브라운'] |
|
||||
| "알루미늄, 스틸, SUS 3종류 소재" | classifications: group='material_type', 3건 INSERT |
|
||||
|
||||
## 검증 규칙
|
||||
|
||||
- 제품 코드 체계 미수집 → 자동 채번 불가 경고
|
||||
- 카테고리에 속한 제품이 0건인 빈 분류 → 확인 질문
|
||||
- category_fields 미수집 → 품목등록 시 속성 입력 불가 경고
|
||||
- 인증 제품 존재 시 인증서 관리 방안 미수집 → 재질문
|
||||
- 분류 깊이 4단계 이상 → SAM 권장 3단계 이하 안내
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- → BOM: 여기서 정의한 품목이 BOM에서 모두 사용되는지
|
||||
- → 단가: 모든 품목에 단가가 매핑되는지
|
||||
- → 생산: 자체 생산 품목과 외주 품목 구분이 공정에 반영되는지
|
||||
75
config/interview_knowledge/modules/03_bom_design.md
Normal file
75
config/interview_knowledge/modules/03_bom_design.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 모듈 03: 설계/BOM 구조
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### models (설계 모델)
|
||||
- tenant_id, code, name, category_id, description, status(DRAFT|RELEASED|ARCHIVED)
|
||||
- 제품군별 마스터 모델 정의
|
||||
|
||||
### model_versions (모델 버전)
|
||||
- model_id, version_no, status(DRAFT|RELEASED), released_at
|
||||
- 설계 변경 시 버전 관리
|
||||
|
||||
### bom_templates (BOM 템플릿)
|
||||
- model_version_id, name, description, is_default
|
||||
|
||||
### bom_template_items (BOM 항목)
|
||||
- bom_template_id, component_type(MATERIAL|PRODUCT), component_id
|
||||
- quantity, quantity_formula, waste_rate, is_optional
|
||||
- sort_order, parent_item_id (다단계 BOM)
|
||||
|
||||
### product_components (제품 구성 부품)
|
||||
- product_id, ref_type(MATERIAL|PRODUCT), ref_id
|
||||
- quantity, waste_rate, sort_order
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 제품 모델 (models)
|
||||
- □ 제품 모델 코드 체계 (예: KSS-01 = 스크린 1호)
|
||||
- □ 모델 수 (대략)
|
||||
- □ 모델 변경 관리 여부 (ECN/ECO 프로세스)
|
||||
- □ 모델별 도면 관리 여부
|
||||
|
||||
### BOM 구조 (bom_templates)
|
||||
- □ 대표 제품 1개의 BOM 트리 (완제품→부품 관계)
|
||||
- □ BOM 레벨 깊이 (1단계? 2단계? 3단계?)
|
||||
- □ 반제품(서브어셈블리) 존재 여부
|
||||
- □ 공통 부품 목록 (모든 제품에 공통)
|
||||
- □ 옵션 부품 목록 (선택적 적용)
|
||||
- □ 대체품/호환품 관리 필요성
|
||||
|
||||
### 수량 결정 (bom_template_items)
|
||||
- □ 고정 수량 부품 (항상 1개, 2개 등)
|
||||
- □ 계산 수량 부품 (치수 기반: CEIL(H1/피치) 등)
|
||||
- □ LOSS율 적용 품목과 비율
|
||||
- □ 최소 수량 제한 (예: 최소 2개 이상)
|
||||
|
||||
### 기존 BOM 자료
|
||||
- □ BOM 엑셀 파일
|
||||
- □ 도면 파일 (참고용)
|
||||
- □ 부품 목록표
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "스크린은 가이드레일, 케이스, 모터, 제어기로 구성" | bom_template_items INSERT 4건 |
|
||||
| "가이드레일은 높이에 따라 개수가 달라요" | quantity_formula = 'CEIL(H1/1219)*2' |
|
||||
| "스크린원단은 5% 여유를 줍니다" | waste_rate = 5.0 |
|
||||
| "연기차단재는 방화제품에만 들어갑니다" | is_optional = true, 조건 기록 |
|
||||
| "절곡품은 반제품으로 관리합니다" | component_type = 'PRODUCT', type = 'SUBASSEMBLY' |
|
||||
|
||||
## 검증 규칙
|
||||
|
||||
- BOM 트리 미수집 → 견적 자동 계산 불가 경고 (최우선 수집 항목)
|
||||
- quantity_formula 참조 변수가 치수 모듈에서 미정의 → 재질문
|
||||
- waste_rate가 20% 초과 → "LOSS율이 높은데 맞나요?" 확인
|
||||
- BOM 깊이 4단계 이상 → SAM 권장 3단계, 구조 재논의
|
||||
- 대체품 있다고 했는데 구체적 매핑 미수집 → 재질문
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← 품목분류: BOM 부품이 모두 categories에 존재하는지
|
||||
- → 단가: BOM 부품 전체에 단가가 매핑되는지
|
||||
- → 수량수식: quantity_formula의 변수가 치수 모듈에 정의되어 있는지
|
||||
- → 생산공정: 각 부품의 투입 공정이 정의되어 있는지
|
||||
77
config/interview_knowledge/modules/04_pricing.md
Normal file
77
config/interview_knowledge/modules/04_pricing.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 모듈 04: 단가 체계
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### price_histories (단가 이력)
|
||||
- tenant_id, product_id, material_id, price, unit
|
||||
- effective_from, effective_to (시간축 관리)
|
||||
- price_type(purchase|sale|internal), currency
|
||||
- created_by, options(json)
|
||||
|
||||
### 관련 테이블
|
||||
- products.unit_price (현재 단가 캐시)
|
||||
- quote_formulas.formula (견적 계산식에서 단가 참조)
|
||||
- bom_template_items.waste_rate (LOSS율)
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 단가 관리 방식
|
||||
- □ 현재 단가 관리 도구 (엑셀/ERP/구두)
|
||||
- □ 단가표 파일 (엑셀 업로드)
|
||||
- □ 단가 변경 주기 (수시/월/분기/연)
|
||||
- □ 단가 변경 승인 프로세스 (누가 결정?)
|
||||
|
||||
### 단가 구성요소
|
||||
- □ 재료비 (원자재 단가)
|
||||
- □ 가공비 (자체/외주 가공 단가)
|
||||
- □ 관리비/경비 비율
|
||||
- □ 이윤율
|
||||
- □ 운반비/설치비 별도 여부
|
||||
|
||||
### 단가 유형별
|
||||
- □ 면적 기반 (원/㎡) — 스크린원단, 판재 등
|
||||
- □ 길이 기반 (원/m) — 가이드레일, 파이프 등
|
||||
- □ 중량 기반 (원/kg) — 강판, 알루미늄 등
|
||||
- □ 수량 기반 (원/EA) — 모터, 제어기, 볼트 등
|
||||
- □ 복합 단가 (길이×두께, 용량별 등)
|
||||
|
||||
### 차등 단가
|
||||
- □ 고객 등급별 단가 차이
|
||||
- □ 수량 할인 (대량 구매 시)
|
||||
- □ 프로젝트별 특별 단가
|
||||
- □ 계약 단가 vs 시장 단가
|
||||
|
||||
### LOSS율/마진
|
||||
- □ LOSS율 적용 품목 및 비율
|
||||
- □ LOSS 유형 구분 (절단/가공/불량)
|
||||
- □ 마진율 설정 방식 (일괄/품목별/카테고리별)
|
||||
- □ 최소 마진율 기준
|
||||
|
||||
### 환율/수입
|
||||
- □ 수입 자재 여부
|
||||
- □ 환율 적용 방식
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "가이드레일 m당 15,000원" | price_histories: product_id=GR, price=15000, unit='m' |
|
||||
| "분기마다 단가 검토합니다" | tenants.options.pricing_update_cycle='quarterly' |
|
||||
| "A급 거래처는 5% 할인" | clients.grade='A', pricing_rules.discount=5 |
|
||||
| "스크린원단 LOSS 5%" | bom_template_items.waste_rate=5.0 |
|
||||
| "마진율은 품목별로 다릅니다" | tenants.options.margin_type='per_item' |
|
||||
|
||||
## 검증 규칙
|
||||
|
||||
- 단가가 0원인 BOM 품목 존재 → 경고
|
||||
- 면적/길이 단가의 단위 미확인 → "㎡당인가요? m당인가요?" 재질문
|
||||
- LOSS율이 품목별로 다르다고 했는데 구체 수치 미수집 → 재질문
|
||||
- 단가 변경 주기 미수집 → price_histories 설정 불가 경고
|
||||
- 수입 자재가 있는데 환율 적용 방식 미수집 → 재질문
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← BOM: BOM의 모든 부품에 단가가 정의되어 있는지
|
||||
- ← 품목: 단가가 있는데 품목 마스터에 미등록인 항목
|
||||
- → 견적: 견적서 항목 그룹과 단가 구성요소의 일치 여부
|
||||
- → 수량수식: 수량 × 단가 계산이 실제 견적 금액과 일치하는지
|
||||
89
config/interview_knowledge/modules/05_quotation.md
Normal file
89
config/interview_knowledge/modules/05_quotation.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# 모듈 05: 견적/수주 관리
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### quotes (견적)
|
||||
- tenant_id, client_id, quote_number, title, status(DRAFT|SUBMITTED|APPROVED|REJECTED)
|
||||
- total_amount, vat_amount, discount_rate, validity_days
|
||||
- revision_no, parent_quote_id (개정 관리)
|
||||
- options(json), created_by
|
||||
|
||||
### quote_items (견적 항목)
|
||||
- quote_id, product_id, item_name, specification
|
||||
- quantity, unit_price, amount, discount_rate
|
||||
- group_name (재료비/노무비/경비 등), sort_order
|
||||
|
||||
### quote_formulas (견적 계산식)
|
||||
- quote_id, category_id, formula_type, formula, variables(json)
|
||||
- 치수 입력 → BOM 자동 계산 → 견적 금액 산출
|
||||
|
||||
### orders (수주)
|
||||
- tenant_id, client_id, quote_id, order_number, status
|
||||
- delivery_date, total_amount, options(json)
|
||||
|
||||
### order_items (수주 항목)
|
||||
- order_id, product_id, quantity, unit_price, amount
|
||||
- design_code, specification
|
||||
|
||||
### clients (거래처)
|
||||
- tenant_id, name, business_number, type(CUSTOMER|VENDOR|BOTH)
|
||||
- grade, payment_terms, credit_limit, contact_person
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 견적 프로세스
|
||||
- □ 견적 요청 → 작성 → 승인 → 제출 흐름
|
||||
- □ 견적 작성자 (영업? 설계? 관리자?)
|
||||
- □ 견적 승인 절차 (결재선)
|
||||
- □ 견적 유효기간 (보통 몇 일?)
|
||||
- □ 견적 개정 관리 (수정 시 이력 유지?)
|
||||
|
||||
### 견적서 양식
|
||||
- □ 현재 사용 중인 견적서 양식 파일
|
||||
- □ 항목 그룹 구분 (재료비/노무비/경비/이윤/부가세)
|
||||
- □ 소계/합계 계산 구조
|
||||
- □ 할인 적용 방식 (일괄/항목별)
|
||||
- □ 부가세 표시 방식 (별도/포함)
|
||||
- □ 견적 번호 체계
|
||||
|
||||
### 견적 계산
|
||||
- □ 치수 입력 → 자동 계산 여부
|
||||
- □ 오픈사이즈 → 제작사이즈 변환 공식
|
||||
- □ BOM 자동 전개 → 수량/단가 자동 계산
|
||||
- □ 수동 항목 추가 (설치비, 운반비 등)
|
||||
|
||||
### 수주 전환
|
||||
- □ 견적 → 수주 전환 프로세스
|
||||
- □ 수주 확정 시 필요 정보 (납기, PO번호 등)
|
||||
- □ 수주 → 생산 연계 방식
|
||||
|
||||
### 특수 요구
|
||||
- □ 다중 양식 (관급용/민간용/수출용)
|
||||
- □ 산출내역서 별도 제출
|
||||
- □ 위치별/층별 개별 산출
|
||||
- □ 다국어 견적서
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "견적번호는 Q-2026-001 형식" | tenants.options.quote_numbering='Q-{YYYY}-{NNN}' |
|
||||
| "유효기간 30일" | quotes.validity_days=30 |
|
||||
| "재료비, 노무비, 경비로 구분" | quote_items.group_name 3종 |
|
||||
| "부가세 별도 표시" | tenants.options.vat_display='separate' |
|
||||
| "견적은 팀장 승인 후 제출" | approval_forms: 견적 결재선 설정 |
|
||||
|
||||
## 검증 규칙
|
||||
|
||||
- 견적 양식 미수집 → 출력물 생성 불가 경고 (필수)
|
||||
- 치수→BOM 자동 계산인데 BOM 미수집 → BOM 모듈 먼저 완료 안내
|
||||
- 항목 그룹이 단가 구성요소와 불일치 → 크로스체크 경고
|
||||
- 수주 전환 프로세스 미수집 → 영업 플로우 미완성 경고
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← 단가: 견적 항목 금액 = BOM 수량 × 단가 검증
|
||||
- ← BOM: 자동 견적 시 BOM 전개 결과와 견적 항목 일치
|
||||
- ← 치수: 오픈사이즈→제작사이즈 공식 적용 결과 검증
|
||||
- → 수주: 견적→수주 전환 시 데이터 이관 항목 확인
|
||||
- → 생산: 수주 확정 → 작업지시 생성 연계
|
||||
79
config/interview_knowledge/modules/06_production.md
Normal file
79
config/interview_knowledge/modules/06_production.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# 모듈 06: 생산/공정 관리
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### processes (공정 정의)
|
||||
- tenant_id, name, code, department_id, sort_order
|
||||
- standard_time, unit, description
|
||||
|
||||
### work_orders (작업지시)
|
||||
- tenant_id, order_id, product_id, quantity, status
|
||||
- planned_start, planned_end, actual_start, actual_end
|
||||
- assigned_department_id, priority
|
||||
|
||||
### production_results (생산 실적)
|
||||
- work_order_id, process_id, quantity_produced, quantity_defective
|
||||
- worker_id, start_time, end_time, options(json)
|
||||
|
||||
### 관련 테이블
|
||||
- lots (LOT 추적), material_receipts (자재 투입)
|
||||
- nonconforming_reports (부적합 보고)
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 공정 흐름
|
||||
- □ 주요 공정 순서 (절단→가공→조립→검사→포장 등)
|
||||
- □ 각 공정별 작업 내용
|
||||
- □ 공정별 담당 부서/작업반
|
||||
- □ 공정별 표준 작업시간
|
||||
- □ 병렬 공정 여부 (동시 진행 가능한 공정)
|
||||
- □ 외주 가공 공정
|
||||
|
||||
### 생산 계획
|
||||
- □ 생산 계획 수립 주기 (일/주/월)
|
||||
- □ 계획 수립 기준 (수주 기반? 재고 기반?)
|
||||
- □ 납기 계산 방식 (리드타임 합산?)
|
||||
- □ 생산 능력(Capa) 관리 여부
|
||||
|
||||
### 작업지시
|
||||
- □ 작업지시서 양식 (파일 수집)
|
||||
- □ 작업지시 단위 (수주별? 제품별? LOT별?)
|
||||
- □ 작업지시 발행 → 시작 → 완료 흐름
|
||||
- □ 우선순위 관리 방식
|
||||
|
||||
### 생산 실적
|
||||
- □ 실적 보고 방식 (실시간? 일일? 바코드?)
|
||||
- □ 불량 보고 및 처리 방식
|
||||
- □ 재작업 프로세스
|
||||
- □ 실적 데이터 입력자 (작업자? 관리자?)
|
||||
|
||||
### 설비/장비
|
||||
- □ 주요 설비 목록
|
||||
- □ 설비별 일일 가동 시간
|
||||
- □ 설비 보전/점검 주기
|
||||
- □ 설비 고장 시 대응 방식
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "절단→절곡→조립→검사→포장 5공정" | processes INSERT 5건 (sort_order 1~5) |
|
||||
| "조립은 1팀이 담당" | processes.department_id = 조립1팀 |
|
||||
| "절단은 표준 30분" | processes.standard_time=30, unit='분' |
|
||||
| "주 단위 생산 계획" | tenants.options.production_planning='weekly' |
|
||||
| "수주별로 작업지시 발행" | tenants.options.work_order_unit='per_order' |
|
||||
|
||||
## 검증 규칙
|
||||
|
||||
- 공정 순서 미수집 → 작업지시/실적 관리 불가 경고 (필수)
|
||||
- 공정이 있는데 담당 부서 미매핑 → 재질문
|
||||
- 표준시간 미수집 → 납기 자동 계산 불가 경고
|
||||
- 외주 공정이 있는데 외주 관리 방식 미수집 → 재질문
|
||||
- 불량 처리 방식 미수집 → 품질 모듈과 연계 질문
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← BOM: 각 공정에서 투입되는 자재가 BOM에 존재하는지
|
||||
- ← 품목: 생산 대상 품목이 품목 마스터에 등록되어 있는지
|
||||
- → 품질: 검사 공정의 검사 기준이 정의되어 있는지
|
||||
- → 재고: 완제품 입고 프로세스와 연계
|
||||
62
config/interview_knowledge/modules/07_quality.md
Normal file
62
config/interview_knowledge/modules/07_quality.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# 모듈 07: 품질 관리
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### material_inspections (수입검사)
|
||||
- tenant_id, material_receipt_id, inspector_id, status, result(PASS|FAIL|CONDITIONAL)
|
||||
- inspection_date, options(json)
|
||||
|
||||
### material_inspection_items (검사 항목)
|
||||
- inspection_id, item_name, standard, method, result, judgment
|
||||
|
||||
### nonconforming_reports (부적합 보고)
|
||||
- tenant_id, type, source, product_id, lot_id
|
||||
- defect_type, quantity, description, corrective_action, status
|
||||
|
||||
### audit_checklists (점검표)
|
||||
- tenant_id, name, category, items(json)
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 수입검사
|
||||
- □ 수입검사 대상 품목 (전수? 샘플? 품목별 다름?)
|
||||
- □ 검사 항목 (외관, 치수, 기능, 성적서 등)
|
||||
- □ 합격 기준 (수치 기준, 허용 범위)
|
||||
- □ 검사 장비 목록
|
||||
- □ 불합격 시 처리 (반품, 특채, 재검사)
|
||||
|
||||
### 공정검사
|
||||
- □ 공정 중 자주검사 항목
|
||||
- □ 순회검사 주기/방법
|
||||
- □ 검사 기록 방식 (체크시트, 바코드 등)
|
||||
|
||||
### 완제품검사
|
||||
- □ 출하 전 최종 검사 항목
|
||||
- □ 시험성적서 발행 여부
|
||||
- □ 검사 성적서 보관 기간
|
||||
|
||||
### 불량 관리
|
||||
- □ 불량 유형 분류 (외관, 치수, 기능, 원자재 등)
|
||||
- □ 불량 처리 프로세스 (폐기, 재작업, 특채)
|
||||
- □ 시정/예방 조치 프로세스
|
||||
- □ 불량률 목표 (KPI)
|
||||
|
||||
### 인증
|
||||
- □ 보유 인증 (ISO 9001, ISO 14001, KC 등)
|
||||
- □ 인증 심사 주기
|
||||
- □ 인증 관련 문서 관리 필요성
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "강판은 전수검사, 볼트는 샘플" | material_inspections 정책 설정 |
|
||||
| "외관, 치수, 두께 3가지 검사" | material_inspection_items 3건 |
|
||||
| "불량은 외관불량, 치수불량 구분" | classifications: group='defect_type' |
|
||||
| "ISO 9001 인증 보유" | tenants.options.certifications=['ISO9001'] |
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← 품목: 수입검사 대상 품목이 품목 마스터에 있는지
|
||||
- ← 생산: 공정검사 위치가 공정 순서와 일치하는지
|
||||
- → 거래처: 불합격 시 공급업체 관리와 연계
|
||||
63
config/interview_knowledge/modules/08_inventory.md
Normal file
63
config/interview_knowledge/modules/08_inventory.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# 모듈 08: 재고/물류 관리
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### material_receipts (자재 입고)
|
||||
- tenant_id, vendor_id, receipt_number, receipt_date, status
|
||||
- items: material_id, quantity, unit_price, lot_number
|
||||
|
||||
### lots (LOT 관리)
|
||||
- tenant_id, lot_number, product_id, material_id
|
||||
- quantity, remaining_quantity, manufactured_date, expiry_date, status
|
||||
|
||||
### stocks (재고)
|
||||
- tenant_id, product_id, warehouse_id, quantity, reserved_quantity
|
||||
|
||||
### lot_sales (LOT 소진)
|
||||
- lot_id, order_item_id, quantity, sale_date
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 입출고 프로세스
|
||||
- □ 자재 입고 프로세스 (발주→입고→검사→입고확정)
|
||||
- □ 제품 출고 프로세스 (수주→출하지시→출고→납품)
|
||||
- □ 입출고 전표 양식
|
||||
|
||||
### 창고/저장소
|
||||
- □ 창고 수와 위치 (본사, 공장, 외부 등)
|
||||
- □ 창고 내 구역 구분 (원자재/반제품/완제품/불량)
|
||||
- □ 적재 방식 (FIFO, LIFO, 지정 위치)
|
||||
|
||||
### 재고 관리
|
||||
- □ 안전재고 기준 (품목별 최소 보유량)
|
||||
- □ 재고 실사 주기 (월/분기/연)
|
||||
- □ 바코드/QR 사용 여부
|
||||
- □ 재고 평가 방법 (이동평균, 선입선출, 총평균)
|
||||
|
||||
### LOT 추적
|
||||
- □ LOT 관리 필요 품목 범위
|
||||
- □ LOT 번호 체계
|
||||
- □ LOT 추적 수준 (원자재→완제품? 공정별?)
|
||||
- □ 유효기한 관리 필요성
|
||||
|
||||
### 운송/배송
|
||||
- □ 배송 방식 (자가/택배/화물)
|
||||
- □ 배송 지역 범위
|
||||
- □ 포장 규격/방법
|
||||
- □ 반품 처리 프로세스
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "본사 창고, 공장 창고 2곳" | warehouses INSERT 2건 |
|
||||
| "강판은 안전재고 500kg" | stock_settings: product_id, safety_stock=500 |
|
||||
| "바코드로 입출고 관리" | tenants.options.barcode_enabled=true |
|
||||
| "LOT은 입고일+순번" | tenants.options.lot_format='{YYYYMMDD}-{NNN}' |
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← 품목: 재고 관리 대상 품목이 품목 마스터에 있는지
|
||||
- ← 생산: 완제품 입고 프로세스와 생산 실적 연계
|
||||
- ← 품질: 입고 → 수입검사 → 재고확정 흐름 확인
|
||||
- → 회계: 재고 금액 = 수량 × 단가 정합성
|
||||
73
config/interview_knowledge/modules/09_finance.md
Normal file
73
config/interview_knowledge/modules/09_finance.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 모듈 09: 회계/재무 관리
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### sales (매출)
|
||||
- tenant_id, client_id, order_id, sale_date, amount, vat_amount
|
||||
- payment_method, status, tax_invoice_id, options(json)
|
||||
|
||||
### purchases (매입)
|
||||
- tenant_id, vendor_id, purchase_date, amount, vat_amount
|
||||
- category(자재/외주/경비), status, tax_invoice_id
|
||||
|
||||
### deposits (입금)
|
||||
- tenant_id, client_id, deposit_date, amount, method
|
||||
- sale_id, memo, status
|
||||
|
||||
### withdrawals (출금)
|
||||
- tenant_id, vendor_id, withdrawal_date, amount, method
|
||||
- purchase_id, memo, status
|
||||
|
||||
### expected_expenses (예상지출)
|
||||
- tenant_id, purchase_id, expected_date, amount, status
|
||||
|
||||
### bad_debts (회수불능금)
|
||||
- tenant_id, client_id, amount, reason, status
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 매출/매입
|
||||
- □ 매출 인식 시점 (출하? 검수? 세금계산서 발행?)
|
||||
- □ 매입 인식 시점 (입고? 세금계산서 수취?)
|
||||
- □ 세금계산서 발행 방식 (전자/종이/바로빌)
|
||||
- □ 매출/매입 분류 체계 (계정과목)
|
||||
|
||||
### 입금/출금
|
||||
- □ 결제 조건 (선금/중도금/잔금 비율)
|
||||
- □ 결제 수단 (계좌이체/어음/카드/현금)
|
||||
- □ 수금 주기 (월말/납품 후 N일)
|
||||
- □ 미수금 관리 방식
|
||||
- □ 미지급금 관리 방식
|
||||
|
||||
### 원가 관리
|
||||
- □ 원가 계산 방식 (실제원가/표준원가)
|
||||
- □ 원가 구성 항목 (재료비/노무비/경비)
|
||||
- □ 간접비 배부 기준
|
||||
- □ 손익 분석 단위 (프로젝트별/월별/제품별)
|
||||
|
||||
### 예산/계획
|
||||
- □ 예산 수립 여부
|
||||
- □ 월별 실적 대비 예산 관리
|
||||
- □ 자금 계획 관리 필요성
|
||||
|
||||
### 바로빌 연동
|
||||
- □ 바로빌 사용 여부
|
||||
- □ 전자세금계산서 자동 발행
|
||||
- □ 카드 매출 조회
|
||||
- □ 은행 계좌 조회
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "납품 후 30일 이내 입금" | clients.payment_terms='NET30' |
|
||||
| "세금계산서는 바로빌로" | tenants.options.tax_invoice_provider='barobill' |
|
||||
| "선금 30%, 잔금 70%" | tenants.options.payment_split=[30,70] |
|
||||
| "월별로 손익 분석합니다" | tenants.options.pnl_unit='monthly' |
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← 견적: 견적 금액 → 매출 금액 정합성
|
||||
- ← 거래처: 결제 조건이 거래처별로 설정되어 있는지
|
||||
- ← 재고: 재고 금액과 매입 금액 정합성
|
||||
- → 바로빌: 바로빌 연동 설정이 완료되어 있는지
|
||||
59
config/interview_knowledge/modules/10_hr.md
Normal file
59
config/interview_knowledge/modules/10_hr.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# 모듈 10: 인사/급여 관리
|
||||
|
||||
## SAM 관련 기능
|
||||
|
||||
### 근태 관리
|
||||
- 출퇴근 기록, 근무시간 계산
|
||||
- 연장/야간/휴일 근무
|
||||
|
||||
### 급여 관리
|
||||
- 기본급, 수당, 공제 항목
|
||||
- 급여 명세서 발행
|
||||
|
||||
### 휴가 관리
|
||||
- 연차, 특별휴가, 경조사
|
||||
- 휴가 잔여일 관리
|
||||
|
||||
### 인사 정보
|
||||
- 직원 정보, 인사 발령
|
||||
- 직급/직위 체계
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 근무 체계
|
||||
- □ 근무 형태 (주 5일/교대/시차 등)
|
||||
- □ 정규 근무시간 (09:00~18:00 등)
|
||||
- □ 출퇴근 기록 방식 (카드/지문/앱/수기)
|
||||
- □ 연장근무 승인 프로세스
|
||||
- □ 교대 근무 패턴 (해당 시)
|
||||
|
||||
### 급여 구조
|
||||
- □ 급여 체계 (월급제/시급제/연봉제)
|
||||
- □ 급여일 (매월 N일)
|
||||
- □ 기본급 외 수당 항목 (직책수당, 자격수당, 식대 등)
|
||||
- □ 공제 항목 (4대보험, 소득세, 조합비 등)
|
||||
- □ 상여금 지급 기준
|
||||
|
||||
### 휴가 정책
|
||||
- □ 연차 부여 기준 (근속 연수별)
|
||||
- □ 특별휴가 종류 (경조사, 보건, 교육 등)
|
||||
- □ 휴가 승인 프로세스
|
||||
|
||||
### 조직/인사
|
||||
- □ 직급 체계 (사원→대리→과장→차장→부장→이사)
|
||||
- □ 인사 평가 주기
|
||||
- □ 교육 훈련 관리 필요성
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "9시~6시 주5일 근무" | work_settings: start=09:00, end=18:00, days=5 |
|
||||
| "매월 25일 급여 지급" | tenants.options.payday=25 |
|
||||
| "입사 1년 미만은 연차 11일" | leave_policies: year=0, days=11 |
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← 부서: 인사 조직과 부서 구조 일치 여부
|
||||
- → 생산: 작업자 배정과 인사 정보 연계
|
||||
- → 회계: 급여 지출과 재무 연계
|
||||
54
config/interview_knowledge/modules/11_approval.md
Normal file
54
config/interview_knowledge/modules/11_approval.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# 모듈 11: 결재/문서 관리
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### approvals (결재 문서)
|
||||
- tenant_id, form_id, title, content(json), status(DRAFT|PENDING|APPROVED|REJECTED)
|
||||
- requester_id, current_step, options(json)
|
||||
|
||||
### approval_steps (결재 단계)
|
||||
- approval_id, step_order, approver_id, status, comment
|
||||
- approved_at, delegated_from_id
|
||||
|
||||
### approval_forms (결재 양식)
|
||||
- tenant_id, name, code, fields(json), approval_line_config(json)
|
||||
- target_type (견적, 구매, 휴가 등과 연계)
|
||||
|
||||
### documents (문서)
|
||||
- tenant_id, template_id, title, content, version, status
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 결재 체계
|
||||
- □ 결재선 구성 (순차/병렬/조건부)
|
||||
- □ 결재 단계 수 (보통 2~4단계)
|
||||
- □ 결재 권한 기준 (직급? 직책? 금액?)
|
||||
- □ 전결 규정 (금액별 전결 범위)
|
||||
- □ 대결/후결 규정
|
||||
|
||||
### 결재 대상
|
||||
- □ 견적서 결재 (금액 기준)
|
||||
- □ 구매 요청 결재
|
||||
- □ 휴가 신청 결재
|
||||
- □ 경비 청구 결재
|
||||
- □ 기타 결재 문서 종류
|
||||
|
||||
### 문서 관리
|
||||
- □ 문서 양식 목록
|
||||
- □ 문서 번호 체계
|
||||
- □ 문서 보관 기간
|
||||
- □ 전자문서 vs 종이문서
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "견적은 팀장→부장→이사 순서" | approval_forms: 견적, 3단계 순차 결재 |
|
||||
| "100만원 이하는 팀장 전결" | approval_forms: amount_threshold=1000000, 1단계 |
|
||||
| "구매요청서, 견적서, 휴가신청 3종" | approval_forms INSERT 3건 |
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← 견적: 견적 결재선 설정이 견적 프로세스와 일치
|
||||
- ← 인사: 휴가 결재선과 부서 구조 일치
|
||||
- ← 조직: 결재자 직급이 조직도에 존재
|
||||
60
config/interview_knowledge/modules/12_barobill.md
Normal file
60
config/interview_knowledge/modules/12_barobill.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# 모듈 12: 바로빌/외부 연동
|
||||
|
||||
## SAM 테이블 구조
|
||||
|
||||
### barobill_members (바로빌 회원)
|
||||
- tenant_id, biz_no, corp_name, cert_key, is_active
|
||||
- server_mode(test|production), options(json)
|
||||
|
||||
### 관련 기능
|
||||
- 전자세금계산서 발행/조회
|
||||
- 카드 매출 자동 수집
|
||||
- 은행 계좌 거래내역 조회
|
||||
- 카카오톡/SMS 알림 발송
|
||||
- 홈택스 연동
|
||||
|
||||
## 필수 수집 항목
|
||||
|
||||
### 전자세금계산서
|
||||
- □ 현재 세금계산서 발행 방식 (종이/전자/홈택스 직접)
|
||||
- □ 월 평균 발행 건수
|
||||
- □ 발행 담당자
|
||||
- □ 매출/매입 세금계산서 자동 연동 필요성
|
||||
|
||||
### 카드/은행
|
||||
- □ 법인카드 사용 여부 + 카드사 목록
|
||||
- □ 주거래 은행 + 계좌 수
|
||||
- □ 카드 매출 자동 수집 필요성
|
||||
- □ 은행 거래내역 자동 조회 필요성
|
||||
|
||||
### 알림 서비스
|
||||
- □ 카카오톡 알림톡 사용 의향
|
||||
- □ SMS 발송 필요성
|
||||
- □ 이메일 알림 범위
|
||||
|
||||
### 기타 외부 연동
|
||||
- □ 기존 사용 중인 외부 서비스
|
||||
- □ 택배/물류 연동 필요성
|
||||
- □ PG 결제 연동 필요성
|
||||
- □ 공공데이터 연동 (기상청, 국세청 등)
|
||||
|
||||
## 매핑 규칙
|
||||
|
||||
| 고객 답변 | SAM 매핑 |
|
||||
|---------|---------|
|
||||
| "바로빌로 세금계산서 발행 중" | barobill_members 설정 + 연동 활성화 |
|
||||
| "법인카드 2장 (삼성, 현대)" | 바로빌 카드 등록 2건 |
|
||||
| "카카오톡 알림 필요" | 바로빌 카카오톡 채널 설정 |
|
||||
| "세금계산서 월 50건 정도" | 구독 플랜 결정 참고 |
|
||||
|
||||
## 검증 규칙
|
||||
|
||||
- 바로빌 사용 시 사업자등록번호 필수 (테넌트 기초 모듈과 연계)
|
||||
- 월 발행 건수에 따른 요금제 안내
|
||||
- 테스트 모드에서 먼저 연동 후 운영 전환 안내
|
||||
|
||||
## 크로스체크
|
||||
|
||||
- ← 테넌트: 사업자등록번호가 테넌트 정보와 일치
|
||||
- ← 회계: 매출/매입 세금계산서와 회계 연동
|
||||
- → Fake 서비스: 데모 시 Fake 모드 활용 안내
|
||||
39
config/interview_knowledge/presets/blinds.md
Normal file
39
config/interview_knowledge/presets/blinds.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# 업종 프리셋: 블라인드/스크린/방화셔터
|
||||
|
||||
## 업종 특성
|
||||
- 치수 기반 주문생산 (수주 → 설계 → 생산)
|
||||
- 오픈사이즈 → 제작사이즈 변환 공식이 핵심
|
||||
- BOM이 치수에 따라 동적 변화 (모터 용량, 가이드레일 수 등)
|
||||
- 방화 인증 제품은 구성 변경 불가
|
||||
- 현장 설치 필요 (설치비 별도 산출)
|
||||
|
||||
## SAM 활성화 권장 모듈
|
||||
- ✅ 품목분류: 제품군별 카테고리 (스크린, 셔터, 블라인드)
|
||||
- ✅ 설계/BOM: 모델별 BOM, 치수 기반 자동 전개
|
||||
- ✅ 견적: 오픈사이즈 입력 → 자동 견적
|
||||
- ✅ 단가: 면적/길이/수량 기반 복합 단가
|
||||
- ✅ 생산: 절단→절곡→조립→검사→포장
|
||||
- ✅ 품질: 방화 인증 검사, 수입검사
|
||||
- ⬜ 재고: 부품 재고 (완제품은 주문생산이라 재고 적음)
|
||||
- ⬜ 회계: 기본 매출/매입
|
||||
- ⬜ 인사: 소규모면 간소화
|
||||
|
||||
## 인터뷰 우선순위
|
||||
1. 제품 분류 + 모델 코드 체계
|
||||
2. BOM 구조 (대표 제품 1개 먼저)
|
||||
3. 치수→제작 변환 공식
|
||||
4. 부품별 선택 조건 (모터 용량, 가이드레일 등)
|
||||
5. 단가 체계 (면적/길이 기반)
|
||||
6. 견적서 양식
|
||||
|
||||
## AI가 미리 알고 있는 것
|
||||
- 가이드레일 표준 길이: 1219, 2438, 3048, 3305mm
|
||||
- 모터 용량 범위: 150K~1000K (무게 기반 선택)
|
||||
- 케이스 크기: 소재 + 높이에 따라 결정
|
||||
- 방화스크린: 내화시험 1~3시간, 구성 고정
|
||||
- 설치유형: 벽면형, 측면형, 천장형 → 부품 차이
|
||||
|
||||
## 예상 질문 힌트
|
||||
- "혹시 방화 인증 제품이 있으신가요? 방화 제품은 구성이 고정이라 별도 관리가 필요합니다"
|
||||
- "가이드레일 길이 조합은 어떻게 하시나요? 보통 1219mm, 2438mm를 조합하시죠?"
|
||||
- "모터 용량 선택이 무게 기반인가요, 면적 기반인가요?"
|
||||
36
config/interview_knowledge/presets/construction.md
Normal file
36
config/interview_knowledge/presets/construction.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# 업종 프리셋: 건설/시공
|
||||
|
||||
## 업종 특성
|
||||
- 프로젝트(현장) 기반 원가 관리
|
||||
- 위치별(층/부호) 산출내역서
|
||||
- 실행예산 vs 견적 비교 관리
|
||||
- 설치/시공 인력 관리 (노무비)
|
||||
- 하도급/협력업체 관리
|
||||
|
||||
## SAM 활성화 권장 모듈
|
||||
- ✅ 품목분류: 제품+시공 분류
|
||||
- ✅ 견적: 위치별 산출, 관급/민간 양식
|
||||
- ✅ 단가: 관급단가, 실행단가 이중 관리
|
||||
- ✅ 생산: 시공 일정, 작업일보
|
||||
- ⬜ BOM: 단순 BOM (설치 자재)
|
||||
- ✅ 회계: 프로젝트별 손익
|
||||
- ✅ 인사: 현장 인력 관리
|
||||
|
||||
## 인터뷰 우선순위
|
||||
1. 시공 유형 (신축/리모델링/유지보수)
|
||||
2. 견적 양식 (관급/민간)
|
||||
3. 산출내역서 구조
|
||||
4. 실행예산 관리
|
||||
5. 하도급/협력업체
|
||||
6. 현장 인력 관리
|
||||
|
||||
## AI가 미리 알고 있는 것
|
||||
- 관급공사: 내역서 양식 규정, 일위대가, 품셈
|
||||
- 민간공사: 자유 양식, 실적 기반
|
||||
- 원가 구조: 재료비 + 노무비 + 경비 + 일반관리비 + 이윤
|
||||
- 하도급법: 하도급대금 30일 이내 지급
|
||||
|
||||
## 예상 질문 힌트
|
||||
- "주로 관급공사인가요, 민간공사인가요?"
|
||||
- "산출내역서를 층별/부호별로 작성하시나요?"
|
||||
- "실행예산과 견적 금액을 별도로 관리하시나요?"
|
||||
36
config/interview_knowledge/presets/food_manufacturing.md
Normal file
36
config/interview_knowledge/presets/food_manufacturing.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# 업종 프리셋: 식품 제조
|
||||
|
||||
## 업종 특성
|
||||
- LOT/유통기한 추적 필수 (식품안전법)
|
||||
- HACCP/GMP 인증 기반 품질 관리
|
||||
- 원재료 시세 변동 (농산물, 수입원료)
|
||||
- 배합 비율 기반 BOM (레시피)
|
||||
- 계량 단위 다양 (kg, L, 포, 박스)
|
||||
|
||||
## SAM 활성화 권장 모듈
|
||||
- ✅ 품목분류: 원재료/반제품/완제품
|
||||
- ✅ BOM: 배합 비율(레시피) 기반
|
||||
- ✅ 단가: 원재료 시세 연동
|
||||
- ✅ 생산: 배합→가공→포장→검사
|
||||
- ✅ 품질: HACCP, 미생물/이화학 검사
|
||||
- ✅ 재고: LOT 추적, 유통기한, FIFO 필수
|
||||
- ✅ 회계: 원가 분석 (원재료비 변동)
|
||||
|
||||
## 인터뷰 우선순위
|
||||
1. 제품 종류 + 원재료 목록
|
||||
2. 배합 비율 (레시피)
|
||||
3. LOT 관리 체계
|
||||
4. 유통기한 관리
|
||||
5. 품질 검사 항목 (HACCP)
|
||||
6. 재고 관리 (FIFO)
|
||||
|
||||
## AI가 미리 알고 있는 것
|
||||
- HACCP 7원칙: 위해분석, CCP, 한계기준, 모니터링, 개선조치, 검증, 기록
|
||||
- LOT 추적: 원재료 LOT → 생산 LOT → 출하 LOT 연계
|
||||
- 유통기한: 제조일+보존일수, 또는 고정 날짜
|
||||
- 계량: 투입량 오차 허용 범위 관리
|
||||
|
||||
## 예상 질문 힌트
|
||||
- "HACCP 인증을 받으셨나요? CCP 관리 포인트가 어디인가요?"
|
||||
- "원재료 LOT에서 완제품 LOT까지 추적이 필요하신가요?"
|
||||
- "유통기한은 제조일 기준 몇 일로 설정하시나요?"
|
||||
27
config/interview_knowledge/presets/general_manufacturing.md
Normal file
27
config/interview_knowledge/presets/general_manufacturing.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# 업종 프리셋: 범용 제조업
|
||||
|
||||
## 업종 특성
|
||||
- 특정 업종에 해당하지 않는 일반 제조업
|
||||
- 표준 MRP/MES 패턴 적용
|
||||
- 모든 모듈을 균형있게 파악 필요
|
||||
|
||||
## SAM 활성화 권장 모듈
|
||||
- ✅ 전체 모듈 균형 파악 후 결정
|
||||
- 인터뷰 과정에서 필요 모듈 자동 판별
|
||||
|
||||
## 인터뷰 우선순위
|
||||
1. 회사 개요 + 주요 제품
|
||||
2. 생산 방식 (주문생산/재고생산/혼합)
|
||||
3. 현재 시스템/도구 (ERP/엑셀/수작업)
|
||||
4. 가장 불편한 점 (Pain Point)
|
||||
5. 위 결과에 따라 도메인 순서 자동 결정
|
||||
|
||||
## AI가 미리 알고 있는 것
|
||||
- 주문생산(MTO): 수주 → 설계 → 자재 → 생산 → 출하
|
||||
- 재고생산(MTS): 수요예측 → 생산계획 → 생산 → 재고 → 출하
|
||||
- 혼합형: 주요 부품 재고생산 + 완제품 주문조립(ATO)
|
||||
|
||||
## 예상 질문 힌트
|
||||
- "주로 주문을 받고 생산하시나요, 아니면 미리 만들어 놓으시나요?"
|
||||
- "현재 ERP나 관리 프로그램을 사용하고 계신가요?"
|
||||
- "업무 중 가장 불편하거나 시간이 많이 걸리는 부분은 어디인가요?"
|
||||
37
config/interview_knowledge/presets/machine_assembly.md
Normal file
37
config/interview_knowledge/presets/machine_assembly.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 업종 프리셋: 기계조립
|
||||
|
||||
## 업종 특성
|
||||
- 다단계 BOM (완제품 → 서브어셈블리 → 부품 → 원자재)
|
||||
- 구매 부품 비중 높음 (모터, 센서, 베어링 등)
|
||||
- 리드타임 관리 중요 (부품 수급 일정)
|
||||
- 대체품/호환품 관리 필요
|
||||
- 시리얼 번호(S/N) 추적
|
||||
|
||||
## SAM 활성화 권장 모듈
|
||||
- ✅ 품목분류: 기능별 부품 카테고리
|
||||
- ✅ BOM: 다단계 BOM (3~4레벨)
|
||||
- ✅ 단가: 수량 기반 (원/EA)
|
||||
- ✅ 생산: 조립 라인 공정
|
||||
- ✅ 품질: 조립 검사, 기능 시험
|
||||
- ✅ 재고: 부품 안전재고, MRP
|
||||
- ✅ 견적: 표준 견적 (BOM 기반)
|
||||
- ✅ 회계: 원가 분석
|
||||
|
||||
## 인터뷰 우선순위
|
||||
1. 제품 구조 (완제품 → 유닛 → 부품)
|
||||
2. BOM 트리 (대표 제품)
|
||||
3. 핵심 구매 부품 목록
|
||||
4. 조립 공정 순서
|
||||
5. 리드타임/납기 관리
|
||||
6. 대체품 관리
|
||||
|
||||
## AI가 미리 알고 있는 것
|
||||
- BOM 3~4단계가 일반적
|
||||
- 구매 부품: MOQ(최소발주수량), 리드타임, 대체품
|
||||
- 조립 공정: 서브어셈블리 조립 → 본체 조립 → 시험 → 포장
|
||||
- S/N 추적: 고가 부품, 보증 대상 부품
|
||||
|
||||
## 예상 질문 힌트
|
||||
- "제품이 여러 유닛으로 나뉘나요? 서브어셈블리 개념이 있나요?"
|
||||
- "구매 부품 중 리드타임이 긴 것은 어떤 건가요?"
|
||||
- "동일 기능의 대체 부품을 관리하시나요?"
|
||||
38
config/interview_knowledge/presets/metal_fabrication.md
Normal file
38
config/interview_knowledge/presets/metal_fabrication.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 업종 프리셋: 금속가공
|
||||
|
||||
## 업종 특성
|
||||
- 소재(강판, SUS, 알루미늄) 중심 원가 구조
|
||||
- 절단/절곡/용접/도장 등 가공 공정 중심
|
||||
- 중량 기반 단가가 주력 (원/kg)
|
||||
- 외주 가공 비중 높음
|
||||
- LOSS율(절단 스크랩) 관리 중요
|
||||
|
||||
## SAM 활성화 권장 모듈
|
||||
- ✅ 품목분류: 소재별 + 가공유형별
|
||||
- ✅ BOM: 원자재 → 가공품 1~2단계
|
||||
- ✅ 단가: 중량 기반 + 가공비 별도
|
||||
- ✅ 생산: 절단→가공→검사 공정
|
||||
- ✅ 품질: 치수 검사, 표면 검사
|
||||
- ✅ 재고: 원자재 재고 관리 (안전재고)
|
||||
- ⬜ 견적: 수동 견적이 많으면 간소화
|
||||
- ⬜ 회계: 기본 매출/매입
|
||||
|
||||
## 인터뷰 우선순위
|
||||
1. 소재 종류와 규격
|
||||
2. 가공 공정 순서
|
||||
3. 단가 구조 (소재비 + 가공비)
|
||||
4. LOSS율 (절단 스크랩 비율)
|
||||
5. 외주 가공 관리
|
||||
6. 재고/안전재고
|
||||
|
||||
## AI가 미리 알고 있는 것
|
||||
- 강판 규격: 두께(t), 폭(W), 길이(L) → 중량 = t×W×L×비중
|
||||
- 비중: 철 7.85, SUS 7.93, 알루미늄 2.71
|
||||
- 절단 LOSS율: 보통 3~10%
|
||||
- 가공비: 절단(원/컷), 절곡(원/벤드), 용접(원/m)
|
||||
- 도금/도장: 면적 기반 (원/㎡)
|
||||
|
||||
## 예상 질문 힌트
|
||||
- "소재는 주로 어떤 것을 사용하시나요? 강판, SUS, 알루미늄 중에서?"
|
||||
- "절단 시 스크랩 비율은 어느 정도 되시나요?"
|
||||
- "가공비는 절단 건당, 절곡 건당으로 계산하시나요?"
|
||||
67
config/interview_knowledge/system_prompt_base.md
Normal file
67
config/interview_knowledge/system_prompt_base.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# SAM AI 인터뷰어 시스템 프롬프트
|
||||
|
||||
당신은 **(주)코드브릿지엑스**가 개발한 **SAM(Smart Automation Management)** ERP/MES 시스템의 전문 도입 컨설턴트입니다.
|
||||
|
||||
## 당신의 역할
|
||||
|
||||
고객사(제조업체)를 방문하여, SAM 시스템에 필요한 모든 업무 정보를 체계적으로 수집하는 **AI 인터뷰어**입니다. 당신은 SAM 시스템의 모든 모듈, 테이블, 비즈니스 로직을 학습한 상태이며, 수집한 정보를 SAM 설정으로 직접 변환할 수 있습니다.
|
||||
|
||||
## SAM 시스템 개요
|
||||
|
||||
SAM은 **멀티테넌트 클라우드 ERP/MES** 시스템입니다:
|
||||
- 하나의 시스템에 여러 고객사(테넌트)가 독립적으로 운영
|
||||
- 각 테넌트는 고유한 품목, BOM, 단가, 공정, 견적 양식을 설정
|
||||
- 견적 → 수주 → 생산 → 출하 → 정산의 비즈니스 플로우
|
||||
- 전자결재, 바코드, 전자세금계산서 연동
|
||||
|
||||
## 핵심 모듈 (학습 완료)
|
||||
|
||||
| 모듈 | 역할 | 핵심 테이블 |
|
||||
|------|------|-----------|
|
||||
| 품목분류 | 제품/자재/부품 카테고리 관리 | categories, category_fields |
|
||||
| 설계/BOM | 제품 모델 설계, BOM 구성 | models, model_versions, bom_templates |
|
||||
| 단가 | 시간축 단가 관리, 원가 구성 | price_histories |
|
||||
| 견적 | 자동 견적 계산, 개정 관리 | quotes, quote_items, quote_formulas |
|
||||
| 수주 | 견적→수주 변환, 납기 관리 | orders, order_items |
|
||||
| 생산 | 작업지시, 공정, 생산 실적 | work_orders, production_results |
|
||||
| 품질 | 수입검사, 공정검사, 부적합 | material_inspections, nonconforming_reports |
|
||||
| 재고 | 입출고, LOT 추적, 안전재고 | material_receipts, lots, stocks |
|
||||
| 회계 | 매출/매입, 입출금, 세금계산서 | sales, purchases, deposits |
|
||||
| 인사 | 근태, 급여, 휴가 | HR 테이블들 |
|
||||
| 결재 | 전자결재, 승인 워크플로우 | approvals, approval_steps |
|
||||
| 거래처 | 고객/공급업체 관리 | clients |
|
||||
|
||||
## 인터뷰 지침
|
||||
|
||||
### 대화 방식
|
||||
1. **자연스러운 한국어 대화체**를 사용한다 (존댓말)
|
||||
2. 한 번에 **1~2개 질문**만 한다 (폭격 금지)
|
||||
3. 답변이 모호하면 **구체적 예시**를 요청한다
|
||||
4. 전문 용어를 쓸 때는 **쉬운 설명**을 함께 한다
|
||||
5. 고객의 현재 방식을 **존중**하며, SAM으로의 전환을 자연스럽게 안내한다
|
||||
|
||||
### 데이터 수집 원칙
|
||||
1. 답변에서 **구조화 가능한 데이터**를 발견하면 즉시 JSON으로 추출한다
|
||||
2. SAM 테이블에 **매핑 불가능한 답변**은 추가 질문으로 구체화한다
|
||||
3. **필수 항목**이 누락되면 대화를 이어가며 자연스럽게 재질문한다
|
||||
4. 이전 도메인에서 수집한 데이터와 **모순**이 있으면 확인 질문한다
|
||||
|
||||
### 응답 형식
|
||||
모든 응답 마지막에 반드시 아래 JSON 블록을 포함한다:
|
||||
|
||||
```json
|
||||
{
|
||||
"extracted_data": {
|
||||
"테이블명": [{"필드": "값"}]
|
||||
},
|
||||
"covered_questions": [1, 3, 5],
|
||||
"coverage_percent": 45,
|
||||
"next_focus": "다음에 물어볼 영역",
|
||||
"warnings": ["BOM에 '보강재'가 있는데 품목 분류에 없음"],
|
||||
"sam_mapping": {
|
||||
"table": "categories",
|
||||
"action": "INSERT",
|
||||
"data": [{"name": "방화스크린", "type": "PRODUCT"}]
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user