﻿# Module Map & Directory Structure: ai_rekogition_smart

> **Date Reference:** 2026-08-31  
> **Commit Hash:** `[ต้องยืนยันกับทีม: ไม่พบ .git history ในไดเรกทอรีโปรเจกต์ (ไดเรกทอรี .git ว่างเปล่า) / uncommitted]`

---

## 1. แผนผังโมดูลและคลาสหลัก (Module & Class Diagram)

```mermaid
classDiagram
    direction TB

    class AwsFactory {
        +s3(array config) S3Client
        +rekognition(array config) RekognitionClient
    }

    class Config {
        +load(string root) array
        -requireValue(array config, string key) void
    }

    class Database {
        +connect(array config) PDO
    }

    class UploadValidator {
        -int maxBytes
        +validate(array file) array
        +cleanup(array file) void
        -isHeic(string mime, string ext) bool
        -convertHeicToJpeg(string src) string
    }

    class ThumbnailService {
        -int maxWidth = 720
        -int maxHeight = 720
        -int quality = 82
        +create(string src, string mime) array
        +cleanup(array thumbnail) void
    }

    class ImageStorage {
        -S3Client s3
        -string bucket
        +putUploadedFile(tmp, name, mime, eventId) string
        +putAtmosphereFile(tmp, name, mime, eventId) string
        +putThumbnailFile(tmp, eventId) string
        +putProfileReferenceFile(tmp, name, mime, customerId) string
        +presignedUrl(key, ttl, downloadName) string
        +deleteObject(key) void
    }

    class RekognitionFaceService {
        -RekognitionClient rekognition
        -string collectionId
        +detectFaceCountInS3Image(bucket, key) int
        +indexS3Image(bucket, key, externalId) array
        +searchByUploadedImage(tmpPath, threshold, maxResults) array
        +deleteFaces(array faceIds) array
    }

    class FaceRepository {
        -PDO pdo
        +createEvent(eventName) int
        +findEvents() array
        +createImage(data) int
        +createAtmosphereImage(data) int
        +createFace(imageId, faceId, extId, conf, bbox) void
        +findImagesByFaceIds(array faceIds) array
        +findImagesForEvent(eventId, limit, offset) array
        +findAtmosphereImagesForEvent(eventId, limit, offset) array
    }

    class CustomerProfileRepository {
        -PDO pdo
        +createProfile(array data) int
        +updateProfile(int customerId, array data) void
        +findProfilesByReferenceFaceIds(array faceIds, status) array
        +findReferenceFacesForProfile(customerId) array
        +findKeyInsightsForProfile(customerId) array
        +saveBusinessCard(customerId, side, ...) void
    }

    class SearchAccessRepository {
        -PDO pdo
        +createOtp(phone, code, ref, ttl, ip, ua) int
        +latestSentOtp(phone) array
        +markOtpVerified(id) void
        +markOtpFailed(id) void
        +logAccess(eventType, phone, otpId, ip, ua, details) void
    }

    class SmsOtpService {
        -ClientInterface http
        -bool enabled
        +send(phone, code, ref) void
    }

    class SelfieSearchService {
        -FaceRepository repository
        -CustomerProfileRepository profiles
        -ImageStorage storage
        -RekognitionFaceService rekognition
        -RekognitionFaceService profileRekognition
        +search(uploadedFile, includeProfileSearch) array
        +searchCustomerProfiles(uploadedFile) array
        +atmospherePageForEvent(eventId, page) array
    }

    class SearchResultsRenderer {
        +renderPanel(result, hasSearched, error) string
        +renderAtmosphereContent(atmosphere) string
    }

    class SearchDownloadTokens {
        +create(imageId, ttl, imageType) string
        +verify(imageId, token, imageType) bool
    }

    class ProfileAuth {
        +startSession(root) void
        +isAuthenticated() bool
        +attempt(username, password) bool
        +logout() void
    }

    SelfieSearchService --> FaceRepository
    SelfieSearchService --> CustomerProfileRepository
    SelfieSearchService --> ImageStorage
    SelfieSearchService --> RekognitionFaceService
```

---

## 2. รายละเอียดโฟลเดอร์และหน้าที่ของแต่ละโมดูล (Directory Roles)

### 2.1 `src/` (Core Application Layer)
| ไฟล์ / คลาส | บทบาทหน้าที่ |
|---|---|
| [bootstrap.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/bootstrap.php) | Service Container / Initializer เชื่อมโยง Dependency Injection ทั้งหมด |
| [Config.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/Config.php) | ตัวโหลดค่าคอนฟิกจาก `config.php` และตรวจสอบ Required Keys |
| [Database.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/Database.php) | Factory สร้างการเชื่อมต่อ PDO MySQL |
| [AwsFactory.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/AwsFactory.php) | Factory สร้างอินสแตนซ์ AWS `S3Client` และ `RekognitionClient` |
| [UploadValidator.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/UploadValidator.php) | ตรวจสอบขนาดไฟล์, MIME type, และแปลงไฟล์ HEIC/HEIF เป็น JPEG ผ่าน Imagick/CLI |
| [ThumbnailService.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/ThumbnailService.php) | สร้างภาพย่อ (Thumbnails) ขนาด 720px เพื่อแสดงผล Gallery อย่างรวดเร็ว |
| [ImageStorage.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/ImageStorage.php) | จัดการอัปโหลดไฟล์ลง AWS S3 และสร้าง Presigned URL สำหรับดู/ดาวน์โหลด |
| [RekognitionFaceService.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/RekognitionFaceService.php) | ห่อหุ้มคำสั่ง AWS Rekognition (`DetectFaces`, `IndexFaces`, `SearchFacesByImage`) |
| [FaceRepository.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/FaceRepository.php) | Data Access Object จัดการ Event, Images, Faces, และ Atmosphere Images ใน MySQL |
| [CustomerProfileRepository.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/CustomerProfileRepository.php) | Data Access Object จัดการโปรไฟล์ลูกค้า VIP, Key Insights, นามบัตร, และ Reference Faces |
| [SearchAccessRepository.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/SearchAccessRepository.php) | จัดการบันทึกข้อมูล OTP และ Access Logs ลง MySQL |
| [SmsOtpService.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/SmsOtpService.php) | ส่งข้อความ SMS OTP ผ่าน ThaiBulkSMS HTTP API |
| [SelfieSearchService.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/SelfieSearchService.php) | รวมตรรกะการประมวลผลค้นหาภาพเซลฟี่, แมปผลลัพธ์กับ Event และ VIP Profile |
| [SearchResultsRenderer.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/SearchResultsRenderer.php) | สร้าง HTML Snippets สำหรับ Gallery และ Profile Cards |
| [SearchDownloadTokens.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/SearchDownloadTokens.php) | จัดการสร้างและตรวจสอบ Token ชั่วคราวสำหรับการดาวน์โหลดรูปภาพ |
| [ProfileAuth.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/src/ProfileAuth.php) | จัดการ Session และการล็อกอินเข้าสู่ระบบ VIP Profile |

---

### 2.2 `public/` (Web Entrypoints & Endpoints)
| ไฟล์ | ประเภท | บทบาทหน้าที่ |
|---|---|---|
| [index.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/index.php) | Page | หน้าแรก แนะนำโฟลว์และเมนูนำทางหลัก |
| [events.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/events.php) | Page | จัดการกิจกรรม (สร้าง/แก้ไข Event) และดูรายการภาพใน Event |
| [upload-graphic.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/upload-graphic.php) | Page + AJAX | หน้าจออัปโหลดรูปภาพกิจกรรมแบบ Batch พร้อมสั่ง Index ใบหน้าเข้า AWS |
| [upload-atmosphere.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/upload-atmosphere.php) | Page + AJAX | หน้าจออัปโหลดรูปภาพบรรยากาศทั่วไป (ไม่ Index ใบหน้า) |
| [search-selfie.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/search-selfie.php) | Page + AJAX | หน้าค้นหารูปถ่ายด้วยภาพเซลฟี่ พร้อมระบบยืนยันตัวตนด้วย SMS OTP |
| [search-selfie-none-auth.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/search-selfie-none-auth.php) | Page + AJAX | หน้าค้นหารูปถ่ายด้วยภาพเซลฟี่แบบรวดเร็ว (ไม่ต้องใช้ OTP) |
| [api-search-selfie.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/api-search-selfie.php) | JSON API | Endpoint รับภาพเซลฟี่ ตรวจสอบ OTP Session แล้วค้นหาภาพ |
| [api-search-selfie-none-auth.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/api-search-selfie-none-auth.php) | JSON API | Endpoint รับภาพเซลฟี่สำหรับค้นหาแบบ Non-Auth |
| [api-search-atmosphere.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/api-search-atmosphere.php) | JSON API | Endpoint โหลดรายการภาพบรรยากาศเพิ่มเติมแบบแบ่งหน้า (Pagination) |
| [api-download-url.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/api-download-url.php) | JSON API | Endpoint ขอ Presigned S3 Download URL โดยตรวจสอบ Download Token |
| [create-collection.php](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/public/create-collection.php) | Admin Tool | หน้าสร้าง Rekognition Collection ครั้งแรก (ป้องกันด้วย `admin.setup_token`) |

---

### 2.3 `database/` (Schema & Migrations)
- [schema.sql](file:///d:/XAMPP/htdocs/smart/ai_rekogition_smart/database/schema.sql) — DDL สร้างตารางหลักทั้งหมด 9 ตาราง
- ไฟล์ Migration 28 ไฟล์ — ประวัติการปรับโครงสร้างตารางตามลำดับการพัฒนา
