Giao diện
Chuyển dữ liệu
Products và Requirements được thêm bằng một migration schema mới và một file seed sinh tự động, không sửa bảng cũ nào ngoài hai cột thêm vào applications.
| File | Nội dung |
|---|---|
0005_planes.sql | Schema hai mặt phẳng: sequences, products, product_capabilities, application_urls, features, requirements, questions, ai_runs, ai_suggestions, decisions, decision_links, evidence, releases, release_requirements; ALTER TABLE applications thêm product_id, repository |
0006_planes_seed.sql | Sinh tự động từ scripts/planes.mjs — sản phẩm, năng lực của sản phẩm, gán sản phẩm cho ứng dụng, URL, feature, yêu cầu mẫu |
0007_requirement_depth.sql | acceptance_criteria và requirement_dependencies, cộng bộ đếm acceptance_criteria — cộng thêm, xem mục dưới |
0008_requirement_depth_seed.sql | Sinh tự động từ scripts/planes.mjs — 12 tiêu chí tách từ văn xuôi nghiệm thu và 2 phụ thuộc, toàn INSERT OR IGNORE |
Danh sách DROP TABLE IF EXISTS của 0005 cũng được chèn lên đầu 0001_init.sql và 0003_execution.sql, để một lần dựng lại từ đầu (npm run db:local) xoá bảng con trước bảng cha.
Không gì đang có bị đổi
Brand BRD-nemo12 và BRD-conan-school giữ nguyên như 0002 nạp. Value stream, chặng, quy trình, hoạt động, dữ liệu, công nghệ, sáng kiến, KPI, đánh giá năng lực, người dùng — không đổi id, code, brand_id, trạng thái hay quan hệ. 0004_execution_seed.sql giữ nguyên từng byte. Sáng kiến chỉ được nối sang mặt phẳng mới qua requirements.initiative_id, không có cột mới trên initiatives.
Mười ứng dụng hiện có được UPDATE, không chèn lại: mỗi object trong scripts/execution.mjs thêm hai trường product và repository, seed sinh ra UPDATE applications SET product_id = ?, repository = ? WHERE id = ?.
| Application id | product_id | repository |
|---|---|---|
| APP-website | PRO-conan1 | https://github.com/dac2205/conan1/tree/main/conan1.com |
| APP-cms | PRO-conan1 | '' |
| APP-crm | PRO-conan1 | '' |
| APP-compass | PRO-conan1 | https://github.com/dac2205/conan1/tree/main/compass.conan1.com |
| APP-analytics-platform | PRO-conan1 | '' |
| APP-finance-system | PRO-conan1 | '' |
| APP-community-platform | PRO-nemo12 | '' |
| APP-lms, APP-assessment-tool, APP-scheduling-system | PRO-conan-school | '' |
Ứng dụng nền tảng dùng chung (CMS, CRM, Analytics, Finance) thuộc sản phẩm Conan1 Platform thay vì để NULL, để mọi ứng dụng đều có chủ trong mặt phẳng Products; brand_id của chúng vẫn NULL nên Compass không đổi gì.
Kho ứng dụng thật
Ngoài mười ứng dụng cũ, seed nạp ứng dụng và URL từ kho Cloudflare thật — nhưng chỉ những thứ thuộc Nemo12, Conan School và nền tảng conan1.com. Brand được gán theo hostname: *.nemo12.com → Nemo12, *.conan.school → Conan School, *.conan1.com → brand_id = NULL (nền tảng Conan1, dùng chung).
| Sản phẩm | Ứng dụng (code) | URL |
|---|---|---|
| PRO-nemo12 | nemo12-web Nemo12 Website | nemo12.com, www.nemo12.com |
nemo12-learn Nemo12 Learn | learn.nemo12.com | |
nemo12-coral Coral | coral.nemo12.com | |
nemo12-dolphin Dolphin · nemo12-pearl Pearl · nemo12-marlins Marlins · nemo12-b21 B21 | dolphin / pearl / marlins / b21 .nemo12.com | |
nemo12-ielts Nemo12 IELTS · nemo12-compass Nemo12 Compass | ielts.nemo12.com, compass.nemo12.com | |
nemo12-playbooks Nemo12 Playbooks (docs) · nemo12-docs Nemo12 Docs (docs) | playbooks.nemo12.com, docs.nemo12.com | |
nemo12-admin Nemo12 Admin (admin) · nemo12-api Nemo12 API (api) | admin.nemo12.com, api.nemo12.com | |
| PRO-conan-school | conan-school-web Conan School Website | www.conan.school |
conan-school-docs Conan School Docs (docs) | docs.conan.school | |
conan-school-api Conan School API (api) | api.conan.school | |
conan-tool-plane Conan Tool Plane (MCP) (api) | mcp.conan.school | |
conan-school-tokyo Conan School Tokyo | tokyo.conan.school, com.conan.school | |
| PRO-conan1 | APP-website (có sẵn) | conan1.com |
APP-compass (có sẵn) | compass.conan1.com (production), api.conan1.com (api) | |
docs-conan1 Conan1 Docs (docs) | docs.conan1.com | |
brands-conan1 Conan1 Brand Library (docs) | brands.conan1.com |
Tên và mô tả song ngữ ngắn, đúng sự thật ("Ứng dụng web tại coral.nemo12.com") — seed không bịa mệnh đề sản phẩm. Các hostname của Brand khác (chuyenchon, ielts27, sutucon, octo101, capos, conan.media, duhoc27, inside6) không được nạp, vì Brand của chúng chưa có trong Compass.
Feature và yêu cầu mẫu
Năm feature: FEA-referral-system (Nemo12, nemo12-web, năng lực referral), FEA-evidence-engine (Nemo12, nemo12-coral, learning-evidence), FEA-learner-dashboard (Nemo12, nemo12-learn, learner-support), FEA-learning-evidence và FEA-rubric-marking (Conan School).
Yêu cầu, câu hỏi, quyết định và bằng chứng mẫu được lấy từ chính ví dụ trong tài liệu đề xuất, với id tường minh, và bộ đếm sequences được đặt tiếp sau số lớn nhất đã nạp:
| Id | Nội dung |
|---|---|
REQ-0241 | Phụ huynh có thể mời một gia đình khác — Nemo12 → nemo12-web → Referral System, clarifying |
REQ-0218 | Phụ huynh xem được tiến bộ của người học — Nemo12 → nemo12-learn → Learner Dashboard, ready |
Q-0881 | Phụ huynh có được sửa điểm thành thạo không? — đã quyết định, cùng hai câu hỏi còn mở |
D-0182 | Phụ huynh không được tự sửa điểm thành thạo — vì mức thành thạo phải dựa trên bằng chứng |
REQ-1832 · REQ-1833 · REQ-1834 | Evidence Engine trên Coral: ghi nhận sản phẩm học tập kèm nhãn kết quả, dòng thời gian bằng chứng cho gia đình, cảnh báo thiếu bằng chứng trước khi tuyên bố thành thạo |
EVI-0001 | Mockup Learner dashboard cho REQ-0218 |
Sau seed: requirements = 1834, questions = 883, decisions = 182, evidence = 1, releases = 0. Bản ghi tạo tiếp theo nhận REQ-1835, Q-0884, D-0183, EVI-0002, REL-0001.
Đưa lên production
Cách đưa lên giống hệt lần đổi dữ liệu trước: sao lưu, dựng lại toàn bộ, kiểm tra. Nhật ký audit_log đang trống và chưa có gì nhập tay, nên dựng lại không mất gì.
bash
cd api.conan1.com
npx wrangler d1 export conan-compass --remote --output=backup-$(date +%Y%m%d).sql # 1. sao lưu
npm run db:remote # 2. chạy 0001 → 0008 theo thứ tự
npx wrangler d1 execute conan-compass --remote --command \
"SELECT id, product_id FROM applications" # 3. kiểm tranpm run db:remote không sinh lại file seed; chạy node scripts/seed.mjs và commit kết quả trước khi merge. Production chỉ được ghi từ nhánh main đã merge — không đẩy dữ liệu từ máy cá nhân.
Chỉ dựng lại được khi chưa có bộ nhớ thật
db:remote chạy cả 0001 và 0003, tức là xoá mọi bảng. Và 0005 / 0006 chạy riêng cũng không phải đường đi cộng thêm: 0005 mở đầu bằng DROP TABLE IF EXISTS trên mọi bảng của hai mặt phẳng (kể cả requirements, questions, decisions, evidence, releases, ai_*, sequences); 0006 mở đầu bằng DELETE FROM các bảng đó và kết thúc bằng đặt lại sequences về 1834 / 883 / 182 / 1 / 0. Chạy lại hai file này trên production xoá bộ nhớ quyết định y như dựng lại toàn bộ, và không có ràng buộc nào ngăn lại — requirements.product_id ON DELETE RESTRICT không giúp gì, vì requirements bị xoá trước products.
Hôm nay điều đó an toàn vì mọi thứ đều đến từ seed. Ngay khi production có yêu cầu, câu hỏi hay quyết định do người nhập (bất kỳ REQ-1835, Q-0884, D-0183 trở đi), không chạy lại bất kỳ file nào từ 0001 đến 0006. Mọi thay đổi về sau — schema hay dữ liệu — phải là một file migration mới, tăng số thứ tự (0007_….sql), chỉ chứa ALTER TABLE / INSERT / UPDATE cần thiết, không DROP, không DELETE bảng, không đặt lại sequences; sao lưu rồi áp dụng riêng file đó:
bash
npx wrangler d1 export conan-compass --remote --output=backup-$(date +%Y%m%d).sql
npx wrangler d1 execute conan-compass --remote --file=migrations/0007_….sql0007 / 0008 — đường đi cộng thêm đầu tiên
0007_requirement_depth.sql và 0008_requirement_depth_seed.sql là ví dụ thật của đúng cái đường đi mà đoạn trên hứa. Chúng áp dụng được lên database đang chạy đã có yêu cầu và quyết định do người nhập:
| Tính chất | 0005 / 0006 | 0007 / 0008 |
|---|---|---|
| Mở đầu | DROP TABLE mọi bảng của hai mặt phẳng | Không DROP dòng nào; chỉ CREATE TABLE IF NOT EXISTS |
| Ghi dữ liệu | DELETE FROM rồi INSERT | Chỉ INSERT OR IGNORE |
sequences | Đặt lại về 1834 / 883 / 182 / 1 / 0 | INSERT OR IGNORE bộ đếm mới, rồi UPDATE … SET last = MAX(last, 12) — không bao giờ lùi |
| Bảng đã có | Bị xoá và dựng lại | Không chạm |
| Trên production có dữ liệu thật | Không được chạy | Chạy được, và chạy lại được |
bash
npx wrangler d1 export conan-compass --remote --output=backup-$(date +%Y%m%d).sql
npx wrangler d1 execute conan-compass --remote --file=migrations/0007_requirement_depth.sql
npx wrangler d1 execute conan-compass --remote --file=migrations/0008_requirement_depth_seed.sqlVì sao 0007 không có dòng DROP nào
0005 mở đầu bằng một danh sách DROP TABLE IF EXISTS, và danh sách đó được chèn lên đầu 0001 / 0003 để một lần dựng lại xoá bảng con trước bảng cha. 0007 cố ý không làm vậy. Hai bảng mới chỉ bị xoá bởi 0001_init.sql và 0003_execution.sql — tức đường dựng lại toàn bộ — và chính đầu file 0007 giải thích:
There is deliberately NO DROP in this file. The two tables are dropped only by 0001_init.sql and 0003_execution.sql, which is the full-rebuild path; dropping them here would make re-applying this file erase hand-entered criteria and dependencies, which is exactly what an additive migration must not do.
Đó là khác biệt biến "chạy được một lần" thành "chạy lại được": một migration cộng thêm mà xoá bảng của chính nó thì chỉ cộng thêm ở lần đầu.
Đã kiểm:
- dựng lại đủ
0001 → 0008sạch,PRAGMA foreign_key_checkkhông trả dòng nào; - áp dụng lại
0007rồi0008trên database đã có một dòng nhập tayAC-9999: dòng đó còn nguyên, tổng 13 tiêu chí = 12 của seed + 1 nhập tay.
Quay lui bước dữ liệu: DELETE FROM các bảng mới và UPDATE applications SET product_id = NULL, repository = ''. Hai cột thêm vào applications ở lại (SQLite không bỏ cột rẻ) và vô hại.