diff --git a/app/Http/Controllers/RoadmapController.php b/app/Http/Controllers/RoadmapController.php index bb9c7de3..048230c6 100644 --- a/app/Http/Controllers/RoadmapController.php +++ b/app/Http/Controllers/RoadmapController.php @@ -4,10 +4,112 @@ use App\Models\Admin\AdminRoadmapPlan; use App\Services\Roadmap\RoadmapPlanService; +use Illuminate\Support\Str; use Illuminate\View\View; class RoadmapController extends Controller { + private const DOCS_BASE = __DIR__.'/../../../../docs'; + + private const DOCUMENT_REGISTRY = [ + [ + 'category' => 'vision', + 'category_label' => '비전 & 전략', + 'icon' => 'ri-lightbulb-line', + 'color' => 'indigo', + 'items' => [ + [ + 'slug' => 'ai-automation-vision', + 'title' => 'SAM AI 자동화 비전', + 'description' => 'SAM의 장기 비전과 AI 자동화 전략. 영업에서 출고까지 End-to-End 자동화 로드맵.', + 'path' => 'system/ai-automation-vision.md', + 'date' => '2026-03-02', + 'badge' => '설계 확정', + ], + [ + 'slug' => 'scaling-roadmap', + 'title' => '10,000 테넌트 스케일링 로드맵', + 'description' => '현재 아키텍처 진단부터 5단계 스케일링 계획까지. 세계 수준 엔지니어링 시나리오.', + 'path' => 'system/scaling-roadmap.md', + 'date' => '2026-02-22', + 'badge' => '가상 시나리오', + ], + ], + ], + [ + 'category' => 'launch', + 'category_label' => '프로젝트 런칭', + 'icon' => 'ri-rocket-line', + 'color' => 'blue', + 'items' => [ + [ + 'slug' => 'project-launch-roadmap', + 'title' => 'SAM 프로젝트 런칭 로드맵', + 'description' => '전체 시스템 구성, MVP 범위, 마일스톤(MS1~MS3), 개발 완료율 현황.', + 'path' => 'guides/project-launch-roadmap.md', + 'date' => '2025-12-02', + 'badge' => '진행중', + ], + [ + 'slug' => 'production-deployment-plan', + 'title' => '운영 환경 배포 계획서', + 'description' => 'MS3 정식 런칭 배포 계획. 무중단 전환, 롤백, Jenkins CI/CD 자동화.', + 'path' => 'plans/production-deployment-plan.md', + 'date' => '2026-02-22', + 'badge' => '계획 수립', + ], + ], + ], + [ + 'category' => 'product', + 'category_label' => '제품 설계', + 'icon' => 'ri-draft-line', + 'color' => 'green', + 'items' => [ + [ + 'slug' => 'erp-storyboard', + 'title' => 'SAM ERP 스토리보드 D1.4', + 'description' => '전체 ERP 메뉴 구조와 화면 설계. 대시보드, MES, HR, 전자결재, 회계, 구독 관리.', + 'path' => 'plans/SAM_ERP_Storyboard_D1.4.md', + 'date' => '2026-01-16', + 'badge' => 'D1.4', + ], + [ + 'slug' => 'erp-accounting-storyboard', + 'title' => 'SAM ERP 회계관리 스토리보드 D1.6', + 'description' => '세금계산서, 계좌 입출금, OCR, 일일 보고서, 건설/생산 대시보드.', + 'path' => 'plans/SAM_ERP_회계관리_Storyboard_D1.6.md', + 'date' => '2026-02-20', + 'badge' => 'D1.6', + ], + [ + 'slug' => 'integrated-master-plan', + 'title' => '통합 개선 마스터 플랜', + 'description' => '제품코드 추적성 + 검사 단위 구조 통합 개선. 7단계 Phase 로드맵.', + 'path' => 'plans/integrated-master-plan.md', + 'date' => '2026-02-27', + 'badge' => 'Phase 0~3 완료', + ], + ], + ], + [ + 'category' => 'system', + 'category_label' => '시스템 개요', + 'icon' => 'ri-server-line', + 'color' => 'gray', + 'items' => [ + [ + 'slug' => 'system-overview', + 'title' => 'SAM 시스템 개요', + 'description' => '프로젝트 아키텍처, 기술 스택, 멀티테넌시, 레거시 마이그레이션 현황.', + 'path' => 'system/overview.md', + 'date' => '2026-02-27', + 'badge' => '최신', + ], + ], + ], + ]; + public function __construct( private readonly RoadmapPlanService $planService ) {} @@ -76,4 +178,49 @@ public function editPlan(int $id): View 'plan', 'statuses', 'categories', 'priorities', 'phases' )); } + + public function documents(): View + { + $registry = self::DOCUMENT_REGISTRY; + + // 각 문서의 파일 존재 여부 확인 + $docsBase = realpath(self::DOCS_BASE) ?: self::DOCS_BASE; + foreach ($registry as &$group) { + foreach ($group['items'] as &$item) { + $item['exists'] = file_exists($docsBase.'/'.$item['path']); + } + } + + return view('roadmap.documents.index', compact('registry')); + } + + public function showDocument(string $slug): View + { + $document = null; + foreach (self::DOCUMENT_REGISTRY as $group) { + foreach ($group['items'] as $item) { + if ($item['slug'] === $slug) { + $document = $item; + $document['category_label'] = $group['category_label']; + $document['color'] = $group['color']; + break 2; + } + } + } + + if (! $document) { + abort(404, '문서를 찾을 수 없습니다.'); + } + + $docsBase = realpath(self::DOCS_BASE) ?: self::DOCS_BASE; + $filePath = $docsBase.'/'.$document['path']; + $content = null; + + if (file_exists($filePath)) { + $markdown = file_get_contents($filePath); + $content = Str::markdown($markdown); + } + + return view('roadmap.documents.show', compact('document', 'content')); + } } diff --git a/resources/views/roadmap/documents/index.blade.php b/resources/views/roadmap/documents/index.blade.php new file mode 100644 index 00000000..ab6aa74d --- /dev/null +++ b/resources/views/roadmap/documents/index.blade.php @@ -0,0 +1,67 @@ +@extends('layouts.app') + +@section('title', '로드맵 문서') + +@section('content') + +
+

+ + + + 로드맵 문서 +

+
+ + + + + 대시보드 + + + 계획 목록 + +
+
+ + +
+

SAM 중장기 계획 문서

+

SAM 프로젝트의 비전, 로드맵, 제품 설계 문서를 한 곳에서 확인할 수 있습니다. 각 문서를 클릭하면 상세 내용을 볼 수 있습니다.

+
+ + +@foreach($registry as $group) +
+

+ + {{ $group['category_label'] }} +

+
+ @foreach($group['items'] as $item) + +
+

{{ $item['title'] }}

+ {{ $item['badge'] }} +
+

{{ $item['description'] }}

+
+ {{ $item['date'] }} + @if($item['exists']) + + 문서 보기 + + + + + @else + 파일 없음 + @endif +
+
+ @endforeach +
+
+@endforeach +@endsection diff --git a/resources/views/roadmap/documents/show.blade.php b/resources/views/roadmap/documents/show.blade.php new file mode 100644 index 00000000..37421f0c --- /dev/null +++ b/resources/views/roadmap/documents/show.blade.php @@ -0,0 +1,56 @@ +@extends('layouts.app') + +@section('title', $document['title']) + +@section('content') + +
+
+ + ← 로드맵 문서 + +

{{ $document['title'] }}

+
+
+ {{ $document['category_label'] }} + {{ $document['badge'] }} + {{ $document['date'] }} +
+
+ +@if($document['description']) +

{{ $document['description'] }}

+@endif + + +@if($content) +
+
+ {!! $content !!} +
+
+@else +
+ + + +

문서 파일을 찾을 수 없습니다.

+

경로: docs/{{ $document['path'] }}

+
+@endif +@endsection diff --git a/routes/web.php b/routes/web.php index e048401e..5f537020 100644 --- a/routes/web.php +++ b/routes/web.php @@ -361,6 +361,8 @@ // 중장기 계획 (Blade 화면만) Route::prefix('roadmap')->name('roadmap.')->group(function () { Route::get('/', [RoadmapController::class, 'index'])->name('index'); + Route::get('/documents', [RoadmapController::class, 'documents'])->name('documents.index'); + Route::get('/documents/{slug}', [RoadmapController::class, 'showDocument'])->name('documents.show'); Route::get('/plans', [RoadmapController::class, 'plans'])->name('plans.index'); Route::get('/plans/create', [RoadmapController::class, 'createPlan'])->name('plans.create'); Route::get('/plans/{id}', [RoadmapController::class, 'showPlan'])->name('plans.show');