251118:1300 ปรับปรุง Project requirement
This commit is contained in:
483
Documnets/0.html
Normal file
483
Documnets/0.html
Normal file
@@ -0,0 +1,483 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LCBP3-DMS V1.4.1 Project Infographic</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Inter', sans-serif;
|
||||
background-color: #f4f7f6;
|
||||
}
|
||||
.chart-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
height: 350px;
|
||||
max-height: 400px;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.chart-container {
|
||||
height: 300px;
|
||||
max-height: 350px;
|
||||
}
|
||||
}
|
||||
.stat-card {
|
||||
background-color: #004AAD;
|
||||
color: white;
|
||||
border-left: 5px solid #FFC107;
|
||||
}
|
||||
.kpi-value {
|
||||
font-size: 2.5rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
.section-card {
|
||||
background-color: white;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 2rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
.section-header {
|
||||
background-color: #002F6C;
|
||||
color: white;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
.section-content {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
.flow-box {
|
||||
border: 2px solid #007BFF;
|
||||
background-color: #B3D7FF;
|
||||
color: #002F6C;
|
||||
padding: 0.75rem;
|
||||
border-radius: 0.5rem;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 4px 6px rgba(0, 75, 173, 0.1);
|
||||
}
|
||||
.flow-arrow {
|
||||
font-size: 2rem;
|
||||
color: #004AAD;
|
||||
align-self: center;
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
.timeline-item {
|
||||
position: relative;
|
||||
padding-left: 2.5rem;
|
||||
padding-bottom: 2rem;
|
||||
border-left: 4px solid #007BFF;
|
||||
}
|
||||
.timeline-dot {
|
||||
position: absolute;
|
||||
left: -11px;
|
||||
top: 0;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background-color: #FFC107;
|
||||
border: 3px solid #004AAD;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.rbac-level {
|
||||
border: 2px dashed;
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="antialiased">
|
||||
|
||||
<header class="bg-white shadow-md sticky top-0 z-50">
|
||||
<nav class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between items-center h-16">
|
||||
<div class="flex-shrink-0 flex items-center">
|
||||
<span class="text-2xl font-bold text-[#002F6C]">LCBP3-DMS</span>
|
||||
<span class="ml-2 text-xl font-semibold text-[#007BFF]">V1.4.1 Project Overview</span>
|
||||
</div>
|
||||
<div class="hidden md:block">
|
||||
<div class="ml-10 flex items-baseline space-x-4">
|
||||
<a href="#kpi" class="text-gray-600 hover:text-[#007BFF] px-3 py-2 rounded-md text-sm font-medium">KPIs</a>
|
||||
<a href="#architecture" class="text-gray-600 hover:text-[#007BFF] px-3 py-2 rounded-md text-sm font-medium">Architecture</a>
|
||||
<a href="#roadmap" class="text-gray-600 hover:text-[#007BFF] px-3 py-2 rounded-md text-sm font-medium">Roadmap</a>
|
||||
<a href="#security" class="text-gray-600 hover:text-[#007BFF] px-3 py-2 rounded-md text-sm font-medium">Security</a>
|
||||
<a href="#stats" class="text-gray-600 hover:text-[#007BFF] px-3 py-2 rounded-md text-sm font-medium">Stats</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="max-w-7xl mx-auto p-4 md:p-8 mt-8">
|
||||
|
||||
<section id="intro" class="section-card">
|
||||
<div class="section-header">
|
||||
<h1 class="text-3xl font-bold">Project Overview: LCBP3 Document Management System (V1.4.1)</h1>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p class="text-lg text-gray-700">
|
||||
นี่คือภาพรวมของระบบบริหารจัดการเอกสารโครงการ (DMS) V1.4.1
|
||||
ที่กำลังพัฒนาสำหรับโครงการแหลมฉบังเฟส 3 (LCBP3)
|
||||
เป้าหมายหลักคือการสร้างเว็บแอปพลิเคชั่นที่ทันสมัย ปลอดภัย
|
||||
และมีประสิทธิภาพสูงเพื่อจัดการและควบคุมการสื่อสารด้วยเอกสารที่ซับซ้อน
|
||||
ลดการใช้กระดาษ และเพิ่มความสะดวกในการทำงานร่วมกันระหว่างองค์กร
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="kpi" class="mb-8">
|
||||
<h2 class="text-3xl font-bold text-gray-800 mb-6">Key Performance Indicators (KPIs)</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
<div class="stat-card p-6 rounded-lg shadow-lg">
|
||||
<h3 class="text-lg font-semibold uppercase tracking-wider">API Response Time</h3>
|
||||
<p class="kpi-value font-bold mt-2">< 200<span class="text-xl">ms</span></p>
|
||||
<p class="text-sm opacity-90">(90th Percentile)</p>
|
||||
</div>
|
||||
<div class="stat-card p-6 rounded-lg shadow-lg">
|
||||
<h3 class="text-lg font-semibold uppercase tracking-wider">Search Performance</h3>
|
||||
<p class="kpi-value font-bold mt-2">< 500<span class="text-xl">ms</span></p>
|
||||
<p class="text-sm opacity-90">(Elasticsearch)</p>
|
||||
</div>
|
||||
<div class="stat-card p-6 rounded-lg shadow-lg">
|
||||
<h3 class="text-lg font-semibold uppercase tracking-wider">File Upload (50MB)</h3>
|
||||
<p class="kpi-value font-bold mt-2">< 30<span class="text-xl">s</span></p>
|
||||
<p class="text-sm opacity-90">(Inc. Virus Scan)</p>
|
||||
</div>
|
||||
<div class="stat-card p-6 rounded-lg shadow-lg">
|
||||
<h3 class="text-lg font-semibold uppercase tracking-wider">Cache Hit Ratio</h3>
|
||||
<p class="kpi-value font-bold mt-2">> 80<span class="text-xl">%</span></p>
|
||||
<p class="text-sm opacity-90">(Redis)</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="architecture" class="section-card">
|
||||
<div class="section-header">
|
||||
<h2 class="text-3xl font-bold">System Architecture & Technology Stack</h2>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p class="text-lg text-gray-700 mb-6">
|
||||
สถาปัตยกรรมระบบเป็นแบบ API-First ที่ทำงานบน QNAP Container Station (Docker)
|
||||
โดยมีการแบ่งส่วนบริการ (Services) อย่างชัดเจน
|
||||
เพื่อความสะดวกในการจัดการและบำรุงรักษา
|
||||
</p>
|
||||
|
||||
<div class="border-2 border-gray-200 rounded-lg p-4">
|
||||
<div class="flex flex-col md:flex-row md:items-center justify-center space-y-4 md:space-y-0 md:space-x-4">
|
||||
<div class="flow-box bg-[#FFC107] border-[#004AAD]">Internet User</div>
|
||||
<div class="flow-arrow hidden md:block">→</div>
|
||||
<div class="flow-arrow md:hidden text-center">↓</div>
|
||||
<div class="flow-box">QNAP (WAN)</div>
|
||||
<div class="flow-arrow hidden md:block">→</div>
|
||||
<div class="flow-arrow md:hidden text-center">↓</div>
|
||||
<div class="flow-box bg-green-100 border-green-500 text-green-800">Nginx Proxy Manager</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t-2 border-dashed border-gray-400 my-6"></div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold text-center text-[#002F6C] mb-4">Public Facing Services (ผ่าน NPM)</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="flow-box">Frontend (Next.js)</div>
|
||||
<div class="flow-box">Backend (NestJS)</div>
|
||||
<div class="flow-box">Gitea (Git)</div>
|
||||
<div class="flow-box">n8n (Automation)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold text-center text-[#002F6C] mb-4">Internal Services (Backend เรียกใช้)</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="flow-box bg-gray-200 border-gray-400 text-gray-800">MariaDB (Database)</div>
|
||||
<div class="flow-box bg-gray-200 border-gray-400 text-gray-800">Redis (Cache)</div>
|
||||
<div class="flow-box bg-gray-200 border-gray-400 text-gray-800">Elasticsearch (Search)</div>
|
||||
<div class="flow-box bg-gray-200 border-gray-400 text-gray-800">ClamAV (Virus Scan)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<section id="roadmap" class="section-card">
|
||||
<div class="section-header">
|
||||
<h2 class="text-3xl font-bold">Development Roadmap</h2>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p class="text-lg text-gray-700 mb-6">
|
||||
แผนการพัฒนาถูกแบ่งออกเป็น Phase (Backend) และ Sprints (Frontend)
|
||||
เพื่อให้สามารถส่งมอบงานได้อย่างต่อเนื่องและเป็นระบบ
|
||||
</p>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold text-[#002F6C] mb-4">Backend (NestJS)</h3>
|
||||
<div class="relative">
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-dot"></div>
|
||||
<h4 class="font-bold">Phase 0-1: Setup & Core</h4>
|
||||
<p class="text-sm text-gray-600">Infrastructure, DB Schema, ORM</p>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-dot"></div>
|
||||
<h4 class="font-bold">Phase 2-3: Auth & RBAC</h4>
|
||||
<p class="text-sm text-gray-600">JWT, Passport, CASL 4-Level</p>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-dot"></div>
|
||||
<h4 class="font-bold">Phase 4-5: Core Features</h4>
|
||||
<p class="text-sm text-gray-600">Document Upload, RFA Workflow</p>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-dot"></div>
|
||||
<h4 class="font-bold">Phase 6-8: Integration & Deploy</h4>
|
||||
<p class="text-sm text-gray-600">Search, Cache, Notification, Deploy</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold text-[#002F6C] mb-4">Frontend (Next.js)</h3>
|
||||
<div class="relative">
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-dot"></div>
|
||||
<h4 class="font-bold">Sprint 1-2: Setup & Auth</h4>
|
||||
<p class="text-sm text-gray-600">shadcn/ui, NextAuth, Layout</p>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-dot"></div>
|
||||
<h4 class="font-bold">Sprint 3: Dashboard</h4>
|
||||
<p class="text-sm text-gray-600">Charts (Recharts), KPIs</p>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-dot"></div>
|
||||
<h4 class="font-bold">Sprint 4-5: Document Module</h4>
|
||||
<p class="text-sm text-gray-600">TanStack Table, Upload, Search</p>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-dot"></div>
|
||||
<h4 class="font-bold">Sprint 6-7: Workflow & Deploy</h4>
|
||||
<p class="text-sm text-gray-600">RFA Forms, Testing, Deploy</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="security" class="section-card">
|
||||
<div class="section-header">
|
||||
<h2 class="text-3xl font-bold">Feature Focus: 4-Level RBAC</h2>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p class="text-lg text-gray-700 mb-6">
|
||||
ระบบควบคุมสิทธิ์ (RBAC) เป็นหัวใจสำคัญของความปลอดภัย
|
||||
โดยใช้สถาปัตยกรรม 4 ระดับ (4-Level) เพื่อการควบคุมที่ละเอียดสูงสุด
|
||||
</p>
|
||||
<div class="rbac-level border-[#002F6C]">
|
||||
<span class="font-bold text-lg text-[#002F6C]">🌍 Level 1: Global</span>
|
||||
<p class="text-sm text-gray-600">(Super Admin, System Settings)</p>
|
||||
|
||||
<div class="rbac-level border-[#004AAD]">
|
||||
<span class="font-bold text-lg text-[#004AAD]">🏢 Level 2: Organization</span>
|
||||
<p class="text-sm text-gray-600">(Org Admin, Manage Users & Projects)</p>
|
||||
|
||||
<div class="rbac-level border-[#007BFF]">
|
||||
<span class="font-bold text-lg text-[#007BFF]">🏗️ Level 3: Project</span>
|
||||
<p class="text-sm text-gray-600">(Project Manager, View All Project Docs)</p>
|
||||
|
||||
<div class="rbac-level border-[#B3D7FF]">
|
||||
<span class="font-bold text-lg text-[#002F6C]">📄 Level 4: Contract</span>
|
||||
<p class="text-sm text-gray-600">(Contractor, Access Own Contract Docs Only)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section id="stats" class="section-card">
|
||||
<div class="section-header">
|
||||
<h2 class="text-3xl font-bold">Document Statistics (Mockup Data)</h2>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<p class="text-lg text-gray-700 mb-6">
|
||||
Dashboard จะแสดงสถิติเอกสารแบบ Real-time
|
||||
(อ้างอิงจาก View: `v_document_statistics` ในฐานข้อมูล)
|
||||
เพื่อช่วยในการติดตามและบริหารจัดการโครงการ
|
||||
</p>
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold text-center text-[#002F6C] mb-4">เอกสารตามประเภท (By Type)</h3>
|
||||
<p class="text-sm text-center text-gray-600 mb-4">
|
||||
แสดงจำนวนเอกสารทั้งหมดโดยแบ่งตามประเภทหลัก
|
||||
ช่วยให้เห็นภาพรวมของเอกสารในระบบ
|
||||
</p>
|
||||
<div class="chart-container">
|
||||
<canvas id="docTypeChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold text-center text-[#002F6C] mb-4">สถานะเอกสาร (By Status)</h3>
|
||||
<p class="text-sm text-center text-gray-600 mb-4">
|
||||
แสดงสัดส่วนของสถานะเอกสารในปัจจุบัน
|
||||
(เช่น ร่าง, รออนุมัติ, อนุมัติแล้ว) เพื่อติดตาม Workflow
|
||||
</p>
|
||||
<div class="chart-container">
|
||||
<canvas id="docStatusChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<footer class="text-center p-6 text-gray-600 text-sm">
|
||||
LCBP3-DMS V1.4.1 Infographic | Generated on: <span id="generation-date"></span>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
document.getElementById('generation-date').textContent = new Date().toLocaleDateString('en-US', {
|
||||
year: 'numeric', month: 'long', day: 'numeric'
|
||||
});
|
||||
|
||||
const wrapLabel = (label) => {
|
||||
const maxChars = 16;
|
||||
if (typeof label === 'string' && label.length > maxChars) {
|
||||
const words = label.split(' ');
|
||||
const lines = [];
|
||||
let currentLine = '';
|
||||
for (const word of words) {
|
||||
if ((currentLine + word).length > maxChars) {
|
||||
lines.push(currentLine.trim());
|
||||
currentLine = '';
|
||||
}
|
||||
currentLine += word + ' ';
|
||||
}
|
||||
lines.push(currentLine.trim());
|
||||
return lines;
|
||||
}
|
||||
return label;
|
||||
};
|
||||
|
||||
const tooltipTitleCallback = (tooltipItems) => {
|
||||
const item = tooltipItems[0];
|
||||
let label = item.chart.data.labels[item.dataIndex];
|
||||
if (Array.isArray(label)) {
|
||||
return label.join(' ');
|
||||
} else {
|
||||
return label;
|
||||
}
|
||||
};
|
||||
|
||||
const sharedChartOptions = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
title: tooltipTitleCallback
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
labels: {
|
||||
font: {
|
||||
family: "'Inter', sans-serif"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
ticks: {
|
||||
font: {
|
||||
family: "'Inter', sans-serif"
|
||||
}
|
||||
}
|
||||
},
|
||||
y: {
|
||||
ticks: {
|
||||
font: {
|
||||
family: "'Inter', sans-serif"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const docTypeCtx = document.getElementById('docTypeChart').getContext('2d');
|
||||
const docTypeChart = new Chart(docTypeCtx, {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [
|
||||
'Correspondence (RFA)',
|
||||
'Shop Drawing',
|
||||
'Contract Drawing',
|
||||
wrapLabel('Technical Specification'),
|
||||
'Method Statement'
|
||||
],
|
||||
datasets: [{
|
||||
label: 'จำนวนเอกสาร',
|
||||
data: [120, 190, 75, 45, 88],
|
||||
backgroundColor: [
|
||||
'#004AAD',
|
||||
'#007BFF',
|
||||
'#B3D7FF',
|
||||
'#002F6C',
|
||||
'#FFC107'
|
||||
],
|
||||
borderColor: '#ffffff',
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: { ...sharedChartOptions }
|
||||
});
|
||||
|
||||
const docStatusCtx = document.getElementById('docStatusChart').getContext('2d');
|
||||
const docStatusChart = new Chart(docStatusCtx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: ['Draft', 'Pending Approval', 'Approved', 'Rejected'],
|
||||
datasets: [{
|
||||
label: 'สถานะเอกสาร',
|
||||
data: [30, 45, 150, 15],
|
||||
backgroundColor: [
|
||||
'#B3D7FF',
|
||||
'#FFC107',
|
||||
'#007BFF',
|
||||
'#D9363E'
|
||||
],
|
||||
hoverOffset: 4
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
title: tooltipTitleCallback
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
font: {
|
||||
family: "'Inter', sans-serif"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
220
Documnets/Git_command.md
Normal file
220
Documnets/Git_command.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# **คำสั่งตั้งค่า Gitea ใหม่ทั้งหมด + คำสั่งใช้งานประจำวัน / แก้ปัญหา / branch”**
|
||||
|
||||
---
|
||||
|
||||
📘 Git + Gitea (QNAP / Container Station) – Cheat Sheet
|
||||
คู่มือนี้รวบรวม:
|
||||
|
||||
- คำสั่งตั้งค่า Gitea ใหม่ทั้งหมด
|
||||
- คำสั่งใช้งาน Git ประจำวัน
|
||||
- การแก้ไขปัญหา repository
|
||||
- การทำงานกับ branch
|
||||
- การ reset / clone / merge / rebase
|
||||
|
||||
---
|
||||
|
||||
## 🧩 SECTION 1 – การตั้งค่า Gitea ใหม่ทั้งหมด
|
||||
|
||||
🔹 1) เคลียร์ host key เดิม ใช้เมื่อ Gitea ถูก reset ใหม่ หรือ IP / key เปลี่ยน
|
||||
|
||||
```bash
|
||||
ssh-keygen -R "[git.np-dms.work]:2222"
|
||||
```
|
||||
|
||||
🔹 2) เชื่อมต่อครั้งแรก (จะมีคำถาม fingerprint)
|
||||
|
||||
```bash
|
||||
ssh -T git@git.np-dms.work -p 2222
|
||||
```
|
||||
|
||||
🔹 3) แสดง SSH public key เพื่อเพิ่มใน Gitea
|
||||
|
||||
```bash
|
||||
cat /root/.ssh/id_ed25519.pub
|
||||
cat /root/.ssh/id_rsa.pub
|
||||
```
|
||||
|
||||
🔹 4) เพิ่ม remote ใหม่ (หากยังไม่ได้เพิ่ม)
|
||||
|
||||
```bash
|
||||
git remote add origin ssh://git@git.np-dms.work:2222/np-dms/lcbp3.git
|
||||
```
|
||||
|
||||
🔹 5) ลบ remote เดิมหากผิด
|
||||
|
||||
```bash
|
||||
git remote remove origin
|
||||
```
|
||||
|
||||
🔹 6) Push ครั้งแรกหลังตั้งค่า
|
||||
|
||||
```bash
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
🔹 7) Clone repo ใหม่ทั้งหมด
|
||||
|
||||
```bash
|
||||
git clone ssh://git@git.np-dms.work:2222/np-dms/lcbp3.git
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧩 SECTION 2 – คำสั่ง Git ใช้งานประจำวัน
|
||||
|
||||
🟦 ตรวจสอบสถานะงาน
|
||||
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
🟦 ดูว่าแก้ไฟล์อะไรไป
|
||||
|
||||
```bash
|
||||
git diff
|
||||
```
|
||||
|
||||
🟦 เพิ่มไฟล์ทั้งหมด
|
||||
|
||||
```bash
|
||||
git add .
|
||||
```
|
||||
|
||||
🟦 Commit การแก้ไข
|
||||
|
||||
```bash
|
||||
git commit -m "message"
|
||||
```
|
||||
|
||||
🟦 Push
|
||||
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
|
||||
🟦 Pull (ดึงงานล่าสุด)
|
||||
|
||||
```bash
|
||||
git pull
|
||||
```
|
||||
|
||||
---
|
||||
## 🧩 SECTION 3 – ทำงานกับ Branch
|
||||
|
||||
### ดู branch ทั้งหมด
|
||||
|
||||
```bash
|
||||
git branch
|
||||
```
|
||||
|
||||
### สร้าง branch ใหม่
|
||||
|
||||
```bash
|
||||
git checkout -b feature/login-page
|
||||
```
|
||||
|
||||
### สลับ branch
|
||||
|
||||
```bash
|
||||
git checkout main
|
||||
```
|
||||
|
||||
### ส่ง branch ขึ้น Gitea
|
||||
|
||||
```bash
|
||||
git push -u origin feature/login-page
|
||||
```
|
||||
|
||||
### ลบ branch ในเครื่อง
|
||||
|
||||
```bash
|
||||
git branch -d feature/login-page
|
||||
```
|
||||
|
||||
### ลบ branch บน Gitea
|
||||
|
||||
```bash
|
||||
git push origin --delete feature/login-page
|
||||
```
|
||||
|
||||
### Merge branch → main
|
||||
|
||||
```bash
|
||||
git checkout main
|
||||
git pull
|
||||
git merge feature/login-page
|
||||
git push
|
||||
```
|
||||
|
||||
### Rebase เพื่อให้ history สวย
|
||||
|
||||
```bash
|
||||
git checkout feature/login-page
|
||||
git rebase main
|
||||
git checkout main
|
||||
git merge feature/login-page
|
||||
git push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧩 SECTION 4 – แก้ไขปัญหา Repo
|
||||
|
||||
🔴 (1) Reset repo ทั้งหมดให้เหมือน remote
|
||||
|
||||
⚠ ใช้เมื่อไฟล์ในเครื่องพัง หรือแก้จนเละ
|
||||
|
||||
```bash
|
||||
git fetch --all
|
||||
git reset --hard origin/main
|
||||
```
|
||||
|
||||
🔴 (2) แก้ปัญหา conflict ตอน pull
|
||||
|
||||
```bash
|
||||
git pull --rebase
|
||||
```
|
||||
|
||||
🔴 (3) ดู remote ว่าชี้ไปทางไหน
|
||||
|
||||
```bash
|
||||
git remote -v
|
||||
```
|
||||
|
||||
🔴 (4) เปลี่ยน remote ใหม่
|
||||
|
||||
```bash
|
||||
git remote remove origin
|
||||
git remote add origin ssh://git@git.np-dms.work:2222/np-dms/lcbp3.git
|
||||
```
|
||||
|
||||
🔴 (5) Commit message ผิด แก้ใหม่
|
||||
|
||||
```bash
|
||||
git commit --amend
|
||||
```
|
||||
|
||||
🔴 (6) ย้อน commit ล่าสุด (ไม่ลบไฟล์)
|
||||
|
||||
```bash
|
||||
git reset --soft HEAD~1
|
||||
```
|
||||
|
||||
🔴 (7) ดู log แบบสรุป
|
||||
|
||||
```bash
|
||||
git log --oneline --graph
|
||||
```
|
||||
|
||||
🔴 (8) Clone repo ใหม่ทั้งหมด (เมื่อพังหนัก)
|
||||
|
||||
```bash
|
||||
rm -rf lcbp3
|
||||
git clone ssh://git@git.np-dms.work:2222/np-dms/lcbp3.git
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📌 END
|
||||
|
||||
```
|
||||
91
Documnets/Gitea_setting.md
Normal file
91
Documnets/Gitea_setting.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# การติดตั้ง Gitea ใน Docker
|
||||
|
||||
* user id ของ gites:
|
||||
|
||||
* uid=1000(git) gid=1000(git) groups=1000(git)
|
||||
|
||||
## กำหนดสิทธิ
|
||||
|
||||
```bash
|
||||
chown -R 1000:1000 /share/Container/gitea/
|
||||
[/share/Container/git] # ls -l /share/Container/gitea/etc/app.ini
|
||||
[/share/Container/git] # setfacl -R -m u:1000:rwx /share/Container/gitea/
|
||||
[/share/Container/git] # setfacl -R -m u:70:rwx /share/Container/git/postgres/
|
||||
getfacl /share/Container/git/etc/app.ini
|
||||
chown -R 1000:1000 /share/Container/gitea/
|
||||
ล้าง
|
||||
setfacl -R -b /share/Container/gitea/
|
||||
|
||||
chgrp -R administrators /share/Container/gitea/
|
||||
chown -R 1000:1000 /share/Container/gitea/etc /share/Container/gitea/lib /share/Container/gitea/backup
|
||||
setfacl -m u:1000:rwx -m g:1000:rwx /share/Container/gitea/etc /share/Container/gitea/lib /share/Container/gitea/backup
|
||||
```
|
||||
|
||||
## Docker file
|
||||
|
||||
```yml
|
||||
# File: share/Container/git/docker-compose.yml
|
||||
# DMS Container v1_4_1 : แยก service และ folder, Application name: git, Servive:gitea
|
||||
networks:
|
||||
lcbp3:
|
||||
external: true
|
||||
giteanet:
|
||||
external: true
|
||||
name: gitnet
|
||||
|
||||
services:
|
||||
gitea:
|
||||
image: gitea/gitea:latest-rootless
|
||||
container_name: gitea
|
||||
restart: always
|
||||
stdin_open: true
|
||||
tty: true
|
||||
environment:
|
||||
# ---- File ownership in QNAP ----
|
||||
USER_UID: "1000"
|
||||
USER_GID: "1000"
|
||||
TZ: Asia/Bangkok
|
||||
# ---- Server / Reverse proxy (NPM) ----
|
||||
GITEA__server__ROOT_URL: https://git.np-dms.work/
|
||||
GITEA__server__DOMAIN: git.np-dms.work
|
||||
GITEA__server__SSH_DOMAIN: git.np-dms.work
|
||||
GITEA__server__START_SSH_SERVER: "true"
|
||||
GITEA__server__SSH_PORT: "22"
|
||||
GITEA__server__SSH_LISTEN_PORT: "22"
|
||||
GITEA__server__LFS_START_SERVER: "true"
|
||||
GITEA__server__HTTP_ADDR: "0.0.0.0"
|
||||
GITEA__server__HTTP_PORT: "3000"
|
||||
GITEA__server__TRUSTED_PROXIES: "127.0.0.1/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
|
||||
# --- การตั้งค่าฐานข้อมูล
|
||||
GITEA__database__DB_TYPE: mysql
|
||||
GITEA__database__HOST: mariadb:3306
|
||||
GITEA__database__NAME: "gitea"
|
||||
GITEA__database__USER: "gitea"
|
||||
GITEA__database__PASSWD: "Center#2025"
|
||||
# --- repos
|
||||
GITEA__repository__ROOT: /var/lib/gitea/git/repositories
|
||||
DISABLE_HTTP_GIT: "false"
|
||||
ENABLE_BASIC_AUTHENTICATION: "true"
|
||||
# --- Enable Package Registry ---
|
||||
GITEA__packages__ENABLED: "true"
|
||||
GITEA__packages__REGISTRY__ENABLED: "true"
|
||||
GITEA__packages__REGISTRY__STORAGE_TYPE: local
|
||||
GITEA__packages__REGISTRY__STORAGE_PATH: /data/registry
|
||||
# Optional: lock install after setup (เปลี่ยนเป็น true เมื่อจบ onboarding)
|
||||
GITEA__security__INSTALL_LOCK: "true"
|
||||
volumes:
|
||||
- /share/Container/gitea/backup:/backup
|
||||
- /share/Container/gitea/etc:/etc/gitea
|
||||
- /share/Container/gitea/lib:/var/lib/gitea
|
||||
# ให้ repo root ใช้จาก /share/dms-data/gitea_repos
|
||||
- /share/dms-data/gitea_repos:/var/lib/gitea/git/repositories
|
||||
- /share/dms-data/gitea_registry:/data/registry
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- "3003:3000" # HTTP (ไปหลัง NPM)
|
||||
- "2222:22" # SSH สำหรับ git clone/push
|
||||
networks:
|
||||
- lcbp3
|
||||
- giteanet
|
||||
```
|
||||
138
Documnets/MariaDB_setting.md
Normal file
138
Documnets/MariaDB_setting.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# การติดตั้ง MAriaDB และ PHPMyAdmin ใน Docker
|
||||
|
||||
* user id ของ mariadb:
|
||||
|
||||
* uid=0(root) gid=0(root) groups=0(root)
|
||||
|
||||
## กำหนดสิทธิ
|
||||
|
||||
```bash
|
||||
chown -R 999:999 /share/Container/mariadb/init
|
||||
chmod 755 /share/Container/mariadb/init
|
||||
setfacl -R -m u:999:r-x /share/Container/mariadb/init
|
||||
setfacl -R -d -m u:999:r-x /share/Container/mariadb/init
|
||||
|
||||
chown -R 33:33 /share/Container/pma/tmp
|
||||
chmod 755 /share/Container/pma/tmp
|
||||
setfacl -R -m u:33:rwx /share/Container/pma/tmp
|
||||
setfacl -R -d -m u:33:rwx /share/Container/pma/tmp
|
||||
|
||||
chown -R 33:33 /share/dms-data/logs/pma
|
||||
chmod 755 /share/dms-data/logs/pma
|
||||
setfacl -R -m u:33:rwx /share/dms-data/logs/pma
|
||||
setfacl -R -d -m u:33:rwx /share/dms-data/logs/pma
|
||||
|
||||
setfacl -R -m u:1000:rwx /share/Container/gitea
|
||||
setfacl -R -m u:1000:rwx /share/dms-data/gitea_repos
|
||||
setfacl -R -m u:1000:rwx /share/dms-data/gitea_registry
|
||||
```
|
||||
|
||||
## เพิ่ม database & user สำหรับ Nginx Proxy Manager (NPM)
|
||||
|
||||
```bash
|
||||
docker exec -it mariadb mysql -u root -p
|
||||
CREATE DATABASE npm;
|
||||
CREATE USER 'npm'@'%' IDENTIFIED BY 'npm';
|
||||
GRANT ALL PRIVILEGES ON npm.* TO 'npm'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
## เพิ่ม database & user สำหรับ Gitea
|
||||
|
||||
```bash
|
||||
docker exec -it mariadb mysql -u root -p
|
||||
CREATE DATABASE gitea CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
|
||||
CREATE USER 'gitea'@'%' IDENTIFIED BY 'Center#2025';
|
||||
GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
```
|
||||
|
||||
## Docker file
|
||||
|
||||
```yml
|
||||
# File: share/Container/mariadb/docker-compose.yml
|
||||
# DMS Container v1_4_1 : แยก service และ folder,Application name: lcbp3-db, Servive: mariadb, pma
|
||||
x-restart: &restart_policy
|
||||
restart: unless-stopped
|
||||
|
||||
x-logging: &default_logging
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "5"
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
<<: [*restart_policy, *default_logging]
|
||||
image: mariadb:11.8
|
||||
container_name: mariadb
|
||||
stdin_open: true
|
||||
tty: true
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "2.0"
|
||||
memory: 4G
|
||||
reservations:
|
||||
cpus: "0.5"
|
||||
memory: 1G
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: "Center#2025"
|
||||
MYSQL_DATABASE: "lcbp3"
|
||||
MYSQL_USER: "center"
|
||||
MYSQL_PASSWORD: "Center#2025"
|
||||
TZ: "Asia/Bangkok"
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- "/share/Container/mariadb/data:/var/lib/mysql"
|
||||
- "/share/Container/mariadb/my.cnf:/etc/mysql/conf.d/my.cnf:ro"
|
||||
- "/share/Container/mariadb/init:/docker-entrypoint-initdb.d:ro"
|
||||
- "/share/dms-data/mariadb/backup:/backup"
|
||||
healthcheck:
|
||||
test:
|
||||
["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -pCenter#2025 || exit 1"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 15
|
||||
networks:
|
||||
lcbp3: {}
|
||||
|
||||
pma:
|
||||
<<: [*restart_policy, *default_logging]
|
||||
image: phpmyadmin:5-apache
|
||||
container_name: pma
|
||||
stdin_open: true
|
||||
tty: true
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "0.25"
|
||||
memory: 256M
|
||||
environment:
|
||||
TZ: "Asia/Bangkok"
|
||||
PMA_HOST: "mariadb"
|
||||
PMA_PORT: "3306"
|
||||
PMA_ABSOLUTE_URI: "https://pma.np-dms.work/"
|
||||
UPLOAD_LIMIT: "1G"
|
||||
MEMORY_LIMIT: "512M"
|
||||
ports:
|
||||
- "89:80"
|
||||
# expose:
|
||||
# - "80"
|
||||
volumes:
|
||||
- "/share/Container/pma/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php:ro"
|
||||
- "/share/Container/pma/zzz-custom.ini:/usr/local/etc/php/conf.d/zzz-custom.ini:ro"
|
||||
- "/share/Container/pma/tmp:/var/lib/phpmyadmin/tmp:rw"
|
||||
- "/share/dms-data/logs/pma:/var/log/apache2"
|
||||
depends_on:
|
||||
mariadb:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
lcbp3: {}
|
||||
|
||||
networks:
|
||||
lcbp3:
|
||||
external: true
|
||||
```
|
||||
99
Documnets/NPM_setting.md
Normal file
99
Documnets/NPM_setting.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# การติดตั้ง Nginx Proxy Manager (NPM) ใน Docker
|
||||
|
||||
* ค่าเริ่มต้นคือ:Email: [admin@example.com] Password: changeme
|
||||
|
||||
* user id ของ NPM:
|
||||
|
||||
* uid=0(root) gid=0(root) groups=0(root)
|
||||
|
||||
---
|
||||
|
||||
## กำหนดสิทธิ
|
||||
|
||||
```bash
|
||||
# ตรวจสอบ user id ของ NPM
|
||||
docker exec -it npm id
|
||||
chown -R 0:0 /share/Container/npm
|
||||
setfacl -R -m u:0:rwx /share/Container/npm
|
||||
```
|
||||
|
||||
## Note: Configurations
|
||||
|
||||
| Domain Names | Forward Hostname | IP Forward Port | Cache Assets | Block Common Exploits | Websockets | Force SSL | HTTP/2 | SupportHSTS Enabled |
|
||||
| :----------------------------- | :--------------- | :-------------- | :----------- | :-------------------- | :--------- | :-------- | :----- | :------------------ |
|
||||
| backend.np-dms.work | backend | 3000 | [ ] | [x] | [ ] | [x] | [x] | [ ] |
|
||||
| lcbp3.np-dms.work | frontend | 3000 | [x] | [x] | [x] | [x] | [x] | [ ] |
|
||||
| db.np-dms.work | mariadb | 3306 | [x] | [x] | [x] | [x] | [x] | [ ] |
|
||||
| git.np-dms.work | gitea | 3000 | [x] | [x] | [x] | [x] | [x] | [ ] |
|
||||
| n8n.np-dms.work | n8n | 5678 | [x] | [x] | [x] | [x] | [x] | [ ] |
|
||||
| npm.np-dms.work | npm | 81 | [ ] | [x] | [x] | [x] | [x] | [ ] |
|
||||
| pma.np-dms.work | pma | 80 | [x] | [x] | [ ] | [x] | [x] | [ ] |
|
||||
| np-dms.work, [www.np-dms.work] | localhost | 80 | [x] | [x] | [ ] | [x] | [x] | [ ] |
|
||||
|
||||
## Docker file
|
||||
|
||||
```yml
|
||||
# File: share/Container/npm/docker-compose-npm.yml
|
||||
# DMS Container v1_4_1 แยก service และ folder, Application name: lcbp3-npm, Servive:npm
|
||||
x-restart: &restart_policy
|
||||
restart: unless-stopped
|
||||
|
||||
x-logging: &default_logging
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "5"
|
||||
services:
|
||||
npm:
|
||||
<<: [*restart_policy, *default_logging]
|
||||
image: jc21/nginx-proxy-manager:latest
|
||||
container_name: npm
|
||||
stdin_open: true
|
||||
tty: true
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "1.0" # 50% CPU
|
||||
memory: 512M
|
||||
ports:
|
||||
- "80:80" # HTTP
|
||||
- "443:443" # HTTPS
|
||||
- "81:81" # NPM Admin UI
|
||||
environment:
|
||||
TZ: "Asia/Bangkok"
|
||||
DB_MYSQL_HOST: "mariadb"
|
||||
DB_MYSQL_PORT: 3306
|
||||
DB_MYSQL_USER: "npm"
|
||||
DB_MYSQL_PASSWORD: "npm"
|
||||
DB_MYSQL_NAME: "npm"
|
||||
# Uncomment this if IPv6 is not enabled on your host
|
||||
DISABLE_IPV6: "true"
|
||||
networks:
|
||||
- lcbp3
|
||||
- giteanet
|
||||
volumes:
|
||||
- "/share/Container/npm/data:/data"
|
||||
- "/share/dms-data/logs/npm:/data/logs" # <-- เพิ่ม logging volume
|
||||
- "/share/Container/npm/letsencrypt:/etc/letsencrypt"
|
||||
- "/share/Container/npm/custom:/data/nginx/custom" # <-- สำคัญสำหรับ http_top.conf
|
||||
# - "/share/Container/lcbp3/npm/landing:/data/landing:ro"
|
||||
landing:
|
||||
image: nginx:1.27-alpine
|
||||
container_name: landing
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- "/share/Container/npm/landing:/usr/share/nginx/html:ro"
|
||||
networks:
|
||||
- lcbp3
|
||||
networks:
|
||||
lcbp3:
|
||||
external: true
|
||||
giteanet:
|
||||
external: true
|
||||
name: gitnet
|
||||
|
||||
|
||||
|
||||
|
||||
```
|
||||
1324
Documnets/Project/LCBP3-DMS_V1_4_1_Backend_Development_Plan.md
Normal file
1324
Documnets/Project/LCBP3-DMS_V1_4_1_Backend_Development_Plan.md
Normal file
File diff suppressed because it is too large
Load Diff
2833
Documnets/Project/LCBP3-DMS_V1_4_1_Data_Dictionary.md
Normal file
2833
Documnets/Project/LCBP3-DMS_V1_4_1_Data_Dictionary.md
Normal file
File diff suppressed because it is too large
Load Diff
2491
Documnets/Project/LCBP3-DMS_V1_4_1_Frontend_Development_Plan.md
Normal file
2491
Documnets/Project/LCBP3-DMS_V1_4_1_Frontend_Development_Plan.md
Normal file
File diff suppressed because it is too large
Load Diff
1553
Documnets/Project/LCBP3-DMS_V1_4_1_FullStackJS.md
Normal file
1553
Documnets/Project/LCBP3-DMS_V1_4_1_FullStackJS.md
Normal file
File diff suppressed because it is too large
Load Diff
673
Documnets/Project/LCBP3-DMS_V1_4_1_Requirements.md
Normal file
673
Documnets/Project/LCBP3-DMS_V1_4_1_Requirements.md
Normal file
@@ -0,0 +1,673 @@
|
||||
# 📝 **Documents Management System Version 1.4.1: Application Requirements Specification (ปรับปรุงโดย deepseek)**
|
||||
|
||||
**ปรับปรุงตามการ review และข้อเสนอแนะล่าสุด*
|
||||
|
||||
## 📌**1. วัตถุประสงค์**
|
||||
|
||||
สร้างเว็บแอปพลิเคชั่นสำหรับระบบบริหารจัดการเอกสารโครงการ (Document Management System)ที่สามารถจัดการและควบคุม การสื่อสารด้วยเอกสารที่ซับซ้อน อย่างมีประสิทธิภาพ
|
||||
|
||||
- มีฟังก์ชันหลักในการอัปโหลด จัดเก็บ ค้นหา แชร์ และควบคุมสิทธิ์การเข้าถึงเอกสาร
|
||||
- ช่วยลดการใช้เอกสารกระดาษ เพิ่มความปลอดภัยในการจัดเก็บข้อมูล
|
||||
- เพิ่มความสะดวกในการทำงานร่วมกันระหว่างองกรณ์
|
||||
- **เสริม:** ปรับปรุงความปลอดภัยของระบบด้วยมาตรการป้องกันที่ทันสมัย
|
||||
- **เสริม:** เพิ่มความทนทานของระบบด้วยกลไก resilience patterns
|
||||
- **เสริม:** สร้างระบบ monitoring และ observability ที่ครอบคลุม
|
||||
|
||||
## 🛠️**2. สถาปัตยกรรมและเทคโนโลยี (System Architecture & Technology Stack)**
|
||||
|
||||
ใช้สถาปัตยกรรมแบบ Headless/API-First ที่ทันสมัย ทำงานทั้งหมดบน QNAP Server ผ่าน Container Station เพื่อความสะดวกในการจัดการและบำรุงรักษา, Domain: np-dms.work, มี fix ip, รัน docker command ใน application ของ Container Station ได้โดยตรง, ประกอบด้วย
|
||||
|
||||
- **2.1. Infrastructure & Environment:**
|
||||
- Server: QNAP (Model: TS-473A, RAM: 32GB, CPU: AMD Ryzen V1500B)
|
||||
- Containerization: Container Station (Docker & Docker Compose) ใช้ UI ของ Container Station เป็นหลัก ในการ configuration และการรัน docker command
|
||||
- Development Environment: VS Code on Windows 11
|
||||
- Domain: np-dms.work, <www.np-dms.work>
|
||||
- ip: 159.192.126.103
|
||||
- Docker Network: ทุก Service จะเชื่อมต่อผ่านเครือข่ายกลางชื่อ lcbp3 เพื่อให้สามารถสื่อสารกันได้
|
||||
- Data Storage: /share/dms-data บน QNAP
|
||||
- ข้อจำกัด: ไม่สามารถใช้ .env ในการกำหนดตัวแปรภายนอกได้ ต้องกำหนดใน docker-compose.yml เท่านั้น
|
||||
|
||||
- **2.2. การจัดการ Configuration:**
|
||||
- ใช้ docker-compose.yml สำหรับ environment variables ตามข้อจำกัดของ QNAP
|
||||
- **แต่ต้องมี mechanism สำหรับจัดการ sensitive secrets อย่างปลอดภัย** โดยใช้:
|
||||
- Docker secrets (ถ้ารองรับ)
|
||||
- External secret management (Hashicorp Vault) หรือ
|
||||
- Encrypted environment variables
|
||||
- Development environment ยังใช้ .env ได้ แต่ต้องไม่ commit เข้า version control
|
||||
- ต้องมี configuration validation during application startup
|
||||
- ต้องแยก configuration ตาม environment (development, staging, production)
|
||||
|
||||
- **2.3. Code Hosting:**
|
||||
- Application name: git
|
||||
- Service: Gitea (Self-hosted on QNAP)
|
||||
- Service name: gitea
|
||||
- Domain: git.np-dms.work
|
||||
- หน้าที่: เป็นศูนย์กลางในการเก็บและจัดการเวอร์ชันของโค้ด (Source Code) สำหรับทุกส่วน
|
||||
|
||||
- **2.4. Backend / Data Platform:**
|
||||
- Application name: lcbp3-backend
|
||||
- Service: NestJS
|
||||
- Service name: backend
|
||||
- Domain: backend.np-dms.work
|
||||
- Framework: NestJS (Node.js, TypeScript, ESM)
|
||||
- หน้าที่: จัดการโครงสร้างข้อมูล (Data Models), สร้าง API, จัดการสิทธิ์ผู้ใช้ (Roles & Permissions), และสร้าง Workflow ทั้งหมดของระบบ
|
||||
|
||||
- **2.5. Database:**
|
||||
- Application name: lcbp3-db
|
||||
- Service: mariadb:10.11
|
||||
- Service name: mariadb
|
||||
- Domain: db.np-dms.work
|
||||
- หน้าที่: ฐานข้อมูลหลักสำหรับเก็บข้อมูลทั้งหมด
|
||||
- Tooling: DBeaver (Community Edition), phpmyadmin สำหรับการออกแบบและจัดการฐานข้อมูล
|
||||
|
||||
- **2.6. Database management:**
|
||||
- Application name: lcbp3-db
|
||||
- Service: phpmyadmin:5-apache
|
||||
- Service name: pma
|
||||
- Domain: pma.np-dms.work
|
||||
- หน้าที่: จัดการฐานข้อมูล mariadb ผ่าน Web UI
|
||||
|
||||
- **2.7. Frontend:**
|
||||
- Application name: lcbp3-frontend
|
||||
- Service: next.js
|
||||
- Service name: frontend
|
||||
- Domain: lcbp3.np-dms.work
|
||||
- Framework: Next.js (App Router, React, TypeScript, ESM)
|
||||
- Styling: Tailwind CSS + PostCSS
|
||||
- Component Library: shadcn/ui
|
||||
- หน้าที่: สร้างหน้าตาเว็บแอปพลิเคชันสำหรับให้ผู้ใช้งานเข้ามาดู Dashboard, จัดการเอกสาร, และติดตามงาน โดยจะสื่อสารกับ Backend ผ่าน API
|
||||
|
||||
- **2.8. Workflow automation:**
|
||||
- Application name: lcbp3-n8n
|
||||
- Service: n8nio/n8n:latest
|
||||
- Service name: n8n
|
||||
- Domain: n8n.np-dms.work
|
||||
- หน้าที่: จัดการ workflow ระหว่าง Backend และ Line
|
||||
|
||||
- **2.9. Reverse Proxy:**
|
||||
- Application name: lcbp3-npm
|
||||
- Service: Nginx Proxy Manager (nginx-proxy-manage: latest)
|
||||
- Service name: npm
|
||||
- Domain: npm.np-dms.work
|
||||
- หน้าที่: เป็นด่านหน้าในการรับ-ส่งข้อมูล จัดการโดเมนทั้งหมด, ทำหน้าที่เป็น Proxy ชี้ไปยัง Service ที่ถูกต้อง, และจัดการ SSL Certificate (HTTPS) ให้อัตโนมัติ
|
||||
|
||||
- **2.10. การจัดการตรรกะทางธุรกิจ (Business Logic Implementation):**
|
||||
- 2.10.1. ตรรกะทางธุรกิจที่ซับซ้อนทั้งหมด (เช่น การเปลี่ยนสถานะ Workflow [cite: 3.5.4, 3.6.5], การบังคับใช้สิทธิ์ [cite: 4.4], การตรวจสอบ Deadline [cite: 3.2.5]) **จะถูกจัดการในฝั่ง Backend (NestJS)** [cite: 2.3] เพื่อให้สามารถบำรุงรักษาและทดสอบได้ง่าย (Testability)
|
||||
- 2.10.2. **จะไม่มีการใช้ SQL Triggers** เพื่อป้องกันตรรกะซ่อนเร้น (Hidden Logic) และความซับซ้อนในการดีบัก
|
||||
- 2.10.3. **การจัดการเลขที่เอกสาร:** ใช้ **application-level locking** (Redis distributed lock) แทน stored procedure เพื่อป้องกัน race condition และให้ง่ายต่อการทดสอบและบำรุงรักษา
|
||||
|
||||
- **2.11 Data Migration และ Schema Versioning:**
|
||||
- ต้องมี database migration scripts สำหรับทุก schema change โดยใช้ TypeORM migrations
|
||||
- ต้องรองรับ rollback ของ migration ได้
|
||||
- ต้องมี data seeding strategy สำหรับ environment ต่างๆ (development, staging, production)
|
||||
- ต้องมี version compatibility between schema versions
|
||||
- Migration scripts ต้องผ่านการทดสอบใน staging environment ก่อน production
|
||||
- ต้องมี database backup ก่อนทำ migration ใน production
|
||||
|
||||
- **2.12 กลยุทธ์ความทนทานและการจัดการข้อผิดพลาด (Resilience & Error Handling Strategy)**
|
||||
- 2.12.1 Circuit Breaker Pattern: ใช้สำหรับ external service calls (Email, LINE, Elasticsearch)
|
||||
- 2.12.2 Retry Mechanism: ด้วย exponential backoff สำหรับ transient failures
|
||||
- 2.12.3 Fallback Strategies: Graceful degradation เมื่อบริการภายนอกล้มเหลว
|
||||
- 2.12.4 Error Handling: Error messages ต้องไม่เปิดเผยข้อมูล sensitive
|
||||
- 2.12.5 Monitoring: Centralized error monitoring และ alerting system
|
||||
|
||||
## **📦 3. ข้อกำหนดด้านฟังก์ชันการทำงาน (Functional Requirements)**
|
||||
|
||||
- **3.1. การจัดการโครงสร้างโครงการและองค์กร**
|
||||
- 3.1.1. โครงการ (Projects): ระบบต้องสามารถจัดการเอกสารภายในหลายโครงการได้ (ปัจจุบันมี 4 โครงการ และจะเพิ่มขึ้นในอนาคต)
|
||||
- 3.1.2. สัญญา (Contracts): ระบบต้องสามารถจัดการเอกสารภายในแต่ละสัญญาได้ ในแต่ละโครงการ มีได้หลายสัญญา หรืออย่างน้อย 1 สัญญา
|
||||
- 3.1.3. องค์กร (Organizations):
|
||||
- มีหลายองค์กรในโครงการ องค์กรณ์ที่เป็น Owner, Designer และ Consultant สามารถอยู่ในหลายโครงการและหลายสัญญาได้
|
||||
- Contractor จะถือ 1 สัญญา และอยู่ใน 1 โครงการเท่านั้น
|
||||
|
||||
- **3.2. การจัดการเอกสารโต้ตอบ (Correspondence Management)**
|
||||
- 3.2.1. วัตถุประสงค์: เอกสารโต้ตอบ (correspondences) ระหว่างองกรณื-องกรณ์ ภายใน โครงการ (Projects) และระหว่าง องค์กร-องค์กร ภายนอก โครงการ (Projects), รองรับ To (ผู้รับหลัก) และ CC (ผู้รับสำเนา) หลายองค์กร
|
||||
- 3.2.2. ประเภทเอกสาร: ระบบต้องรองรับเอกสารรูปแบบ ไฟล์ PDF หลายประเภท (Types) เช่น จดหมาย (Letter), อีเมล์ (Email), Request for Information (RFI), และสามารถเพิ่มประเภทใหม่ได้ในภายหลัง
|
||||
- 3.2.3. การสร้างเอกสาร (Correspondence):
|
||||
- ผู้ใช้ที่มีสิทธิ์ (เช่น Document Control) สามารถสร้างเอกสารรอไว้ในสถานะ ฉบับร่าง" (Draft) ได้ ซึ่งผู้ใช้งานต่างองค์กรจะมองไม่เห็น
|
||||
- เมื่อกด "Submitted" แล้ว การแก้ไข, ถอนเอกสารกลับไปสถานะ Draft, หรือยกเลิก (Cancel) จะต้องทำโดยผู้ใช้ระดับ Admin ขึ้นไป พร้อมระบุเหตุผล
|
||||
- 3.2.4. การอ้างอิงและจัดกลุ่ม:
|
||||
- เอกสารสามารถอ้างถึง (Reference) เอกสารฉบับก่อนหน้าได้หลายฉบับ
|
||||
- สามารถกำหนด Tag ได้หลาย Tag เพื่อจัดกลุ่มและใช้ในการค้นหาขั้นสูง
|
||||
- 3.2.5. Correspondence Routing & Workflow
|
||||
- 3.2.5.1 Routing Templates (แม่แบบการส่งต่อ)
|
||||
- ผู้ดูแลระบบต้องสามารถสร้างแม่แบบการส่งต่อได้
|
||||
- แม่แบบสามารถเป็นแบบทั่วไป (ใช้ได้ทุกโครงการ) หรือเฉพาะโครงการ
|
||||
- แต่ละแม่แบบประกอบด้วยลำดับขั้นตอนการส่งต่อ
|
||||
- การส่งจาก Originator -> Organization 1 -> Organization 2 -> Organization 3 แล้วส่งผลกลับตามลำดับเดิม (โดยถ้า องกรณ์ใดใน Wouting ให้ส่งกลับ ก็สามารถส่งผลกลับตามลำดับเดิมโดยไม่ต้องรอให้ถึง องกรณืในลำดับถัดไป)
|
||||
- 3.2.5.2 Routing Steps (ขั้นตอนการส่งต่อ) แต่ละขั้นตอนในแม่แบบต้องกำหนด:
|
||||
- **ลำดับขั้นตอน** (Sequence)
|
||||
- **องค์กรผู้รับ** (To Organization)
|
||||
- **วัตถุประสงค์** (Purpose): เพื่ออนุมัติ (FOR_APPROVAL), เพื่อตรวจสอบ (FOR_REVIEW), เพื่อทราบ (FOR_INFORMATION), เพื่อดำเนินการ (FOR_ACTION)
|
||||
- **ระยะเวลาที่คาดหวัง** (Expected Duration)
|
||||
- 3.2.5.3 Actual Routing Execution (การส่งต่อจริง) เมื่อสร้างเอกสารและเลือกใช้แม่แบบ ระบบต้อง:
|
||||
- สร้างลำดับการส่งต่อตามแม่แบบ
|
||||
- ติดตามสถานะของแต่ละขั้นตอน: ส่งแล้ว (SENT), กำลังดำเนินการ (IN_PROGRESS), ดำเนินการแล้ว (ACTIONED), ส่งต่อแล้ว (FORWARDED), ตอบกลับแล้ว (REPLIED)
|
||||
- ระบุวันครบกำหนด (Due Date) สำหรับแต่ละขั้นตอน
|
||||
- บันทึกผู้ดำเนินการและเวลาที่ดำเนินการ
|
||||
- 3.2.5.4 Routing Flexibility (ความยืดหยุ่น)
|
||||
- สามารถข้ามขั้นตอนได้ในกรณีพิเศษ (โดยผู้มีสิทธิ์)
|
||||
- สามารถส่งกลับขั้นตอนก่อนหน้าได้
|
||||
- สามารถเพิ่มความคิดเห็นในแต่ละขั้นตอน
|
||||
- แจ้งเตือนอัตโนมัติเมื่อถึงขั้นตอนใหม่หรือใกล้ครบกำหนด
|
||||
- 3.2.6. การจัดการ: มีการจัดการอย่างน้อยดังนี้
|
||||
- สามารถกำหนดวันแล้วเสร็จ (Deadline) สำหรับผู้รับผิดชอบของ องกรณ์ ที่เป็นผู้รับได้
|
||||
- มีระบบแจ้งเตือน ให้ผู้รับผิดชอบขององกรณ์ที่เป็น ผู้รับ/ผู้ส่ง ทราบ เมื่อมีเอกสารใหม่ หรือมีการเปลี่ยนสถานะ
|
||||
|
||||
- **3.3. การจัดกาแบบคู่สัญญา (Contract Drawing)**
|
||||
- 3.3.1. วัตถุประสงค์: แบบคู่สัญญา (Contract Drawing) ใช้เพื่ออ้างอิงและใช้ในการตรวจสอบ
|
||||
- 3.3.2. ประเภทเอกสาร: ไฟล์ PDF
|
||||
- 3.3.3. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
|
||||
- 3.3.4. การอ้างอิงและจัดกลุ่ม: ใช้สำหรับอ้างอิง ใน Shop Drawings, มีการจัดหมวดหมู่ของ Contract Drawing
|
||||
|
||||
- **3.4. การจัดกาแบบก่อสร้าง (Shop Drawing)**
|
||||
- 3.4.1. วัตถุประสงค์: แบบก่อสร้าง (Shop Drawing) ใช้เในการตรวจสอบ โดยจัดส่งด้วย Request for Approval (RFA)
|
||||
- 3.4.2. ประเภทเอกสาร: ไฟล์ PDF
|
||||
- 3.4.3. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
|
||||
- 3.4.4. การอ้างอิงและจัดกลุ่ม: ช้สำหรับอ้างอิง ใน Shop Drawings, มีการจัดหมวดหมู่ของ Shop Drawings
|
||||
|
||||
- **3.5. การจัดการเอกสารขออนุมัติ (Request for Approval & Workflow)**
|
||||
- 3.5.1. วัตถุประสงค์: เอกสารขออนุมัติ (Request for Approval) ใช้ในการส่งเอกสารเพิอขออนุมัติ
|
||||
- 3.5.2. ประเภทเอกสาร: Request for Approval (RFA) เป็นชนิดหนึ่งของ Correspondence ที่มีลักษณะเฉพาะที่ต้องได้รับการอนุมัติ มีประเภทดังนี้:
|
||||
- Request for Drawing Approval (RFA_DWG)
|
||||
- Request for Document Approval (RFA_DOC)
|
||||
- Request for Method statement Approval (RFA_MES)
|
||||
- Request for Material Approval (RFA_MAT)
|
||||
- 3.5.2. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
|
||||
- 3.5.4. การอ้างอิงและจัดกลุ่ม: การจัดการ Drawing (RFA_DWG):
|
||||
- เอกสาร RFA_DWG จะประกอบไปด้วย Shop Drawing (shop_drawings) หลายแผ่น ซึ่งแต่ละแผ่นมี Revision ของตัวเอง
|
||||
- Shop Drawing แต่ละ Revision สามารถอ้างอิงถึง Contract Drawing (Ccontract_drawings) หลายแผ่น หรือไม่อ้างถึงก็ได้
|
||||
- ระบบต้องมีส่วนสำหรับจัดการข้อมูล Master Data ของทั้ง Shop Drawing และ Contract Drawing แยกจากกัน
|
||||
- 3.5.5. Workflow การอนุมัติ: ต้องรองรับกระบวนการอนุมัติที่ซับซ้อนและเป็นลำดับ เช่น
|
||||
- ส่งจาก Originator -> Organization 1 -> Organization 2 -> Organization 3 แล้วส่งผลกลับตามลำดับเดิม (โดยถ้า องกรณ์ใดใน Workflow ให้ส่งกลับ ก็สามารถส่งผลกลับตามลำดับเดิมโดยไม่ต้องรอให้ถึง องกรณืในลำดับถัดไป)
|
||||
- 3.5.6. การจัดการ: มีการจัดการอย่างน้อยดังนี้
|
||||
- สามารถกำหนดวันแล้วเสร็จ (Deadline) สำหรับผู้รับผิดชอบของ องกรณ์ ที่อยู่ใน Workflow ได้
|
||||
- มีระบบแจ้งเตือน ให้ผู้รับผิดชอบของ องกรณ์ ที่อยู่ใน Workflow ทราบ เมื่อมี RFA ใหม่ หรือมีการเปลี่ยนสถานะ
|
||||
|
||||
- **3.6.การจัดการเอกสารนำส่ง (Transmittals)**
|
||||
- 3.6.1. วัตถุประสงค์: เอกสารนำส่ง ใช้สำหรับ นำส่ง Request for Approval (RFAS) หลายฉบับ ไปยังองค์กรอื่น
|
||||
- 3.6.2. ประเภทเอกสาร: ไฟล์ PDF
|
||||
- 3.6.3. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ สามารถสร้างและแก้ไขได้
|
||||
- 3.6.4. การอ้างอิงและจัดกลุ่ม: เอกสารนำส่ง เป็นส่วนหนึ่งใน Correspondence
|
||||
|
||||
- **3.7. ใบเวียนเอกสาร (Circulation Sheet)**
|
||||
- 3.7.1. วัตถุประสงค์: การสื่อสาร เอกสาร (Correspondence) ทุกฉบับ จะมีใบเวียนเอกสารเพื่อควบคุมและมอบหมายงานภายในองค์กร (สามารถดูและแก้ไขได้เฉพาะคนในองค์กร)
|
||||
- 3.7.2. ประเภทเอกสาร: ไฟล์ PDF
|
||||
- 3.7.3. การสร้างเอกสาร: ผู้ใช้ที่มีสิทธิ์ในองค์กรนั้น สามารถสร้างและแก้ไขได้
|
||||
- 3.7.4. การอ้างอิงและจัดกลุ่ม: การระบุผู้รับผิดชอบ:
|
||||
- ผู้รับผิดชอบหลัก (Main): มีได้หลายคน
|
||||
- ผู้ร่วมปฏิบัติงาน (Action): มีได้หลายคน
|
||||
- ผู้ที่ต้องรับทราบ (Information): มีได้หลายคน
|
||||
- 3.7.5. การติดตามงาน:
|
||||
- สามารถกำหนดวันแล้วเสร็จ (Deadline) สำหรับผู้รับผิดชอบประเภท Main และ Action ได้
|
||||
- มีระบบแจ้งเตือนเมื่อมี Circulation ใหม่ และแจ้งเตือนล่วงหน้าก่อนถึงวันแล้วเสร็จ
|
||||
- สามารถปิด Circulation ได้เมื่อดำเนินการตอบกลับไปยังองค์กรผู้ส่ง (Originator) แล้ว หรือ รับทราบแล้ว (For Information)
|
||||
|
||||
- **3.8. ประวัติการแก้ไข (Revisions):** ระบบจะเก็บประวัติการสร้างและแก้ไข เอกสารทั้งหมด
|
||||
|
||||
- **3.9. การจัดเก็บ: (ปรับปรุงตามสถาปัตยกรรมใหม่)**
|
||||
- เอกสารและไฟล์แนบทั้งหมดจะถูกจัดเก็บในโฟลเดอร์บน Server (/share/dms-data/) [cite: 2.1]
|
||||
- ข้อมูล Metadata ของไฟล์ (เช่น ชื่อไฟล์, ขนาด, path) จะถูกเก็บในตาราง attachments (ตารางกลาง)
|
||||
- ไฟล์จะถูกเชื่อมโยงกับเอกสารประเภทต่างๆ ผ่านตารางเชื่อม (Junction tables) เช่น correspondence_attachments, circulation_attachments, shop_drawing_revision_attachments ,และ contracy_drawing_attachments
|
||||
- สถาปัตยกรรมแบบรวมศูนย์นี้ แทนที่ แนวคิดเดิมที่จะแยกโฟลเดอร์ตามประเภทเอกสาร เพื่อรองรับการขยายระบบที่ดีกว่า
|
||||
|
||||
- **3.9.6 ความปลอดภัยของการจัดเก็บไฟล์:**
|
||||
- ต้องมีการ scan virus สำหรับไฟล์ที่อัปโหลดทั้งหมด โดยใช้ ClamAV หรือบริการ third-party
|
||||
- จำกัดประเภทไฟล์ที่อนุญาต: PDF, DWG, DOCX, XLSX, ZIP (ต้องระบุรายการที่ชัดเจน)
|
||||
- ขนาดไฟล์สูงสุด: 50MB ต่อไฟล์
|
||||
- ไฟล์ต้องถูกเก็บนอก web root และเข้าถึงได้ผ่าน authenticated endpoint เท่านั้น
|
||||
- ต้องมี file integrity check (checksum) เพื่อป้องกันการแก้ไขไฟล์
|
||||
- Download links ต้องมี expiration time (default: 24 ชั่วโมง)
|
||||
- ต้องบันทึก audit log ทุกครั้งที่มีการดาวน์โหลดไฟล์สำคัญ
|
||||
|
||||
- **3.10. การจัดการเลขที่เอกสาร (Document Numbering):**
|
||||
- 3.10.1. ระบบต้องสามารถสร้างเลขที่เอกสาร (เช่น correspondence_number) ได้โดยอัตโนมัติ
|
||||
- 3.10.2. การนับเลข Running Number (SEQ) จะต้องนับแยกตาม Key ดังนี้: **โครงการ (Project)**, **องค์กรผู้ส่ง (Originator Organization)**, **ประเภทเอกสาร (Document Type)** และ **ปีปัจจุบัน (Year)**
|
||||
- 3.10.3. ผู้ดูแลระบบ (Admin) ต้องสามารถกำหนด "รูปแบบ" (Format Template) ของเลขที่เอกสารได้ (เช่น {ORG_CODE}-{TYPE_CODE}-{YEAR_SHORT}-{SEQ:4}) โดยกำหนดแยกตามโครงการและประเภทเอกสาร
|
||||
- 3.10.4. **ใช้ application-level locking** (Redis distributed lock) แทน stored procedure เพื่อป้องกัน race condition
|
||||
- 3.10.5. ต้องมี retry mechanism และ fallback strategy เมื่อการ generate เลขที่เอกสารล้มเหลว
|
||||
|
||||
- **3.11 การจัดการ JSON Details**
|
||||
- **3.11.1 วัตถุประสงค์**
|
||||
- จัดเก็บข้อมูลแบบไดนามิกที่เฉพาะเจาะจงกับแต่ละประเภทของเอกสาร
|
||||
- รองรับการขยายตัวของระบบโดยไม่ต้องเปลี่ยนแปลง database schema
|
||||
- จัดการ metadata และข้อมูลประกอบสำหรับ correspondence, routing, และ workflows
|
||||
- **3.11.2 โครงสร้าง JSON Schema**
|
||||
ระบบต้องมี predefined JSON schemas สำหรับประเภทเอกสารต่างๆ:
|
||||
- **3.11.2.1 Correspondence Types**
|
||||
- **GENERIC**: ข้อมูลพื้นฐานสำหรับเอกสารทั่วไป
|
||||
- **RFI**: รายละเอียดคำถามและข้อมูลทางเทคนิค
|
||||
- **RFA**: ข้อมูลการขออนุมัติแบบและวัสดุ
|
||||
- **TRANSMITTAL**: รายการเอกสารที่ส่งต่อ
|
||||
- **LETTER**: ข้อมูลจดหมายทางการ
|
||||
- **EMAIL**: ข้อมูลอีเมล
|
||||
- **3.11.2.2 Routing Types**
|
||||
- **ROUTING_TEMPLATE**: กฎและเงื่อนไขการส่งต่อ
|
||||
- **ROUTING_INSTANCE**: สถานะและประวัติการส่งต่อ
|
||||
- **ROUTING_ACTION**: การดำเนินการในแต่ละขั้นตอน
|
||||
- **3.11.2.3 Audit Types**
|
||||
- **AUDIT_LOG**: ข้อมูลการตรวจสอบ
|
||||
- **SECURITY_SCAN**: ผลการตรวจสอบความปลอดภัย
|
||||
- **3.11.3 Validation Rules**
|
||||
- ต้องมี JSON schema validation สำหรับแต่ละประเภท
|
||||
- ต้องรองรับ versioning ของ schema
|
||||
- ต้องมี default values สำหรับ field ที่ไม่บังคับ
|
||||
- ต้องตรวจสอบ data types และ format ให้ถูกต้อง
|
||||
- **3.11.4 Performance Requirements**
|
||||
- JSON field ต้องมีขนาดไม่เกิน 50KB
|
||||
- ต้องรองรับ indexing สำหรับ field ที่ใช้ค้นหาบ่อย
|
||||
- ต้องมี compression สำหรับ JSON ขนาดใหญ่
|
||||
- **3.11.5 Security Requirements**
|
||||
- ต้อง sanitize JSON input เพื่อป้องกัน injection attacks
|
||||
- ต้อง validate JSON structure ก่อนบันทึก
|
||||
- ต้อง encrypt sensitive data ใน JSON fields
|
||||
|
||||
## **🔐 4. ข้อกำหนดด้านสิทธิ์และการเข้าถึง (Access Control Requirements)**
|
||||
|
||||
- **4.1. ภาพรวม:** ผู้ใช้และองค์กรสามารถดูและแก้ไขเอกสารได้ตามสิทธิ์ที่ได้รับ โดยระบบสิทธิ์จะเป็นแบบ Role-Based Access Control (RBAC)
|
||||
|
||||
- **4.2. ลำดับชั้นของสิทธิ์ (Permission Hierarchy)**
|
||||
- Global: สิทธิ์สูงสุดของระบบ
|
||||
- Organization: สิทธิ์ภายในองค์กร เป็นสิทธิ์พื้นฐานของผู้ใช้
|
||||
- Project: สิทธิ์เฉพาะในโครงการ จะถูกพิจารณาเมื่อผู้ใช้อยู่ในโครงการนั้น
|
||||
- Contract: สิทธิ์เฉพาะในสัญญา จะถูกพิจารณาเมื่อผู้ใช้อยู่ในสัญญานั้น (สัญญาเป็นส่วนหนึ่งของโครงการ)
|
||||
|
||||
กฎการบังคับใช้: เมื่อตรวจสอบสิทธิ์ ระบบจะพิจารณาสิทธิ์จากทุกระดับที่ผู้ใช้มี และใช้ สิทธิ์ที่มากที่สุด (Most Permissive) เป็นตัวตัดสิน
|
||||
|
||||
ตัวอย่าง: ผู้ใช้ A เป็น Viewer ในองค์กร แต่ถูกมอบหมายเป็น Editor ในโครงการ X เมื่ออยู่ในโครงการ X ผู้ใช้ A จะมีสิทธิ์แก้ไขได้
|
||||
|
||||
- **4.3. การกำหนดบทบาท (Roles) และขอบเขต (Scope)**
|
||||
|
||||
| บทบาท (Role) | ขอบเขต (Scope) | คำอธิบาย | สิทธิ์หลัก (Key Permissions) |
|
||||
| :------------------- | :------------- | :---------------------- | :------------------------------------------------------------------------------------- |
|
||||
| **Superadmin** | Global | ผู้ดูแลระบบสูงสุด | ทำทุกอย่างในระบบ, จัดการองค์กร, จัดการข้อมูลหลักระดับ Global |
|
||||
| **Org Admin** | Organization | ผู้ดูแลองค์กร | จัดการผู้ใช้ในองค์กร, จัดการบทบาท/สิทธิ์ภายในองค์กร, ดูรายงานขององค์กร |
|
||||
| **Document Control** | Organization | ควบคุมเอกสารขององค์กร | เพิ่ม/แก้ไข/ลบเอกสาร, กำหนดสิทธิ์เอกสารภายในองค์กร |
|
||||
| **Editor** | Organization | ผู้แก้ไขเอกสารขององค์กร | เพิ่ม/แก้ไขเอกสารที่ได้รับมอบหมาย |
|
||||
| **Viewer** | Organization | ผู้ดูเอกสารขององค์กร | ดูเอกสารที่มีสิทธิ์เข้าถึง |
|
||||
| **Project Manager** | Project | ผู้จัดการโครงการ | จัดการสมาชิกในโครงการ (เพิ่ม/ลบ/มอบบทบาท), สร้าง/จัดการสัญญาในโครงการ, ดูรายงานโครงการ |
|
||||
| **Contract Admin** | Contract | ผู้ดูแลสัญญา | จัดการสมาชิกในสัญญา, สร้าง/จัดการข้อมูลหลักเฉพาะสัญญา (ถ้ามี), อนุมัติเอกสารในสัญญา |
|
||||
|
||||
- **4.4. กระบวนการเริ่มต้นใช้งาน (Onboarding Workflow) ที่สมบูรณ์**
|
||||
- **4.4.1. สร้างองค์กร (Organization)**
|
||||
- **Superadmin** สร้างองค์กรใหม่ (เช่น บริษัท A)
|
||||
- **Superadmin** แต่งตั้งผู้ใช้อย่างน้อย 1 คนให้เป็น **Org Admin** หรือ **Document Control** ของบริษัท A
|
||||
- **4.4.2. เพิ่มผู้ใช้ในองค์กร**
|
||||
- **Org Admin** ของบริษัท A เพิ่มผู้ใช้อื่นๆ (Editor, Viewer) เข้ามาในองค์กรของตน
|
||||
- **4.4.3. มอบหมายผู้ใช้ให้กับโครงการ (Project)**
|
||||
- **Project Manager** ของโครงการ X (ซึ่งอาจมาจากบริษัท A หรือบริษัทอื่น) ทำการ "เชิญ" หรือ "มอบหมาย" ผู้ใช้จากองค์กรต่างๆ ที่เกี่ยวข้องเข้ามาในโครงการ X
|
||||
- ในขั้นตอนนี้ **Project Manager** จะกำหนด **บทบาทระดับโครงการ** (เช่น Project Member, หรืออาจไม่มีบทบาทพิเศษ ให้ใช้สิทธิ์จากระดับองค์กรไปก่อน)
|
||||
- **4.4.4. เมอบหมายผู้ใช้ให้กับสัญญา (Contract)**
|
||||
- **Contract Admin** ของสัญญา Y (ซึ่งเป็นส่วนหนึ่งของโครงการ X) ทำการเลือกผู้ใช้ที่อยู่ในโครงการ X แล้ว มอบหมายให้เข้ามาในสัญญา Y
|
||||
- ในขั้นตอนนี้ **Contract Admin** จะกำหนด **บทบาทระดับสัญญา** (เช่น Contract Member) และสิทธิ์เฉพาะที่จำเป็น
|
||||
- **4.4.5 Security Onboarding:**
|
||||
- ต้องบังคับเปลี่ยน password ครั้งแรกสำหรับผู้ใช้ใหม่
|
||||
- ต้องมี security awareness training สำหรับผู้ใช้ที่มีสิทธิ์สูง
|
||||
- ต้องมี process สำหรับการรีเซ็ต password ที่ปลอดภัย
|
||||
- ต้องบันทึก audit log ทุกครั้งที่มีการเปลี่ยนแปลง permissions
|
||||
|
||||
- **4.5. การจัดการข้อมูลหลัก (Master Data Management) ที่แบ่งตามระดับ**
|
||||
|
||||
| ข้อมูลหลัก | ผู้มีสิทธิ์จัดการ | ระดับ |
|
||||
| :---------------------------------- | :------------------------------ | :--------------------------------- |
|
||||
| ประเภทเอกสาร (Correspondence, RFA) | **Superadmin** | Global |
|
||||
| สถานะเอกสาร (Draft, Approved, etc.) | **Superadmin** | Global |
|
||||
| หมวดหมู่แบบ (Shop Drawing) | **Project Manager** | Project (สร้างใหม่ได้ภายในโครงการ) |
|
||||
| Tags | **Org Admin / Project Manager** | Organization / Project |
|
||||
| บทบาทและสิทธิ์ (Custom Roles) | **Superadmin / Org Admin** | Global / Organization |
|
||||
| Document Numbering Formats | **Superadmin / Admin** | Global / Organization |
|
||||
|
||||
## **👥 5. ข้อกำหนดด้านผู้ใช้งาน (User Interface & Experience)**
|
||||
|
||||
- **5.1. Layout หลัก:** หน้าเว็บใช้รูปแบบ App Shell ที่ประกอบด้วย:
|
||||
- Navbar (ส่วนบน): แสดงชื่อระบบ, เมนูผู้ใช้ (Profile), เมนูสำหรับ Document Control/เมนูสำหรับ Admin/Superadmin (จัดการผู้ใช้, จัดการสิทธิ์), และปุ่ม Login/Logout
|
||||
- Sidebar (ด้านข้าง): เป็นเมนูหลักสำหรับเข้าถึงส่วนที่เกี่ยวข้องกับเอกสารทั้งหมด เช่น Dashboard, Correspondences, RFA, Drawings
|
||||
- Main Content Area: พื้นที่สำหรับแสดงเนื้อหาหลักของหน้าที่เลือก
|
||||
- **5.2. หน้า Landing Page:** เป็นหน้าแรกที่แสดงข้อมูลบางส่วนของโครงการสำหรับผู้ใช้ที่ยังไม่ได้ล็อกอิน
|
||||
- **5.3. หน้า Dashboard:** เป็นหน้าแรกหลังจากล็อกอิน ประกอบด้วย:
|
||||
- การ์ดสรุปภาพรวม (KPI Cards): แสดงข้อมูลสรุปที่สำคัญขององค์กร เช่น จำนวนเอกสาร, งานที่เกินกำหนด
|
||||
- ตาราง "งานของฉัน" (My Tasks Table): แสดงรายการงานทั้งหมดจาก Circulation ที่ผู้ใช้ต้องดำเนินการ
|
||||
- Security Metrics: แสดงจำนวน files scanned, security incidents, failed login attempts
|
||||
- **5.4. การติดตามสถานะ:** องค์กรสามารถติดตามสถานะเอกสารทั้งของตนเอง (Originator) และสถานะเอกสารที่ส่งมาถึงตนเอง (Recipient)
|
||||
- **5.5. การจัดการข้อมูลส่วนตัว (Profile Page):** ผู้ใช้สามารถจัดการข้อมูลส่วนตัวและเปลี่ยนรหัสผ่านของตนเองได้
|
||||
- **5.6. การจัดการเอกสารทางเทคนิค (RFA & Workflow):** ผู้ใช้สามารถดู RFA ในรูปแบบ Workflow ทั้งหมดได้ในหน้าเดียว, ขั้นตอนที่ยังไม่ถึงหรือผ่านไปแล้วจะเป็นรูปแบบ diable, สามารถดำเนินการได้เฉพาะในขั้นตอนที่ได้รับมอบหมายงาน (active) เช่น ตรวจสอบแล้ว เพื่อไปยังขั้นตอนต่อไป, สิทธิ์ Document Control ขึ้นไป สามรถกด ไปยังขั้นตอนต่อไป ได้ทุกขั้นตอน, การย้อนกลับ ไปขั้นตอนก่อนหน้า สามารถทำได้โดย สิทธิ์ Document Control ขึ้นไป
|
||||
- **5.7. การจัดการใบเวียนเอกสาร (Circulation):** ผู้ใช้สามารถดู Circulation ในรูปแบบ Workflow ทั้งหมดได้ในหน้าเดียว,ขั้นตอนที่ยังไม่ถึงหรือผ่านไปแล้วจะเป็นรูปแบบ diable, สามารถดำเนินการได้เฉพาะในขั้นตอนที่ได้รับมอบหมายงาน (active) เช่น ตรวจสอบแล้ว เพื่อไปยังขั้นตอนต่อไป, สิทธิ์ Document Control ขึ้นไป สามรถกด ไปยังขั้นตอนต่อไป ได้ทุกขั้นตอน, การย้อนกลับ ไปขั้นตอนก่อนหน้า สามารถทำได้โดย สิทธิ์ Document Control ขึ้นไป
|
||||
- **5.8. การจัดการเอกสารนำส่ง (Transmittals):** ผู้ใช้สามารถดู Transmittals ในรูปแบบรายการทั้งหมดได้ในหน้าเดียว
|
||||
- **5.9. ข้อกำหนด UI/UX การแนบไฟล์ (File Attachment UX):**
|
||||
- ระบบต้องรองรับการอัปโหลดไฟล์หลายไฟล์พร้อมกัน (Multi-file upload) เช่น การลากและวาง (Drag-and-Drop)
|
||||
- ในหน้าอัปโหลด (เช่น สร้าง RFA หรือ Correspondence) ผู้ใช้ต้องสามารถกำหนดได้ว่าไฟล์ใดเป็น "เอกสารหลัก" (Main Document เช่น PDF) และไฟล์ใดเป็น "เอกสารแนบประกอบ" (Supporting Attachments เช่น .dwg, .docx, .zip)
|
||||
- **Security Feedback:** แสดง security warnings สำหรับ file types ที่เสี่ยงหรือ files ที่ fail virus scan
|
||||
- **File Type Indicators:** แสดง file type icons และ security status
|
||||
|
||||
## **6. ข้อกำหนดที่ไม่ใช่ฟังก์ชันการทำงาน (Non-Functional Requirements)**
|
||||
|
||||
- **6.1. การบันทึกการกระทำ (Audit Log):** ทุกการกระทำที่สำคัญของผู้ใช้ (สร้าง, แก้ไข, ลบ, ส่ง) จะถูกบันทึกไว้ใน audit_logs เพื่อการตรวจสอบย้อนหลัง
|
||||
- **6.1.1 ขอบเขตการบันทึก Audit Log:**
|
||||
- ทุกการสร้าง/แก้ไข/ลบ ข้อมูลสำคัญ (correspondences, RFAs, drawings, users, permissions)
|
||||
- ทุกการเข้าถึงข้อมูล sensitive (user data, financial information)
|
||||
- ทุกการเปลี่ยนสถานะ workflow (status transitions)
|
||||
- ทุกการดาวน์โหลดไฟล์สำคัญ (contract documents, financial reports)
|
||||
- ทุกการเปลี่ยนแปลง permission และ role assignment
|
||||
- ทุกการล็อกอินที่สำเร็จและล้มเหลว
|
||||
- ทุกการส่งคำขอ API ที่สำคัญ
|
||||
- **6.1.2 ข้อมูลที่ต้องบันทึกใน Audit Log:**
|
||||
- ผู้ใช้งาน (user_id)
|
||||
- การกระทำ (action)
|
||||
- ชนิดของ entity (entity_type)
|
||||
- ID ของ entity (entity_id)
|
||||
- ข้อมูลก่อนการเปลี่ยนแปลง (old_values) - สำหรับ update operations
|
||||
- ข้อมูลหลังการเปลี่ยนแปลง (new_values) - สำหรับ update operations
|
||||
- IP address
|
||||
- User agent
|
||||
- Timestamp
|
||||
- Request ID สำหรับ tracing
|
||||
|
||||
- **6.2. การค้นหา (Search):** ระบบต้องมีฟังก์ชันการค้นหาขั้นสูง ที่สามารถค้นหาเอกสาร **correspondence**, **rfa**, **shop_drawing**, **contract-drawing**, **transmittal** และ **ใบเวียน (Circulations)** จากหลายเงื่อนไขพร้อมกันได้ เช่น ค้นหาจากชื่อเรื่อง, ประเภท, วันที่, และ Tag
|
||||
|
||||
- **6.3. การทำรายงาน (Reporting):** สามารถจัดทำรายงานสรุปแยกประเภทของ Correspondence ประจำวัน, สัปดาห์, เดือน, และปีได้
|
||||
|
||||
- **6.4. ประสิทธิภาพ (Performance):** มีการใช้ Caching กับข้อมูลที่เรียกใช้บ่อย และใช้ Pagination ในตารางข้อมูลเพื่อจัดการข้อมูลจำนวนมาก
|
||||
|
||||
- **6.4.1 ตัวชี้วัดประสิทธิภาพ:**
|
||||
- **API Response Time:** < 200ms (90th percentile) สำหรับ operation ทั่วไป
|
||||
- **Search Query Performance:** < 500ms สำหรับการค้นหาขั้นสูง
|
||||
- **File Upload Performance:** < 30 seconds สำหรับไฟล์ขนาด 50MB
|
||||
- **Concurrent Users:** รองรับผู้ใช้พร้อมกันอย่างน้อย 100 คน
|
||||
- **Database Connection Pool:** ขนาดเหมาะสมกับ workload (default: min 5, max 20 connections)
|
||||
- **Cache Hit Ratio:** > 80% สำหรับ cached data
|
||||
- **Application Startup Time:** < 30 seconds
|
||||
|
||||
- **6.4.2 Caching Strategy:**
|
||||
- **Master Data Cache:** Roles, Permissions, Organizations, Project metadata (TTL: 1 hour)
|
||||
- **User Session Cache:** User permissions และ profile data (TTL: 30 minutes)
|
||||
- **Search Result Cache:** Frequently searched queries (TTL: 15 minutes)
|
||||
- **File Metadata Cache:** Attachment metadata (TTL: 1 hour)
|
||||
- **Document Cache:** Frequently accessed document metadata (TTL: 30 minutes)
|
||||
- **ต้องมี cache invalidation strategy ที่ชัดเจน:**
|
||||
- Invalidate on update/delete operations
|
||||
- Time-based expiration
|
||||
- Manual cache clearance สำหรับ admin operations
|
||||
- ใช้ Redis เป็น distributed cache backend
|
||||
- ต้องมี cache monitoring (hit/miss ratios)
|
||||
|
||||
- **6.5. ความปลอดภัย (Security):**
|
||||
- มีระบบ Rate Limiting เพื่อป้องกันการโจมตีแบบ Brute-force
|
||||
- การจัดการ Secret (เช่น รหัสผ่าน DB, JWT Secret) จะต้องทำผ่าน Environment Variable ของ Docker เพื่อความปลอดภัยสูงสุด
|
||||
- **6.5.1 Rate Limiting Strategy:**
|
||||
- **Anonymous Endpoints:** 100 requests/hour ต่อ IP address
|
||||
- **Authenticated Endpoints:**
|
||||
- Viewer: 500 requests/hour
|
||||
- Editor: 1000 requests/hour
|
||||
- Document Control: 2000 requests/hour
|
||||
- Admin/Superadmin: 5000 requests/hour
|
||||
- **File Upload Endpoints:** 50 requests/hour ต่อ user
|
||||
- **Search Endpoints:** 500 requests/hour ต่อ user
|
||||
- **Authentication Endpoints:** 10 requests/minute ต่อ IP address
|
||||
- **ต้องมี mechanism สำหรับยกเว้น rate limiting สำหรับ trusted services**
|
||||
- ต้องบันทึก log เมื่อมีการ trigger rate limiting
|
||||
- **6.5.2 Error Handling และ Resilience:**
|
||||
- ต้องมี circuit breaker pattern สำหรับ external service calls
|
||||
- ต้องมี retry mechanism ด้วย exponential backoff
|
||||
- ต้องมี graceful degradation เมื่อบริการภายนอกล้มเหลว
|
||||
- Error messages ต้องไม่เปิดเผยข้อมูล sensitive
|
||||
- **6.5.3 Input Validation:**
|
||||
- ต้องมี input validation ทั้งฝั่ง client และ server (defense in depth)
|
||||
- ต้องป้องกัน OWASP Top 10 vulnerabilities:
|
||||
- SQL Injection (ใช้ parameterized queries ผ่าน ORM)
|
||||
- XSS (input sanitization และ output encoding)
|
||||
- CSRF (CSRF tokens สำหรับ state-changing operations)
|
||||
- ต้อง validate file uploads:
|
||||
- File type (white-list approach)
|
||||
- File size
|
||||
- File content (magic number verification)
|
||||
- ต้อง sanitize user inputs ก่อนแสดงผลใน UI
|
||||
- ต้องใช้ content security policy (CSP) headers
|
||||
- ต้องมี request size limits เพื่อป้องกัน DoS attacks
|
||||
- **6.5.4 Session และ Token Management:**
|
||||
- **JWT token expiration:** 8 hours สำหรับ access token
|
||||
- **Refresh token expiration:** 7 days
|
||||
- **Refresh token mechanism:** ต้องรองรับ token rotation และ revocation
|
||||
- **Token revocation on logout:** ต้องบันทึก revoked tokens จนกว่าจะ expire
|
||||
- **Concurrent session management:**
|
||||
- จำกัดจำนวน session พร้อมกันได้ (default: 5 devices)
|
||||
- ต้องแจ้งเตือนเมื่อมี login จาก device/location ใหม่
|
||||
- **Device fingerprinting:** สำหรับ security และ audit purposes
|
||||
- **Password policy:**
|
||||
- ความยาวขั้นต่ำ: 8 characters
|
||||
- ต้องมี uppercase, lowercase, number, special character
|
||||
- ต้องเปลี่ยน password ทุก 90 วัน
|
||||
- ต้องป้องกันการใช้ password ที่เคยใช้มาแล้ว 5 ครั้งล่าสุด
|
||||
|
||||
- **6.6. การสำรองข้อมูลและการกู้คืน (Backup & Recovery):**
|
||||
- ระบบจะต้องมีกลไกการสำรองข้อมูลอัตโนมัติสำหรับฐานข้อมูล MariaDB [cite: 2.4] และไฟล์เอกสารทั้งหมดใน /share/dms-data [cite: 2.1] (เช่น ใช้ HBS 3 ของ QNAP หรือสคริปต์สำรองข้อมูล) อย่างน้อยวันละ 1 ครั้ง
|
||||
- ต้องมีแผนการกู้คืนระบบ (Disaster Recovery Plan) ในกรณีที่ Server หลัก (QNAP) ใช้งานไม่ได้
|
||||
|
||||
- **6.6.1 ขั้นตอนการกู้คืน:**
|
||||
- **Database Restoration Procedure:**
|
||||
- สร้างจาก full backup ล่าสุด
|
||||
- Apply transaction logs ถึง point-in-time ที่ต้องการ
|
||||
- Verify data integrity post-restoration
|
||||
- **File Storage Restoration Procedure:**
|
||||
- Restore จาก QNAP snapshot หรือ backup
|
||||
- Verify file integrity และ permissions
|
||||
- **Application Redeployment Procedure:**
|
||||
- Deploy จาก version ล่าสุดที่รู้ว่าทำงานได้
|
||||
- Verify application health
|
||||
- **Data Integrity Verification Post-Recovery:**
|
||||
- Run data consistency checks
|
||||
- Verify critical business data
|
||||
- **Recovery Time Objective (RTO):** < 4 ชั่วโมง
|
||||
- **Recovery Point Objective (RPO):** < 1 ชั่วโมง
|
||||
|
||||
- **6.7. กลยุทธ์การแจ้งเตือน (Notification Strategy):**
|
||||
- **6.7.1 ระบบจะส่งการแจ้งเตือน (ผ่าน Email หรือ Line [cite: 2.7]) เมื่อมีการกระทำที่สำคัญ** ดังนี้:
|
||||
1. เมื่อมีเอกสารใหม่ (Correspondence, RFA) ถูกส่งมาถึงองค์กรณ์ของเรา
|
||||
2. เมื่อมีใบเวียน (Circulation) ใหม่ มอบหมายงานมาที่เรา
|
||||
3. (ทางเลือก) เมื่อเอกสารที่เราส่งไป ถูกดำเนินการ (เช่น อนุมัติ/ปฏิเสธ)
|
||||
4. (ทางเลือก) เมื่อใกล้ถึงวันครบกำหนด (Deadline) [cite: 3.2.5, 3.6.6, 3.7.5]
|
||||
- **6.7.2 Notification Delivery Guarantees:**
|
||||
- **At-least-once delivery:** สำหรับ important notifications
|
||||
- **Retry mechanism:** ด้วย exponential backoff (max 3 retries)
|
||||
- **Dead letter queue:** สำหรับ notifications ที่ส่งไม่สำเร็จหลังจาก retries
|
||||
- **Delivery status tracking:** ต้องบันทึกสถานะการส่ง notifications
|
||||
- **Fallback channels:** ถ้า Email ล้มเหลว ให้ส่งผ่าน SYSTEM notification
|
||||
- **Notification preferences:** ผู้ใช้ต้องสามารถกำหนด channel preferences ได้
|
||||
|
||||
- **6.8. Monitoring และ Observability**
|
||||
- **6.8.1 Application Monitoring:**
|
||||
- **Health checks:** /health endpoint สำหรับ load balancer
|
||||
- **Metrics collection:** Response times, error rates, throughput
|
||||
- **Distributed tracing:** สำหรับ request tracing across services
|
||||
- **Log aggregation:** Structured logging ด้วย JSON format
|
||||
- **Alerting:** สำหรับ critical errors และ performance degradation
|
||||
- **6.8.2 Business Metrics:**
|
||||
- จำนวน documents created ต่อวัน
|
||||
- Workflow completion rates
|
||||
- User activity metrics
|
||||
- System utilization rates
|
||||
- Search query performance
|
||||
- **6.8.3 Security Monitoring:**
|
||||
- Failed login attempts
|
||||
- Rate limiting triggers
|
||||
- Virus scan results
|
||||
- File download activities
|
||||
- Permission changes
|
||||
|
||||
- **6.9 JSON Processing & Validation**
|
||||
- **6.9.1 JSON Schema Management**
|
||||
- ต้องมี centralized JSON schema registry
|
||||
- ต้องรองรับ schema versioning และ migration
|
||||
- ต้องมี schema validation during runtime
|
||||
- **6.9.2 Performance Optimization**
|
||||
- **Caching:** Cache parsed JSON structures
|
||||
- **Compression:** ใช้ compression สำหรับ JSON ขนาดใหญ่
|
||||
- **Indexing:** Support JSON path indexing สำหรับ query
|
||||
- **6.9.3 Error Handling**
|
||||
- ต้องมี graceful degradation เมื่อ JSON validation ล้มเหลว
|
||||
- ต้องมี default fallback values
|
||||
- ต้องบันทึก error logs สำหรับ validation failures
|
||||
|
||||
---
|
||||
|
||||
## **7. ข้อกำหนดด้านการทดสอบ (Testing Requirements)**
|
||||
|
||||
- **7.1. Unit Testing:**
|
||||
- ต้องมี unit tests สำหรับ business logic ทั้งหมด
|
||||
- Code coverage อย่างน้อย 70% สำหรับ backend services
|
||||
- ต้องทดสอบ RBAC permission logic ทุกระดับ
|
||||
|
||||
- **7.2. Integration Testing:**
|
||||
- ทดสอบการทำงานร่วมกันของ modules
|
||||
- ทดสอบ database migrations และ data integrity
|
||||
- ทดสอบ API endpoints ด้วย realistic data
|
||||
|
||||
- **7.3. End-to-End Testing:**
|
||||
- ทดสอบ complete user workflows
|
||||
- ทดสอบ document lifecycle จาก creation ถึง archival
|
||||
- ทดสอบ cross-module integrations
|
||||
|
||||
- **7.4. Security Testing:**
|
||||
- **Penetration Testing:** ทดสอบ OWASP Top 10 vulnerabilities
|
||||
- **Security Audit:** Review code สำหรับ security flaws
|
||||
- **Virus Scanning Test:** ทดสอบ file upload security
|
||||
- **Rate Limiting Test:** ทดสอบ rate limiting functionality
|
||||
|
||||
- **7.5. Performance Testing:**
|
||||
- **Load Testing:** ทดสอบด้วย realistic workloads
|
||||
- **Stress Testing:** หา breaking points ของระบบ
|
||||
- **Endurance Testing:** ทดสอบการทำงานต่อเนื่องเป็นเวลานาน
|
||||
|
||||
- **7.6. Disaster Recovery Testing:**
|
||||
- ทดสอบ backup และ restoration procedures
|
||||
- ทดสอบ failover mechanisms
|
||||
- ทดสอบ data integrity หลังการ recovery
|
||||
|
||||
---
|
||||
|
||||
## **8. ข้อกำหนดด้านการบำรุงรักษา (Maintenance Requirements)**
|
||||
|
||||
- **8.1. Log Retention:**
|
||||
- Audit logs: 7 ปี
|
||||
- Application logs: 1 ปี
|
||||
- Performance metrics: 2 ปี
|
||||
|
||||
- **8.2. Monitoring และ Alerting:**
|
||||
- ต้องมี proactive monitoring สำหรับ critical systems
|
||||
- ต้องมี alerting สำหรับ security incidents
|
||||
- ต้องมี performance degradation alerts
|
||||
|
||||
- **8.3. Patch Management:**
|
||||
- ต้องมี process สำหรับ security patches
|
||||
- ต้องทดสอบ patches ใน staging environment
|
||||
- ต้องมี rollback plan สำหรับ failed updates
|
||||
|
||||
- **8.4. Capacity Planning:**
|
||||
- ต้อง monitor resource utilization
|
||||
- ต้องมี scaling strategy สำหรับ growth
|
||||
- ต้องมี performance baselines และ trending
|
||||
|
||||
---
|
||||
|
||||
## **9. ข้อกำหนดด้านการปฏิบัติตามกฎระเบียบ (Compliance Requirements)**
|
||||
|
||||
- **9.1. Data Privacy:**
|
||||
- ต้องปฏิบัติตามกฎหมายคุ้มครองข้อมูลส่วนบุคคล
|
||||
- ต้องมี data retention policies
|
||||
- ต้องมี data deletion procedures
|
||||
|
||||
- **9.2. Audit Compliance:**
|
||||
- ต้องรองรับ internal และ external audits
|
||||
- ต้องมี comprehensive audit trails
|
||||
- ต้องมี reporting capabilities สำหรับ compliance
|
||||
|
||||
- **9.3. Security Standards:**
|
||||
- ต้องปฏิบัติตาม organizational security policies
|
||||
- ต้องมี security incident response plan
|
||||
- ต้องมี regular security assessments
|
||||
|
||||
---
|
||||
|
||||
## **10. ข้อกำหนดด้าน Testing Strategy**
|
||||
|
||||
### **10.1 Testing Gates แต่ละ Phase**
|
||||
|
||||
ทุก Phase ต้องผ่านการทดสอบต่อไปนี้ก่อนดำเนินการ Phase ถัดไป:
|
||||
|
||||
#### **10.1.1 Unit Testing Requirements**
|
||||
|
||||
- Code coverage อย่างน้อย 80% สำหรับ components ที่พัฒนาใน Phase
|
||||
- ทดสอบ business logic ทั้งหมด
|
||||
- ทดสอบ error scenarios และ edge cases
|
||||
|
||||
#### **10.1.2 Integration Testing Requirements**
|
||||
|
||||
- ทดสอบการทำงานร่วมกันของ modules ใน Phase
|
||||
- ทดสอบ database operations
|
||||
- ทดสอบ external service integrations
|
||||
|
||||
#### **10.1.3 Security Testing Requirements**
|
||||
|
||||
- ทดสอบ security vulnerabilities
|
||||
- ทดสอบ permission และ access control
|
||||
- ทดสอบ input validation
|
||||
|
||||
#### **10.1.4 Performance Testing Requirements**
|
||||
|
||||
- ทดสอบ response time ตามเป้าหมาย
|
||||
- ทดสอบภายใต้ load ที่คาดหมาย
|
||||
- ทดสอบ memory usage และ resource utilization
|
||||
|
||||
### **10.2 Testing Automation**
|
||||
|
||||
- ต้องมี automated test pipelines
|
||||
- ต้องมี test reports และ metrics
|
||||
- ต้องมี regression testing
|
||||
|
||||
---
|
||||
|
||||
## **📋 สรุปการปรับปรุงจากเวอร์ชันก่อนหน้า**
|
||||
|
||||
### **Security Enhancements:**
|
||||
|
||||
1. **File Upload Security** - Virus scanning, file type validation, access controls
|
||||
2. **Input Validation** - OWASP Top 10 protection, XSS/CSRF prevention
|
||||
3. **Rate Limiting** - Comprehensive rate limiting strategy
|
||||
4. **Secrets Management** - Secure handling of sensitive configuration
|
||||
|
||||
### **Architecture Improvements:**
|
||||
|
||||
1. **Document Numbering** - Changed from Stored Procedure to Application-level Locking
|
||||
2. **Resilience Patterns** - Circuit breaker, retry mechanisms, fallback strategies
|
||||
3. **Monitoring & Observability** - Health checks, metrics, distributed tracing
|
||||
4. **Caching Strategy** - Comprehensive caching with proper invalidation
|
||||
|
||||
### **Performance Targets:**
|
||||
|
||||
1. **API Response Time** - < 200ms (90th percentile)
|
||||
2. **Search Performance** - < 500ms
|
||||
3. **File Upload** - < 30 seconds for 50MB files
|
||||
4. **Cache Hit Ratio** - > 80%
|
||||
|
||||
### **Operational Excellence:**
|
||||
|
||||
1. **Disaster Recovery** - RTO < 4 hours, RPO < 1 hour
|
||||
2. **Backup Procedures** - Comprehensive backup and restoration
|
||||
3. **Security Testing** - Penetration testing and security audits
|
||||
4. **Performance Testing** - Load testing with realistic workloads
|
||||
|
||||
เอกสารนี้สะท้อนถึงความมุ่งมั่นในการสร้างระบบที่มีความปลอดภัย, มีความทนทาน, และมีประสิทธิภาพสูง พร้อมรองรับการเติบโตในอนาคตและความต้องการทางธุรกิจที่เปลี่ยนแปลงไป
|
||||
|
||||
**หมายเหตุ:** Requirements นี้จะถูกทบทวนและปรับปรุงเป็นระยะตาม feedback จากทีมพัฒนาและความต้องการทางธุรกิจที่เปลี่ยนแปลงไป
|
||||
|
||||
## **Document Control:**
|
||||
|
||||
- Document for Application Requirements Specification DMS v1.4.1
|
||||
- Version: 1.4.1
|
||||
- Date: 2025-11-16
|
||||
- Author: System Architecture Team
|
||||
- Status: FINAL
|
||||
- Classification: Internal Technical Documentation
|
||||
|
||||
---
|
||||
|
||||
_End of Requirements Specification
|
||||
119
Documnets/Securities.md
Normal file
119
Documnets/Securities.md
Normal file
@@ -0,0 +1,119 @@
|
||||
สวัสดีครับ! การตั้งค่า Network Segmentation และ Firewall Rules เป็นขั้นตอนที่ฉลาดมากครับ โดยเฉพาะเมื่อคุณมี Services ที่ต้องเปิดสู่ Public (เช่น `lcbp3.np-dms.work`) และ Services ภายใน (เช่น `db.np-dms.work`)
|
||||
|
||||
สำหรับอุปกรณ์ Omada (ER7206 + OC200) กลยุทธ์หลักคือการใช้ **VLANs (Virtual LANs)** เพื่อแบ่งกลุ่มอุปกรณ์ และใช้ **Firewall ACLs (Access Control Lists)** เพื่อควบคุมการจราจรระหว่างกลุ่มเหล่านั้น
|
||||
|
||||
นี่คือคำแนะนำตามแนวทาง "Zero Trust" ที่ปรับให้เข้ากับสถาปัตยกรรมของคุณครับ
|
||||
|
||||
---
|
||||
|
||||
## 1. 🌐 การแบ่งส่วนเครือข่าย (VLAN Segmentation)
|
||||
|
||||
ใน Omada Controller (OC200) ให้คุณไปที่ `Settings > Wired Networks > LAN` และสร้างเครือข่ายย่อย (VLANs) ดังนี้:
|
||||
|
||||
* **VLAN 1 (Default): Management**
|
||||
* **IP Range:** 192.168.1.x
|
||||
* **วัตถุประสงค์:** ใช้สำหรับอุปกรณ์ Network (ER7206, OC200, Switches) และ PC ของผู้ดูแลระบบ (Admin) เท่านั้น
|
||||
|
||||
* **VLAN 10: Servers (DMZ)**
|
||||
* **IP Range:** 192.168.10.x
|
||||
* **วัตถุประสงค์:** นี่คือ VLAN ที่คุณจะเสียบสาย LAN ของ **QNAP NAS** ครับ QNAP จะได้รับ IP ในกลุ่มนี้ (เช่น `192.168.10.100`)
|
||||
|
||||
* **VLAN 20: Office / Trusted**
|
||||
* **IP Range:** 192.168.20.x
|
||||
* **วัตถุประสงค์:** สำหรับ PC, Notebook, และ Wi-Fi ของพนักงานทั่วไปที่ต้องเข้าใช้งานระบบ (เช่น `lcbp3.np-dms.work`)
|
||||
|
||||
* **VLAN 30: Guests / Untrusted**
|
||||
* **IP Range:** 192.168.30.x
|
||||
* **วัตถุประสงค์:** สำหรับ Wi-Fi แขก (Guest) ห้ามเข้าถึงเครือข่ายภายในโดยเด็ดขาด
|
||||
|
||||
**การตั้งค่า Port Switch:**
|
||||
หลังจากสร้าง VLANs แล้ว ให้ไปที่ `Devices` > เลือก Switch ของคุณ > `Ports` > กำหนด Port Profile:
|
||||
|
||||
* Port ที่เสียบ QNAP NAS: ตั้งค่า Profile เป็น **VLAN 10**
|
||||
* Port ที่เสียบ PC พนักงาน: ตั้งค่า Profile เป็น **VLAN 20**
|
||||
|
||||
---
|
||||
|
||||
## 2. 🔥 Firewall Rules (ACLs)
|
||||
|
||||
นี่คือหัวใจสำคัญครับ ไปที่ `Settings > Network Security > ACL (Access Control)`
|
||||
|
||||
กฎของ Firewall จะทำงานจากบนลงล่าง (ข้อ 1 ทำก่อนข้อ 2)
|
||||
|
||||
### A. กฎการห้าม (Deny Rules) - สำคัญที่สุด
|
||||
|
||||
**กฎข้อ 1: บล็อก Guest (VLAN 30) ไม่ให้ยุ่งกับใคร**
|
||||
|
||||
* **Name:** Isolate-Guests
|
||||
* **Policy:** Deny
|
||||
* **Source:** `Network` -> `VLAN 30`
|
||||
* **Destination:** `Network` -> `VLAN 1`, `VLAN 10`, `VLAN 20`
|
||||
* *(กฎนี้จะทำให้ Guest ออกอินเทอร์เน็ตได้อย่างเดียว แต่คุยข้าม VLAN ไม่ได้)*
|
||||
|
||||
**กฎข้อ 2: บล็อก Server (VLAN 10) ไม่ให้โจมตีคนอื่น**
|
||||
|
||||
* **Name:** Isolate-Servers
|
||||
* **Policy:** Deny
|
||||
* **Source:** `Network` -> `VLAN 10`
|
||||
* **Destination:** `Network` -> `VLAN 20`
|
||||
* *(กฎนี้ป้องกันไม่ให้ Server (QNAP) ที่อาจถูกแฮก เริ่มเชื่อมต่อไปยัง PC ของพนักงาน (VLAN 20) เพื่อแพร่กระจาย Malware)*
|
||||
|
||||
**กฎข้อ 3: บล็อก Office ไม่ให้เข้าหน้า Admin**
|
||||
|
||||
* **Name:** Block-Office-to-Management
|
||||
* **Policy:** Deny
|
||||
* **Source:** `Network` -> `VLAN 20`
|
||||
* **Destination:** `Network` -> `VLAN 1`
|
||||
* *(ป้องกันไม่ให้พนักงานทั่วไปเข้าหน้าตั้งค่า Router หรือ Controller)*
|
||||
|
||||
### B. กฎการอนุญาต (Allow Rules)
|
||||
|
||||
**กฎข้อ 4: อนุญาตให้ Office (VLAN 20) ใช้งาน Services ที่จำเป็น**
|
||||
|
||||
* **Name:** Allow-Office-to-Services
|
||||
* **Policy:** Allow
|
||||
* **Source:** `Network` -> `VLAN 20`
|
||||
* **Destination:** `IP Group` -> (สร้าง Group ชื่อ `QNAP_Services` ชี้ไปที่ `192.168.10.100` (IP ของ QNAP))
|
||||
* **Port:** `Service` -> (สร้าง Port Group ชื่อ `Web_Services`):
|
||||
* TCP 443 (HTTPS - สำหรับทุก Service เช่น lcbp3, git, pma)
|
||||
* TCP 80 (HTTP - สำหรับ NPM redirect)
|
||||
* TCP 81 (NPM Admin UI)
|
||||
* TCP 2222 (Gitea SSH)
|
||||
* (ไม่จำเป็นต้องเปิด Port 3000, 3003, 5678, 89 เพราะ NPM จัดการให้แล้ว)
|
||||
|
||||
### C. กฎสุดท้าย (Default)
|
||||
|
||||
Omada มักจะมีกฎ "Allow All" อยู่ล่างสุด ให้ปล่อยไว้ หรือถ้าคุณต้องการความปลอดภัยสูงสุด (Zero Trust) ให้เปลี่ยนกฎสุดท้ายเป็น "Deny All" (แต่ต้องมั่นใจว่ากฎ Allow ของคุณครอบคลุมทั้งหมดแล้ว)
|
||||
|
||||
---
|
||||
|
||||
## 3. 🚪 Port Forwarding (การเปิด Service สู่สาธารณะ)
|
||||
|
||||
ส่วนนี้ไม่ใช่ Firewall ACL แต่จำเป็นเพื่อให้คนนอกเข้าใช้งานได้ครับ
|
||||
ไปที่ `Settings > Transmission > Port Forwarding`
|
||||
|
||||
สร้างกฎเพื่อส่งต่อการจราจรจาก WAN (อินเทอร์เน็ต) ไปยัง Nginx Proxy Manager (NPM) ที่อยู่บน QNAP (VLAN 10)
|
||||
|
||||
* **Name:** Allow-NPM-HTTPS
|
||||
* **External Port:** 443
|
||||
* **Internal Port:** 443
|
||||
* **Internal IP:** `192.168.10.100` (IP ของ QNAP)
|
||||
* **Protocol:** TCP
|
||||
|
||||
* **Name:** Allow-NPM-HTTP (สำหรับ Let's Encrypt)
|
||||
* **External Port:** 80
|
||||
* **Internal Port:** 80
|
||||
* **Internal IP:** `192.168.10.100` (IP ของ QNAP)
|
||||
* **Protocol:** TCP
|
||||
|
||||
### สรุปผังการเชื่อมต่อ
|
||||
|
||||
1. **ผู้ใช้ภายนอก** -> `https://lcbp3.np-dms.work`
|
||||
2. **ER7206** รับที่ Port 443
|
||||
3. **Port Forwarding** ส่งต่อไปยัง `192.168.10.100:443` (QNAP NPM)
|
||||
4. **NPM** (บน QNAP) ส่งต่อไปยัง `backend:3000` หรือ `frontend:3000` ภายใน Docker
|
||||
5. **ผู้ใช้ภายใน (Office)** -> `https://lcbp3.np-dms.work`
|
||||
6. **Firewall ACL** (กฎข้อ 4) อนุญาตให้ VLAN 20 คุยกับ `192.168.10.100:443`
|
||||
7. (ขั้นตอนที่ 3-4 ทำงานเหมือนเดิม)
|
||||
|
||||
การตั้งค่าตามนี้จะช่วยแยกส่วน Server ของคุณออกจากเครือข่ายพนักงานอย่างชัดเจน ซึ่งปลอดภัยกว่าการวางทุกอย่างไว้ในวง LAN เดียวกันมากครับ
|
||||
143
Documnets/Service_setting.md
Normal file
143
Documnets/Service_setting.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# การติดตั้ง Nginx Proxy Manager (NPM) ใน Docker
|
||||
|
||||
---
|
||||
|
||||
## **📝 คำอธิบายและข้อควรพิจารณา**
|
||||
|
||||
* 1 Redis (Service: cache)
|
||||
|
||||
* Image: redis:7-alpine มีขนาดเล็กและทันสมัย
|
||||
|
||||
* Port: ไม่ได้ expose port 6379 ออกมาที่ Host QNAP เพราะตามสถาปัตยกรรม Service backend (NestJS) จะคุยกับ cache (Redis) ผ่าน lcbp3 network ภายในโดยตรง ซึ่งปลอดภัยกว่าครับ
|
||||
|
||||
* Volume: map data ไปที่ /share/Container/cache/data เผื่อใช้ Redis ในการทำ Persistent Cache (ถ้าต้องการแค่ Locking อาจจะไม่จำเป็นต้อง map volume ก็ได้ครับ)
|
||||
|
||||
* User ID: Image redis:7-alpine รันด้วย user redis (UID 999)
|
||||
|
||||
* 2 Elasticsearch (Service: search)
|
||||
|
||||
* Image: elasticsearch:8.11.1 ผมเลือกเวอร์ชัน 8 ที่ใหม่และระบุชัดเจน (ไม่ใช้ latest) เพื่อความเสถียรครับ
|
||||
|
||||
* Port: ไม่ได้ expose port 9200 ออกมาที่ Host เช่นกัน เพราะ NPM_setting.md ระบุว่า npm (Nginx Proxy Manager) จะ forward search.np-dms.work ไปยัง service search ที่ port 9200 ผ่าน lcbp3 network ครับ
|
||||
|
||||
* Environment (สำคัญมาก):
|
||||
|
||||
* discovery.type: "single-node": ต้องมี ไม่อย่างนั้น Elasticsearch V.8 จะไม่ยอม start ถ้าไม่พบ node อื่นใน cluster
|
||||
|
||||
* xpack.security.enabled: "false": เพื่อความสะดวกในการพัฒนาระยะแรก NestJS จะได้เชื่อมต่อ API port 9200 ได้เลย (หากเปิดใช้งานจะต้องตั้งค่า SSL และ Token ซึ่งซับซ้อนกว่ามาก)
|
||||
|
||||
* ES_JAVA_OPTS: "-Xms1g -Xmx1g": เป็น Best Practice ที่ต้องกำหนด Heap Size ให้ Elasticsearch (ในที่นี้คือ 1GB)
|
||||
|
||||
* User ID: Image elasticsearch รันด้วย user elasticsearch (UID 1000)
|
||||
|
||||
---
|
||||
|
||||
## กำหนดสิทธิ
|
||||
|
||||
```bash
|
||||
# สร้าง Directory
|
||||
mkdir -p /share/Container/services/cache/data
|
||||
mkdir -p /share/Container/services/search/data
|
||||
|
||||
# กำหนดสิทธิ์ให้ตรงกับ User ID ใน Container
|
||||
# Redis (UID 999)
|
||||
chown -R 999:999 /share/Container/services/cache/data
|
||||
chmod -R 750 /share/Container/services/cache/data
|
||||
|
||||
# Elasticsearch (UID 1000)
|
||||
chown -R 1000:1000 /share/Container/services/search/data
|
||||
chmod -R 750 /share/Container/services/search/data
|
||||
```
|
||||
|
||||
## Docker file
|
||||
|
||||
```yml
|
||||
# File: /share/Container/services/docker-compose.yml (หรือไฟล์ที่คุณใช้รวม)
|
||||
# DMS Container v1_4_1: เพิ่ม Application name: services, Services 'cache' (Redis) และ 'search' (Elasticsearch)
|
||||
|
||||
x-restart: &restart_policy
|
||||
restart: unless-stopped
|
||||
|
||||
x-logging: &default_logging
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "5"
|
||||
|
||||
networks:
|
||||
lcbp3:
|
||||
external: true
|
||||
|
||||
services:
|
||||
# ----------------------------------------------------------------
|
||||
# 1. Redis (สำหรับ Caching และ Distributed Lock)
|
||||
# Service Name: cache (ตามที่ NPM และ Backend Plan อ้างอิง)
|
||||
# ----------------------------------------------------------------
|
||||
cache:
|
||||
<<: [*restart_policy, *default_logging]
|
||||
image: redis:7-alpine # ใช้ Alpine image เพื่อให้มีขนาดเล็ก
|
||||
container_name: cache
|
||||
stdin_open: true
|
||||
tty: true
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "1.0"
|
||||
memory: 2G # Redis เป็น in-memory, ให้ memory เพียงพอต่อการใช้งาน
|
||||
reservations:
|
||||
cpus: "0.25"
|
||||
memory: 512M
|
||||
environment:
|
||||
TZ: "Asia/Bangkok"
|
||||
networks:
|
||||
- lcbp3 # เชื่อมต่อ network ภายในเท่านั้น
|
||||
volumes:
|
||||
- "/share/Container/cache/data:/data" # Map volume สำหรับเก็บข้อมูล (ถ้าต้องการ persistence)
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"] # ตรวจสอบว่า service พร้อมใช้งาน
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# 2. Elasticsearch (สำหรับ Advanced Search)
|
||||
# Service Name: search (ตามที่ NPM และ Backend Plan อ้างอิง)
|
||||
# ----------------------------------------------------------------
|
||||
search:
|
||||
<<: [*restart_policy, *default_logging]
|
||||
image: elasticsearch:8.11.1 # แนะนำให้ระบุเวอร์ชันชัดเจน (V.8)
|
||||
container_name: search
|
||||
stdin_open: true
|
||||
tty: true
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "2.0" # Elasticsearch ใช้ CPU และ Memory ค่อนข้างหนัก
|
||||
memory: 4G
|
||||
reservations:
|
||||
cpus: "0.5"
|
||||
memory: 2G
|
||||
environment:
|
||||
TZ: "Asia/Bangkok"
|
||||
# --- Critical Settings for Single-Node ---
|
||||
discovery.type: "single-node" # สำคัญมาก: กำหนดให้รันแบบ 1 node
|
||||
# --- Security (Disable for Development) ---
|
||||
# ปิด xpack security เพื่อให้ NestJS เชื่อมต่อง่าย (backend -> search:9200)
|
||||
# หากเป็น Production จริง ควรเปิดใช้งานและตั้งค่า token/cert ครับ
|
||||
xpack.security.enabled: "false"
|
||||
# --- Performance Tuning ---
|
||||
# กำหนด Heap size (1GB) ให้เหมาะสมกับ memory limit (4GB)
|
||||
ES_JAVA_OPTS: "-Xms1g -Xmx1g"
|
||||
networks:
|
||||
- lcbp3 # เชื่อมต่อ network ภายใน (NPM จะ proxy port 9200 จากภายนอก)
|
||||
volumes:
|
||||
- "/share/Container/search/data:/usr/share/elasticsearch/data" # Map volume สำหรับเก็บ data/indices
|
||||
healthcheck:
|
||||
# รอจนกว่า cluster health จะเป็น yellow หรือ green
|
||||
test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -q '\"status\":\"green\"\\|\\\"status\":\"yellow\"'"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
```
|
||||
91
Documnets/n8n_setting.md
Normal file
91
Documnets/n8n_setting.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# การติดตั้ง n8n ใน Docker
|
||||
|
||||
* user id ของ gites:
|
||||
|
||||
* uid=1000(node) gid=1000(node) groups=1000(node)
|
||||
|
||||
## กำหนดสิทธิ
|
||||
|
||||
```bash
|
||||
# สำหรับ n8n volumes
|
||||
chown -R 1000:1000 /share/Container/n8n
|
||||
chmod -R 755 /share/Container/n8n
|
||||
```
|
||||
|
||||
## Docker file
|
||||
|
||||
```yml
|
||||
# File: share/Container/n8n/docker-compose.yml
|
||||
# DMS Container v1_4_1 แยก service และ folder, Application name:n8n service n8n
|
||||
x-restart: &restart_policy
|
||||
restart: unless-stopped
|
||||
|
||||
x-logging: &default_logging
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "5"
|
||||
services:
|
||||
n8n:
|
||||
<<: [*restart_policy, *default_logging]
|
||||
image: n8nio/n8n:latest
|
||||
container_name: n8n
|
||||
stdin_open: true
|
||||
tty: true
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: "1.5"
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: "0.25"
|
||||
memory: 512M
|
||||
environment:
|
||||
TZ: "Asia/Bangkok"
|
||||
NODE_ENV: "production"
|
||||
# N8N_PATH: "/n8n/"
|
||||
N8N_PUBLIC_URL: "https://n8n.np-dms.work/"
|
||||
WEBHOOK_URL: "https://n8n.np-dms.work/"
|
||||
N8N_EDITOR_BASE_URL: "https://n8n.np-dms.work/"
|
||||
N8N_PROTOCOL: "https"
|
||||
N8N_HOST: "n8n.np-dms.work"
|
||||
N8N_PORT: 5678
|
||||
N8N_PROXY_HOPS: "1"
|
||||
N8N_DIAGNOSTICS_ENABLED: 'false'
|
||||
N8N_SECURE_COOKIE: 'true'
|
||||
N8N_ENCRYPTION_KEY: "9AAIB7Da9DW1qAhJE5/Bz4SnbQjeAngI"
|
||||
N8N_BASIC_AUTH_ACTIVE: 'true'
|
||||
N8N_BASIC_AUTH_USER: admin
|
||||
N8N_BASIC_AUTH_PASSWORD: Center#2025
|
||||
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: 'true'
|
||||
GENERIC_TIMEZONE: "Asia/Bangkok"
|
||||
DB_TYPE: mysqldb
|
||||
DB_MYSQLDB_DATABASE: "n8n"
|
||||
DB_MYSQLDB_USER: "center"
|
||||
DB_MYSQLDB_PASSWORD: "Center#2025"
|
||||
DB_MYSQLDB_HOST: "mariadb"
|
||||
DB_MYSQLDB_PORT: 3306
|
||||
|
||||
ports:
|
||||
- "5678:5678"
|
||||
networks:
|
||||
lcbp3: {}
|
||||
volumes:
|
||||
- "/share/Container/n8n:/home/node/.n8n"
|
||||
- "/share/Container/n8n/cache:/home/node/.cache"
|
||||
- "/share/Container/n8n/scripts:/scripts"
|
||||
- "/share/Container/n8n/data:/data"
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:5678/"]
|
||||
# test: ["CMD", "curl", "-f", "http://127.0.0.1:5678/ || exit 1"]
|
||||
interval: 15s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
|
||||
networks:
|
||||
lcbp3:
|
||||
external: true
|
||||
```
|
||||
120
Documnets/แผนผัง Network.md
Normal file
120
Documnets/แผนผัง Network.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# **🗺️ แผนผัง Network Architecture & Firewall (LCBP3-DMS)**
|
||||
|
||||
แผนผังนี้แสดงการแบ่งส่วนเครือข่าย (VLANs) และกฎ Firewall (ACLs) สำหรับ TP-Link Omada (ER7206/OC200) เพื่อรักษาความปลอดภัยของ QNAP NAS และ Docker Services
|
||||
|
||||
## **1\. แผนผังการเชื่อมต่อ (Connection Flow Diagram)**
|
||||
|
||||
graph TD
|
||||
direction TB
|
||||
|
||||
subgraph Flow1 \[\<b\>การเชื่อมต่อจากภายนอก (Public WAN)\</b\>\]
|
||||
User\[ผู้ใช้งานภายนอก (Internet)\]
|
||||
end
|
||||
|
||||
subgraph Router \[\<b\>Router (ER7206)\</b\> \- Gateway\]
|
||||
User \-- "Port 80/443 (HTTPS/HTTP)" \--\> ER7206
|
||||
ER7206(\<b\>Port Forwarding\</b\>\<br/\>TCP 80 \-\> 192.168.10.100:80\<br/\>TCP 443 \-\> 192.168.10.100:443)
|
||||
end
|
||||
|
||||
subgraph VLANs \[\<b\>เครือข่ายภายใน (VLANs & Firewall Rules)\</b\>\]
|
||||
direction LR
|
||||
|
||||
subgraph VLAN10 \[\<b\>VLAN 10: Servers (DMZ)\</b\>\<br/\>192.168.10.x\]
|
||||
QNAP\[\<b\>QNAP NAS (192.168.10.100)\</b\>\]
|
||||
end
|
||||
|
||||
subgraph VLAN20 \[\<b\>VLAN 20: Office\</b\>\<br/\>192.168.20.x\]
|
||||
OfficePC\[PC พนักงาน/Wi-Fi\]
|
||||
end
|
||||
|
||||
subgraph VLAN30 \[\<b\>VLAN 30: Guests\</b\>\<br/\>192.168.30.x\]
|
||||
GuestPC\[Guest Wi-Fi\]
|
||||
end
|
||||
|
||||
subgraph Firewall \[\<b\>Firewall ACLs (ควบคุมโดย OC200)\</b\>\]
|
||||
direction TB
|
||||
rule1(\<b\>Rule 1: DENY\</b\>\<br/\>Guest (VLAN 30\) \-\> All VLANs)
|
||||
rule2(\<b\>Rule 2: DENY\</b\>\<br/\>Server (VLAN 10\) \-\> Office (VLAN 20))
|
||||
rule3(\<b\>Rule 3: ALLOW\</b\>\<br/\>Office (VLAN 20\) \-\> QNAP (192.168.10.100)\<br/\>Ports: 443, 80, 81, 2222\)
|
||||
end
|
||||
|
||||
%% \--- แสดงผล Firewall Rules \---
|
||||
GuestPC \-.x|rule1| QNAP
|
||||
QNAP \-.x|rule2| OfficePC
|
||||
OfficePC \-- "\[https://lcbp3.np-dms.work\](https://lcbp3.np-dms.work)" \--\>|rule3| QNAP
|
||||
end
|
||||
|
||||
%% \--- เชื่อมต่อ Router กับ QNAP \---
|
||||
ER7206 \--\> QNAP
|
||||
|
||||
subgraph Docker \[\<b\>Docker Network 'lcbp3' (ภายใน QNAP)\</b\>\]
|
||||
direction TB
|
||||
|
||||
subgraph PublicServices \[Services ที่ NPM เปิดสู่ภายนอก\]
|
||||
direction LR
|
||||
NPM\[\<b\>NPM (Nginx Proxy Manager)\</b\>\<br/\>รับการจราจรจาก QNAP\]
|
||||
Frontend(frontend:3000)
|
||||
Backend(backend:3000)
|
||||
Gitea(gitea:3000)
|
||||
PMA(pma:80)
|
||||
N8N(n8n:5678)
|
||||
end
|
||||
|
||||
subgraph InternalServices \[Internal Services (Backend เรียกใช้เท่านั้น)\]
|
||||
direction LR
|
||||
DB(mariadb:3306)
|
||||
Cache(cache:6379)
|
||||
Search(search:9200)
|
||||
end
|
||||
|
||||
%% \--- การเชื่อมต่อภายใน Docker \---
|
||||
NPM \-- "lcbp3.np-dms.work" \--\> Frontend
|
||||
NPM \-- "backend.np-dms.work" \--\> Backend
|
||||
NPM \-- "git.np-dms.work" \--\> Gitea
|
||||
NPM \-- "pma.np-dms.work" \--\> PMA
|
||||
NPM \-- "n8n.np-dms.work" \--\> N8N
|
||||
|
||||
Backend \-- "lcbp3 Network" \--\> DB
|
||||
Backend \-- "lcbp3 Network" \--\> Cache
|
||||
Backend \-- "lcbp3 Network" \--\> Search
|
||||
|
||||
end
|
||||
|
||||
%% \--- เชื่อมต่อ QNAP กับ Docker \---
|
||||
QNAP \--\> NPM
|
||||
|
||||
%% \--- Styling \---
|
||||
classDef default fill:\#f9f9f9,stroke:\#333,stroke-width:2px;
|
||||
classDef router fill:\#e6f7ff,stroke:\#0056b3,stroke-width:2px;
|
||||
classDef vlan fill:\#fffbe6,stroke:\#d46b08,stroke-width:2px;
|
||||
classDef docker fill:\#e6ffed,stroke:\#096dd9,stroke-width:2px;
|
||||
classDef internal fill:\#f0f0f0,stroke:\#595959,stroke-width:2px,stroke-dasharray: 5 5;
|
||||
classDef fw fill:\#fff0f0,stroke:\#d9363e,stroke-width:2px,stroke-dasharray: 3 3;
|
||||
|
||||
class Router,ER7206 router;
|
||||
class VLANs,VLAN10,VLAN20,VLAN30 vlan;
|
||||
class Docker,PublicServices,InternalServices docker;
|
||||
class DB,Cache,Search internal;
|
||||
class Firewall,rule1,rule2,rule3 fw;
|
||||
|
||||
## **2\. สรุปการตั้งค่า Firewall ACLs (สำหรับ Omada OC200)**
|
||||
|
||||
นี่คือรายการกฎ (Rules) ที่คุณต้องสร้างใน Settings \> Network Security \> ACL (เรียงลำดับจากบนลงล่าง):
|
||||
|
||||
| ลำดับ | Name | Policy | Source | Destination | Ports |
|
||||
| :---- | :---- | :---- | :---- | :---- | :---- |
|
||||
| **1** | Isolate-Guests | **Deny** | Network \-\> VLAN 30 (Guests) | Network \-\> VLAN 1, 10, 20 | All |
|
||||
| **2** | Isolate-Servers | **Deny** | Network \-\> VLAN 10 (Servers) | Network \-\> VLAN 20 (Office) | All |
|
||||
| **3** | Block-Office-to-Mgmt | **Deny** | Network \-\> VLAN 20 (Office) | Network \-\> VLAN 1 (Mgmt) | All |
|
||||
| **4** | Allow-Office-to-Services | **Allow** | Network \-\> VLAN 20 (Office) | IP Group \-\> QNAP\_Services (192.168.10.100) | Port Group \-\> Web\_Services (443, 80, 81, 2222\) |
|
||||
| **5** | (Default) | Allow | Any | Any | All |
|
||||
|
||||
## **3\. สรุปการตั้งค่า Port Forwarding (สำหรับ Omada ER7206)**
|
||||
|
||||
นี่คือรายการกฎที่คุณต้องสร้างใน Settings \> Transmission \> Port Forwarding:
|
||||
|
||||
| Name | External Port | Internal IP | Internal Port | Protocol |
|
||||
| :---- | :---- | :---- | :---- | :---- |
|
||||
| Allow-NPM-HTTPS | 443 | 192.168.10.100 | 443 | TCP |
|
||||
| Allow-NPM-HTTP | 80 | 192.168.10.100 | 80 | TCP |
|
||||
|
||||
Reference in New Issue
Block a user