Suốt 199 phần, ta đã xây một module quan_ca_phe chạy được: model, view, controller, OWL, test, tối ưu. Nhưng "chạy được" và "chuyên nghiệp" là hai chuyện. Một module chuyên nghiệp phải có cấu trúc chuẩn, manifest đầy đủ, code sạch theo quy ước — để người khác đọc được, đóng góp được, tin dùng được. Chuẩn đó do OCA (Odoo Community Association) đặt ra. Bài cuối cùng này khép lại sê-ri bằng cách đưa module về chuẩn OCA và kiểm chất lượng.

Cấu trúc thư mục và manifest chuẩn

OCA quy định mỗi loại file nằm ở một thư mục riêng, và __manifest__.py phải khai đủ metadata:

Ảnh chụp mã cây thư mục chuẩn OCA và manifest nền tối. Phần trên cấu trúc module quan_ca_phe gồm models logic nghiệp vụ py, views giao diện XML list form kanban, security ir model access csv và record rules, data dữ liệu mẫu sequence cron, static JS SCSS ảnh OWL asset bundle, tests i18n migrations controllers, và các file manifest py README rst LICENSE. Phần dưới manifest py các khoá bắt buộc gồm name Quản lý quán cà phê, version 19.0.1.0.0 theo định dạng odoo major minor patch build, license LGPL-3 bắt buộc AGPL-3 hoặc LGPL-3, author Cà Phê Việt, website coffeecode.vn, category Sales, depends base contacts mail base_automation, data danh sách file, installable True application True

Hình 1: Mỗi thư mục một nhiệm vụ — models/ cho logic, views/ cho XML, security/ cho phân quyền, static/ cho tài nguyên OWL... Manifest phải có version 5 số (19.0.1.0.0 — hai số đầu là phiên bản Odoo), license (bắt buộc — thiếu là pylint-odoo báo lỗi), author, category, depends khai đúng và đủ. README.rst và LICENSE là hai file OCA yêu cầu ở thư mục gốc.

Kiểm chất lượng thật

Chất lượng không tự nhận — phải kiểm. Đây là kết quả thật trên quan_ca_phe:

Ảnh chụp terminal nền tối kiểm chất lượng module quan_ca_phe chạy thật. Lệnh ls quan_ca_phe cấu trúc thật cho manifest py models views security data static. Lệnh find name py wc l cho 13 file Python. Lệnh python3 m py_compile find name py kiểm cú pháp tất cả cho PY_COMPILE_OK màu xanh chú thích 13 trên 13 file biên dịch sạch không lỗi cú pháp. Trong odoo shell MODSTATE installed ver 19.0.1.0.0, MODELS the 4 lichsu 3 uudai 3 chú thích module nạp sạch trong registry. Checklist OCA pylint-odoo tự động kiểm gồm license khai trong manifest LGPL-3, version chuẩn 5 số, model dùng dấu chấm quan the thanh vien, field snake_case, không SQL injection dùng ORM params, XML id có ý nghĩa, security ir model access csv cho mỗi model

Hình 2: Thật. find đếm 13 file Python; python3 -m py_compile toàn bộ → PY_COMPILE_OK, 13/13 biên dịch sạch, không lỗi cú pháp. Trong odoo shell: module installed, version 19.0.1.0.0, các model nạp sạch (4 thẻ, 3 lịch sử, 3 ưu đãi). Bên dưới là checklist mà pylint-odoo tự động kiểm — công cụ chuẩn của OCA để bắt lỗi manifest, SQL injection, thiếu license, sai quy ước đặt tên.

Công cụ giữ chất lượng tự động

Kiểm bằng tay không đủ — OCA dùng công cụ tự động chạy trên mỗi lần commit:

  • pylint-odoo: plugin pylint chuyên cho Odoo, bắt các lỗi đặc thù — manifest thiếu khoá, chuỗi SQL nối tay (nguy cơ injection), thiếu license, XML id trùng, field không có nhãn.
  • pre-commit: chạy một loạt kiểm ngay trước khi commit — black (định dạng code), isort (sắp xếp import), flake8 (lỗi style), pylint. Không đạt thì không commit được.
  • OCA runbot: hạ tầng CI dựng và test module tự động trên nhiều phiên bản Odoo.
# .pre-commit-config.yaml — tối thiểu cho một module OCA
repos:
  - repo: https://github.com/psf/black          # định dạng code
  - repo: https://github.com/PyCQA/isort         # sắp xếp import
  - repo: https://github.com/OCA/pylint-odoo     # kiểm lỗi Odoo

Quy ước đặt tên

Chất lượng còn nằm ở cách đặt tên — người sau đọc code phải hiểu ngay:

  • Model dùng dấu chấm: quan.the.thanh.vien (không phải gạch dưới). Bảng SQL Odoo tự sinh với gạch dưới: quan_the_thanh_vien.
  • Field snake_case: hang_the, diem_tich_luy — không camelCase.
  • XML id có ý nghĩa: view_the_form, action_the_thanh_vien — đọc tên biết là gì, không đặt view1, act2.
  • security/ir.model.access.csv cho MỌI model — thiếu là model không ai truy cập được (hoặc ai cũng truy cập được, tuỳ Odoo).

200 phần — chặng đường đã qua

Đây là phần cuối. Nhìn lại, sê-ri "Odoo 19: Lập trình chuyên sâu" đã đi qua trọn vẹn hành trình của một lập trình viên Odoo:

  • Nền ORM — model, field, quan hệ, env.ref, cache, read_group, ràng buộc, @api.depends.
  • Web & controller — http.route, auth, JSON, CSRF, upload/download, sitemap, SEO, redirect Werkzeug.
  • Giao diện OWL — component, hooks, useRef, error boundary, widget, field, notification, dialog, asset bundle, SCSS, QWeb, snippet, editor plugin.
  • Website & portal — page, menu, portal, chatter, theme, dynamic snippet, ecommerce.
  • Tích hợp — XML-RPC, JSON-RPC, gọi API ngoài bằng requests, webhook ký HMAC.
  • Kiểm thử — TransactionCase, @tagged, assertRecordValues, subTest.
  • Hiệu năng — bẫy N+1, read_group, index và EXPLAIN ANALYZE.
  • Triển khai — workers đa tiến trình, nginx reverse proxy, backup/restore, migration script.
  • Đóng gói — chuẩn OCA, pylint-odoo, chất lượng code.

Mỗi phần đều đo trên hệ thống Odoo 19 thật: chạy odoo shell, curl, EXPLAIN ANALYZE, ps, pg_dump, screenshot giao diện thật — không một con số nào bịa ra.

Ba ý mang về

  1. OCA chuẩn hoá cấu trúc (mỗi loại file một thư mục: models/, views/, security/, static/, tests/...) và manifest (đủ name, version 5 số, license, author, category, depends).
  2. Kiểm chất lượng bằng công cụ tự động: pylint-odoo bắt lỗi đặc thù Odoo, pre-commit (black/isort/flake8/pylint) chặn commit code bẩn — đã xác nhận thật module quan_ca_phe với 13 file py biên dịch sạch, nạp installed trong registry.
  3. Quy ước đặt tên (model dấu chấm, field snake_case, XML id có nghĩa, access CSV cho mọi model) là phần chất lượng con người phải giữ, công cụ không thay được.

Cảm ơn bạn đã đi cùng cả 200 phần. Từ dòng fields.Char đầu tiên tới một module đóng gói chuẩn OCA chạy sau nginx với nhiều worker — đó là trọn vẹn con đường từ người mới thành lập trình viên Odoo vững vàng. Chúc bạn viết nên những module thật, hữu ích, và sạch đẹp. Hẹn gặp lại trong những dự án Odoo của chính bạn.