UserMetadata
Provides a flexible key-value storage system for user-specific data that doesn't fit into the standard user schema. This entity acts as an extension mechanism, allowing applications to store custom attributes, feature flags, integration data, or any additional information about users without modifying the core database schema. It's particularly useful for storing data from third-party integrations (like CRM IDs, external system references), A/B testing flags, user-specific feature toggles, custom profile fields that vary by deployment, or temporary data during migrations. Each metadata entry can be typed (string, number, boolean, JSON) to ensure proper handling, encrypted for sensitive data, and indexed for searchability. The category field helps organize related metadata, making it easier to retrieve all settings for a specific feature or integration. This pattern provides unlimited extensibility while maintaining database performance, as only frequently accessed metadata needs to be indexed. It's commonly used for multi-tenant applications where different customers need different user attributes, or for gradually rolling out features by storing beta access flags.
Properties
| Property | Type | Mode | Description | Required |
|---|---|---|---|---|
| userId | uuid | stored | The user this metadata belongs to | Required |
| metadataKey | string | stored | Unique key identifying this piece of metadata Example: | Required |
| metadataValue | string | stored | The actual value stored as a string (parsed based on valueType) Example: | Required |
| valueType | string | enum | Data type for proper parsing and validation Values: | Optional |
| category | string | stored | Grouping category for related metadata Example: | Optional |
| description | string | stored | Human-readable explanation of what this metadata represents | Optional |
| source | string | stored | System or integration that created this metadata Example: | Optional |
| isEncrypted | boolean | stored | Whether the value is encrypted for sensitive data | Optional |
| isIndexed | boolean | stored | Whether this metadata should be indexed for fast searching | Optional |
| isPublic | boolean | stored | Whether this metadata is visible to the user | Optional |
| isEditable | boolean | stored | Whether users can modify this value themselves | Optional |
| validFrom | DateTime | stored | When this metadata becomes valid/active | Optional |
| validUntil | DateTime | stored | When this metadata expires | Optional |
| createdAt | DateTime | stored | When this metadata was first created | Required |
| updatedAt | DateTime | stored | Last time this metadata was modified | Optional |
| createdBy | User | stored | Who created this metadata entry | Optional |
| updatedBy | User | stored | Who last modified this metadata | Optional |
Examples
Example 1
{
"@type": "UserMetadata",
"userId": "user_123456",
"metadataKey": "feature_flags.new_dashboard",
"metadataValue": "true",
"valueType": "boolean",
"category": "feature_flags",
"description": "Beta access to the new dashboard interface",
"source": "admin_panel",
"isEncrypted": false,
"isIndexed": true,
"isPublic": false,
"isEditable": false,
"validFrom": "2024-03-01T00:00:00Z",
"validUntil": "2024-06-01T00:00:00Z",
"createdAt": "2024-03-01T10:00:00Z",
"createdBy": "admin_789"
}Example 2
{
"@type": "UserMetadata",
"userId": "user_789012",
"metadataKey": "integrations.stripe.customerId",
"metadataValue": "cus_P0K9mNbVcXyZ123",
"valueType": "string",
"category": "integrations",
"description": "Stripe customer ID for billing integration",
"source": "stripe_webhook",
"isEncrypted": true,
"isIndexed": true,
"isPublic": false,
"isEditable": false,
"createdAt": "2024-01-15T14:30:00Z",
"updatedAt": "2024-03-10T09:00:00Z"
}