diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..cd80c8d86 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,51 @@ +# Speckle Server - Business Logic & Architecture + +Đây là tài liệu tập trung vào Business Logic của toàn bộ giải pháp **Speckle Server**, dùng để tái thiết kế, chuyển đổi nền tảng hoặc để onboarding thành viên mới một cách nhanh nhất. + +## 1. Quick Info +Speckle là một "Data Hub" mã nguồn mở dành cho ngành AEC (Architecture, Engineering, Construction). Speckle không lưu trữ file tĩnh mà **băm nhỏ (decompose) các model 3D thành dữ liệu Object/JSON**. + +- **Tech Stack hiện tại**: + - Backend: Node.js (TypeScript), Express, Apollo GraphQL. + - Frontend: Vue 3, Nuxt 3 (SSR). + - Khác: Three.js (Viewer), Postgres (DB), Redis (Cache/PubSub), Minio/S3 (Blob storage). + +## 2. Các thực thể cốt lõi (Core Entities) +Bạn cần hiểu các thuật ngữ sau vì chúng là xương sống của business: + +| Thực thể | Mô tả | +| --- | --- | +| **User** | Người dùng hệ thống. Có Role (ServerAdmin, ServerUser). | +| **Stream (Project)** | Tương tự như một kho chứa (Repository) lưu trữ model. | +| **Branch (Model)** | Một nhánh của Stream, đại diện cho những phiên bản của một thiết kế hoặc một category (ví dụ: `architectural`, `structural`). | +| **Commit (Version)** | Một snapshot dữ liệu được đẩy lên Branch. Chứa metadata và tham chiếu tới một thẻ `objectId` gốc (root object). | +| **Object** | Đơn vị dữ liệu nhỏ nhất. Khi lấy dữ liệu 3D, Client/Plugin phân tách các mặt cắt, vật liệu... thành các Object nhỏ và gửi lên server. Có tính Immutable và được băm (hash) thành ID. Chứa các tham chiếu (references) tới các mảng Object khác. | +| **Workspace** | (Tính năng Enterprise) Không gian làm việc quản lý nhiều Project và Billing. | + +## 3. Kiến trúc luồng hệ thống +1. **Desktop Client / Web App** sử dụng REST API (hoặc SDK) kết nối với Server với token. +2. Dữ liệu khi Push được gọi là **Commit**, dữ liệu payload được chia thành nhiều Objects và push đồng thời lên backend. +3. Backend GraphQL xử lý Metadata, còn dữ liệu thô (Object payload) được gửi lên Server theo lô (batch) và nhét vào **Blob storage (S3)** hoặc lưu trực tiếp vào cơ sở dữ liệu `objects`. +4. **Redis** đóng vai trò Pub/Sub để push event qua WebSockets/GraphQL Subscriptions tới các client đang online (Realtime Updates). +5. Khi có bản lưu (Commit) mới, hệ thống **Microservices** chạy ngầm: + - **Preview Service:** Bắt event từ Redis, kéo object xuống, chuyển tải vào engine web-standard, chụp lại screenshot rồi lưu thành ảnh cho frontend. + - **Webhook Service:** Bắn thông tin tới các tool thứ 3 của người dùng. + - **Automate:** Trigger các function tự động hóa của user trên server. + +## 4. Documentation Structure +Chi tiết luồng hoạt động từng hệ thống con được ghi trong các thư mục sau: + +- [Backend API & DB (Node.js)](./server/README.md) +- [Frontend (Vue/Nuxt 3)](./frontend/README.md) +- [Microservices (File import, Webhook, Preview)](./services/README.md) +- [Core 3D Engine (Viewer)](./viewer/README.md) + +## 5. Portability Note (Viết lại ngôn ngữ) +**Tính tái định tuyến khả thi (High Portability)**: +- Logic backend tương đối stateless nhưng phụ thuộc nặng vào **GraphQL Federation/Apollo** và Postgres DB Schema. +- Có thể rewrite qua Go / C# / Rust nhưng phải đảm bảo: + 1. Kế thừa chuẩn xác thuật toán Hash Object của Speckle (để objectId luôn khớp). + 2. Maintain được cấu trúc Database Schema (hoặc tự chuyển đổi Data Mapper hiệu quả). + 3. Quản lý Pub/Sub cực tốt để giữ kết nối Realtime. + +> Xem thư mục con để rõ chi tiết logic từng module. diff --git a/docs/audit_report.md b/docs/audit_report.md new file mode 100644 index 000000000..211959a9b --- /dev/null +++ b/docs/audit_report.md @@ -0,0 +1,28 @@ +# Cố Vấn Tái Cấu Trúc Bậc Cáo (Speckle Architecture Audit Report) + +Tài liệu này là kết quả Audit kỹ thuật của hệ thống Speckle, do các AI Agent phân tích và chắt lọc dựa trên mã nguồn. Nó phục vụ cho bất cứ Dev Team nào muốn thiết kế lại, clone dự án, hoặc porting (chuyển ngôn ngữ) hoàn toàn cho một startup BIM mới. + +## 1. Ưu điểm nổi bật (Strengths) đoạt giải kiến trúc +- **Khái niệm Data Hashing Graph**: Việc biến mô hình 3D (vertices, faces) thành các Node JSON có SHA256 ID là cốt lõi lớn nhất. Nếu 1 bức tường 3 triệu mặt cắt giống hệt nhau ở cả 2 commit, hash id của bức tường sẽ ko đổi, backend không lưu gấp đôi -> **Data deduplication thần thánh**. +- **Viewer quá mạnh mẽ**: Kỹ thuật Instanced Mesh (Batching) của `@speckle/viewer` đủ sức nhúng tòa nhà siêu to khổng lồ (> 1 triệu geometries) mượt mà lên WebGL. +- **Decoupled Architecture**: Việc tách vụn Webhooks, Preview, IFC Conversion thành các Worker Jobs (Microservices) bảo vệ GraphQL Server luôn có phản hồi nhanh ở mức 20ms - 50ms. + +## 2. Rủi ro / Điểm yếu hiện tại (Bottlenecks) +- **Node.js Memory Bound**: Mặc định Node giới hạn bộ nhớ V8 tầm 1.5GB - 4GB. Khi client đẩy lên 1 commit khổng lồ dính đến hàng trăm nghìn objects, tốc độ nhét object vào PostgreSQL nếu không có Batching rất dễ ngốn RAM + Thắt cổ chai. Việc team Speckle phải viết riêng luồng busboy-stream API để upload cho thấy Node.js backend đang phải gồng mình. +- **Dính chặt vào Apollo & CodeGen**: Frontend xài GraphQL bị khóa chặt với cấu trúc dữ liệu Backend. Việc đổi database từ Postgres sang MongoDB không sao (nếu backend vẫn giữ GQL schema), nhưng đổi Backend bỏ GraphQL là đập luôn toàn bộ Frontend. + +## 3. Bản Kế Hoạch Tái Cấu Trúc (How to Re-write/Port this Project) +Giả định bạn muốn viết lại Speckle bằng `Golang + ReactJS + Postgres`. + +### A. Core Backend API +- **Ngôn ngữ**: Rất khuyến khích dùng Go (Golang) hoặc Rust thay cho Node.js hiện tại để tăng thông lượng network throughput và memory safety gấp 10 lần. +- **Tiêu chuẩn Hash**: Bắt buộc phải sao chép chính xác hàm Hash SHA256 các node property của Speckle API (Cần đảo ngược/dịch mã code C# Speckle SDK) để tương thích ngược với các Plugin Revit/Rhino đã cài ở máy người dùng. +- **Database**: Vẫn phải là PostgreSQL (Hoặc CockroachDB). Dữ liệu là đồ thị (Graph), nhưng Speckle không dùng Neo4j mà dùng Postgres relation - Bạn phải giữ đúng kiến trúc bảng `objects`, `commits`, `branches`, và `streams`. + +### B. Frontend +- Dẹp bỏ Nuxt 3 (Nếu team không thạo Vue). Xài Next.js 14+ (App Router). +- Phần `@speckle/viewer` tuyệt đối không nên viết lại (vì đó là công sức tối ưu toán học 5 năm trời). Gói nó thành một React Component `` qua `useRef` gắp thả cái canvas của Three.js thẳng vào DOM Node. +- Đọc stream API giải nén dữ liệu `@speckle/objectloader` giữ nguyên vì là pure TypeScript. + +### C. Giao tiếp Thời gian thực (Realtime) +- Bỏ GraphQL Subscriptions nếu thấy nặng. Chuyển qua xài Server-Sent Events (SSE) hoặc WebSocket (Gorilla Mux / Socket.io) kết nối cùng Redis Pub/Sub. Cơ chế cực kỳ đơn giản: *"Có commit mới vào Stream X" -> Emit JSON -> Client tải lại.* diff --git a/docs/frontend/README.md b/docs/frontend/README.md new file mode 100644 index 000000000..6f38fec48 --- /dev/null +++ b/docs/frontend/README.md @@ -0,0 +1,26 @@ +# Frontend Architecture (Speckle Web) + +Speckle Frontend (tại `packages/frontend-2`) là ứng dụng web tương tác chính để người dùng có thể quản lý, cấp quyền và xem các mô hình 3D trên nền web. + +## 1. Công nghệ sử dụng +- **Framework:** Vue 3 + Nuxt 3 (SSR + Composition API). Hỗ trợ Server-Side Rendering giúp cải thiện SEO (ví dụ các model public có thể crawl được), đồng thời cải thiện First Contentful Paint. +- **State & Data Fetching:** `@vue/apollo-composable`, `@apollo/client`. Gần như **không có store cục bộ/Redux/Pinia** phức tạp. Speckle dùng ngay bộ [Apollo InMemoryCache] làm Single Source of Truth cho dữ liệu, kết hợp với Vue Composables để cung cấp reactivity. +- **UI & Styling:** Tailwind CSS v3 (`@tailwindcss/...`), Headless UI (`@headlessui/vue`) cho accessible components, các components tái sử dụng nằm ở `packages/ui-components`. +- **Editor:** Tiptap cho trình soạn thảo comment (Rich text format). +- **GraphQL Codegen:** Dùng `@graphql-codegen` để tự động sinh Data Type TypeScript từ file gql nhằm đồng bộ hoá Type từ Server -> Frontend. + +## 2. Kiến trúc Data Flow +1. **SSR Fetching**: Khi gọi các URL chứa Model ID cụ thể (ví dụ `/projects/abc/models/xyz`), Nuxt Server sẽ gọi GraphQL về backend để lấy cấu trúc dữ liệu Metadata của file 3D. +2. **Viewer Mount (Client Only)**: Việc xử lý Load 3D WebGL chỉ diễn ra ở phía Browser. Module `@speckle/viewer` được mount vào và khởi tạo `Streaming Object Loader`. +3. **Lazy Loading 3D Objects**: Thay vì fetch về 1 cục khổng lồ, Apollo/Viewer sẽ stream objects dạng mảng (arrays of nested buffers) qua REST API `/objects/`. + +## 3. Quản lý Component Design +- Tailwind Config của `frontend-2` kế thừa từ `@speckle/tailwind-theme` (Monorepo Workspace). +- Bạn sẽ ít thấy `