Kiến trúc cho Casa Estimate, viết để tái dùng cho JC, Hirsh và các web app sau. Bốn hình, ít chữ.
Anthony · 15 Sep 2026 · nguồn: họp 7/9, 14/9, demo của Sky, API staging của Phillip
Tiền và sự thật ở Odoo. Giá, folio, invoice chỉ tính và ghi trong Odoo. Không ai viết lại pricing lần thứ tư.
Nháp không vào Odoo. 5 đến 10 vòng sửa sống ở tầng biên, có TTL. Odoo chỉ nhận một cú submit do người bấm.
Chốt hợp đồng, không chốt chỗ đặt UI. OpenAPI v1 là giao diện duy nhất. UI ở đâu đổi sau được.
Anthony lead dự án và tầng biên. Phillip làm chủ tầng Odoo. Gặp nhau tại một file OpenAPI.
Fresher không chạm Odoo. TypeScript trên client sinh từ spec, mock server từ spec.
Hình 1Kiến trúc Core & Edge
Ba vùng tin cậy, một ranh giới. BFF là cổng đặc quyền duy nhất; hai đường cấm dừng trước ranh giới thay vì đi xuyên qua. Diver là ngoại lệ có chủ ý: đăng nhập thẳng vào Odoo portal.
Hình 2Một báo giá đi qua hệ thống
Bước 03 chỉ đọc. Bước 04 lặp bao nhiêu lần cũng nằm ở Draft store. Bước 05 là lần ghi duy nhất vào Odoo.
Chốt ở standupBa quyết định
ADR = Architecture Decision Record. Mỗi quyết định là một trang: bối cảnh, quyết định, lý do, hậu quả, ngày, người ký. Đã ký thì không sửa; đổi ý thì viết ADR mới và ghi "thay thế ADR cũ". Nhờ vậy không có chuyện dời quyết định từ họp này sang họp khác.
ADR-001
Odoo chỉ nhận submit
Nháp, hội thoại, kết quả AI, snapshot giá ở Draft store, TTL 90 ngày. Khai tử: câu hỏi một hay hai DB, hack gộp request, nỗi lo AI ghi bậy.
ADR-002
Hợp đồng trước, host sau
OpenAPI v1 đóng băng. MVP giữ trang Evane đã UAT, thay calc() bằng compute sau flag. Dive Passport dùng Odoo portal. Khai tử: tranh luận Odoo website hay standalone.
ADR-003
Biên = TypeScript + Postgres RLS
Vercel, client sinh từ spec, Supabase project mới dưới TechNext, RLS đóng từ đầu. Browser chỉ nói với BFF; BFF giữ key Odoo theo vai. Khai tử: key trong trang tĩnh, admin/admin, n8n.
Số nào lên hóa đơn thì đến từ Odoo. Chưa lên hóa đơn thì là nháp, không vào Odoo.
Dữ liệu
Ở đâu
Sống bao lâu
Rate card, promo 5+1, điều khoản cọc
Odoo product + engine
vĩnh viễn
Folio, quotation, sale order, invoice
Odoo, chỉ qua submit
vĩnh viễn
Scenario nháp, các vòng sửa, snapshot giá
Draft store (Edge)
90 ngày
Tin nhắn gốc, kết quả trích xuất
Draft store, cột riêng
30 ngày, che PII khi làm eval
Hồ sơ diver
Odoo portal (Dive Passport)
theo chính sách Casa
Hình 3Vì sao hai cuộc họp chưa chốt được
Sky tự gọi mình là "half-broken solutions architect". Mọi thứ khác là hệ quả.
Hình 4Ai lead, ai support
Anthony không quyết bên trong Odoo, Phillip không quyết stack bên ngoài, nhưng cả hai đều có tiếng nói về sản phẩm, latency và security; bất đồng thì Sky phân xử. ADR (Architecture Decision Record) là một trang ghi quyết định, lý do, hậu quả, ngày và người ký; không sửa ADR cũ, chỉ viết ADR mới thay thế.
Gửi PhillipSáu việc cho API v1
Khai báo securitySchemes: API key theo vai. Spec hiện nói về 401 nhưng không nói xác thực bằng gì.
rates_version trong response compute, để snapshot chứng minh được giá cũ.
Idempotency-Key cho submit. Thay cho hack "một khách một request mở", vốn gộp hai đoàn của cùng agency.
Guest và diver trong submit, kèm external_ref mỗi guest và mỗi line.
GET /v1/booking/{folio_id} trả draft, sent, paid.
Rate limit ở tầng biên. compute ẩn danh đang mở, mỗi request chiếm một worker Odoo.
Ba bản giá đang lệch
File Sky (₱)
Odoo staging (₱)
Boat dive, 1 diver / ngày
4.500
10.000
hơn gấp đôi
Boat dive, 4+ diver, mỗi người
2.900
3.600
24%
Deluxe, 3–4 pax / đêm
14.500
16.400
13%
Van khứ hồi sân bay
14.000
13.000
ngược chiều
Full board / người / ngày
1.500
1.500
khớp
Odoo thắng, sau khi Eloa xác nhận. Differential test của pod Contract sẽ lộ hết các dòng còn lại.
Kế hoạchHai tuần đầu
Tuần 1 · chốt và đo
Ký ba ADR ở standup. Ghi file.
Jett viết trang capability một mặt giấy.
Gửi Phillip sáu việc, thống nhất ngày freeze v1.
Differential test + mock server. Supabase mới, RLS đóng.
Eloa xác nhận rate card, cho 30 tin nhắn thật đã che tên.
Tuần 2 · nối và cho Evane xem
BFF trên Vercel preview gọi compute staging.
Trang estimator có flag "tính từ Odoo", hai số cạnh nhau.
Extractor xuất Trip đúng schema, đổ vào form.
Demo 20 phút với Evane.
Báo p50 / p95 thật của compute. Hết sợ theo số của Hirsh.
Minh bạchĐã và chưa kiểm chứng
Đã chạy thật:rates và compute ẩn danh trả 200, role guest, override giá bị bỏ qua đúng spec. Không gọi submit vì nó tạo folio thật.
Gần chắc: FastAPI chạy trong worker Odoo, không phải container riêng (module OCA fastapi, header Server: Odoo.sh).
Chưa biết: xác thực staff và agent, hiệu năng Odoo của chính Casa, và Phillip có chấp nhận UI ngoài Odoo cho MVP không. Điểm cuối là Sky quyết, ghi thành ADR.