Member extra-data objects
Grouped and custom-fields operations share one extra-data table scoped by user and resource. This is distinct from the resource relationship’s user.extra map and the configured Firestore document. These operations do not establish automatic synchronization between these stores.
Extra-data row
| Field | Type / presence | Meaning |
|---|---|---|
id | stored integer ID | Extra-data row ID, not user/session ID. |
user_id, resource_id | stored integer IDs | Member and integration resource owning this row. |
group_key | stored string / nullable | Integration-defined group; custom-fields operations use custom_fields. |
field_key | stored string / nullable | Name within the group. |
field_value | stored string / nullable | Stored text after input string filtering/trim. Not a typed JSON-value promise. |
created_at, updated_at | stored timestamp strings | Row creation and latest-save time; save sets updated_at, creation sets both. Timezone unspecified. |
IDs have no explicit scalar conversion in this model. The handlers allow group keys up to 64 characters and field keys up to 128; the model annotations declare 32 for both. Field values are annotated as nullable strings of length 1024, but the handlers do not check that length.
These are different limits, not a guarantee that the database accepts every handler-valid input. Choose short, stable names and bounded strings, then inspect stored values after a write. These operations add no provider validation.
Grouped items is a dynamic group-name map of row arrays when records exist, and [] when none. Custom-fields items is always a row array. There is no paginator or declared ordering. Updates create or update only the valid keys you supply. They preserve untouched rows and silently skip invalid or overlength keys; they do not replace every group. Repeated keys are processed sequentially, with no atomic-batch guarantee or independent save-result reporting.
Grouped deletion has an ordinary empty JSON response; custom-field deletion returns success:true after its helper returns. Neither reports deletion counts/skips. Missing targets have no idempotent-success guarantee. Read the relevant collection afterward to decide what to display.