# TDShift Agent API v1

Skill cha: [tdshift-paas](https://app.tdshift.info/skill) · Token: [tai-khoan](https://app.tdshift.info/skill/tai-khoan.md)

Base URL: `https://app.tdshift.info`. Mọi request gửi `Authorization: Bearer $PAAS_API_TOKEN`; request có body gửi thêm `Content-Type: application/json`. Chỉ thấy và thao tác project của chính chủ token.

Lấy token: người dùng vào `https://app.tdshift.info/account` → **API Token cho AI** → **＋ Tạo token** (chi tiết và quy tắc ở [tai-khoan](https://app.tdshift.info/skill/tai-khoan.md)). Thiếu token thì dừng và hướng dẫn người dùng lấy; không tự đoán hay dùng lại token không rõ nguồn.

## Endpoint

| Method | Path | Body | Thành công |
|---|---|---|---|
| GET | `/api/v1/agent/projects` | - | 200 `{"projects":[{"id":"<UUID>","name":"...","kind":"compose","status":"ready"}]}` |
| POST | `/api/v1/agent/projects` | `{"name":"my-app","type":"compose"}` | 201 `{"id":"<UUID>","name":"my-app","type":"compose","status":"ready"}` |
| GET | `/api/v1/agent/projects/<UUID>` | - | 200 `{"id","name","type","status","error"}` |
| PUT | `/api/v1/agent/projects/<UUID>/compose` | `{"compose":"<YAML>","web_service":"web","port":80,"health_path":"/"}` | 200 `{"saved":true,"deployed":false,...}` |
| PUT | `/api/v1/agent/projects/<UUID>/env` | `{"variables":{"APP_ENV":"production"}}` | 200 `{"updated_keys":[...],"redeploy_required":true}` |
| PUT | `/api/v1/agent/projects/<UUID>/registry` | `{"registry":"registry.gitlab.com","username":"<USER>","token":"<TOKEN>"}` | 200 `{"configured":true,"registry":"..."}` |
| PUT | `/api/v1/agent/projects/<UUID>/image` | `{"image":"registry.gitlab.com/g/app:<sha>"}` hoặc thêm `"service":"<tên>"` | 200 `{"saved":true,"deployed":false,"service":"web","image":"..."}` |
| POST | `/api/v1/agent/projects/<UUID>/deploy` | - | 202 `{"status":"updating","deployed":false,...}` |
| GET | `/api/v1/agent/projects/<UUID>/configuration` | - | 200 `{"compose":"<bản nháp>","web_service","port","health_path","images":{"web":"..."},"registry_configured":bool,"environment_keys":[...]}` |

- `type` chỉ nhận `compose`. `name` 1–60 ký tự.
- `compose` tối đa 50000 byte, phải qua quy tắc Compose trong [deploy-compose](https://app.tdshift.info/skill/deploy-compose.md).
- `/compose` lưu bản nháp cùng `web_service`, `port`, `health_path`; giao diện và `/deploy` dùng lại đúng các giá trị này.
- `/env`: tối đa 100 biến mỗi request. Khoá biến `^[A-Za-z_][A-Za-z0-9_]*$`, giá trị là chuỗi một dòng (có xuống dòng → 400).
- `/image`: đổi image của một service trong bản nháp đã lưu (mặc định web service), kiểm tra lại toàn bộ Compose, **không deploy**. YAML được ghi lại nên comment bị mất. Chưa có bản nháp → 409.
- `/deploy`: deploy bản nháp đã lưu, chạy nền giống nút **Deploy Compose Stack ↗**. Theo dõi bằng `GET /api/v1/agent/projects/<UUID>`: `updating` → `ready`; `error` khác `null` nghĩa là deploy lỗi và cấu hình cũ được khôi phục.
- `configuration` chỉ trả **tên** biến, không trả giá trị; không trả lại registry token.

## Không có trong API

Build image, xem log, domain, backup/restore, xoá project, project PostgreSQL. Các việc này làm trên giao diện hoặc GitLab CI. Lưu Compose, env, registry, image **không tự deploy**: chỉ `POST .../deploy` mới deploy.

## Quy trình chuẩn cho AI

Ứng dụng của người dùng phải chạy bằng **image riêng** do GitLab CI build (chi tiết Dockerfile, `.gitlab-ci.yml`: [build-image-rieng](https://app.tdshift.info/skill/build-image-rieng.md)).

1. `GET /api/v1/agent/projects` để xác minh token (200).
2. Hỏi hoặc đọc giá trị thật: tên project, image và tag đã push, tên web service, cổng nội bộ, health path.
3. `POST /api/v1/agent/projects` một lần; lưu `id`.
4. Nếu image private: `PUT .../registry`.
5. `PUT .../env` với các biến cần thiết. Không in giá trị bí mật ra output.
6. `PUT .../compose`; xác nhận `saved:true`, `deployed:false`.
7. `GET .../configuration` để đối chiếu.
8. Khi người dùng muốn chạy: `POST .../deploy` (202), rồi `GET .../<UUID>` mỗi 10 giây tới khi hết `updating`. Chỉ báo đã chạy khi `status:"ready"` và `error:null`; nếu `error` có nội dung thì báo lỗi, không deploy lặp lại khi chưa sửa gì.
9. Bản mới: `PUT .../image` với tag mới → `POST .../deploy`.

```bash
export PAAS_URL=https://app.tdshift.info
curl -fsS "$PAAS_URL/api/v1/agent/projects" -H "Authorization: Bearer $PAAS_API_TOKEN"
curl -fsS -X PUT "$PAAS_URL/api/v1/agent/projects/$UUID/compose" \
  -H "Authorization: Bearer $PAAS_API_TOKEN" -H 'Content-Type: application/json' \
  --data '{"compose":"services:\n  web:\n    image: nginx:stable-alpine\n","web_service":"web","port":80,"health_path":"/"}'
```

## Mã lỗi

| Mã | Ý nghĩa |
|---|---|
| 400 | Body hoặc field không hợp lệ |
| 401 | Thiếu, sai hoặc đã thu hồi token: nhờ người dùng tạo token mới ở `/account` |
| 404 | Project không tồn tại hoặc không thuộc chủ token |
| 409 | Project đang bận, sai loại, đã đạt giới hạn số project, hoặc chưa lưu Compose (`/image`, `/deploy`) |
| 415 | Thiếu `Content-Type: application/json` |
| 422 | Compose, registry hoặc biến không qua kiểm tra (đọc `error`) |
| 500 | Lỗi server; không lặp lại tạo project liên tục |
