External identifiers for parties (passport, SSN, microchip, tax ID, etc.)
| Tier | identity |
| Role | unclassified (baselined) |
| Path | crates/identity/identifiers |
| Edition | 2021 |
| Targets | identity_identifiers, integration_tests |
| Public items | 7 across 1 module |
| Tests | 28 |
What it is for
# identity-identifiers
External identifier library crates for attaching IDs to any party.
Core Concepts
- Generic FK pattern: Attach identifiers to any party using
party_type+party_id - Multiple identifiers per party: Animals can have microchip AND tattoo AND registry
- Verification tracking: Track if an identifier has been verified
- Expiration support: Handle IDs that expire (passports, licenses)
Example
use identity_identifiers::{Identifier, IdentifierType, PartyId, PartyType};
// Create a microchip identifier for an animal
let microchip = Identifier::new(
PartyType::Animal,
PartyId::new_v4(),
IdentifierType::Microchip,
"985141404123456",
)
.with_issuer("AVID")
.verified();
// Create a passport for a person
let passport = Identifier::new(
PartyType::Person,
PartyId::new_v4(),
IdentifierType::Passport,
"AB1234567",
)
.with_issuer("US Department of State")
.with_country("US")
.with_expiry(chrono::Utc::now() + chrono::Duration::days(3650));
Capabilities
repo (other)
Repository functions for identifier models.
| Item |
|---|
async fn create_identifier(pool : & PgPool, identifier : & Identifier,) -> Result <Identifier, IdentifierError> |
async fn find_identifier_by_id(pool : & PgPool, id : Uuid,) -> Result <Option <Identifier>, IdentifierError> |
async fn find_identifiers_for_party(pool : & PgPool, party_type : PartyType, party_id : PartyId,) -> Result <Vec <Identifier>, IdentifierError> |
async fn find_identifier_by_value(pool : & PgPool, identifier_type : IdentifierType, value : & str,) -> Result <Option <Identifier>, IdentifierError> |
async fn find_primary_identifier(pool : & PgPool, party_type : PartyType, party_id : PartyId, identifier_type : IdentifierType,) -> Result <Option <Identifier>, IdentifierError> |
async fn verify_identifier(pool : & PgPool, id : Uuid, verified_by : Option <Uuid>,) -> Result <(), IdentifierError> |
async fn soft_delete_identifier(pool : & PgPool, id : Uuid) -> Result <(), IdentifierError> |
How to use it
From this crate's own rustdoc:
use identity_identifiers::{Identifier, IdentifierType, PartyId, PartyType};
// Create a microchip identifier for an animal
let microchip = Identifier::new(
PartyType::Animal,
PartyId::new_v4(),
IdentifierType::Microchip,
"985141404123456",
)
.with_issuer("AVID")
.verified();
// Create a passport for a person
let passport = Identifier::new(
PartyType::Person,
PartyId::new_v4(),
IdentifierType::Passport,
"AB1234567",
)
.with_issuer("US Department of State")
.with_country("US")
.with_expiry(chrono::Utc::now() + chrono::Duration::days(3650));
Module structure
identity_identifiers
repo
Public surface
`repo`
| Item | What it is |
|---|---|
async fn create_identifier(pool : & PgPool, identifier : & Identifier,) -> Result <Identifier, IdentifierError> | Create a new identifier in the database |
async fn find_identifier_by_id(pool : & PgPool, id : Uuid,) -> Result <Option <Identifier>, IdentifierError> | Find an identifier by ID |
async fn find_identifiers_for_party(pool : & PgPool, party_type : PartyType, party_id : PartyId,) -> Result <Vec <Identifier>, IdentifierError> | Find all identifiers for a party |
async fn find_identifier_by_value(pool : & PgPool, identifier_type : IdentifierType, value : & str,) -> Result <Option <Identifier>, IdentifierError> | Find identifier by type and value (for uniqueness checks) |
async fn find_primary_identifier(pool : & PgPool, party_type : PartyType, party_id : PartyId, identifier_type : IdentifierType,) -> Result <Option <Identifier>, IdentifierError> | Find the primary identifier of a given type for a party |
async fn verify_identifier(pool : & PgPool, id : Uuid, verified_by : Option <Uuid>,) -> Result <(), IdentifierError> | Mark an identifier as verified |
async fn soft_delete_identifier(pool : & PgPool, id : Uuid) -> Result <(), IdentifierError> | Soft delete an identifier |
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
IdentifierError | error::IdentifierError |
{HasId,SoftDeletable,Timestamped} | foundation_basemodels::{HasId,SoftDeletable,Timestamped} |
{Identifier,IdentifierType} | identifier::{Identifier,IdentifierType} |
{PartyId,PartyType} | identity_parties::{PartyId,PartyType} |
Boundary
Reaches into foundation.
Shares tier identity with 7 other crates: identity-auth, identity-impersonation, identity-parties, identity-party-places, identity-rbac, identity-tenant, identity-user-prefs.
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | identity |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/identity/identifiers |
| Vocabulary in force (lexicon) | current |
Tier flow. Which tiers this crate's own edges cross.
flowchart LR n_identity["identity"] --> n_foundation["foundation"]
Dependencies
Runtime, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `foundation-basemodels` | foundation | no | always |
| `identity-parties` | identity | no | always |
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
chrono | ^0.4 | serde | no | always |
serde | ^1 | derive | no | always |
serde_json | ^1 | — | no | always |
sqlx | ^0.8 | runtime-tokio, postgres, chrono, uuid, json | no | always |
thiserror | ^2 | — | no | always |
uuid | ^1 | v4, v7, serde, js | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
dotenvy | ^0.15 | — | no | always |
tokio | ^1 | full | no | always |
tokio-test | ^0.4 | — | no | always |
Build. None.
Depended on by. 1 workspace crate.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_application_identifiers["application-identifiers"] -->|uses| SELF SELF["identity-identifiers"] SELF -->|runtime| n_foundation_basemodels["foundation-basemodels"] SELF -->|runtime| n_identity_parties["identity-parties"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
| Feature | Enables | On by default |
|---|---|---|
postgres | — | no |
flowchart LR n_postgres["postgres"]
Targets
| Kind | Name | Source |
|---|---|---|
| lib | identity_identifiers | `src/lib.rs` |
| test | integration_tests | `tests/integration_tests.rs` |
Error model
No public error type was detected: no public item declares a type named *Error, and no public signature returns one.
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | yes |
| async runtime | none detected |
| database access | yes |
| network I/O | none detected |
| unsafe code | none detected |
| environment variables | none detected |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.
Related capabilities
1 workspace crate depends on this one: application-identifiers.
Verification
| Kind | Count |
|---|---|
| Unit tests | 21 |
| Integration tests | 7 |
| Examples | 0 |
| Doctests | 1 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
repo | 7 | 0 | 0 |
What the tests establish, by name:
test_create_identifier_for_person—tests/integration_tests.rstest_find_identifier_by_id—tests/integration_tests.rstest_find_identifier_by_value—tests/integration_tests.rstest_find_identifiers_for_party—tests/integration_tests.rstest_find_primary_identifier—tests/integration_tests.rstest_soft_delete_identifier—tests/integration_tests.rstest_verify_identifier—tests/integration_tests.rstest_create_microchip_identifier—src/lib.rstest_create_passport_identifier—src/lib.rstest_create_tax_id_identifier—src/lib.rstest_expired_identifier—src/lib.rstest_identifier_belongs_to—src/lib.rstest_identifier_error_helpers—src/lib.rstest_identifier_has_id_trait—src/lib.rstest_identifier_is_valid—src/lib.rstest_identifier_masked_value—src/lib.rstest_identifier_short_value_masked—src/lib.rstest_identifier_soft_delete—src/lib.rstest_identifier_type_as_str—src/lib.rstest_identifier_type_is_sensitive—src/lib.rstest_identifier_type_parse—src/lib.rstest_identifier_type_typically_expires—src/lib.rstest_identifier_verified_by—src/lib.rstest_identifier_with_issued_at—src/lib.rstest_identifier_with_notes—src/lib.rstest_multiple_identifiers_for_animal—src/lib.rstest_party_type_as_str—src/lib.rstest_party_type_parse—src/lib.rs
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 7 | 7 |
Public modules with a //! block | 1 | 1 |
pie showData
title Public items with rustdoc
"Documented" : 7
"No rustdoc detected" : 0
Metrics
| Metric | Value |
|---|---|
| Rust source files | 4 |
| Source lines | 1083 |
| Code lines | 763 |
| Public API items | 7 |
| Public modules | 1 |
| Tests | 28 |
| Examples | 0 |
| Cargo features | 1 |
| Direct runtime dependencies | 8 |
| Workspace reverse dependencies | 1 |
pie showData
title Public API by kind
"function" : 7
pie showData
title Rust source composition
"Code" : 763
"Blank or comment" : 320
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.