# Generate and apply YDB table schema DDL safely

local-ydb-toolkit keeps YDB schema DDL work plan-first. `local_ydb_generate_schema` is read-only. `local_ydb_apply_schema` validates first and applies only when `action` is `apply` and `confirm: true` is supplied.

## Safe schema workflow

1. Inspect the target tenant with `local_ydb_status_report` and `local_ydb_scheme`.
2. Call `local_ydb_generate_schema` with a strict JSON table spec and `validate: true`.
3. Review generated DDL, script SHA-256, warnings, risk, and SDK validation status.
4. Call `local_ydb_apply_schema` with `action: validate`.
5. Call `local_ydb_apply_schema` with `action: apply` and `confirm: false` to return the plan.
6. Execute only after approval with the exact same apply call plus `confirm: true`.
7. Verify with `local_ydb_scheme` using `action: describe`.

## Example generator spec

```json
{
  "validate": true,
  "statements": [
    {
      "kind": "createTable",
      "tableName": "schema_apply_smoke",
      "columns": [
        { "name": "id", "type": "Uint64", "notNull": true },
        { "name": "value", "type": "Utf8" }
      ],
      "primaryKey": ["id"],
      "indexes": [
        {
          "name": "schema_apply_smoke_by_value",
          "columns": ["value"],
          "global": true
        }
      ]
    }
  ]
}
```

## Important constraints

- Use `notNull` only for primary key columns in generated CREATE TABLE specs.
- Use the top-level `store` field instead of `with.STORE`.
- Keep secondary and vector indexes on row-oriented tables.
- Do not add an index on a column added or dropped in the same ALTER TABLE spec.
- Prefer adding vector indexes after representative data is loaded.
