Files
tailscale-custom/.agent/workflows/prepair-ifc-workflow.md
T
huanld 2fb067ecbf
checklocks / checklocks (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
natlab-integrationtest / natlab-integrationtest (push) Has been cancelled
CI / gomod-cache (push) Has been cancelled
CI / race-root-integration (1/4) (push) Has been cancelled
CI / race-root-integration (2/4) (push) Has been cancelled
CI / race-root-integration (3/4) (push) Has been cancelled
CI / race-root-integration (4/4) (push) Has been cancelled
CI / test (-race, amd64, 1/3) (push) Has been cancelled
CI / test (-race, amd64, 2/3) (push) Has been cancelled
CI / test (-race, amd64, 3/3) (push) Has been cancelled
CI / test (386) (push) Has been cancelled
CI / test (amd64) (push) Has been cancelled
CI / Windows (benchmarks) (push) Has been cancelled
CI / Windows (1/2) (push) Has been cancelled
CI / Windows (2/2) (push) Has been cancelled
CI / macos (push) Has been cancelled
CI / privileged (push) Has been cancelled
CI / vm (push) Has been cancelled
CI / cross (386, linux) (push) Has been cancelled
CI / cross (amd64, darwin) (push) Has been cancelled
CI / cross (amd64, freebsd) (push) Has been cancelled
CI / cross (amd64, openbsd) (push) Has been cancelled
CI / cross (amd64, windows) (push) Has been cancelled
CI / cross (arm, 5, linux) (push) Has been cancelled
CI / cross (arm, 7, linux) (push) Has been cancelled
CI / cross (arm64, darwin) (push) Has been cancelled
CI / cross (arm64, linux) (push) Has been cancelled
CI / cross (arm64, windows) (push) Has been cancelled
CI / cross (loong64, linux) (push) Has been cancelled
CI / ios (push) Has been cancelled
CI / crossmin (amd64, illumos) (push) Has been cancelled
CI / crossmin (amd64, plan9) (push) Has been cancelled
CI / crossmin (amd64, solaris) (push) Has been cancelled
CI / crossmin (ppc64, aix) (push) Has been cancelled
CI / android (push) Has been cancelled
CI / wasm (push) Has been cancelled
CI / tailscale_go (push) Has been cancelled
CI / fuzz (push) Has been cancelled
CI / depaware (push) Has been cancelled
CI / go_generate (push) Has been cancelled
CI / make_tidy (push) Has been cancelled
CI / licenses (push) Has been cancelled
CI / staticcheck (macOS) (push) Has been cancelled
CI / staticcheck (Linux) (push) Has been cancelled
CI / staticcheck (Windows) (push) Has been cancelled
CI / staticcheck (Portable (1/4)) (push) Has been cancelled
CI / staticcheck (Portable (2/4)) (push) Has been cancelled
CI / staticcheck (Portable (3/4)) (push) Has been cancelled
CI / staticcheck (Portable (4/4)) (push) Has been cancelled
CI / notify_slack (push) Has been cancelled
CI / merge_blocker (push) Has been cancelled
CI / check_mergeability_strict (push) Has been cancelled
CI / check_mergeability (push) Has been cancelled
Dockerfile build / deploy (push) Has been cancelled
test installer.sh / test (curl, alpine:3.21) (push) Has been cancelled
test installer.sh / test (curl, alpine:edge) (push) Has been cancelled
test installer.sh / test (curl, alpine:latest) (push) Has been cancelled
test installer.sh / test (curl, amazonlinux:latest) (push) Has been cancelled
test installer.sh / test (curl, archlinux:latest) (push) Has been cancelled
test installer.sh / test (curl, debian:oldstable-slim) (push) Has been cancelled
test installer.sh / test (curl, debian:sid-slim) (push) Has been cancelled
test installer.sh / test (curl, debian:stable-slim, 1.80.0) (push) Has been cancelled
test installer.sh / test (curl, debian:testing-slim) (push) Has been cancelled
test installer.sh / test (curl, elementary/docker:stable) (push) Has been cancelled
test installer.sh / test (curl, elementary/docker:unstable) (push) Has been cancelled
test installer.sh / test (curl, fedora:latest, 1.80.0) (push) Has been cancelled
test installer.sh / test (curl, kalilinux/kali-dev) (push) Has been cancelled
test installer.sh / test (curl, kalilinux/kali-rolling) (push) Has been cancelled
test installer.sh / test (curl, opensuse/leap:latest) (push) Has been cancelled
test installer.sh / test (curl, opensuse/tumbleweed:latest) (push) Has been cancelled
test installer.sh / test (curl, oraclelinux:8) (push) Has been cancelled
test installer.sh / test (curl, oraclelinux:9) (push) Has been cancelled
test installer.sh / test (curl, parrotsec/core:latest) (push) Has been cancelled
test installer.sh / test (curl, rockylinux:8.7) (push) Has been cancelled
test installer.sh / test (curl, rockylinux:9) (push) Has been cancelled
test installer.sh / test (curl, ubuntu:20.04) (push) Has been cancelled
test installer.sh / test (curl, ubuntu:22.04) (push) Has been cancelled
test installer.sh / test (curl, ubuntu:24.04, 1.80.0) (push) Has been cancelled
test installer.sh / test (wget, debian:oldstable-slim) (push) Has been cancelled
test installer.sh / test (wget, debian:sid-slim) (push) Has been cancelled
update-flake / update-flake (push) Has been cancelled
tailscale.com/cmd/vet / vet (push) Has been cancelled
test installer.sh / notify-slack (push) Has been cancelled
feat: security hardening, production roadmap, admin panel v1
Client security fixes (cmd/tailscale-tray/main.go):
- SSRF protection in Add Server dialog (validateControlURL): reject
  private/loopback/link-local/cloud-metadata IPs via DNS resolution
- RCE gate on AuthURL/BrowseToURL exec paths (validateAuthURL)
- Sanitized URL logging (sanitizeURLForLog drops query auth tokens)
- Error handling on exec.Command with user-facing showError()

Admin panel security (web-admin):
- Bcrypt password hashing (replaces SHA256)
- Rate limiting: 5 failed logins → 15-min lockout
- Session + login attempt cleanup goroutine (hourly)
- url.QueryEscape / encodeURIComponent for all API params
- Fail-hard startup when no TLS and non-loopback bind
- ADMIN_PASSWORD required (no default), password min 12 chars
- Username regex whitelist

Installer hardening (Setup.wxs):
- util:PermissionEx restricts SCM access: only Administrators +
  SYSTEM can start/stop/reconfigure service. Authenticated Users
  limited to QueryStatus/QueryConfig/Interrogate
- Vital="yes" on ServiceInstall

Docs & roadmap:
- PRODUCTION_ROADMAP.md: 5-milestone plan (security + features +
  distribution + ops) with granular tasks, effort, done-when
- CLIENT_SECURITY_AUDIT.md, SECURITY_FIXES.md, DEPLOYMENT.md
- AI assistant rules (.cursorrules, .antigravityrules, etc.)

Build & distribution:
- build-msi.ps1, deploy-and-sign.ps1, sign-release.ps1
- redeploy.ps1, tray-deploy.ps1, test-msi.ps1
- installer/msi/ alternative WXS setup
- Restored .github/workflows/ removed in mirror cleanup

.gitignore hardened: *.pfx, *.p12, *.key, *.pem, .env*
2026-04-22 15:18:11 +07:00

4.7 KiB

description
description
Workflow for preparing IFC models, standardizing filenames, and syncing with APIs & FTP across ATAD software modules

Workflow: Prepare IFC Model Deployment

This workflow standardizes the IFC integration process across ATAD's software modules. It downloads raw IFC files from Autodesk Forge, unifies their syntax/naming conventions, uploads them via the new 3-step API, updates the database URNs, syncs with FTP, and handles dynamic routing.


Mức 0: Xác định Tiền Tố (Prefix)

Khi Agent bắt đầu chạy workflow này để ứng dụng cho một project khác, phải chủ động hỏi người dùng về tiền tố sẽ được áp dụng cho tên file IFC đối với dự án hiện tại (Ví dụ: atad-, ins-, swe-, v.v...). 🚫 TUYỆT ĐỐI KHÔNG fix cứng chữ atad- trong code mẫu. Luôn khai báo động và dùng tiền tố người dùng cung cấp vào tên file đầu ra.

1. Khởi tạo Razor Component

  • Khởi tạo file Component View (thường sẽ là PrepairIFC.razor hoặc PrepareIFC.razor) với route tương ứng cơ chế của project (VD: @page "/prepair-ifc/{unitid}").
  • Bắt buộc gắn thuộc tính cấu hình @attribute [Microsoft.AspNetCore.Authorization.AllowAnonymous] để cho phép việc trigger/webhook trích xuất tự động không cần xác thực User Auth.
  • Xây dựng UI Loading thể hiện các bước Process (Đang Authenticate, Đang Load Forge, Uploading API...).
  • Inject các cấu phần Service: Base DbContext, IHttpClientFactory, Service Forge (IForgeUploadServices), Service FTP (IFTPUploadServices).

2. Tiêu Chuẩn Hóa Tên File IFC (Naming Format)

Sau khi load dữ liệu DB chứa thông số của Model, tiến hành sinh chuỗi tên File IFC. Tên File tải từ Forge về có thể sai lệch hoặc không tuân thủ mẫu mới nhất. Luôn thực thi cấu trúc: <Prefix><ProjectCode>_<AreaCode>_<UnitCode>_<Revision>.ifc

  • $Prefix: Truyền biến từ Mức 0.
  • Quy tắc Revision: Khi lấy code version từ DB (VD lấy IfcModelVersion), kiểm tra định dạng chữ R. Nếu format rỗng hoặc chỉ có số 1, hệ thống bắt buộc tự convert thành chuẩn 2 char R01:
// Logic mẫu cho AI Agent áp dụng:
string rev = dbUnit.IfcModelVersion ?? "00";
if (!rev.StartsWith("R", StringComparison.OrdinalIgnoreCase)) {
    rev = int.TryParse(rev, out int rInt) ? $"R{rInt:D2}" : $"R{rev}";
}
string desiredFilename = $"{prefix}{dbProject.Code}_{dbArea.Code}_{dbUnit.Code}_{rev}.ifc";

3. Tích hợp Autodesk Forge

  • Gọi hàm Authenticate của Cấu phần Hệ Thống (Ví dụ ForgeUploadServices.Forge_AuthenticateV2) để lấy access token.
  • Khởi tạo ObjectsApi gọi GetObjectsAsync(bucketKey) để trích xuất ObjectKey cho thư mục Bucket của Model.
  • Bỏ qua API SDK nếu Download Stream gặp hạn chế (Memory Stream Leak), hãy trực tiếp sử dụng lệnh HttpClient.GetAsync() download File thông qua Url tĩnh của Forge (https://developer.api.autodesk.com/oss/v2/buckets/...) cùng header Bearer để ghi dữ liệu về một Temp Caching Directiory trong Thư mục Uploads.

4. Luồng API Upload IFC V2

  • Truy xuất thông số từ bảng Cấu hình của dự án (Thường là GLBSystems với các cột: ModelApiDomain, ModelUserId, ModelProjectId, ModelFolderId).
  • Đẩy File Temp ở Bước 3 qua Multipart Data vào Endpoints API /api/files/upload. Đọc JSON trả về lấy itemId. (Lưu ý: Status Conflict vẫn cần bóc tách đọc ItemID bình thường).
  • Gọi tiếp sang API Endpoint Lấy Urn (/api/Files/urn?itemId=...). Lấy ra giá trị objectUrn của File 3D.
  • Kết nối DbContext, Gọi hàm Raw SQL Update Urn và cờ View(IsModelReadyView = 1) gán qua cho Table chứa cấu trúc lưu trữ 3D tương ứng.

5. FTP Server Synchronization (Hệ thống File Server)

  • Build định dạng đường dẫn lưu trên FTP: ${ProjectCode}/${AreaCode}/${UnitCode}/All/{desiredFilename}.
  • Gọi UploadFile thao tác đẩy Cache File lên FTP để lưu trữ.
  • Nếu trả về FtpStatus Success, cập nhật trực tiếp biến Remote Path đó vào cột lưu trữ vật lý của DB.

6. Cleanup & Bypass Routing

  • Xóa Temp Caching File bằng lệnh File.Delete() an toàn để giải phóng cấu trúc vùng nhớ và không gian ổ đĩa.
  • Gọi NavigationManager.NavigateTo bay thẳng qua URL hiển thị mô hình (/eview/{unit_id}). Có thể chèn hàm trễ Task.Delay(2000) để hiển thị Message báo kết quả Upload xong trước khi đổi trang.