---
url: https://docs.nemo12.com/reference/data-dictionary/operations.md
description: >-
  Từ điển dữ liệu D1, domain Vận hành: 2 bảng, queue_dead_letters tới
  rate_limit_buckets; cột, kiểu, khoá ngoại, index.
---

# Data Dictionary · Vận hành

> ⚙️ **Trang này sinh tự động** từ source code bằng `scripts/gen-reference.mjs` — đừng sửa tay, sửa code rồi chạy `npm run gen:reference`.

Thuộc [Data Dictionary](../data-dictionary.md). 2 bảng, `queue_dead_letters` tới `rate_limit_buckets`.

## `queue_dead_letters`

\--------------------------------------------------------------------------- 1. queue_dead_letters — DLQ có đường quay lại (AS-08.2.3) --------------------------------------------------------------------------- wrangler.jsonc đã khai dead_letter_queue 'nemo12-events-dlq' với max_retries 5, nhưng message rơi vào đó thì hiện không ai biết và không có cách chạy lại. Bảng này là sổ của DLQ: giữ nguyên payload để replay được, giữ error để biết vì sao chết, giữ replay_status để không replay hai lần.

migration: `0036_ops.sql`

| Cột | Kiểu | Ràng buộc / ghi chú |
| --- | --- | --- |
| `id` | TEXT | PRIMARY KEY |
| `message_id` | TEXT | NOT NULL,          -- id message của Cloudflare Queues |
| `queue_name` | TEXT | NOT NULL |
| `payload_json` | TEXT | NOT NULL,        -- nguyên văn body để replay đúng như cũ |
| `error_text` | TEXT | ,                   -- lỗi lần cuối khiến message bị đẩy sang DLQ |
| `received_at` | TEXT | NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')) |
| `replayed_at` | TEXT | — |
| `replay_status` | TEXT | — |
| — | *table constraint* | `CHECK (replay_status IN ('pending','replayed','failed','discarded'))` |

**Index:** `idx_dlq_message`(queue_name, message_id) UNIQUE · `idx_dlq_status`(replay_status, received_at DESC)

## `rate_limit_buckets`

\--------------------------------------------------------------------------- 2. rate_limit_buckets — cửa sổ đếm request --------------------------------------------------------------------------- Chọn D1 chứ không phải KV, vì hai lý do: KV eventually consistent giữa các colo nên hạn mức bị rò (mỗi colo đếm riêng), và ta cần đọc lại được ai đang bị chặn khi điều tra sự cố. Đổi lại là mỗi lần đếm tốn một lượt ghi D1 — chỉ đặt trên các route đắt tiền (gọi AI, đăng nhập, gửi bài), KHÔNG đặt trên route đọc thường.   key          = '\<scope>:<định danh>', vd 'ai-chat:user_abc' hoặc 'login:203.0.113.9'   window_start = mốc đầu cửa sổ dạng ISO UTC; đổi cửa sổ thì reset count về 1

migration: `0036_ops.sql`

| Cột | Kiểu | Ràng buộc / ghi chú |
| --- | --- | --- |
| `key` | TEXT | PRIMARY KEY |
| `window_start` | TEXT | NOT NULL |
| `count` | INTEGER | NOT NULL DEFAULT 0 |

**Index:** `idx_rate_limit_window`(window_start)
