Module V1.Contact

Contact metadata with temporal support.

Contact schema V1 with temporal support.

This module defines the V1 contact schema with support for time-bounded information such as emails and organizations that are valid only during specific periods.

Schema Version Policy:

Schema Version

val version : int

The schema version number for V1. Currently 1.

Types

type contact_kind =
  1. | Person
    (*

    Individual person

    *)
  2. | Organization
    (*

    Company, lab, department

    *)

Contact kind - what type of entity this represents.

type activitypub_variant =
  1. | Mastodon
    (*

    Mastodon instance

    *)
  2. | Pixelfed
    (*

    Pixelfed instance

    *)
  3. | PeerTube
    (*

    PeerTube instance

    *)
  4. | Other_activitypub of string
    (*

    Other ActivityPub-compatible service

    *)

ActivityPub service variants.

type service_kind =
  1. | ActivityPub of activitypub_variant
    (*

    ActivityPub-compatible services

    *)
  2. | Github
    (*

    GitHub

    *)
  3. | Git
    (*

    GitLab, Gitea, Codeberg, etc

    *)
  4. | Twitter
    (*

    Twitter/X

    *)
  5. | LinkedIn
    (*

    LinkedIn

    *)
  6. | Photo
    (*

    Immich, Flickr, Instagram, etc

    *)
  7. | Custom of string
    (*

    Other service types

    *)

Service kind - categorization of online presence.

type service = {
  1. url : string;
    (*

    Full URL (primary identifier)

    *)
  2. kind : service_kind option;
    (*

    Optional service categorization

    *)
  3. handle : string option;
    (*

    Optional short handle/username

    *)
  4. label : string option;
    (*

    Human description: "Cambridge GitLab", "Work account"

    *)
  5. range : Sortal_schema__.Sortal_schema_temporal.range option;
    (*

    Temporal validity

    *)
  6. primary : bool;
    (*

    Is this the primary/preferred service of its kind?

    *)
}

An online service/identity.

type email_type =
  1. | Work
  2. | Personal
  3. | Other
type email = {
  1. address : string;
  2. type_ : email_type option;
  3. range : Sortal_schema__.Sortal_schema_temporal.range option;
    (*

    Validity period

    *)
  4. note : string option;
    (*

    Context note, e.g., "NetApp position"

    *)
}
type organization = {
  1. name : string;
  2. title : string option;
  3. department : string option;
  4. range : Sortal_schema__.Sortal_schema_temporal.range option;
    (*

    Employment period

    *)
  5. email : string option;
    (*

    Work email during this period

    *)
  6. url : string option;
    (*

    Work homepage during this period

    *)
  7. address : string option;
    (*

    Office/postal address

    *)
}
type url_entry = {
  1. url : string;
  2. label : string option;
    (*

    Human-readable label

    *)
  3. range : Sortal_schema__.Sortal_schema_temporal.range option;
    (*

    Validity period

    *)
}
type atproto_service_type =
  1. | ATBluesky
  2. | ATTangled
  3. | ATCustom of string

AT Protocol service type.

type atproto_service = {
  1. atp_type : atproto_service_type;
  2. atp_url : string;
}

An AT Protocol service entry.

type atproto = {
  1. atp_handle : string;
  2. atp_did : string option;
    (*

    None until sync resolves

    *)
  3. atp_services : atproto_service list;
}

AT Protocol identity with handle, cached DID, and services.

type t = {
  1. version : int;
    (*

    Schema version (always 1 for V1)

    *)
  2. kind : contact_kind;
    (*

    Type of entity (Person, Organization, etc)

    *)
  3. handle : string;
    (*

    Unique identifier

    *)
  4. names : string list;
    (*

    Names, first is primary

    *)
  5. emails : email list;
    (*

    Email addresses with temporal validity

    *)
  6. organizations : organization list;
    (*

    Employment/affiliation history

    *)
  7. urls : url_entry list;
    (*

    URLs with optional temporal validity

    *)
  8. services : service list;
    (*

    Online services/identities

    *)
  9. icon : string option;
    (*

    Avatar URL

    *)
  10. thumbnail : string option;
    (*

    Local thumbnail path

    *)
  11. orcid : string option;
    (*

    ORCID identifier

    *)
  12. feeds : Sortal_schema__.Sortal_schema_feed.t list option;
    (*

    Feed subscriptions

    *)
  13. atproto : atproto option;
    (*

    AT Protocol identity

    *)
}

Construction

val make : handle:string -> names:string list -> ?kind:contact_kind -> ?emails:email list -> ?organizations:organization list -> ?urls:url_entry list -> ?services:service list -> ?icon:string -> ?thumbnail:string -> ?orcid:string -> ?feeds:Sortal_schema__.Sortal_schema_feed.t list -> ?atproto:atproto -> unit -> t

make ~handle ~names ?kind ?emails ?organizations ?urls ?services ?icon ?thumbnail ?orcid ?feeds () creates a new V1 contact.

The version field is automatically set to 1. The kind defaults to Person if not specified.

Email Helpers

val make_email : ?type_:email_type -> ?from:Ptime.date -> ?until:Ptime.date -> ?note:string -> string -> email

make_email ?type_ ?from ?until ?note address creates an email entry.

  • parameter type_

    Email type (Work, Personal, Other)

  • parameter from

    Start date of validity

  • parameter until

    End date of validity (exclusive)

  • parameter note

    Contextual note

val email_of_string : string -> email

email_of_string s creates a simple always-valid personal email.

Organization Helpers

val make_org : ?title:string -> ?department:string -> ?from:Ptime.date -> ?until:Ptime.date -> ?email:string -> ?url:string -> ?address:string -> string -> organization

make_org ?title ?department ?from ?until ?email ?url ?address name creates an organization entry.

URL Helpers

val make_url : ?label:string -> ?from:Ptime.date -> ?until:Ptime.date -> string -> url_entry

make_url ?label ?from ?until url creates a URL entry.

val url_of_string : string -> url_entry

url_of_string s creates a simple always-valid URL.

Service Helpers

val make_service : ?kind:service_kind -> ?handle:string -> ?label:string -> ?from:Ptime.date -> ?until:Ptime.date -> ?primary:bool -> string -> service

make_service ?kind ?handle ?label ?from ?until ?primary url creates a service entry.

  • parameter kind

    Optional service categorization

  • parameter handle

    Optional short handle/username

  • parameter label

    Optional description (e.g., "Work account", "Cambridge GitLab")

  • parameter from

    Start date of validity

  • parameter until

    End date of validity (exclusive)

  • parameter primary

    Whether this is the primary service of its kind

  • parameter url

    Full URL to the service (required)

val service_of_url : string -> service

service_of_url url creates a simple always-valid service from just a URL.

Accessors

val version_of : t -> int
val kind : t -> contact_kind
val handle : t -> string
val names : t -> string list
val name : t -> string
val primary_name : t -> string
val emails : t -> email list
val organizations : t -> organization list
val urls : t -> url_entry list
val services : t -> service list
val icon : t -> string option
val thumbnail : t -> string option
val orcid : t -> string option
val feeds : t -> Sortal_schema__.Sortal_schema_feed.t list option

ATProto Accessors

val atproto : t -> atproto option

atproto t returns the AT Protocol identity if present.

val atproto_handle : t -> string option

atproto_handle t returns the AT Protocol handle if present.

val atproto_did : t -> string option

atproto_did t returns the cached DID if resolved.

val atproto_services : t -> atproto_service list

atproto_services t returns the list of AT Protocol services.

val set_atproto_did : t -> string -> t

set_atproto_did t did returns a contact with the DID set.

Service Convenience Accessors

These accessors provide easy access to common service types.

val github : t -> service option

github t returns the GitHub service entry if present.

val github_handle : t -> string option

github_handle t returns the GitHub username if present.

val twitter : t -> service option

twitter t returns the Twitter/X service entry if present.

val twitter_handle : t -> string option

twitter_handle t returns the Twitter/X username if present.

val mastodon : t -> service option

mastodon t returns the Mastodon service entry if present.

val mastodon_handle : t -> string option

mastodon_handle t returns the Mastodon handle if present.

val bluesky_handle : t -> string option

bluesky_handle t returns the Bluesky handle from AT Protocol identity if present.

val linkedin : t -> service option

linkedin t returns the LinkedIn service entry if present.

val linkedin_handle : t -> string option

linkedin_handle t returns the LinkedIn handle if present.

val instagram : t -> service option

instagram t returns the Instagram/Photo service entry if present.

val peertube : t -> service option

peertube t returns the PeerTube service entry if present.

val threads : t -> service option

threads t returns the Threads service entry if present.

val matrix : t -> service option

matrix t returns the Matrix service entry if present.

val zulip : t -> service option

zulip t returns the Zulip service entry if present.

val discourse : t -> service list

discourse t returns all Discourse service entries.

Temporal Queries

val email_at : t -> date:Ptime.date -> string option

email_at t ~date returns the primary email valid at date.

val emails_at : t -> date:Ptime.date -> email list

emails_at t ~date returns all emails valid at date.

val current_email : t -> string option

current_email t returns the current primary email.

val organization_at : t -> date:Ptime.date -> organization option

organization_at t ~date returns the organization at date.

val current_organization : t -> organization option

current_organization t returns the current organization.

val current_organizations : t -> organization list

current_organizations t returns all current organizations.

val url_at : t -> date:Ptime.date -> string option

url_at t ~date returns the primary URL valid at date.

val current_url : t -> string option

current_url t returns the current primary URL.

val all_email_addresses : t -> string list

all_email_addresses t returns all email addresses (any period).

val best_url : t -> string option

best_url t returns the best available URL (current URL or service fallback).

Service Queries

val services_of_kind : t -> service_kind -> service list

services_of_kind t kind returns all services matching the given kind.

val services_at : t -> date:Ptime.date -> service list

services_at t ~date returns all services valid at date.

val current_services : t -> service list

current_services t returns all currently valid services.

val primary_service : t -> service_kind -> service option

primary_service t kind returns the primary service of the given kind.

Modification

val add_feed : t -> Sortal_schema__.Sortal_schema_feed.t -> t
val remove_feed : t -> string -> t

Comparison and Display

val compare : t -> t -> int
val pp : Format.formatter -> t -> unit

JSON Encoding

val json_t : t Jsont.t

json_t is the jsont encoder/decoder for V1 contacts.

The schema includes a version field that is always encoded and must equal 1 when decoded.

Type Utilities

val contact_kind_to_string : contact_kind -> string
val contact_kind_of_string : string -> contact_kind option
val activitypub_variant_to_string : activitypub_variant -> string
val activitypub_variant_of_string : string -> activitypub_variant
val service_kind_to_string : service_kind -> string
val service_kind_of_string : string -> service_kind option
val email_type_to_string : email_type -> string
val email_type_of_string : string -> email_type option
val atproto_service_type_to_string : atproto_service_type -> string
val atproto_service_type_of_string : string -> atproto_service_type