domain

package
v0.46.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: AGPL-3.0 Imports: 20 Imported by: 0

Documentation

Overview

Package domain holds the entities, value objects and signal rules of Arnakoff. It is pure Go: no I/O, no clock and no logging (ADR 0002).

Index

Constants

View Source
const MaxKeyLabelRunes = 100

MaxKeyLabelRunes is the longest label ParseKeyLabel accepts, in runes.

View Source
const NoSignalSummary = "Aucun signal connu dans nos sources"

NoSignalSummary is the summary of a report without any signal. It never says the input is safe: an absence from the sources proves nothing.

Variables

View Source
var (
	// ErrInvalidDomain means the input is not a domain name or a web URL.
	ErrInvalidDomain = errors.New("invalid domain")
	// ErrUnsupportedScheme means the input is a URL whose scheme is neither
	// http nor https.
	ErrUnsupportedScheme = fmt.Errorf("%w: unsupported URL scheme", ErrInvalidDomain)
	// ErrIPAddress means the host is an IP address, not a domain name.
	ErrIPAddress = fmt.Errorf("%w: IP address", ErrInvalidDomain)
)

Domain errors. ErrUnsupportedScheme and ErrIPAddress also match ErrInvalidDomain with errors.Is.

View Source
var (
	ErrSnapshotSource        = errors.New("snapshot of another source")
	ErrSnapshotEmpty         = errors.New("snapshot has no row")
	ErrSnapshotTooSmall      = errors.New("snapshot has fewer rows than expected")
	ErrSnapshotColumnMissing = errors.New("missing column")
	ErrSnapshotShrunk        = errors.New("shrunk by more than 20 %")
)

Snapshot validation errors, checked with errors.Is.

View Source
var ErrInvalidAPIKey = errors.New("invalid API key")

ErrInvalidAPIKey means a string is not a well-formed API key: wrong prefix, environment, length, alphabet or checksum.

View Source
var ErrInvalidEmail = errors.New("invalid email address")

ErrInvalidEmail means the input is not a single email address with a valid domain. Its message never quotes the input, which is personal data.

View Source
var ErrInvalidIBAN = errors.New("invalid IBAN")

ErrInvalidIBAN means the input is not a valid IBAN. Its message never quotes the input, which is personal data.

View Source
var ErrInvalidKeyLabel = errors.New("invalid API key label")

ErrInvalidKeyLabel means a key label is empty, too long or holds a control character.

View Source
var ErrInvalidPhone = errors.New("invalid phone number")

ErrInvalidPhone means the input is not a single dialable phone number. Its message never quotes the input, which is personal data.

View Source
var ErrInvalidRange = errors.New("invalid numbering range")

ErrInvalidRange means a range of phone numbers is not one of the French numbering plan, or overlaps another.

View Source
var ErrInvalidSIREN = errors.New("invalid SIREN")

ErrInvalidSIREN means the input is not a valid SIREN number.

View Source
var ErrInvalidSIRET = errors.New("invalid SIRET")

ErrInvalidSIRET means the input is not a valid SIRET number.

View Source
var ErrUnknownKind = errors.New("unknown input kind")

ErrUnknownKind means a name is not the name of an input kind.

View Source
var ErrUnrecognisedInput = errors.New("unrecognised input")

ErrUnrecognisedInput means the input is not a domain, a web URL, an email address, a phone number, an IBAN, a SIREN or a SIRET. When a kind was assumed, the error also wraps that kind's error, such as ErrInvalidIBAN. The message may quote part of an input read as a domain: log the kind of error, matched with errors.Is, not its text.

Functions

func DecodeName added in v0.29.0

func DecodeName(name string) string

DecodeName returns name with its A-labels decoded to Unicode under the profile that encodes them ("xn--bcher-kva.de" is "bücher.de"), or name as it is when it does not decode.

func FormatDate

func FormatDate(t time.Time) string

FormatDate formats t as a French date, JJ/MM/AAAA, in t's own location. The caller picks the location (Europe/Paris for user-facing dates): the domain loads no time zone data.

func KindNames added in v0.45.0

func KindNames() []string

KindNames returns the name of every kind ParseKind accepts, in the order of the kinds; "auto" is not one of them.

func NumberingPlanCovers added in v0.28.0

func NumberingPlanCovers(p Phone) bool

NumberingPlanCovers reports whether p belongs to the French numbering plan, metropolitan France and the overseas departments and regions that dial as French numbers: only those can be looked up in a NumberingPlan.

func ParseKeyLabel added in v0.39.0

func ParseKeyLabel(s string) (string, error)

ParseKeyLabel trims the spaces around s and accepts from 1 to MaxKeyLabelRunes runes of valid UTF-8 with no control character, which would garble a listing.

Types

type APIKey added in v0.39.0

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

APIKey is an API key: "ark_live_" or "ark_test_", 30 random base62 characters, then the CRC-32 of everything before it in 6 base62 characters, which lets a scanner tell a real key from a look-alike without asking the API. It is a secret: only Redacted may be logged. The zero value is not a valid key.

func NewAPIKey added in v0.39.0

func NewAPIKey(env KeyEnvironment, random io.Reader) (APIKey, error)

NewAPIKey draws a new key of env from random, such as crypto/rand.Reader.

func ParseAPIKey added in v0.39.0

func ParseAPIKey(s string) (APIKey, error)

ParseAPIKey reads a key as NewAPIKey writes it, exactly: no space, no change of case.

func (APIKey) Environment added in v0.39.0

func (k APIKey) Environment() KeyEnvironment

Environment returns where the key is valid.

func (APIKey) Hint added in v0.39.0

func (k APIKey) Hint() string

Hint returns the last 4 characters of the key, part of its checksum: they tell keys apart in a listing and reveal nothing of the random part.

func (APIKey) Redacted added in v0.39.0

func (k APIKey) Redacted() string

Redacted returns the prefix and the hint, such as "ark_live_…a1B2": safe for logs.

func (APIKey) String added in v0.39.0

func (k APIKey) String() string

String returns the whole key: a secret, shown once to its holder.

type Authorisation added in v0.26.0

type Authorisation struct {
	// Name is the provider or offer name, as the publisher lists it.
	Name string
	// Number is the publisher's number of the authorisation or offer.
	Number string
	// Kind is the kind of authorisation ("Agrément MICA"), "" when the list
	// has one kind only.
	Kind string
	// From is the day the authorisation started.
	From time.Time
	// Until is the day it ended, zero while it runs.
	Until time.Time
}

Authorisation is one entry of a white list: a provider or an offer the publisher authorised or registered, under a site, an address, a phone number or a SIREN.

func (Authorisation) Ended added in v0.26.0

func (a Authorisation) Ended() bool

Ended reports whether the authorisation has ended.

type Blacklist added in v0.25.0

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

Blacklist indexes the listings of one blacklist by the host or address they name. Once built it is read-only: readers share it.

func NewBlacklist added in v0.25.0

func NewBlacklist() *Blacklist

NewBlacklist returns an empty Blacklist.

func (*Blacklist) AddEmail added in v0.25.0

func (b *Blacklist) AddEmail(e Email, l Listing)

AddEmail lists the address e alone.

func (*Blacklist) AddSite added in v0.25.0

func (b *Blacklist) AddSite(d Domain, l Listing)

AddSite lists the whole site d: its host and every subdomain of it. A "www." host names its site, so www.exemple.fr lists exemple.fr, unless that is a public suffix.

func (*Blacklist) Listings added in v0.25.0

func (b *Blacklist) Listings(in Input) []Listing

Listings returns the listings that cover in, nil when none does: for an address, those of the address itself; for a domain, those of its host, then of each host it is a subdomain of. A listed site thus covers its subdomains, never its parent. The caller must not change the listings it gets.

type Company added in v0.21.0

type Company struct {
	// Name is the company's full name, as SIRENE writes it.
	Name string
	// Created is when the company was created.
	Created time.Time
	// HeadOfficeClosed reports whether SIRENE lists the head office as
	// closed.
	HeadOfficeClosed bool
	// HeadOfficeClosedOn is when the head office closed.
	HeadOfficeClosedOn time.Time
	// URL is the public address the register published the record at,
	// where anyone can check it.
	URL string
}

Company holds what the SIRENE register publishes about a company and its head office (siège), and nothing about the people who run it. A zero time means the register did not publish that date.

type Domain added in v0.2.0

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

Domain is a normalised domain name: lower case, A-labels, no final dot. The zero value is not a valid domain.

func ParseDomain added in v0.2.0

func ParseDomain(s string) (Domain, error)

ParseDomain normalises a domain name or a web URL, as a user would paste it, into a Domain. A URL keeps its host only: credentials before the host are dropped, as a browser does ("https://amf-france.org@exemple.com" is exemple.com). Only http and https URLs are accepted, and IP addresses are reported with ErrIPAddress.

func ParseRegistrable added in v0.29.1

func ParseRegistrable(s string) (Domain, error)

ParseRegistrable parses s, which must be a normalised registrable domain as Registrable returns it ("linktr.ee", not "www.linktr.ee" nor "Linktr.ee"), as the rows of a reference list name domains.

func (Domain) Kind added in v0.7.0

func (Domain) Kind() Kind

Kind returns KindDomain.

func (Domain) Label added in v0.29.0

func (d Domain) Label() string

Label returns the registrable domain less its public suffix, the name a registrant chose: "ameli" for www.ameli.fr, "atos-limited" for www.atos-limited.co.uk.

func (Domain) Registrable added in v0.2.0

func (d Domain) Registrable() string

Registrable returns the public suffix plus one label, the part a registrant controls: "groupe-ytria.com" for www.groupe-ytria.com, "atos-limited.co.uk" for www.atos-limited.co.uk. Private suffixes of the Public Suffix List count, so arnaque.github.io is its own registrable domain.

func (Domain) String added in v0.2.0

func (d Domain) String() string

String returns the normalised name, such as "www.groupe-ytria.com".

type Email added in v0.3.0

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

Email is an email address: the local part as written, the domain normalised by ParseDomain's rules. It is personal data: log Redacted, never String. The zero value is not a valid address.

func ParseEmail added in v0.3.0

func ParseEmail(s string) (Email, error)

ParseEmail reads a single RFC 5322 address, as a user would paste it from a message header ("Service client <contact@exemple.fr>"), and keeps the address only. The local part keeps its case, since RFC 5321 lets the receiving server tell cases apart. Nothing is checked over the network.

func (Email) Domain added in v0.3.0

func (e Email) Domain() Domain

Domain returns the domain part.

func (Email) Kind added in v0.7.0

func (Email) Kind() Kind

Kind returns KindEmail.

func (Email) Local added in v0.3.0

func (e Email) Local() string

Local returns the local part, unquoted.

func (Email) Redacted added in v0.3.0

func (e Email) Redacted() string

Redacted returns a form safe for logs, the domain only: "***@exemple.fr".

func (Email) String added in v0.3.0

func (e Email) String() string

String returns the address, such as "Jean.Dupont@exemple.fr", with the local part quoted when RFC 5322 requires it.

type IBAN added in v0.5.0

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

IBAN is an International Bank Account Number in electronic form, upper case without spaces. It is personal data: log Redacted, never String. The zero value is not a valid IBAN.

func ParseIBAN added in v0.5.0

func ParseIBAN(s string) (IBAN, error)

ParseIBAN reads an IBAN as a user would write it, in electronic form ("FR1420041010050500013M02606") or paper form ("FR14 2004 1010 0505 0001 3M02 606"), in any case and with any spaces between characters. The country's length and format and the check digits are validated; the account is not checked for existing.

func (IBAN) Country added in v0.5.0

func (i IBAN) Country() string

Country returns the ISO 3166-1 alpha-2 code of the country holding the account, the IBAN's first two letters, such as "FR".

func (IBAN) FrenchBankCode added in v0.5.0

func (i IBAN) FrenchBankCode() (string, bool)

FrenchBankCode returns the five-digit bank code ("code banque") of a French IBAN, the first five characters after the check digits, such as "20041". It reports false for an IBAN of any other country.

func (IBAN) Kind added in v0.7.0

func (IBAN) Kind() Kind

Kind returns KindIBAN.

func (IBAN) Redacted added in v0.5.0

func (i IBAN) Redacted() string

Redacted returns a form safe for logs, the country and the last four characters only: "FR***2606". The zero value gives "***".

func (IBAN) String added in v0.5.0

func (i IBAN) String() string

String returns the IBAN in electronic form, such as "FR1420041010050500013M02606".

type Input added in v0.7.0

type Input interface {
	Kind() Kind
	String() string
	// contains filtered or unexported methods
}

Input is a parsed input: a Domain, an Email, a Phone, an IBAN, a SIREN or a SIRET. Use a type switch to reach the value. String returns the normalised form, which is personal data for an Email, a Phone and an IBAN.

func ParseInput added in v0.7.0

func ParseInput(raw string, hint Kind) (Input, error)

ParseInput reads what a user pasted into an Input. A hint other than KindAuto forces that kind. KindAuto detects the kind from the input's shape, in this order:

  1. an "@" outside a URL: an email address ("contact@exemple.fr");
  2. only letters, digits and spaces, starting with two letters then two digits: an IBAN ("FR14 2004 …");
  3. only digits and spaces: nine digits are a SIREN, even with a wrong check digit; fourteen digits are a SIRET, or else a phone number ("0044 20 7946 0958"); any other count is a phone number;
  4. only digits, spaces and "+.-/()": a phone number ("+33 6 12 34 56 78");
  5. anything else: a domain or a web URL.

The error matches ErrUnrecognisedInput and, once a kind is assumed, the error of the first kind tried.

type KeyDigest added in v0.39.0

type KeyDigest [sha256.Size]byte

KeyDigest is the HMAC-SHA256 of an API key: what is stored in place of the key. Keyed with a secret of the application kept out of the store, a copy of the store alone does not let anyone check a guessed key.

func DigestAPIKey added in v0.39.0

func DigestAPIKey(secret []byte, k APIKey) KeyDigest

DigestAPIKey returns the KeyDigest of k under secret.

type KeyEnvironment added in v0.39.0

type KeyEnvironment int

KeyEnvironment tells where an API key is valid: production or the staging and development environments. The zero value is none.

const (
	KeyLive KeyEnvironment = iota + 1
	KeyTest
)

The environments of an API key.

func ParseKeyEnvironment added in v0.39.0

func ParseKeyEnvironment(s string) (KeyEnvironment, error)

ParseKeyEnvironment reads "live" or "test".

func (KeyEnvironment) String added in v0.39.0

func (e KeyEnvironment) String() string

String returns "live" or "test", the name the prefix of a key carries.

type KeyRecord added in v0.39.0

type KeyRecord struct {
	// ID identifies the key in the administration command; the store sets
	// it.
	ID int64
	// Digest is the KeyDigest of the key.
	Digest KeyDigest
	// Environment is where the key is valid.
	Environment KeyEnvironment
	// Label tells the operator whom the key was issued to.
	Label string
	// Hint is APIKey.Hint, to tell keys apart in a listing.
	Hint string
	// CreatedAt is when the key was issued.
	CreatedAt time.Time
	// RevokedAt is when the key was revoked; zero while it is active.
	RevokedAt time.Time
}

KeyRecord is what is kept about an issued API key: never the key itself.

func (KeyRecord) Active added in v0.39.0

func (r KeyRecord) Active() bool

Active reports whether the key was never revoked.

type Kind added in v0.7.0

type Kind uint8

Kind is the kind of an Input.

const (
	KindAuto Kind = iota
	KindDomain
	KindEmail
	KindPhone
	KindIBAN
	KindSIREN
	KindSIRET
)

Input kinds. KindAuto, the zero value, is no kind: as a hint to ParseInput, it asks for the kind to be detected.

func ParseKind added in v0.23.0

func ParseKind(s string) (Kind, error)

ParseKind returns the kind named s, as Kind.String writes it, such as "iban". "auto" is not a kind and is rejected.

func (Kind) String added in v0.7.0

func (k Kind) String() string

String returns the lower-case name of k, such as "iban".

type Level

type Level int

Level is the severity of a signal. Levels are ordered: a greater Level is more severe, so levels compare with the usual operators. The zero value is not a valid level.

const (
	// LevelInfo is a neutral fact worth knowing.
	LevelInfo Level = iota + 1
	// LevelAttention is a heuristic that calls for a check before acting.
	LevelAttention
	// LevelAlert is a fact an authority published, such as a blacklist entry.
	LevelAlert
)

Signal levels, from the least to the most severe.

func (Level) String

func (l Level) String() string

String returns the level's stable French code: "info", "attention" or "alerte".

type Listing added in v0.25.0

type Listing struct {
	// Categories are the publisher's categories, as it labels them.
	Categories []string
	// ListedOn is the day the publisher listed the entry.
	ListedOn time.Time
}

Listing is one inscription of a site or an address on a blacklist.

type Notice added in v0.22.0

type Notice struct {
	// ID is the BODACC's identifier of the notice, such as "A202601993983".
	ID string
	// Kind is the notice's family.
	Kind NoticeKind
	// Published is the day the BODACC published the notice.
	Published time.Time
	// URL is the notice's public page on the BODACC.
	URL string
}

Notice is a notice the BODACC published about a company, and nothing about the people it names.

type NoticeKind added in v0.22.0

type NoticeKind int

NoticeKind is the family of a BODACC notice that bears on a company's state. Each is a BODACC family as the BODACC names it, kept apart: what a family means for a signal is the signal's rule.

const (
	// NoticeCollectiveProcedure is « Procédures collectives ».
	NoticeCollectiveProcedure NoticeKind = iota + 1
	// NoticeRadiation is « Radiations ».
	NoticeRadiation
	// NoticeConciliation is « Procédures de conciliation ».
	NoticeConciliation
	// NoticeProfessionalRecovery is « Procédures de rétablissement
	// professionnel ».
	NoticeProfessionalRecovery
)

The BODACC families read; the BODACC's own label is quoted.

type NumberAssignment added in v0.28.0

type NumberAssignment struct {
	// Prefix is the range's prefix ("EZABPQM"), such as "0612".
	Prefix string
	// Operator is the code of the operator holding the range, such as
	// "SFR0".
	Operator string
	// OperatorName and OperatorSIREN are "" when the regulator does not
	// give them; OperatorSIREN also for a foreign operator.
	OperatorName  string
	OperatorSIREN string
	// Territory is where the range is used, as the regulator names it
	// ("Métropole", "Martinique", "National").
	Territory string
	// AssignedOn is the day the range was assigned.
	AssignedOn time.Time
}

NumberAssignment is a range of phone numbers the national regulator assigned and who it assigned it to. It says which operator holds a number's range, nothing about who uses the number, which may have been ported to another operator.

type NumberRange added in v0.28.0

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

NumberRange is an assigned range of numbers of the same number of digits, first and last included.

func NewNumberRange added in v0.28.0

func NewNumberRange(first, last string, a NumberAssignment) (NumberRange, error)

NewNumberRange returns the range from first to last, numbers in national form of the same number of digits, assigned as a. It rejects with ErrInvalidRange bounds that are not numbers of the plan, as when a spreadsheet drops the leading zero, or a first number after the last.

type NumberingPlan added in v0.28.0

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

NumberingPlan indexes the assigned ranges of the French numbering plan. Once built it is read-only: readers share it.

func NewNumberingPlan added in v0.28.0

func NewNumberingPlan(ranges []NumberRange) (*NumberingPlan, error)

NewNumberingPlan indexes ranges, which it does not change. It rejects with ErrInvalidRange ranges that overlap: a number would then have two holders.

func (*NumberingPlan) Lookup added in v0.28.0

func (np *NumberingPlan) Lookup(p Phone) (NumberAssignment, bool)

Lookup returns the assignment of the range p falls in. It reports false for a number outside the French numbering plan or in no assigned range: such a number cannot be in service.

type Phone added in v0.4.0

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

Phone is a phone number in E.164 form. It is personal data: log Redacted, never String. The zero value is not a valid number.

func ParsePhone added in v0.4.0

func ParsePhone(s string) (Phone, error)

ParsePhone reads a phone number as a user would write it, in French national form ("06 12 34 56 78") or international form ("+33 6 12 34 56 78", "0033 6 12 34 56 78"), with spaces, dots, dashes, slashes or brackets between digits. National overseas numbers ("0690 12 34 56") get their overseas country code. Letters, extensions and short numbers are rejected. The number is checked for a plausible length, not for being in service: that is ARCEP's numbering plan's job.

func (Phone) CountryCode added in v0.4.0

func (p Phone) CountryCode() int

CountryCode returns the country calling code, such as 33.

func (Phone) FrenchNational added in v0.4.0

func (p Phone) FrenchNational() (string, bool)

FrenchNational returns the number as dialled within France, ten digits starting with 0 ("0612345678"), the form ARCEP's numbering plan ranges use. It reports false for a number outside the French numbering plan (metropolitan France and the overseas departments and regions above).

func (Phone) Kind added in v0.7.0

func (Phone) Kind() Kind

Kind returns KindPhone.

func (Phone) Redacted added in v0.4.0

func (p Phone) Redacted() string

Redacted returns a form safe for logs, the country code and the last two digits only: "+33***78". The zero value gives "***".

func (Phone) String added in v0.4.0

func (p Phone) String() string

String returns the number in E.164 form, such as "+33612345678".

type Platforms added in v0.29.1

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

Platforms are the shared platforms that host their users' pages under a path of their own registrable domain (linktr.ee/x, t.me/x): a page there is a user's, never the platform's site. Its zero value lists none.

func NewPlatforms added in v0.29.1

func NewPlatforms(domains []string) (Platforms, error)

NewPlatforms returns the Platforms of domains, each a normalised registrable domain listed once.

func (Platforms) PageStandsForSite added in v0.29.1

func (p Platforms) PageStandsForSite(d Domain) bool

PageStandsForSite reports whether a list entry that names a page of the host d stands for the whole site of d. It does when d is its registrable domain, with or without "www.", and that domain is no shared platform: a subdomain may be one of many sites its registrant hosts (sites.google.com/view/x), and a platform hosts its users' pages.

type Registration added in v0.20.0

type Registration struct {
	// Registered is when the domain was first registered.
	Registered time.Time
	// LastChanged is when the registry last changed the domain's record.
	LastChanged time.Time
	// URL is the public address the registry published the record at,
	// where anyone can check the dates.
	URL string
}

Registration holds the dates a domain registry publishes about a registrable domain, and nothing about its holder. A zero time means the registry did not publish that date.

type Report

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

Report is the result of checking one input at one time: its signals, most severe first, and the state of each source consulted. A Report is immutable: its accessors return copies.

func NewReport

func NewReport(input string, checkedAt time.Time, signals []Signal, sources []SourceState) Report

NewReport builds the report for the normalised input, checked at checkedAt. A signal repeating the code, source and message of an earlier one is dropped. Signals are sorted by level, most severe first; signals of equal level keep their order. The slices are copied, the caller's are left untouched.

func (Report) CheckedAt added in v0.35.0

func (r Report) CheckedAt() time.Time

CheckedAt returns when the input was checked.

func (Report) Input

func (r Report) Input() string

Input returns the normalised input that was checked.

func (Report) Signals

func (r Report) Signals() []Signal

Signals returns a copy of the signals, most severe first.

func (Report) Sources

func (r Report) Sources() []SourceState

Sources returns a copy of the state of each source.

func (Report) Summary added in v0.24.0

func (r Report) Summary() string

Summary returns NoSignalSummary when the report has no signal, and "" otherwise: the signals speak for themselves.

type SIREN added in v0.6.0

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

SIREN is the nine-digit number the SIRENE register gives to a company. The zero value is not a valid SIREN.

func ParseSIREN added in v0.6.0

func ParseSIREN(s string) (SIREN, error)

ParseSIREN reads a SIREN as a user would write it, nine digits alone ("120027016") or in groups ("120 027 016") with any spaces between them. The Luhn check digit is validated; the company is not checked for existing.

func (SIREN) Kind added in v0.7.0

func (SIREN) Kind() Kind

Kind returns KindSIREN.

func (SIREN) String added in v0.6.0

func (n SIREN) String() string

String returns the nine digits, such as "120027016".

type SIRET added in v0.6.0

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

SIRET is the fourteen-digit number the SIRENE register gives to an establishment: the company's SIREN followed by a five-digit NIC. The zero value is not a valid SIRET.

func ParseSIRET added in v0.6.0

func ParseSIRET(s string) (SIRET, error)

ParseSIRET reads a SIRET as a user would write it, fourteen digits alone ("12002701600563") or in groups ("120 027 016 00563") with any spaces between them. The SIREN part and the whole number are checked; the establishment is not checked for existing.

func (SIRET) Kind added in v0.7.0

func (SIRET) Kind() Kind

Kind returns KindSIRET.

func (SIRET) NIC added in v0.6.0

func (n SIRET) NIC() string

NIC returns the five-digit establishment number ("numéro interne de classement"), the last five digits, such as "00563".

func (SIRET) SIREN added in v0.6.0

func (n SIRET) SIREN() SIREN

SIREN returns the SIREN of the company the establishment belongs to, the first nine digits, such as "120027016".

func (SIRET) String added in v0.6.0

func (n SIRET) String() string

String returns the fourteen digits, such as "12002701600563".

type Signal

type Signal struct {
	// Code is the stable snake_case identifier of the rule, such as
	// "amf_blacklist". It is part of the public contract.
	Code string
	// Level is the severity of the signal.
	Level Level
	// Message is one factual French sentence stating what was observed.
	Message string
	// Advice is an optional French sentence telling the user what to do.
	Advice string
	// Source is the upstream source the fact comes from.
	Source Source
	// SourceURL is the public page where the fact can be checked.
	SourceURL string
	// ObservedAt is when the fact was read from the source.
	ObservedAt time.Time
}

Signal is one sourced fact about a checked input. Every field but Advice is set: a signal without its source and observation date is not published.

type Snapshot added in v0.13.0

type Snapshot struct {
	// Source is the upstream source the file comes from.
	Source Source
	// Header names the fields of each row, in order.
	Header []string
	// Rows holds the entries, one slice of fields per row.
	Rows [][]string
	// FetchedAt is when the file was downloaded.
	FetchedAt time.Time
	// Newest is the date of the most recent entry, zero when the source
	// dates none.
	Newest time.Time
}

Snapshot is one validated copy of an upstream file, as rows of fields under a header. It is read-only once built: readers share it.

type SnapshotSpec added in v0.13.0

type SnapshotSpec struct {
	Source  Source
	Columns []string
	MinRows int
}

SnapshotSpec is what a connector declares about its source's file: the columns it reads and the least number of rows a sane file holds.

func (SnapshotSpec) Validate added in v0.13.0

func (spec SnapshotSpec) Validate(s Snapshot, previousRows int) error

Validate reports why s cannot replace a snapshot of previousRows rows (0 when there is none), or nil when it can.

type Source

type Source string

Source names an upstream data source, as shown to users ("AMF", "SIRENE").

type SourceInfo added in v0.37.0

type SourceInfo struct {
	Name Source
	// Publisher is the body that publishes the source.
	Publisher string
	// Licence is the licence the source is reused under.
	Licence string
	// URL is the public page of the source.
	URL string
}

SourceInfo is what a source is, as GET /v1/sources shows it: who publishes it, under which licence it is reused and where to read it.

type SourceState

type SourceState struct {
	Source Source
	Status SourceStatus
}

SourceState is the status of one source in a report.

type SourceStatus

type SourceStatus int

SourceStatus tells how a source took part in a check. The zero value is not a valid status.

const (
	// SourceOK means the source was consulted.
	SourceOK SourceStatus = iota + 1
	// SourceUnavailable means the source could not be consulted: the absence
	// of a signal from it proves nothing.
	SourceUnavailable
	// SourceNotApplicable means the source does not cover this input type.
	SourceNotApplicable
)

Source statuses.

func (SourceStatus) String

func (s SourceStatus) String() string

String returns the status's stable French code: "ok", "indisponible" or "non_applicable", the values of the public contract.

type Whitelist added in v0.26.0

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

Whitelist indexes the authorisations of one white list by the site, address, phone number or SIREN they name. Once built it is read-only: readers share it.

func NewWhitelist added in v0.26.0

func NewWhitelist() *Whitelist

NewWhitelist returns an empty Whitelist.

func (*Whitelist) AddEmail added in v0.26.0

func (w *Whitelist) AddEmail(e Email, a Authorisation)

AddEmail lists the address e alone.

func (*Whitelist) AddPhone added in v0.26.0

func (w *Whitelist) AddPhone(p Phone, a Authorisation)

AddPhone lists the phone number p.

func (*Whitelist) AddSIREN added in v0.26.0

func (w *Whitelist) AddSIREN(n SIREN, a Authorisation)

AddSIREN lists the company n: its SIREN and every SIRET of it.

func (*Whitelist) AddSite added in v0.26.0

func (w *Whitelist) AddSite(d Domain, a Authorisation)

AddSite lists the whole site d: its host and every subdomain of it. A "www." host names its site, unless its site is a public suffix.

func (*Whitelist) Authorisations added in v0.26.0

func (w *Whitelist) Authorisations(in Input) []Authorisation

Authorisations returns the authorisations that cover in, nil when none does. A listed site covers its subdomains, never its parent; a listed SIREN covers the SIRETs of the company. The caller must not change the authorisations it gets.

Directories

Path Synopsis
Package signal holds the signal rules: pure functions from domain values to signals, with the French wording of each in one place (docs/signals.md).
Package signal holds the signal rules: pure functions from domain values to signals, with the French wording of each in one place (docs/signals.md).

Jump to

Keyboard shortcuts

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