Account Updated Payload
Payload emitted when an identity account is updated. A full snapshot (RFC-030 SS10), not a delta: every field is present on every emission regardless of which the request changed, because the Legacy Bridge converges the monolith onto the payload rather than replaying changes. Shares its shape with the account-created payload, so a consumer can apply either through one path and resolve-or-create from whichever arrives first (RFC-030 SS18) - which matters most for legacy installers, who emit no created event at all. v1.1.0 adds phoneNumber, language, the role, groups and address; widens accountType to TEXECOM_USER; and types the nullable columns as such (SOFTC-7120).
| $id | https://schemas.texecom-prod.com/v2/events/payload/service/identity/account/updated/v1.1.0.json |
| $schema | http://json-schema.org/draft-07/schema |
Properties
accountId
| Description |
UUID of the account that was updated (identity.accounts.account_id). |
| Type | String |
| Required |
Yes |
| Format |
uuid |
email
| Description |
Email address of the account (identity.accounts.email). Case-insensitive, not unique across accounts. |
| Type | String |
| Required |
Yes |
| Format |
email |
accountType
| Description |
Type of the account (identity.accounts.account_type). |
| Type | String |
| Required |
Yes |
| Enum |
- END_USER
- INSTALLER_USER
- TEXECOM_USER
|
firstName
| Description |
First name of the account holder (identity.accounts.first_name). Null when the column is unset - a snapshot states an empty field rather than omitting it, so a cleared value can converge. |
| Type | [string, null] |
| Required |
Yes |
lastName
| Description |
Last name of the account holder (identity.accounts.last_name). Null when the column is unset. |
| Type | [string, null] |
| Required |
Yes |
phoneNumber
| Description |
Phone number of the account holder (identity.accounts.phone_number). Null when the column is unset. |
| Type | [string, null] |
| Required |
Yes |
language
| Description |
ISO 639-1 language preference (identity.accounts.language). Defaults to 'en' at the column level; always the value the database committed, never one the producer assumed. |
| Type | String |
| Required |
Yes |
| Min Length |
2 |
| Max Length |
2 |
version
| Description |
Version of the account row after this update (identity.accounts.version). Incremented in SQL and read back with RETURNING, so it is the value the database committed. Downstream projections must discard this event if it is not greater than the last version they applied. |
| Type | Integer |
| Required |
Yes |
userType
| Description |
Role of an END_USER account (identity.users.user_type). Exactly one of userType, installerType and texecomUserType is present, selected by accountType. |
| Type | String |
| Required |
No |
| Enum |
- MASTER_END_USER
- STANDARD_END_USER
|
installerType
| Description |
Role of an INSTALLER_USER account (identity.installers.installer_type). Exactly one of userType, installerType and texecomUserType is present, selected by accountType. |
| Type | String |
| Required |
No |
| Enum |
- INSTALLER_ADMIN
- INSTALLER_ENGINEER
|
texecomUserType
| Description |
Role of a TEXECOM_USER account (identity.texecom_users.texecom_user_types). Exactly one of userType, installerType and texecomUserType is present, selected by accountType. |
| Type | String |
| Required |
No |
| Enum |
- TEXECOM_TECH_SUPPORT
- TEXECOM_SUPERVISOR
- SYSTEM_ADMINISTRATOR
|
groups
| Description |
Every group the account currently belongs to - user_groups for END_USER, installer_groups for INSTALLER_USER, always empty for TEXECOM_USER. An array because both membership tables are many-to-many: an installer's whole set is re-synced from the monolith on each legacy login, and end-users can be added to further groups. This is the complete set, not an addition, so a membership that has gone is expressible; consumers should converge on it rather than merge it. |
| Type | Array |
| Required |
Yes |
groups.groupId
| Description |
UUID of the group (identity.{user,installer}_groups.group_id). |
| Type | String |
| Format |
uuid |
groups.name
| Description |
Display name of the group. |
| Type | String |
groups.countryCode
| Description |
ISO 3166-1 alpha-2 country of the group. |
| Type | String |
| Min Length |
2 |
| Max Length |
2 |
groups.currency
| Description |
ISO 4217 currency of the group. |
| Type | String |
| Min Length |
3 |
| Max Length |
3 |
groups.version
| Description |
Version of the group row. The group is its own aggregate: guard on this, not on the account's version. |
| Type | Integer |
groups.monolithGroupId
| Description |
Installer groups only. Non-null means the MONOLITH owns this group, not identity-service: it was vivified locally as a placeholder (name 'Installer Group <prefix>', GB/GBP, empty businessSummary) purely so membership had something to point at. Converging the monolith onto such a row would overwrite real company detail with a stub - check this before treating a group as authoritative. Null for a natively registered group. |
| Type | [string, null] |
groups.businessSummary
| Description |
Installer groups only (identity.installer_groups.business_summary). |
| Type | String |
groups.address
| Description |
Installer groups only - the company's street address (identity.installer_groups.address), a plain string. Not to be confused with the account's top-level `address` object, which is an END_USER's home address. |
| Type | [string, null] |
groups.town
| Description |
Installer groups only (identity.installer_groups.town). |
| Type | [string, null] |
groups.postcode
| Description |
Installer groups only (identity.installer_groups.postcode). |
| Type | [string, null] |
groups.vatNumber
| Description |
Installer groups only (identity.installer_groups.vat_number). |
| Type | [string, null] |
address
| Description |
END_USER accounts only - the account holder's home address, from the identity.users row. Optional parts are explicit nulls so the object has one shape. Distinct from a group's `address`, which is an installer company's. |
| Type | Object |
| Required |
No |
Properties
address.line1
| Type | [string, null] |
| Required |
Yes |
address.line2
| Type | [string, null] |
| Required |
Yes |
address.town
| Type | [string, null] |
| Required |
Yes |
address.county
| Type | [string, null] |
| Required |
Yes |
address.postcode
| Type | [string, null] |
| Required |
Yes |
address.country
| Description |
ISO 3166-1 alpha-2. |
| Type | [string, null] |
| Required |
Yes |
Schema
{
"$id": "https://schemas.texecom-prod.com/v2/events/payload/service/identity/account/updated/v1.1.0.json",
"$schema": "http://json-schema.org/draft-07/schema",
"title": "Account Updated Payload",
"description": "Payload emitted when an identity account is updated. A full snapshot (RFC-030 SS10), not a delta: every field is present on every emission regardless of which the request changed, because the Legacy Bridge converges the monolith onto the payload rather than replaying changes. Shares its shape with the account-created payload, so a consumer can apply either through one path and resolve-or-create from whichever arrives first (RFC-030 SS18) - which matters most for legacy installers, who emit no created event at all. v1.1.0 adds phoneNumber, language, the role, groups and address; widens accountType to TEXECOM_USER; and types the nullable columns as such (SOFTC-7120).",
"type": "object",
"properties": {
"accountId": {
"description": "UUID of the account that was updated (identity.accounts.account_id).",
"type": "string",
"format": "uuid"
},
"email": {
"description": "Email address of the account (identity.accounts.email). Case-insensitive, not unique across accounts.",
"type": "string",
"format": "email"
},
"accountType": {
"description": "Type of the account (identity.accounts.account_type).",
"type": "string",
"enum": [
"END_USER",
"INSTALLER_USER",
"TEXECOM_USER"
]
},
"firstName": {
"description": "First name of the account holder (identity.accounts.first_name). Null when the column is unset - a snapshot states an empty field rather than omitting it, so a cleared value can converge.",
"type": [
"string",
"null"
]
},
"lastName": {
"description": "Last name of the account holder (identity.accounts.last_name). Null when the column is unset.",
"type": [
"string",
"null"
]
},
"phoneNumber": {
"description": "Phone number of the account holder (identity.accounts.phone_number). Null when the column is unset.",
"type": [
"string",
"null"
]
},
"language": {
"description": "ISO 639-1 language preference (identity.accounts.language). Defaults to 'en' at the column level; always the value the database committed, never one the producer assumed.",
"type": "string",
"minLength": 2,
"maxLength": 2
},
"version": {
"description": "Version of the account row after this update (identity.accounts.version). Incremented in SQL and read back with RETURNING, so it is the value the database committed. Downstream projections must discard this event if it is not greater than the last version they applied.",
"type": "integer",
"minimum": 0
},
"userType": {
"description": "Role of an END_USER account (identity.users.user_type). Exactly one of userType, installerType and texecomUserType is present, selected by accountType.",
"type": "string",
"enum": [
"MASTER_END_USER",
"STANDARD_END_USER"
]
},
"installerType": {
"description": "Role of an INSTALLER_USER account (identity.installers.installer_type). Exactly one of userType, installerType and texecomUserType is present, selected by accountType.",
"type": "string",
"enum": [
"INSTALLER_ADMIN",
"INSTALLER_ENGINEER"
]
},
"texecomUserType": {
"description": "Role of a TEXECOM_USER account (identity.texecom_users.texecom_user_types). Exactly one of userType, installerType and texecomUserType is present, selected by accountType.",
"type": "string",
"enum": [
"TEXECOM_TECH_SUPPORT",
"TEXECOM_SUPERVISOR",
"SYSTEM_ADMINISTRATOR"
]
},
"groups": {
"description": "Every group the account currently belongs to - user_groups for END_USER, installer_groups for INSTALLER_USER, always empty for TEXECOM_USER. An array because both membership tables are many-to-many: an installer's whole set is re-synced from the monolith on each legacy login, and end-users can be added to further groups. This is the complete set, not an addition, so a membership that has gone is expressible; consumers should converge on it rather than merge it.",
"type": "array",
"items": {
"type": "object",
"properties": {
"groupId": {
"description": "UUID of the group (identity.{user,installer}_groups.group_id).",
"type": "string",
"format": "uuid"
},
"name": {
"description": "Display name of the group.",
"type": "string"
},
"countryCode": {
"description": "ISO 3166-1 alpha-2 country of the group.",
"type": "string",
"minLength": 2,
"maxLength": 2
},
"currency": {
"description": "ISO 4217 currency of the group.",
"type": "string",
"minLength": 3,
"maxLength": 3
},
"version": {
"description": "Version of the group row. The group is its own aggregate: guard on this, not on the account's version.",
"type": "integer",
"minimum": 0
},
"monolithGroupId": {
"description": "Installer groups only. Non-null means the MONOLITH owns this group, not identity-service: it was vivified locally as a placeholder (name 'Installer Group <prefix>', GB/GBP, empty businessSummary) purely so membership had something to point at. Converging the monolith onto such a row would overwrite real company detail with a stub - check this before treating a group as authoritative. Null for a natively registered group.",
"type": [
"string",
"null"
]
},
"businessSummary": {
"description": "Installer groups only (identity.installer_groups.business_summary).",
"type": "string"
},
"address": {
"description": "Installer groups only - the company's street address (identity.installer_groups.address), a plain string. Not to be confused with the account's top-level `address` object, which is an END_USER's home address.",
"type": [
"string",
"null"
]
},
"town": {
"description": "Installer groups only (identity.installer_groups.town).",
"type": [
"string",
"null"
]
},
"postcode": {
"description": "Installer groups only (identity.installer_groups.postcode).",
"type": [
"string",
"null"
]
},
"vatNumber": {
"description": "Installer groups only (identity.installer_groups.vat_number).",
"type": [
"string",
"null"
]
}
},
"required": [
"groupId",
"name",
"countryCode",
"currency",
"version"
],
"additionalProperties": false
}
},
"address": {
"description": "END_USER accounts only - the account holder's home address, from the identity.users row. Optional parts are explicit nulls so the object has one shape. Distinct from a group's `address`, which is an installer company's.",
"type": "object",
"properties": {
"line1": {
"type": [
"string",
"null"
]
},
"line2": {
"type": [
"string",
"null"
]
},
"town": {
"type": [
"string",
"null"
]
},
"county": {
"type": [
"string",
"null"
]
},
"postcode": {
"type": [
"string",
"null"
]
},
"country": {
"description": "ISO 3166-1 alpha-2.",
"type": [
"string",
"null"
]
}
},
"required": [
"line1",
"line2",
"town",
"county",
"postcode",
"country"
],
"additionalProperties": false
}
},
"required": [
"accountId",
"email",
"accountType",
"firstName",
"lastName",
"phoneNumber",
"language",
"version",
"groups"
],
"oneOf": [
{
"properties": {
"accountType": {
"const": "END_USER"
}
},
"required": [
"userType"
],
"not": {
"anyOf": [
{
"required": [
"installerType"
]
},
{
"required": [
"texecomUserType"
]
}
]
}
},
{
"properties": {
"accountType": {
"const": "INSTALLER_USER"
}
},
"required": [
"installerType"
],
"not": {
"anyOf": [
{
"required": [
"userType"
]
},
{
"required": [
"texecomUserType"
]
}
]
}
},
{
"properties": {
"accountType": {
"const": "TEXECOM_USER"
}
},
"required": [
"texecomUserType"
],
"not": {
"anyOf": [
{
"required": [
"userType"
]
},
{
"required": [
"installerType"
]
}
]
}
}
],
"additionalProperties": false
}