# 영일전기철물 GPT 시스템 생태계 감사

- 생성: `2026-05-22 17:38:01`
- 루트: `/volume1/web/gpt`
- 모드: read-only audit / DB write 없음

## 1. 전체 생태계 한눈 구조

```text
사용자 입력
  ↓
api.php / engine.php
  ↓
Agent.php
  ↓
SystemGate / FollowupResolver / RouteSanityChecker
  ↓
ToolSelector.php / RoutePipeline
  ↓
ToolRegistry → ToolExecutor
  ↓
각 Tool 실행
  ├─ ScheduleTool
  ├─ CustomerTool
  ├─ PaymentTool
  ├─ HistoryMemoTool
  ├─ HistorySearchTool
  ├─ PersonalExpenseTool
  └─ 기타 도구들
  ↓
DB / JSON / reports / logs
  ↓
repair_jobs/ssh_answers
  ↓
WORK_STATE.md / WORK_REPORT.md / SSH_ANSWER_INDEX.md
  ↓
운영자 UI
```

## 2. 핵심 파일 계층

### 진입점
- `api.php` : FOUND
- `engine.php` : FOUND

### Agent
- `engine_modules/agent/Agent.php` : FOUND
- `engine_modules/agent/AutoCodeAgent.php` : FOUND

### 도구 핵심
- `engine_modules/tools/bootstrap.php` : FOUND
- `engine_modules/tools/Tool.php` : FOUND
- `engine_modules/tools/ToolRegistry.php` : FOUND
- `engine_modules/tools/ToolExecutor.php` : FOUND
- `engine_modules/tools/ToolSelector.php` : FOUND

### 라우팅
- `engine_modules/tools/routing/RoutePipeline.php` : FOUND
- `engine_modules/tools/routing/MoneyRoute.php` : FOUND
- `engine_modules/tools/routing/ScheduleRoute.php` : FOUND
- `engine_modules/tools/routing/CustomerRoute.php` : FOUND
- `engine_modules/tools/routing/WorksiteRoute.php` : FOUND

### 개인 지출
- `engine_modules/tools/PersonalExpenseTool.php` : FOUND
- `engine_modules/services/PersonalExpenseParseService.php` : FOUND
- `engine_modules/services/PersonalExpenseSaveService.php` : FOUND

### 문서/상태
- `WORK_STATE.md` : FOUND
- `WORK_REPORT.md` : FOUND
- `repair_jobs/SSH_ANSWER_INDEX.md` : FOUND
- `reports/auto_work_summary.md` : FOUND
- `reports/personal_expense_pipeline_status.md` : FOUND

## 3. ToolRegistry 도구 목록

- registry class: `ToolRegistry`
- tool count: `41`

| # | name | class | intents |
|---:|---|---|---|
| 1 | `transaction_search` | `TransactionSearchTool` | `transaction_search, ledger_search, integrated_transaction_lookup` |
| 2 | `quotation` | `QuotationTool` | `quotation, quote, estimate, quotation_list, quotation_detail` |
| 3 | `payment` | `PaymentTool` | `payment` |
| 4 | `memory` | `MemoryTool` | `memory` |
| 5 | `sales` | `SalesTool` | `sales` |
| 6 | `schedule` | `ScheduleTool` | `schedule, schedule_create` |
| 7 | `weather` | `WeatherTool` | `weather, 날씨, 주간날씨, 기온, 강수, 비` |
| 8 | `customer` | `CustomerTool` | `customer` |
| 9 | `stock` | `StockTool` | `stock` |
| 10 | `planner` | `PlannerTool` | `planner` |
| 11 | `code_stats` | `CodeStatsTool` | `code_stats, code_statistics, code_readonly_stats` |
| 12 | `code_diagnostic` | `CodeDiagnosticTool` | `code_diagnostic, code_analysis` |
| 13 | `flow_diagnostic` | `FlowDiagnosticTool` | `flow_diagnostic, flow_self_suspicion, routing_diagnostic, route_diagnostic, pipeline_diagnostic, tool_selector_diagnostic` |
| 14 | `code_fix` | `CodeFixTool` | `code_fix, code_modify` |
| 15 | `auto_scan` | `AutoScanTool` | `auto_scan, proactive_review` |
| 16 | `auto_modularize` | `AutoModularizeTool` | `auto_modularize, refactor_scan, modularize_top3, modularize_plan` |
| 17 | `worksite` | `WorksiteTool` | `worksite, worksite_list, project, project_list, site, site_list` |
| 18 | `worklog` | `WorklogTool` | `worklog, work_record, field_work` |
| 19 | `chat` | `ChatTool` | `chat, general, fallback` |
| 20 | `capability_help` | `CapabilityHelpTool` | `capability_help, help, usage, assistant_role` |
| 21 | `business_module_diagnostic` | `BusinessModuleDiagnosticTool` | `business_module_diagnostic, business_module_structure, code_diagnostic` |
| 22 | `safety_block` | `SafetyBlockTool` | `safety_block, device_action, dangerous_blocked, physical_action_block` |
| 23 | `code_search` | `CodeSearchTool` | `code_search, code_lookup, code_find` |
| 24 | `code_patch_plan` | `CodePatchPlannerTool` | `code_patch_plan, patch_plan, where_to_edit, code_edit_plan, fix_location` |
| 25 | `system_status` | `SystemStatusTool` | `system_status, bottleneck_check, resource_check, gpt_health_check` |
| 26 | `news_review` | `NewsReviewTool` | `news_review, briefing_review, brain_status, insight_review, judgment_check` |
| 27 | `news` | `NewsTool` | `news` |
| 28 | `data_catalog` | `DataCatalogTool` | `data_catalog, data_map, category_list` |
| 29 | `data_source_map` | `DataSourceMapTool` | `data_source_map, data_source, pipeline_map, source_explain, table_explain` |
| 30 | `data_lookup` | `DataLookupTool` | `data_lookup, evidence_lookup, entity_lookup, 자료조회, 장부조회, 근거조회` |
| 31 | `synology_search` | `SynologySearchTool` | `synology_search, file_search, folder_search, home_search, photo_search, log_search` |
| 32 | `synology_file_read` | `SynologyFileReadTool` | `synology_file_read, file_read, document_read, log_read, code_read` |
| 33 | `expense` | `ExpenseTool` | `expense, expense_list, expense_query` |
| 34 | `code_map` | `CodeMapTool` | `code_map, file_map, code_category, related_files, where_to_fix` |
| 35 | `person_context` | `PersonContextTool` | `person_context, person_lookup, unified_person_lookup` |
| 36 | `record_context_note` | `RecordContextNoteTool` | `record_context_note, record_enrichment, append_record_context` |
| 37 | `history_search` | `HistorySearchTool` | `history_search, chat_history_search, memory_history_search, past_conversation_search` |
| 38 | `history_memo` | `HistoryMemoTool` | `history_memo, memory_create, personal_history_create, history_list, memory_list` |
| 39 | `personal_expense` | `PersonalExpenseTool` | `personal_expense, personal_expense.create, expense.personal, history.personal_expense` |
| 40 | `work_done_list` | `WorkDoneListTool` | `work_done_list, work_list, worklog_read, work_history_read` |
| 41 | `business_data_structure` | `BusinessDataStructureTool` | `business_data_structure, business_data_diagnose, business_integrity` |

- registry has `personal_expense`: `true`
- registry has `history_memo`: `true`
- registry has `history_search`: `true`
- registry has `payment`: `true`
- registry has `schedule`: `true`
- registry has `customer`: `true`
- registry has `worklog`: `true`

## 4. 현재 핵심 패치 마커

### Agent.php
- `189:        // AGENT_PERSONAL_EXPENSE_RECORD_NO_PAYMENT_APPROVAL_V1`
- `228:                        // AGENT_PERSONAL_EXPENSE_INTENT_RULE_TOOLS_SHAPE_FIX_V1`
- `231:            // AGENT_PERSONAL_EXPENSE_TO_PERSONAL_EXPENSE_TOOL_V1`

### ToolSelector.php
- `495:                // SCHEDULE_HISTORY_COMBO_ROUTE_V2`

### HistorySearchTool.php
- `298:            // HISTORY_SEARCH_PERIOD_FILTER_V2`

### PersonalExpenseTool.php
- `5: * PERSONAL_EXPENSE_TOOL_V1`
- `31:    // PERSONAL_EXPENSE_TOOL_INTENTS_V1`
- `69:                    'PERSONAL_EXPENSE_TOOL_V1 dry_run',`
- `87:                'PERSONAL_EXPENSE_TOOL_V1 saved',`

### PersonalExpenseParseService.php
- `5: * PERSONAL_EXPENSE_PARSE_SERVICE_V1`
- `37:                'parser' => 'PERSONAL_EXPENSE_PARSE_SERVICE_V1',`

### PersonalExpenseSaveService.php
- `5: * PERSONAL_EXPENSE_SAVE_SERVICE_V1`
- `139:            'version' => 'PERSONAL_EXPENSE_SAVE_SERVICE_V1',`

### PaymentTool.php
- `34:        // PAYMENT_PERSONAL_EXPENSE_BLOCK_VALIDATE_V1`
- `137:        // PAYMENT_BAD_NAME_BLOCK_BEFORE_SAVE_V1`

### operator_status.php
- `37:// OPERATOR_LATEST_SSH_ANSWER_SAFE_V3`

## 5. DB 생태계 읽기 감사

- PDO: `OK`

| table | exists | rows | columns |
|---|---:|---:|---|
| `personal_memo_inbox` | true | `10` | `id, tag, content, created_at, parent_id, work_date, customer_name, amount, status, meta_json` |
| `personal_expense_records` | true | `1` | `id, source_memo_id, record_date, title, total_known_amount, unknown_amount_exists, transport_pending, raw_text, raw_hash, memo, meta_json, created_at, updated_at` |
| `personal_expense_items` | true | `4` | `id, record_id, item_name, amount, category, amount_status, note, sort_order, raw_fragment, created_at` |
| `incomes` | true | `282` | `id, category, amount, memo, income_date, quotation_id, customer_id, created_at, updated_at, project_id, payer_name` |
| `income` | true | `0` | `id, category, amount, memo, received_at, created_at` |
| `schedule_events` | true | `62` | `id, event_date, start_time, end_time, color, title, memo, project_id, done, created_at, updated_at, category, source_type, raw_text, amount, normalized_at` |
| `calendar_projects` | true | `41` | `id, cal, mt, title, start_date, end_date, status, description, steps, image, attachment, locked, created_at` |
| `customers` | true | `164` | `id, name, gender, customer_type, business_reg_no, phone, prev_phone, second_phone, email, address, notes, previous_phone, prev_orders, construction_memo, last_order_summary, last_construction_amount, total_construction_amount, is_active` |
| `projects` | true | `77` | `id, project_name, project_address, memo, client_name, customer_id, quotation_id, manager_name, project_status, created_at, updated_at, is_in_progress, status_stage` |
| `quotations` | true | `66` | `id, project_id, quotation_code, project_name, customer_name, project_address, client_name, customer_id, manager_name, quotation_date, start_date, completion_date, total_amount, contract_amount, apply_vat, status, memo, a4_items_html` |

### 개인 지출 최근 records
- `{"id":1,"source_memo_id":68,"record_date":"2026-05-01","title":"애들 데리고 외출","total_known_amount":133000,"unknown_amount_exists":1,"transport_pending":1,"created_at":"2026-05-02 11:59:24"}`

## 6. 문서 자동 갱신 생태계

### WORK_STATE.md
- path: `/volume1/web/gpt/WORK_STATE.md`
- exists: `true`
- size: `4586` bytes
- mtime: `2026-05-02 12:38:01`
  - `# WORK_STATE`
  - ``
  - `자동 갱신: 2026-05-02 12:38:01`
  - `root: '/volume1/web/gpt'`
  - ``
  - `## 1. 현재 한줄 상태`
  - ``
  - `- 최신 SSH 답변: 'personal_expense_live_test_and_cleanup_v1'`

### WORK_REPORT.md
- path: `/volume1/web/gpt/WORK_REPORT.md`
- exists: `true`
- size: `5596` bytes
- mtime: `2026-05-02 12:38:01`
  - `# WORK_REPORT`
  - ``
  - `자동 갱신: 2026-05-02 12:38:01`
  - ``
  - `## 1. 최근 작업 요약`
  - ``
  - `### 1. personal_expense_live_test_and_cleanup_v1`
  - ``

### SSH_ANSWER_INDEX.md
- path: `/volume1/web/gpt/repair_jobs/SSH_ANSWER_INDEX.md`
- exists: `true`
- size: `15343` bytes
- mtime: `2026-05-02 12:38:01`
  - `# SSH_ANSWER_INDEX`
  - ``
  - `자동 갱신: 2026-05-02 12:38:01`
  - ``
  - `| 시각 | 상태 | title | 파일 |`
  - `|---|---|---|---|`
  - `| 2026-05-02 12:37:52 | OK | 'personal_expense_live_test_and_cleanup_v1' | '/volume1/web/gpt/repair_jobs/ssh_answers/20260502_123752_personal_expense_live_test_and_cleanup_v1.txt' |`
  - `| 2026-05-02 12:35:22 | OK | 'personal_expense_registry_create_tool_registry_check_v1' | '/volume1/web/gpt/repair_jobs/ssh_answers/20260502_123522_personal_expense_registry_create_tool_registry_check_v1.txt' |`

### auto_work_summary.md
- path: `/volume1/web/gpt/reports/auto_work_summary.md`
- exists: `true`
- size: `414` bytes
- mtime: `2026-05-02 12:38:01`
  - `# 자동 작업 요약`
  - ``
  - `자동 갱신: 2026-05-02 12:38:01`
  - ``
  - `## 최신`
  - ``
  - `- title: 'personal_expense_live_test_and_cleanup_v1'`
  - `- time: '2026-05-02 12:37:52'`

### personal_expense_pipeline_status.md
- path: `/volume1/web/gpt/reports/personal_expense_pipeline_status.md`
- exists: `true`
- size: `641` bytes
- mtime: `2026-05-02 12:15:26`
  - `# 개인 지출 기록 파이프라인 상태 정리`
  - ``
  - `자동 최소본 생성: 2026-05-02 12:15:26`
  - ``
  - `## 현재 결론`
  - ``
  - `- 개인 지출은 'payment/incomes/schedule_events'로 저장하면 안 된다.`
  - `- 원본 히스토리: 'personal_memo_inbox.id=68' 유지.`

## 7. 최근 SSH 답변 흐름

- `20260502_124023_system_ecosystem_audit_v1.txt` / `2026-05-02 12:40:23` / `system_ecosystem_audit_v1` / ``
- `20260502_123922_safety_gate_schedule_breaker_misroute_diagnose_v1.txt` / `2026-05-02 12:39:22` / `safety_gate_schedule_breaker_misroute_diagnose_v1` / ``
- `20260502_123752_personal_expense_live_test_and_cleanup_v1.txt` / `2026-05-02 12:37:52` / `personal_expense_live_test_and_cleanup_v1` / `PERSONAL_EXPENSE_LIVE_TEST_AND_CLEANUP_OK`
- `20260502_123522_personal_expense_registry_create_tool_registry_check_v1.txt` / `2026-05-02 12:35:22` / `personal_expense_registry_create_tool_registry_check_v1` / `PERSONAL_EXPENSE_REGISTRY_AND_SELECTOR_OK`
- `20260502_123436_personal_expense_registry_register_v1.txt` / `2026-05-02 12:34:36` / `personal_expense_registry_register_v1` / `PERSONAL_EXPENSE_REGISTRY_REGISTER_V1_LOAD_OK_REGISTRY_UNKNOWN`
- `20260502_123137_inspect_safety_block_schedule_misroute_v1.txt` / `2026-05-02 12:31:38` / `inspect_safety_block_schedule_misroute_v1` / ``
- `20260502_123040_personal_expense_tool_add_intents_v1.txt` / `2026-05-02 12:30:40` / `personal_expense_tool_add_intents_v1` / `PERSONAL_EXPENSE_TOOL_ADD_INTENTS_V1_OK`
- `20260502_123011_rollback_schedule_context_bypass_500_recovery_v1.txt` / `2026-05-02 12:30:12` / `rollback_schedule_context_bypass_500_recovery_v1` / ``
- `20260502_122943_personal_expense_tool_extends_tool_fix_v1.txt` / `2026-05-02 12:29:43` / `personal_expense_tool_extends_tool_fix_v1` / ``
- `20260502_122855_personal_expense_tool_auto_save_v1.txt` / `2026-05-02 12:28:55` / `personal_expense_tool_auto_save_v1` / `PERSONAL_EXPENSE_TOOL_AUTO_SAVE_V1_NEED_CHECK`
- `20260502_122523_history_search_period_filter_v2_fix_python_braces.txt` / `2026-05-02 12:25:23` / `history_search_period_filter_v2_fix_python_braces` / `HISTORY_SEARCH_PERIOD_FILTER_V2_OK`
- `20260502_122354_history_search_period_filter_v1.txt` / `2026-05-02 12:23:54` / `history_search_period_filter_v1` / ``
- `20260502_122203_schedule_history_combo_route_v2_fix_insert.txt` / `2026-05-02 12:22:03` / `schedule_history_combo_route_v2_fix_insert` / `SCHEDULE_HISTORY_COMBO_ROUTE_V2_PATCHED`
- `20260502_122052_schedule_history_combo_route_v1.txt` / `2026-05-02 12:20:52` / `schedule_history_combo_route_v1` / `SCHEDULE_HISTORY_COMBO_ROUTE_V1_NEED_CHECK`
- `20260502_121904_operator_status_latest_ssh_answer_v2_fix_parse_error.txt` / `2026-05-02 12:19:04` / `operator_status_latest_ssh_answer_v2_fix_parse_error` / ``

## 8. 현재 판정

```text
생태계 구성은 다음 단위로 분리되어 있음.

1. 입력/엔진 진입: api.php, engine.php
2. 판단/실행 루프: Agent.php
3. 라우팅: ToolSelector.php, RoutePipeline.php, 각 Route 클래스
4. 도구 등록: bootstrap.php, ToolRegistry.php
5. 도구 실행: ToolExecutor.php
6. 업무 도구: schedule/customer/payment/worklog/history/personal_expense 등
7. 서비스 계층: PersonalExpenseParseService, PersonalExpenseSaveService 등
8. 저장 계층: DB 테이블 + JSON/history/logs
9. 상태 기록: repair_jobs/ssh_answers, WORK_STATE, WORK_REPORT
10. 운영자 UI: operator_status, work_state, report, module maps
```

