familio

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

README

go-familio

Go client for the familio.org genealogy API. Extracted from terraform-provider-familio so the same HTTP layer is usable from CLI tools, migration scripts, and other projects.

Disclaimer

This library is an unofficial integration. familio.org publishes no write API; its endpoints were reverse-engineered from the tree editor. It is not endorsed, operated, or sponsored by familio.org, and the endpoints may change or break without notice. Use it only on your own genealogy data, with a session you established yourself.

Install

go get github.com/dmalch/go-familio

Usage

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    familio "github.com/dmalch/go-familio"
)

func main() {
    cookies := os.Getenv("FAMILIO_COOKIES")
    if cookies == "" {
        log.Fatal("set FAMILIO_COOKIES")
    }

    client, err := familio.NewClient(familio.Options{
        Cookies: familio.CookiesFromHeader(cookies),
    })
    if err != nil {
        log.Fatal(err)
    }

    person, err := client.GetPersonBasic(context.Background(), "<person-uuid>")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("name: %s\n", person.DisplayName)
}

A runnable version of this example lives in examples/getperson/.

Command-line tool

cmd/familio is a read-only CLI façade over the library — handy for quick lookups (familio person get, familio settlement get, familio whoami, …) without writing Go:

go install github.com/dmalch/go-familio/cmd/familio@latest
familio settlement persons <uuid>      # public, no auth
FAMILIO_COOKIES='t=eyJ…' familio whoami

See cmd/familio/README.md for the full command list, auth, and flags.

Auth

familio's auth is two-layer. The t session cookie alone is rejected by the authed API; familio's Next.js SSR embeds a short-lived JWT bearer in the page's __NEXT_DATA__. The client takes the t cookie, scrapes that JWT from an HTML page, caches it (refreshing ~5 minutes before its exp), and sends it as Authorization: Bearer on /api/v2/* calls. The JWT's uuid claim is the account id, exposed via Client.AccountUUID.

Supply the session cookie via Options.Cookies, built with one of:

familio.CookiesFromHeader("t=eyJ…; …")  // raw DevTools / $FAMILIO_COOKIES header
familio.CookieFromSessionToken("eyJ…")   // bare `t` value / $FAMILIO_SESSION
familio.CookiesFromBrowser("chrome")     // a logged-in browser (via sweetcookie)

The settlement-persons read is public and needs no credentials.

Behaviour

  • Rate-limited requests (via golang.org/x/time/rate); override with Options.RateLimit.
  • Retries on 429 and transient 5xx responses.
  • JWT bearer cached and refreshed automatically with a 5-minute skew before expiry.
  • ErrNotLoggedIn, ErrNotFound, and ErrAccessDenied map the auth/404/403 cases for errors.Is checks.

Documentation

API reference: https://pkg.go.dev/github.com/dmalch/go-familio

The reverse-engineered HTTP surface (endpoints, request/response shapes, the auth model) is documented in API.md.

Contributing

make test     # unit tests (no network)
make lint     # golangci-lint
make check    # build + vet + lint + test (CI parity)

The live decode test self-skips unless FAMILIO_NETWORK_TEST=1 is set; run make test-acceptance to exercise it against production data before pushing changes that touch endpoint or wire-shape code. CI does not run it.

License

Apache-2.0. See LICENSE.

Documentation

Overview

Package familio is a Go client for the familio.org genealogy API. Auth is two-layer: a session `t` cookie (installed on a jar scoped to https://familio.org/) bootstraps a JWT bearer scraped from the page's __NEXT_DATA__ (see auth.go), which authenticates the /api/v2 calls.

It covers the public settlement-persons read plus full person CRUD, life-fact events, sources, and the wedding-event (marriage) endpoints. See API.md for the endpoint reference.

Index

Constants

View Source
const (
	RangeBefore  = "before"
	RangeAfter   = "after"
	RangeBetween = "between"
)

Range kinds accepted on a DateRange (the provider's user-facing vocabulary, mirroring the sibling terraform-provider-genealogy date model).

View Source
const (
	GenderMale   = "male"
	GenderFemale = "female"

	PrivacyVisibleForAll = "visible_for_all"
	PrivacyInvisible     = "invisible"
)

Gender and privacy literals accepted by familio's /api/v2/persons surface.

View Source
const (
	EventBirth   = "birth"
	EventDeath   = "death"
	EventBaptism = "baptism" // христианское крещение (christening)
	EventWedding = "wedding"

	RoleChild  = "child"
	RoleParent = "parent"
	RoleOwner  = "owner"
	RoleSpouse = "spouse"

	// SelfRef is the placeholder personUuid for the person being created in the
	// same POST /api/v2/persons request (resolved server-side to the new uuid).
	SelfRef = "self"
)

Event types and the participant roles seen in the tree editor.

View Source
const (
	// SourceTypeCase is an archive document (дело) from the digitised
	// organization → fund → register → case catalog. Its CatalogKey is null.
	SourceTypeCase = "case"
	// SourceTypeCatalogPerson is a record from a people index
	// (persons?type=catalogPerson). Its CatalogKey names the source catalog.
	SourceTypeCatalogPerson = "catalog_person"
)

Source types — the two "add source" flows familio offers. See API.md.

Variables

View Source
var (
	// ErrNoCookies is returned when no familio.org cookies were found in any
	// browser store on the host. Log in to familio.org in a browser first.
	ErrNoCookies = errors.New("familio: no familio.org cookies found in any browser")

	// ErrFullDiskAccessRequired wraps macOS "operation not permitted" failures
	// reading browser cookie stores (e.g. Safari's container needs Full Disk
	// Access). Grant it in System Settings → Privacy & Security → Full Disk
	// Access for the binary running this code.
	ErrFullDiskAccessRequired = errors.New(
		"familio: cannot read browser cookie store (on macOS, grant Full Disk " +
			"Access in System Settings → Privacy & Security)")
)
View Source
var (
	// ErrNotFound is returned when a person/event UUID resolves to nothing
	// (HTTP 404). Resource Read paths use it to drop the resource from state.
	ErrNotFound = errors.New("familio: resource not found")

	// ErrNotLoggedIn is returned when familio.org redirects to a login page,
	// meaning the session cookie (`t`) is missing or expired.
	ErrNotLoggedIn = errors.New("familio: not logged in (session cookie missing or expired)")

	// ErrAccessDenied is returned on HTTP 401/403.
	ErrAccessDenied = errors.New("familio: access denied")
)
View Source
var FactEventTypes = []string{
	"arrest", "barMitzvah", "batMitzvah", "blessing", "militaryAward", "militaryService",
	"citizenship", "titleOfNobility", "demobilization", "immigration", "naming", "confirmation",
	"concentrationCamp", "location", "award", "education", "circumcision", "condemnation",
	"sentenceServing", "reburial", "militaryRankObtaining", "captured", "ordination", "burial",
	"conscription", "missing", "profession", "convictRehabilitation", "renaming", "resurnaming",
	"crime", "hajj", "exhumation", "emigration", "injury", "travel", "pilgrimage", "collectiveFarm",
	"party", "evacuation", "scienceDegree", "dekulakization", "treatment", "combat",
	"militaryCemetery", "heroicAct", "reference", "godparent", "warranter",
}

FactEventTypes is the set of single-subject "fact" event types a familio_event resource may carry (role "owner"). It EXCLUDES the events managed by dedicated surfaces — birth/death/baptism (folded into familio_person) and the true two-person relationship events wedding/divorce/affiance/nikah — so the two never fight over one event.

godparent (Восприемник) and warranter (Поручитель) ARE included: per Familio's own model (confirmed by their team in the official group) these are single-subject events recorded on the godparent/witness themselves — Familio deliberately does NOT link them to the specific godchild/party, so the godchild is noted in the comment, exactly as Familio's power users do. Source: the editor's event catalogue (internal/familio/API.md).

View Source
var SupportedBrowsers = []string{
	"chrome", "edge", "brave", "arc", "chromium",
	"vivaldi", "opera", "firefox", "safari",
}

SupportedBrowsers lists the browser names accepted by CookiesFromBrowser.

Functions

func ChildrenOf

func ChildrenOf(events []Event, personUUID string) []string

ChildrenOf returns the uuids of personUUID's children: the child participant of every birth event in which personUUID is a parent. It is the inverse of OwnBirthEvent (which finds the event where personUUID is the child), so a person's own birth never counts as a child.

func CookieFromSessionToken

func CookieFromSessionToken(token string) []*http.Cookie

CookieFromSessionToken wraps a bare `t` session token value (from the session_token provider attr / $FAMILIO_SESSION) as a single `t` cookie.

func CookiesFromBrowser

func CookiesFromBrowser(browsers ...string) ([]*http.Cookie, error)

CookiesFromBrowser reads valid (non-expired) familio.org cookies from the host's browser stores. With no arguments, sweetcookie's default browser priority is used; with names, only those backends are queried in order. Mirrors go-geni's browsercookies.FromGeniCom.

func CookiesFromHeader

func CookiesFromHeader(header string) []*http.Cookie

CookiesFromHeader parses a "name=value; name=value" cookie header (the form copied out of a browser's DevTools Network panel, or the $FAMILIO_COOKIES env var) into a slice of *http.Cookie suitable for Options.Cookies. Lifted from go-geni's web.CookiesFromHeader.

func SpousesOf

func SpousesOf(events []Event, personUUID string) []string

SpousesOf returns the uuids of personUUID's spouses across the wedding events they take part in (every spouse participant other than the person). Weddings that do not include the person are ignored.

Types

type BasicFields

type BasicFields struct {
	FirstName      string `json:"firstName"`
	LastName       string `json:"lastName"`
	MiddleName     string `json:"middleName"`     // отчество (patronymic)
	BirthFirstName string `json:"birthFirstName"` // maiden given name
	BirthLastName  string `json:"birthLastName"`  // maiden surname
	Gender         string `json:"gender"`
	Privacy        string `json:"privacy"`
}

BasicFields are the editable name/gender/privacy fields of a tree person — the "basic" object of POST /persons and the (flat) body of PUT /persons/<id>/basic.

type BasicRecord

type BasicRecord struct {
	BasicFields
	UUID        string `json:"uuid"`
	DisplayName string `json:"displayName"`
	CreatedAt   string `json:"createdAt"`
	UpdatedAt   string `json:"updatedAt"`
}

BasicRecord is the basic person view. GET /persons/<uuid>/basic returns it flat (no displayName); the POST /persons 201 nests it under "basic" and does include displayName, so the field is populated on create but empty on a /basic read (use GetPersonDisplay for reads).

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client talks to familio.org's /api/v2 surface with a session cookie.

Authenticated calls need a JWT bearer, which familio does not mint via an API endpoint — it embeds it in the page's __NEXT_DATA__. The client scrapes it (using the session cookie) on first use and re-scrapes when it nears expiry; see auth.go.

func NewClient

func NewClient(opts Options) (*Client, error)

NewClient builds a Client from Options.

func (*Client) AccountUUID

func (c *Client) AccountUUID(ctx context.Context) (string, error)

AccountUUID returns the uuid of the authenticated account, read from the `uuid` claim of the scraped JWT (the same value sent as ?owner= on creates). It triggers a token scrape when one has not happened yet, so it doubles as a credential check: a missing or expired session surfaces as ErrNotLoggedIn.

func (*Client) CreateEvent

func (c *Client) CreateEvent(ctx context.Context, personUUID string, ev Event) (*Event, error)

CreateEvent posts a life event anchored on a person (POST /api/v2/persons/<uuid>/events). The event is visible on every participant's /events; anchor on any participant. Returns the created event (with its new uuid).

func (*Client) CreatePerson

func (c *Client) CreatePerson(ctx context.Context, in CreatePersonInput) (*createResponse, error)

CreatePerson mints a new tree person (POST /api/v2/persons), owned by the authenticated account. Returns the server's basic record (incl. the new uuid) and the events it created.

func (*Client) CreateSource

func (c *Client) CreateSource(ctx context.Context, personUUID string, ref SourceRef) (*Source, error)

CreateSource attaches a source citation to a person (POST /api/v2/persons/<uuid>/sources). Returns the enriched source.

func (*Client) DeleteEvent

func (c *Client) DeleteEvent(ctx context.Context, personUUID, eventUUID string) error

DeleteEvent removes an event (DELETE /api/v2/persons/<uuid>/events/<eventUuid>). personUUID may be any participant of the event.

func (*Client) DeletePerson

func (c *Client) DeletePerson(ctx context.Context, uuid string) error

DeletePerson removes a tree person (DELETE /api/v2/persons/<uuid>).

func (*Client) DeleteSource

func (c *Client) DeleteSource(ctx context.Context, personUUID, sourceUUID string) error

DeleteSource removes a source citation from a person (DELETE /api/v2/persons/<uuid>/sources/<sourceUuid>) → 204.

func (*Client) GetPersonBasic

func (c *Client) GetPersonBasic(ctx context.Context, uuid string) (*BasicRecord, error)

GetPersonBasic reads the editable basic fields (+ timestamps) of a person. ErrNotFound ⇒ the person is gone; the Read path drops it from state.

func (*Client) GetPersonDisplay

func (c *Client) GetPersonDisplay(ctx context.Context, uuid string) (*personDisplay, error)

GetPersonDisplay reads the computed display name from the regularPerson view.

func (*Client) GetPersonEvents

func (c *Client) GetPersonEvents(ctx context.Context, uuid string) ([]Event, error)

GetPersonEvents reads a person's life events (for birth/death dates).

func (*Client) GetPersonRegular

func (c *Client) GetPersonRegular(ctx context.Context, uuid string) (*RegularRecord, error)

GetPersonRegular reads the regularPerson view, including the owning account (ownerId) used to tell one's own tree from other researchers' profiles.

func (*Client) GetPersonSources

func (c *Client) GetPersonSources(ctx context.Context, personUUID string) ([]Source, error)

GetPersonSources lists a person's source citations (GET /api/v2/persons/<uuid>/sources).

func (*Client) GetSettlement

func (c *Client) GetSettlement(ctx context.Context, uuid string) (*SettlementDetail, error)

GetSettlement reads a settlement's full record (GET /api/v2/settlements/<uuid>, Bearer). Returns ErrNotFound for an unknown uuid.

func (*Client) ListSettlementPersons

func (c *Client) ListSettlementPersons(ctx context.Context, settlement string) ([]Person, error)

ListSettlementPersons returns every person (catalog-sourced + user-created) linked to a settlement, paging through GET /api/v2/persons?settlement=<uuid>. This is the one fully-known, public endpoint and the provider's working read path. Callers filter by CatalogKey client-side (there is no server-side catalog facet).

func (*Client) UpdatePersonBasic

func (c *Client) UpdatePersonBasic(ctx context.Context, uuid string, fields BasicFields, version string) (*BasicRecord, error)

UpdatePersonBasic edits a person's basic fields. version is the optimistic- lock token (the updatedAt last read from GetPersonBasic), sent in the X-Base-Version header that familio's editor uses; a stale value is rejected with HTTP 409. Returns the refreshed basic record.

func (*Client) UpdateSourceComment

func (c *Client) UpdateSourceComment(ctx context.Context, personUUID, sourceUUID, comment string) (*Source, error)

UpdateSourceComment edits a source's comment in place (PATCH /api/v2/persons/<uuid>/sources/<sourceUuid>). Only the comment is mutable; the reference is fixed. Returns the updated source.

type Coordinate

type Coordinate struct {
	Type        string    `json:"type"`
	Coordinates []float64 `json:"coordinates"`
}

Coordinate is a GeoJSON Point: Coordinates is [longitude, latitude].

func (*Coordinate) LatLon

func (c *Coordinate) LatLon() (lat, lon float64, ok bool)

LatLon returns (latitude, longitude, ok); ok is false when the coordinate is absent or malformed.

type CreatePersonInput

type CreatePersonInput struct {
	Basic  BasicFields
	Events []Event
}

CreatePersonInput is the caller-facing create payload: the basic fields plus the life events to attach. Exactly one birth event is required; build them with SelfBirthEvent / SelfDeathEvent.

type DatePart

type DatePart struct {
	Day   *int   `json:"day"`
	Month *int   `json:"month"`
	Year  int    `json:"year"`
	Type  string `json:"type"`
}

DatePart is one endpoint of a complex date. Year is required; Month/Day are optional (nil ⇒ unspecified). Type carries the per-part calendar.

type DateRange

type DateRange struct {
	Year  int
	Month *int
	Day   *int
	Circa bool

	Range    string // "" | RangeBefore | RangeAfter | RangeBetween
	EndYear  *int
	EndMonth *int
	EndDay   *int
	EndCirca bool

	Calendar string // "" => gregorian
}

DateRange is the provider's domain value object for a genealogical date: a primary {Year,Month,Day}, an optional approximation (Circa) or bound/range (Range plus the End* second date), and a Calendar. It mirrors the date model of the sibling terraform-provider-genealogy so configs read the same across both providers.

familio's wire shape (EventDate{calendar,type,first,second}) is an infrastructure detail; translate with EventDateFromRange / RangeFromEventDate. familio carries a single whole-date `type`, so Circa maps to type "about" and Range to before/after/between — the two are mutually exclusive on familio and the schema rejects combining them (familio has no per-endpoint approximation, so EndCirca is accepted only for cross-provider config symmetry and never reaches the wire).

func RangeFromEventDate

func RangeFromEventDate(date EventDate) *DateRange

RangeFromEventDate translates a wire EventDate back into the domain DateRange for read-back. It returns nil when the date is unknown (no first part). gregorian is the default calendar, so it surfaces as an empty Calendar (no spurious diff against a config that omits calendar).

type Event

type Event struct {
	UUID         *string       `json:"uuid"` // null on create; real uuid on read-back
	Type         string        `json:"type"`
	Date         EventDate     `json:"date"`
	Participants []Participant `json:"participants"`
	Settlement   *Settlement   `json:"settlement"` // place (Место); nil ⇒ null (no place)
	Comment      string        `json:"comment"`
	CreatedAt    string        `json:"createdAt,omitempty"`
	UpdatedAt    string        `json:"updatedAt,omitempty"`
}

Event is a life event (birth/death/wedding) with its participants.

func BaptismEvent

func BaptismEvent(date *DateRange, ownerRef, place, comment string) Event

BaptismEvent builds a christening (familio "baptism") event owned by ownerRef (SelfRef on create, or the person's uuid otherwise). Unlike birth/death, a baptism is a repeatable fact event: re-POSTing does NOT replace it, so editing a christening date means deleting the old event and creating a new one. place is the christening settlement uuid ("" ⇒ no place); comment is free text.

func BirthEvent

func BirthEvent(date *DateRange, childRef string, parents []string, place, comment string) Event

BirthEvent builds a birth event for childRef (SelfRef when the child is being created in the same POST /persons request, or the child's uuid when rebuilding an existing person's birth event), attaching 0–2 parent persons (role "parent"). familio upserts a person's single birth event by its child participant, so POSTing this event replaces the whole event (participants + date) in place — that is how parents are added/removed and the birth date is edited without recreating the person. place is the birth settlement uuid ("" ⇒ no place) and comment is free text; like the date they are part of the event and must be re-sent on every upsert (a full replace would otherwise clear them).

func DeathEvent

func DeathEvent(date *DateRange, ownerRef, place, comment string) Event

DeathEvent builds a death event owned by ownerRef (SelfRef on create, or the person's uuid when upserting an existing person's death event). Like the birth event, re-POSTing it replaces the person's single death event in place. place is the death settlement uuid ("" ⇒ no place); comment is free text.

func FactEvent

func FactEvent(eventType string, date *DateRange, ownerRef, comment string) Event

FactEvent builds a single-subject fact event (role "owner") of the given type for ownerRef, with a free-text comment. Pass nil for an unknown date.

func FindByID

func FindByID(events []Event, uuid string) *Event

FindByID returns the event with the given uuid, or nil.

func OwnBirthEvent

func OwnBirthEvent(events []Event, personUUID string) *Event

OwnBirthEvent returns the birth event in which personUUID is the child — the person's *own* birth. A person who is also a parent has the births of their children on their /events too (where they are the parent), so a plain type-filter is not enough. Returns nil when there is no such event yet. On a create read-back the child participant carries the resolved uuid, so passing the new uuid works there too.

func SelfBaptismEvent

func SelfBaptismEvent(date *DateRange, place, comment string) Event

SelfBaptismEvent builds an optional christening event for the person being created.

func SelfBirthEvent

func SelfBirthEvent(date *DateRange, place, comment string) Event

SelfBirthEvent builds the mandatory birth event for the person being created. Pass nil for an unknown date and "" for no place/comment.

func SelfDeathEvent

func SelfDeathEvent(date *DateRange, place, comment string) Event

SelfDeathEvent builds an optional death event for the person being created.

func WeddingEvent

func WeddingEvent(date *DateRange, partnerA, partnerB, comment string) Event

WeddingEvent builds a marriage event linking two existing persons as spouses. Pass nil for an unknown date and "" for no comment.

func (*Event) ID

func (e *Event) ID() string

ID returns the event's uuid (empty when unset, e.g. a request-side event).

func (*Event) ParentUUIDs

func (e *Event) ParentUUIDs() []string

ParentUUIDs returns the personUuids of an event's parent participants.

func (*Event) SettlementUUID

func (e *Event) SettlementUUID() string

SettlementUUID returns the event's place uuid, or "" when no place is set.

func (*Event) SpouseUUIDs

func (e *Event) SpouseUUIDs() []string

SpouseUUIDs returns the personUuids of an event's spouse participants.

type EventDate

type EventDate struct {
	Calendar string    `json:"calendar"`
	Type     string    `json:"type"`
	First    *DatePart `json:"first"`
	Second   *DatePart `json:"second"`
	// Formatted is server-computed on reads; never sent.
	Formatted string `json:"formatted,omitempty"`
}

EventDate is familio's complex-date object. A nil First means "date unknown".

func EventDateFromRange

func EventDateFromRange(r *DateRange) EventDate

EventDateFromRange translates the domain DateRange into familio's wire EventDate. A nil DateRange is an unknown date (no parts). This is the single place that knows familio's calendar/type/first/second encoding.

type FlexDate

type FlexDate struct {
	Formatted string
	Present   bool
}

FlexDate tolerates familio's heterogeneous date encodings: a JSON null, a plain string, or a structured object {type, calendar, first, second, formatted}. It exposes the human-readable "formatted" form.

func (*FlexDate) UnmarshalJSON

func (d *FlexDate) UnmarshalJSON(b []byte) error

func (FlexDate) Value

func (d FlexDate) Value() (string, bool)

Value returns the formatted date and whether a non-empty value is present.

type Georequisite

type Georequisite struct {
	Level1 string `json:"level1"`
	Level2 string `json:"level2"`
	Year   int    `json:"year"`
}

Georequisite is one administrative «реквизит» of a settlement: the level-1 (region/oblast) and level-2 (district/city) administrative units as of Year.

type Options

type Options struct {
	// Cookies carries the familio.org session. NewClient installs them on a
	// cookie jar scoped to BaseURL. Build with CookiesFromHeader (paste from
	// DevTools / $FAMILIO_COOKIES) or CookiesFromBrowser (sweetcookie).
	Cookies []*http.Cookie

	// BaseURL overrides https://familio.org/. Useful for tests; production
	// callers should leave it empty.
	BaseURL string

	// UserAgent is sent on every request. Defaults to defaultUserAgent.
	UserAgent string

	// RateLimit caps outgoing requests in requests-per-second. Defaults to
	// defaultRateLimit if unset or non-positive.
	RateLimit float64

	// HTTPClient overrides the default *http.Client. NewClient always sets its
	// Jar from Cookies and its CheckRedirect to detect login bounces, so the
	// override does not need to.
	HTTPClient *http.Client
}

Options configures a Client. At least one cookie carrying the `t` session token should be supplied for any authenticated (write, or gated read) call; the public settlement-persons read works without one.

type Participant

type Participant struct {
	PersonUUID  string `json:"personUuid"`
	Role        string `json:"role"`
	DisplayName string `json:"displayName,omitempty"`
	Gender      string `json:"gender,omitempty"`
}

Participant links a person into an event by role.

type Person

type Person struct {
	UUID                string   `json:"uuid"`
	DisplayName         string   `json:"displayName"`
	ShortDisplayName    string   `json:"shortDisplayName"`
	CatalogKey          *string  `json:"catalogKey"`
	CatalogName         string   `json:"catalogName"`
	Type                string   `json:"type"`
	Gender              string   `json:"gender"`
	BirthDate           FlexDate `json:"birthDate"`
	DeathDate           FlexDate `json:"deathDate"`
	HasDeathEvent       bool     `json:"hasDeathEvent"`
	BirthSettlementText string   `json:"birthSettlementText"`
	UpdatedAt           string   `json:"updatedAt"`
}

Person is one entry from GET /api/v2/persons. The data array is heterogeneous: catalog persons carry catalogKey/catalogName, while user-created tree persons instead carry gender/birthPlace/ownerId/etc. CatalogKey is a pointer so a JSON null (tree person) is distinguishable from an empty string; birth/death dates use FlexDate because familio encodes them as null, a string, or an object depending on the record.

type RegularRecord

type RegularRecord struct {
	UUID        string `json:"uuid"`
	DisplayName string `json:"displayName"`
	OwnerID     string `json:"ownerId"`
	Gender      string `json:"gender"`
	PrivacyType string `json:"privacyType"`
}

RegularRecord is the slice of the regularPerson view (GET /persons/<uuid>) the provider surfaces beyond the basic record: notably ownerId, the account that owns the profile, which is not present on the public settlement list.

type Settlement

type Settlement struct {
	UUID string `json:"uuid"`
}

Settlement is a place attached to an event — familio's «Место рождения / смерти / etc.». The write contract is a structured object, NOT a bare uuid: a bare string is rejected (HTTP 400). The minimal accepted body is `{"uuid": "<id>"}`; the server enriches the name and administrative requisites («реквизиты»), which come back on read but are not needed by the provider, so only the uuid is modelled (extra read fields are ignored). See the "Settlement / place on events" section of internal/familio/API.md.

func SettlementRef

func SettlementRef(uuid string) *Settlement

SettlementRef wraps a settlement uuid as an event place. An empty uuid yields nil — i.e. no place (which clears any existing place on an upsert).

type SettlementDetail

type SettlementDetail struct {
	UUID             string        `json:"uuid"`
	PrimaryName      string        `json:"primaryName"`
	AdditionalNames  []string      `json:"additionalNames"`
	MainGeorequisite *Georequisite `json:"mainGeorequisite"`
	Type             string        `json:"type"`   // settlement kind, e.g. «село», «город».
	Status           string        `json:"status"` // e.g. «жилой» (inhabited).
	Coordinate       *Coordinate   `json:"coordinate"`
}

SettlementDetail is the full settlement record from GET /api/v2/settlements/<uuid>: the canonical name, its administrative requisites («реквизиты»), classification and coordinates. Distinct from the Settlement write-ref above (which carries only the uuid). nearestSettlements is returned by the API but not surfaced by the provider.

type Source

type Source struct {
	UUID       string         `json:"uuid"`
	Type       string         `json:"type"`
	Comment    string         `json:"comment"`
	Name       string         `json:"name,omitempty"`
	Requisites string         `json:"requisites,omitempty"`
	Years      string         `json:"years,omitempty"`
	Catalog    *SourceCatalog `json:"catalog,omitempty"`
	CreatedAt  string         `json:"createdAt,omitempty"`
	UpdatedAt  string         `json:"updatedAt,omitempty"`
}

Source is a person's source citation (the «Источники» sub-resource). It is an immutable reference to a catalogued entity (UUID + Type + CatalogKey) plus an editable Comment. Name/Requisites/Years/Catalog are server-derived and read back only (never sent). The referenced entity's UUID is the source's identity within the person, so a person cannot cite the same entity twice.

func FindSourceByID

func FindSourceByID(sources []Source, uuid string) *Source

FindSourceByID returns the source with the given (entity) uuid, or nil.

type SourceCatalog

type SourceCatalog struct {
	Key    string `json:"key"`
	Hidden bool   `json:"hidden"`
}

SourceCatalog is the server-derived catalog descriptor on a catalog_person source. The API returns it as an OBJECT ({key, hidden}); a `case` source omits it. UnmarshalJSON also tolerates a bare string or null for forward-compat.

func (*SourceCatalog) String

func (c *SourceCatalog) String() string

String renders the catalog for the computed `catalog` attribute: its key (the stable catalog id, e.g. "vss"), or "" when absent.

func (*SourceCatalog) UnmarshalJSON

func (c *SourceCatalog) UnmarshalJSON(b []byte) error

type SourceRef

type SourceRef struct {
	UUID       string  `json:"uuid"`
	Type       string  `json:"type"`
	CatalogKey *string `json:"catalogKey"`
}

SourceRef is the write body of a source create: the reference triple familio accepts. CatalogKey is sent explicitly (null for a `case`, the catalog id for a `catalog_person`) — it is write-only and never echoed on reads.

Directories

Path Synopsis
cmd
familio command
Command familio is a read-only command-line client for the familio.org genealogy API.
Command familio is a read-only command-line client for the familio.org genealogy API.
examples
getperson command
Command getperson is a minimal smoke example that constructs a go-familio Client from a session cookie and fetches a single person's basic record.
Command getperson is a minimal smoke example that constructs a go-familio Client from a session cookie and fetches a single person's basic record.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL