erDiagram
"auth.otp" |o--|| "auth.accounts" : "FOREIGN KEY (user_email) REFERENCES auth.accounts(email) ON DELETE CASCADE"
"auth.vessels" }o--|| "auth.accounts" : "FOREIGN KEY (owner_email) REFERENCES auth.accounts(email) ON DELETE CASCADE"
"auth.otp" {
text otp_pass ""
timestamp_with_time_zone otp_timestamp ""
smallint otp_tries ""
citext user_email FK ""
}
"auth.accounts" {
timestamp_with_time_zone connected_at ""
timestamp_with_time_zone created_at ""
citext email ""
text first "User first name with CONSTRAINT CHECK"
text last "User last name with CONSTRAINT CHECK"
text pass ""
jsonb preferences "User-identity preferences. Always-present keys: email_notifications (bool),\n language (ISO 639-1, default #quot;gb#quot;).\n public_windy (bool) as user-controlled toggle.\n public_* visibility fields kept temporarily pending web UI rework.\n badges per account\n telegram, pushover_user_key, phone_notifications: user-identity notification\n credentials."
name role ""
timestamp_with_time_zone updated_at ""
text user_id ""
}
"auth.vessels" {
timestamp_with_time_zone created_at ""
numeric mmsi "MMSI as a validated numeric value with CHECK constraint enforcing range.\n Intentionally differs from api.metadata.mmsi (text, permissive).\n This is the authoritative MMSI — api.metadata.mmsi is the raw SignalK input."
text name ""
citext owner_email FK ""
name role ""
timestamp_with_time_zone updated_at ""
text vessel_id ""
}