docs: подводные камни от Соннета (Required+Default, json-теги, value_list)

This commit is contained in:
“Naeel”
2026-07-16 14:33:53 +04:00
parent c197fb8b0c
commit c5e2b77ab5
+64 -8
View File
@@ -83,13 +83,15 @@ if v == "map-fixed" || v == "array-map-fixed" {
**map-fixed** (один объект) → `schema.SingleNestedAttribute`:
```go
// ⚠️ Подполя с default → Optional+Computed+Default (см. 4.1)
// Подполя без default → Required
"clusterConfiguration": schema.SingleNestedAttribute{
Required: true,
Attributes: map[string]schema.Attribute{
"cpu": schema.Int64Attribute{Required: true, ...},
"memory": schema.Int64Attribute{Required: true, Default: int64default.StaticInt64(512)},
"replicas": schema.Int64Attribute{Required: true, Default: int64default.StaticInt64(1)},
"disk": schema.Int64Attribute{Required: true, Default: int64default.StaticInt64(10)},
"cpu": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500)},
"memory": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(512)},
"replicas": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(1)},
"disk": schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(10)},
},
},
```
@@ -113,11 +115,12 @@ if v == "map-fixed" || v == "array-map-fixed" {
Для `clusterConfiguration` → `PostgresClusterConfigurationModel`:
```go
// ⚠️ json-теги = оригинальный code (camelCase), tfsdk-теги = snake_case (см. 4.2)
type PostgresClusterConfigurationModel struct {
Cpu types.Int64 `tfsdk:"cpu"`
Memory types.Int64 `tfsdk:"memory"`
Replicas types.Int64 `tfsdk:"replicas"`
Disk types.Int64 `tfsdk:"disk"`
Cpu types.Int64 `tfsdk:"cpu" json:"cpu"`
Memory types.Int64 `tfsdk:"memory" json:"memory"`
Replicas types.Int64 `tfsdk:"replicas" json:"replicas"`
Disk types.Int64 `tfsdk:"disk" json:"disk"`
}
```
@@ -223,3 +226,56 @@ map — обратная конвертация из JSON в nested struct не
- В Schema: `SingleNestedAttribute` / `ListNestedAttribute`
- В Create/Modify: сериализация в JSON по родительскому ID
6. Протестировать на postgres (самый сложный — 8 map-fixed + 1 array-map-fixed)
---
## Блок 4. Подводные камни (найдены Соннетом при сверке с terraform-plugin-framework)
### 4.1 — Конфликт Required + Default (БЛОКИРУЮЩИЙ)
Во фреймворке атрибут не может быть одновременно `Required` и иметь `Default`.
`Default` работает только с `Optional + Computed`.
А sub_params имеют `required: true` И `default` одновременно:
```yaml
sub_params:
- code: cpu
required: true
default: 500
- code: memory
required: true
default: 512
```
**Решение**: для подполей с default → `Optional + Computed + Default`.
Для подполей без default → `Required` без Default.
```go
// Есть default:
schema.Int64Attribute{Optional: true, Computed: true, Default: int64default.StaticInt64(500)}
// Нет default:
schema.Int64Attribute{Required: true}
```
### 4.2 — JSON-ключи для API (БЛОКИРУЮЩИЙ)
`tfsdk`-теги генерятся в snake_case (`cluster_configuration`), но API ждёт
оригинальный camelCase code (`cpu`, `memory`, `replicas`).
`json.Marshal` struct'а с tfsdk-тегами даст неверные ключи при сериализации
map-fixed → JSON для отправки в API.
**Решение**: генерировать отдельные `json`-теги = оригинальный `code`:
```go
type PostgresClusterConfigurationModel struct {
Cpu types.Int64 `tfsdk:"cpu" json:"cpu"`
Memory types.Int64 `tfsdk:"memory" json:"memory"`
Replicas types.Int64 `tfsdk:"replicas" json:"replicas"`
Disk types.Int64 `tfsdk:"disk" json:"disk"`
}
```
### 4.3 — value_list подполей (out of scope)
Подполя имеют `value_list` (например `replicas: [1,3,5,7]`, `version: ["17","16"]`).
Генерация enum-валидаторов — на этом этапе не делать. Оставить на будущее.