# Migration: hợp đồng, baseline và phục hồi

Tra cứu file, lệnh, quyền, rủi ro, nhánh Git, SDK, CI và cách xử lý kết quả chưa xác định.

Nguồn: https://whypik.com/docs/data-migrations-reference
Nhóm: Lập trình viên
Phiên bản tài liệu: 2026-10-14.10
Ngôn ngữ: vi

## Availability và capabilities

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-0

GET capabilities và status trả format_version:1; enabled:false nghĩa là tính năng chưa mở trên môi trường đó. Các field contract/engine/transactional/max_* mô tả hợp đồng triển khai, không tự bật dịch vụ và không chứng minh runtime đã được nghiệm thu. Database hiện có không tự đổi mode.

Khi tính năng tắt, Dashboard vẫn giải thích trạng thái; các endpoint history, pull, plan, apply, baseline, operation/resume và khóa Migration bị từ chối. Không chuyển sang sửa SQL hoặc gọi API cũ để vượt managed mode.

Migration cần WhyPik CLI 0.3.0rc1 hoặc bản tương thích được phát hành sau đó; package 0.2.0 không hỗ trợ migration. Kiểm tra whypik db --help sau khi cài. ci init yêu cầu manifest trên môi trường đích khớp phiên bản CLI; nếu bản CLI phù hợp chưa được phát hành ở đó, lệnh dừng và không ghi pipeline dùng nhầm package cũ. Có lệnh db không đồng nghĩa Project hosted đã được mở migration.

Bộ local dùng source và dịch vụ PostgreSQL/PostgREST thật khi được chạy. Việc CLI validate, kiểm thử SDK HTTP hoặc browser API giả lập đạt không chứng minh Compose đã chạy, local/hosted tương đương hoặc pipeline provider đã triển khai thành công. Bản thử đã chạy chuỗi migration, Admin CRUD và backup trên Docker rootless Linux. Windows Docker Desktop, ba provider CI và canary hosted vẫn cần nghiệm thu riêng; không coi kết quả local là chứng nhận production-ready.


## Nguồn sự thật và file portable

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-1

schema.json là ý định cấu trúc. Chuỗi migration JSON là các thay đổi được phát hành. Lịch sử đã commit ở Database là bằng chứng migration đã chạy; trạng thái API ready được theo dõi riêng. Revision môi trường, migration ID, generation và lineage là các định danh khác nhau, không dùng thay cho nhau.

V1 dùng format_version:1, contract whypik-schema-v1, UUID bất biến và một parent cho mỗi migration. Profile canonical whypik-json-v1 dùng UTF-8, sắp khóa theo Unicode scalar, không float/NaN/Infinity/surrogate hoặc số nguyên ngoài safe53. Không gọi đây là RFC 8785/JCS. bigint/numeric literal phải dùng chuỗi chính xác.

Tối đa 128 migration, 256 KiB mỗi file và 2 MiB mỗi bundle portable. Không chứa SQL, Python, hook, credential, UUID role vật lý, generation hoặc tên schema PostgreSQL. Checksum SHA-256 không tự cấp quyền chạy và không thay thế validation trên đích.

Policy dùng subject role:@editor trong definition portable. File whypik/bindings/staging.json ánh xạ editor tới UUID role. Có thể thêm symbol mới, nhưng không đổi hoặc xóa ánh xạ đã ghi trong history; giữ cả binding lịch sử không còn được dùng, tối đa 32 symbol. CLI không tự tạo role hay sao chép thành viên; policy_sets/policy_bindings vẫn giữ mô hình quyền hiện có.

Chỉ role được schema đích của migration chưa áp dụng tham chiếu mới bắt buộc còn tồn tại trong đúng Project; compiler kiểm lại trước DDL. History giữ UUID gốc kể cả khi role đã xóa: migration tiếp theo có thể bỏ grant của role đó, nhưng không gán lại symbol cũ cho role mới dù trùng tên.

```
whypik.toml
whypik/schema.json
whypik/migrations/<uuid>_<name>.json
whypik/bindings/staging.json
.whypik/  # private: local credentials, plans and receipts; ignored by Git
```


## Lệnh và kết quả

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-2

| Lệnh | Phạm vi |
| --- | --- |
| db init/start/stop/doctor | Tạo cấu hình hoặc quản lý stack local; start không apply migration. |
| db diff --name NAME [--changes FILE] | So head repository với schema.json, sinh file mới; không đoán rename. |
| db validate | Kiểm chuỗi, checksum, version và head khớp schema.json; không chứng minh DDL chạy được trên dữ liệu đích. |
| db link --env LABEL --project UUID | Xác minh endpoint/Project/Database, lưu liên kết không secret. |
| db plan --env LABEL --out FILE [--to UUID] [--baseline] | Tạo kế hoạch ràng buộc đích và trạng thái hiện tại; không chạy DDL. |
| db migrate --env local | Validate + plan + apply local có xác nhận. |
| db migrate --env LABEL --plan FILE | Apply hosted từ plan đã review. --yes không cấp thêm quyền. |
| db status/history/operation ID --env LABEL | Đọc trạng thái/lịch sử/tiếp tục đối soát; operation chờ tối đa --timeout. |
| db pull --env LABEL --out FILE | Xuất definition và bindings; không export dữ liệu/Auth/secret hay tự baseline. |
| db baseline --env LABEL --plan FILE | Nhận một root đã chứng minh khớp Database chưa có history; không chạy lại CREATE. |
| db reset --confirm-workspace UUID | Chỉ local, xóa dữ liệu/lịch sử workspace đã xác nhận; không có remote reset. |
| db operation ID --env LABEL --resume | Yêu cầu server tiếp tục đúng operation đã nhận; không tự chạy trong GET/poll. |
| db replay --env local --yes [--approve-policy] [--approve-destructive] | Replay tuần tự trên workspace local trống hoặc tiếp tục receipt khớp; backup từng bước destructive. |
| db status --env LABEL --expect-plan FILE | Đối chiếu đích/head/lineage với plan đã áp dụng, không drift và operation gần nhất đã API-ready trước khi deploy. |


## Cấp khóa Migration riêng cho CI

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-3

Chủ Project mở Database → Migration → Khóa Migration cho CI/CD → + Tạo khóa Migration. Nhập tên và hiệu lực 1–90 ngày. Mặc định có plan/apply; quyền phê duyệt policy và thay đổi phá hủy đều tắt. Không bật hai quyền này chỉ để pipeline hết báo lỗi.

Khóa chỉ xuất hiện một lần; lưu trong secret CI WHYPIK_MIGRATION_KEY. Danh sách chỉ có tên, scopes, hạn và trạng thái, không đọc lại secret. Khi mất phản hồi cấp khóa, đóng cửa sổ và làm mới để kiểm tra; nếu khóa đã được tạo nhưng mất secret, thu hồi trước khi cấp lại. Không tự retry mù.

Khóa Migration không có CRUD, Auth, Variables, deploy hoặc quyền Project khác. plan đọc trạng thái/lịch sử và tạo kế hoạch; apply gửi kế hoạch; policy/destructive chỉ cho phép phê duyệt rủi ro tương ứng, vẫn cần flags/backup/xác nhận khi thực hiện. Tối đa 20 khóa đang hoạt động trên Database.

Tài khoản hoặc Project bị tạm ngừng ghi không được chạy migration mới, kể cả baseline/reconcile bằng phiên chủ sở hữu. Worker kiểm tra lại trước mỗi bước chưa commit; phần đã commit vẫn được đối soát, không tự chạy lại hoặc rollback.

API cấp khóa chỉ dùng phiên đăng nhập owner và CSRF: GET/POST /api/v1/seller/cloud/projects/PROJECT_UUID/database/migrations/keys; POST {name,scopes:["plan","apply"],days:30} trả {format_version:1,key,secret}. DELETE cùng /keys/KEY_UUID thu hồi. Staff có thể đọc trạng thái Migration theo quyền quản trị hiện có nhưng không cấp/thu hồi khóa hoặc áp dụng Migration.


## Phạm vi thay đổi và dữ liệu hiện có

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-4

V1 dùng compiler/evolution hiện có và transaction PostgreSQL. Tạo bảng, thêm cột nullable hoặc có default, rename tường minh, default/nullability, index, UNIQUE/FK và policy chỉ được chấp nhận trong phạm vi compiler hỗ trợ. UNIQUE/FK/NOT NULL vẫn kiểm dữ liệu khi apply; giữa plan và apply dữ liệu có thể thay đổi.

Không hỗ trợ đổi type/PK/identity/max_length của cột hiện có, raw SQL, CREATE INDEX CONCURRENTLY, hook tùy ý, multi-head merge, down tự sinh hoặc lời hứa zero-downtime. Index v1 là thao tác transactional có thể giữ lock; không âm thầm đổi cú pháp concurrent thành index blocking.

Plan phân loại additive, constraint-sensitive, permission-widening, application-breaking, destructive hoặc adoption và hiển thị preconditions/policy delta. Thay đổi cấp quyền cần --approve-policy và credential có quyền policy; xóa cần backup hợp lệ, --backup-id và --confirm-project đúng ID ngắn, cùng quyền destructive. --yes không bỏ bất kỳ kiểm tra nào.


## Thêm cột, đổi tên, index và policy

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-5

Ví dụ đầy đủ có trong examples/database-migrations trong source repository WhyPik. Sau mỗi lần sửa schema.json, chạy diff với tên riêng rồi validate. Không đưa nhiều ý nghĩa rename/drop vào cùng một thay đổi nếu compiler yêu cầu tách.

Thêm cột note kiểu text nullable:true để giữ bản ghi hiện có. Đổi note thành description cần sửa cả policy/index/reference liên quan trong schema mong muốn và chỉ rõ mapping dưới đây. Thiếu mapping là lỗi, không suy ra rename từ hai tên gần giống.

Thêm index {name:"products_name_idx",columns:["name"],unique:false} vào indexes. Muốn unique:true, xử lý dữ liệu trùng trước và xem plan constraint-sensitive; không coi index đã validate JSON là chắc chắn thành công.

Khi cho anonymous đọc description, thêm tên cột vào policy select tương ứng. Quyền cột mới không tự sinh từ việc thêm cột. Plan sẽ yêu cầu review policy; credential chỉ plan/apply không thể tự mở quyền.

```
# rename-note.json
{"columns":{"products":{"note":"description"}}}

# Sau khi sửa schema.json:
whypik db diff --name rename_note --changes rename-note.json
whypik db validate
```


## Baseline Database đã có dữ liệu

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-6

Dùng pull để lấy definition portable cùng bindings vào file tạm, review trước khi đưa vào schema.json và bindings của môi trường. V1 chỉ baseline một migration root duy nhất trên Database chưa có history. Root phải mô tả chính xác toàn bộ cấu trúc hiện tại; không dùng migrate lên bảng có sẵn hoặc nhận tùy ý một chuỗi nhiều file.

Plan --baseline đối chiếu cấu trúc vật lý, metadata, policy/bindings và root đã chọn. Khi khớp, baseline chỉ nhận root trong transaction và chuyển sang mode migration. Sai khác, history đã có hoặc policy không khớp phải dừng; không mark-applied bằng tay.

Credential, generation và security revision vẫn được kiểm lại khi áp dụng. Baseline không làm dữ liệu trở nên an toàn hơn và không cho phép bỏ drift.

```
whypik db pull --env staging --out .whypik/existing.json
# Review definition/bindings rồi cập nhật các file portable.
whypik db diff --name baseline_existing
whypik db validate
whypik db plan --env staging --baseline --out .whypik/baseline-plan.json
whypik db baseline --env staging --plan .whypik/baseline-plan.json
```


## Plan tới một migration trong chuỗi

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-7

db plan --env LABEL --to MIGRATION_UUID --out FILE chọn prefix từ root tới UUID có trong repository. Toàn bộ repository vẫn phải validate và khớp schema.json; plan artifact giữ digest cả chuỗi để phát hiện file thay đổi. Các file sau UUID được giữ nguyên, không xóa, sửa checksum hoặc đổi schema.json để giả một head cũ.

Dùng --to để áp dụng phần trước một bước phá hủy, tạo backup đúng revision/generation hiện tại, rồi tạo plan riêng tới bước phá hủy đó. Server chỉ nhận một bước destructive chưa áp dụng trong mỗi plan; không dùng một backup ban đầu cho nhiều bước làm thay đổi dữ liệu.

--to không rollback, không chạy down và không cho chọn lịch sử ngắn hơn history đã commit. Nếu mục tiêu hoặc history thay đổi, đọc status rồi review plan mới. Với hosted, người vận hành vẫn chọn backup hợp lệ và xác nhận Project qua workflow hiện có.

```
whypik db plan --env staging --to PREFIX_MIGRATION_UUID --out .whypik/prefix-plan.json
whypik db migrate --env staging --plan .whypik/prefix-plan.json
# Tạo và xác minh backup đúng revision/generation sau prefix.
whypik db plan --env staging --to DROP_MIGRATION_UUID --out .whypik/drop-plan.json
whypik db migrate --env staging --plan .whypik/drop-plan.json --backup-id BACKUP_UUID --confirm-project PROJECT_ID
```


## Replay toàn bộ lịch sử trên Database local

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-8

db replay chỉ nhận --env local với stack đã khởi động và workspace local riêng. Lần đầu yêu cầu Database trống, không history/operation/bảng hiện có. Không tự reset, không gọi hosted và không lấy khóa production. Nếu cần xóa một workspace thử, dùng db reset --confirm-workspace WORKSPACE_UUID có chủ đích rồi start lại; dữ liệu local sẽ mất.

Bắt buộc --yes để xác nhận replay workspace này. Policy cần --approve-policy; bước xóa dữ liệu cần --approve-destructive riêng. Replay lần lượt lập plan prefix và áp dụng từng migration; các phê duyệt này chỉ áp dụng cho local, không cấp thêm quyền cho credential hoặc pipeline hosted.

Trước từng bước destructive, CLI yêu cầu backup local đúng revision/generation, chờ verified rồi dùng recovery trả về trong cùng cơ chế apply thông thường. Worker vẫn kiểm chứng scratch restore; không bỏ backup guard hoặc bật chế độ SQL không an toàn để chạy lại lịch sử.

Receipt nằm trong .whypik/migration-replay, migration-plans và migration-backups. Chạy lại cùng replay sau mất phản hồi giữ plan/request/idempotency gốc để đối soát. Nếu workspace, generation, lineage, bundle hoặc head không khớp thì dừng; không sửa receipt hay reset để che kết quả chưa xác định.

Kết quả thành công là {format_version:1,replay:{workspace,head,completed,api_ready:true}}. Exit 3 hoặc backup pending chưa phải đã xong; giữ receipt và kiểm tra trạng thái. Không tự biến lỗi apply thành thành công hoặc rollback lịch sử đã commit.

Đây là luồng được triển khai cho replay local có kiểm soát. Docker/Compose và pipeline GitHub/GitLab/Bitbucket chưa được chạy để nghiệm thu trong đợt này; validation/unit/transport tests không thay cho bằng chứng đó.

```
# Chỉ trong workspace local trống đã được kiểm tra:
whypik db replay --env local --yes --approve-policy --approve-destructive --timeout 600
whypik db status --env local
whypik db history --env local
```


## API backup riêng của local replay

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-9

Local-only POST /local/projects/PROJECT_UUID/backup nhận {expected_revision,expected_generation} và Idempotency-Key UUID. GET /local/projects/PROJECT_UUID/backups/BACKUP_UUID đọc trạng thái. Cả hai cần X-WhyPik-Local-Workspace, X-WhyPik-Local-Token và X-WhyPik-Key là Admin key local thuộc đúng Project fixture; không có route tương đương này trên hosted.

Response có format_version:1, backup:{id,state,error_code,revision,generation,verified} và recovery:null hoặc {backup_id,confirm_project}. Backup chạy bất đồng bộ qua worker hiện có, mã hóa ở storage local. Chỉ khi verified và đúng revision/generation mới dùng recovery; HTTP nhận yêu cầu không có nghĩa backup hoàn tất.

API không trả secret, nội dung backup hay quyền bỏ qua xác minh. Không dùng Admin key hosted qua HTTP. CLI replay đã xử lý receipt và polling, ứng dụng thường không cần tự gọi endpoint này.

Python AdminClient có local_backup(expected_revision=REV,expected_generation=UUID,idempotency_key=UUID) và local_backup_status(BACKUP_UUID). Node WhyPikAdmin có localBackup({expected_revision,expected_generation},idempotencyKey) và localBackupStatus(BACKUP_UUID). Các phương thức này chỉ nhận client được tạo với profile local; response giữ nguyên envelope backup/recovery, không tự chờ backup sẵn sàng.


## Expand → backfill → contract

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-10

Expand: thêm description nullable, deploy ứng dụng có thể đọc cả note/description và ghi cột mới. Migrate thành công không tự chuyển dữ liệu cũ.

Backfill: chương trình Admin SDK ngoài worker cập nhật theo batch nhỏ với điều kiện description còn null và khóa id. Có checkpoint, đo số dòng còn null; mất phản hồi ghi thì đối soát khóa nghiệp vụ trước retry. Không chạy hook tùy ý bên trong migration đặc quyền.

Contract: chỉ sau khi bản ứng dụng cũ đã hết dùng, dữ liệu được backfill và constraint kiểm đạt mới siết NOT NULL hoặc bỏ cột cũ. Xóa là migration khác, cần backup và xác nhận riêng. Không sinh down tự động để cố đảo ngược dữ liệu.


## Nhánh Git, plan cũ và drift

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-11

Hai nhánh cùng parent tạo hai head sẽ bị validate từ chối. Hợp nhất nội dung schema, rồi tạo lại migration CHƯA phát hành trên head mới; không sửa ID/checksum/parent của migration đã chạy trên bất kỳ môi trường dùng chung nào. Không squash lịch sử đã phát hành.

Plan hết hạn hoặc không còn khớp head/generation/lineage/security revision/permission phải bị từ chối. Đọc status/history, review trạng thái mới rồi tạo plan mới; không thay digest trong file plan hoặc thêm force.

Drift gồm file/history không khớp, cấu trúc vật lý lệch metadata hoặc quyền hiện hành lệch lịch sử. Dashboard hiển thị lý do để đối soát. Pull chỉ xuất bằng chứng đọc, không tự hợp thức hóa drift.


## Timeout, partial batch và API chưa sẵn sàng

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-12

JSON stdout có format_version:1; tiến độ ra stderr. Với migrate/baseline/replay, exit 0 chỉ khi các migration đích commit và API sẵn sàng; exit 1 là từ chối/lỗi terminal, exit 3 là chưa có kết quả cuối. Các lệnh chỉ đọc hoặc validate không chạy DDL. HTTP 202 không phải thành công cuối.

Mỗi migration commit riêng theo chuỗi. Nếu A đã commit và B lỗi, history giữ A; không rollback cả batch bằng cách chạy DDL ngược. Giữ operation ID và xem completed/pending/error_code/recovery, sửa nguyên nhân có chủ đích trước bước tiếp.

SQL đã commit nhưng PostgREST/schema cache chưa sẵn sàng là trạng thái đối soát. Không re-execute DDL, không báo hoàn tất chỉ vì head đã tăng. Ctrl+C hoặc hết timeout chỉ dừng chờ; không hủy hoặc rollback yêu cầu server đã nhận.

CLI giữ receipt trong .whypik. SDK caller phải lưu request JSON và Idempotency-Key trước gửi; khi mất receipt dùng cùng plan và cùng UUID để đối chiếu. Không tạo UUID mới chỉ vì chưa nhận phản hồi.

Sau khi đọc trạng thái và xử lý nguyên nhân, dùng operation ID --env LABEL --resume để yêu cầu tiếp tục đúng operation. Không thêm --resume vào vòng đọc trạng thái tự động.

```
whypik db operation OPERATION_UUID --env staging --timeout 120
whypik db status --env staging
whypik db history --env staging
# Chỉ sau khi đối soát và quyết định tiếp tục cùng operation:
whypik db operation OPERATION_UUID --env staging --resume
```


## Backup, restore và reset

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-13

Backup/restore giữ nguyên các kiểm tra hiện có. Restore dùng generation và lineage riêng, lưu lịch sử nguồn để đối soát; plan cũ bị fence. Reset Database hosted chỉ qua workflow owner có backup/xác nhận hiện tại, không qua db reset.

Quyền đã thu hồi sau backup không được tự mở lại khi restore. Nếu quyền phục hồi an toàn khác definition portable của history, phải ghi nhận drift/security overlay và dừng apply tới khi đối soát được phê duyệt; không dùng restore để hồi sinh grant đã thu hồi.

Làm trống bắt đầu lineage mới, lưu riêng lịch sử cũ. Tên bảng/cột cũ có thể dùng lại nhưng không gắn history cũ thành đã-applied vào Database rỗng. Muốn dùng lại cấu trúc, review rồi chạy chuỗi trên lineage mới; generation/lineage mới vô hiệu hóa plan/receipt đích cũ.

Logical object ID portable được tạo ổn định bằng uuid5(migration_id, object_path). Binding vật lý gồm Database, lineage và logical ID. Vì vậy replay cùng root sau reset có thể giữ logical ID nhưng không gắn lại bảng/cột vật lý đã xóa ở lineage cũ.


## Đối soát quyền an toàn sau restore

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-14

Một trường hợp riêng được hỗ trợ: restore tạo security overlay giữ lại việc thu hồi quyền, khiến quyền hiện hành khác history. Chỉ chủ Project bằng phiên đăng nhập được tạo kế hoạch reconcile cho overlay này. Đây không phải cơ chế sửa drift tùy ý hoặc force migration.

Đọc status/history và pull để so quyền hiện hành với toàn bộ chuỗi trong Git. Review vì sao quyền bị thu hồi và bảo đảm chuỗi/bindings đúng lineage. Gửi POST /api/v1/seller/cloud/projects/PROJECT_UUID/database/migrations/plan với CSRF, mode:"reconcile", migrations là toàn bộ chuỗi đã có, bindings, environment và reason dài 10–500 ký tự. Plan không tự áp dụng.

Sau review, owner gửi POST cùng base /apply với plan_id, plan_digest và Idempotency-Key UUID của yêu cầu này. Server kiểm lại overlay/head/security revision rồi ghi một sự kiện đối soát có audit. Không chạy DDL, không mở lại grant cũ, không đổi checksum hay viết lại migration history.

Đối soát xong mới được review migration đi tới tiếp theo. Admin SDK, khóa CI hoặc staff không thay phiên owner cho thao tác này. CLI v1 chưa có lệnh reconcile; không dùng baseline, pull, --resume hoặc sửa file plan làm đường tắt.


## Python, Node và HTTP

Liên kết mục: https://whypik.com/docs/data-migrations-reference#section-15

Python AdminClient: migration_capabilities(), migration_status(), migration_history(offset=0,limit=100), migration_pull(), migration_plan(migrations=CHAIN,environment=LABEL,bindings={},mode="apply"), migration_apply(plan_id=ID,plan_digest=SHA,idempotency_key=UUID,approve_policy=False,recovery=None), migration_baseline(...), migration_operation(ID) và migration_resume(ID).

Node WhyPikAdmin: migrationCapabilities(), migrationStatus(), migrationHistory({offset,limit}), migrationPull(), migrationPlan({migrations,environment,bindings?,mode?}), migrationApply({plan_id,plan_digest,approve_policy?,recovery?},idempotencyKey), migrationBaseline(...), migrationOperation(ID) và migrationResume(ID). Chỉ ở @whypik/js/server; không đưa vào bundle trình duyệt.

Các endpoint dùng /api/v1/admin/db/PROJECT_UUID/migrations/: GET capabilities/status/history/pull/operations/ID; POST plan/apply/baseline. Response có format_version:1 và field capabilities/status/history/definition/plan/operation. Mutation apply/baseline cần Idempotency-Key UUID; plan không chạy DDL.

Admin có toàn quyền dữ liệu trong Project, bỏ policy client, nhưng không bỏ mode migration, quota, ràng buộc, quyền phê duyệt hoặc backup. apply_schema/applySchema cũ chỉ sửa trực tiếp ở mode manual; schema()/CRUD vẫn dùng được khi managed. Dedicated migration key không cấp CRUD hay deploy.

Local SDK nhận endpoint loopback chính xác và local={workspace,token} từ private state do stack tạo; key cũng là khóa local riêng. Hosted chỉ HTTPS. Không bật allowInsecure chung, không dùng hosted key qua HTTP, không tự fallback khi local unavailable.

migration_resume/migrationResume gửi POST operations/ID/resume để tiếp tục đúng operation đã nhận sau khi đối soát. Không tạo plan mới hoặc chạy lại migration đã commit. Status/operation GET không tự resume; timeout vẫn yêu cầu đọc lại kết quả.


## Đọc tiếp

- [Tham chiếu cấu trúc bảng](https://whypik.com/docs/schema-reference)
- [Quản trị viên và quyền dữ liệu dùng chung](https://whypik.com/docs/database-permissions)
- [CI/CD với GitHub, GitLab và Bitbucket](https://whypik.com/docs/cicd)
- [Backup, khôi phục và lịch sử Database](https://whypik.com/docs/database-recovery)
- [Admin SDK: Database của Project](https://whypik.com/docs/data-admin)
- [Bắt đầu với Database Migration](https://whypik.com/docs/data-migrations)
