Forge parties module — Person/Organization/Group/Animal with relationships + contact info. Wraps identity-parties + identity-party-places.
| Tier | application |
| Role | unclassified (baselined) |
| Path | crates/application/parties |
| Edition | 2024 |
| Targets | application_parties, pg_forge_parties, pg_party_addresses |
| Public items | 53 across 5 modules |
| Tests | 118 |
What it is for
application-parties — Person/Organization/Group/Animal modeling.
Capabilities
PartiesModule
application-parties — Person/Organization/Group/Animal modeling.
| Item |
|---|
pub struct PartiesModule |
PartiesModule :: fn new() -> Self |
PartiesModule :: fn name(& self) -> & 'static str |
PartiesModule :: fn version(& self) -> & 'static str |
PartiesModule :: fn migrations(& self) -> Vec <MigrationSet> |
PartiesModule :: async fn migrate_pending(& self, pool : & PgPool) -> std::result::Result <u32, MigrationError> |
PartiesModule :: fn permission_codes(& self) -> Vec <String> |
api (other)
HTTP API routers for application-parties.
| Item |
|---|
fn admin_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, |
api::organizations_admin (other)
Organizations admin REST router.
| Item |
|---|
pub const MAX_PAGE_SIZE: u32 |
pub const DEFAULT_PAGE_SIZE: u32 |
fn opt(s : & str) -> Option <String> |
fn to_summary(o : & Organization) -> OrganizationSummary |
fn to_detail(o : & Organization) -> OrganizationDetail |
fn organization_from_create(req : & CreateOrganizationRequest,) -> Result <Organization, PartyError> |
fn apply_update(o : & mut Organization, req : & UpdateOrganizationRequest) |
fn clamp_paging(page : Option <u32>, page_size : Option <u32>) ->(u32, u32) |
fn page_offset(page : u32, page_size : u32) -> i64 |
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, |
ListOrganizationsQuery
Organizations admin REST router.
| Item |
|---|
pub struct ListOrganizationsQuery |
TenantQuery
Organizations admin REST router.
| Item |
|---|
pub struct TenantQuery |
api::party_places_admin (other)
Party-address admin REST router.
| Item |
|---|
fn party_address_from_create(req : & CreatePartyAddressRequest,) -> Result <NewPartyAddress, PartyAddressRequestError> |
fn apply_update_fields(existing : & PartyAddress, req : & UpdatePartyAddressRequest,) -> Result <UpdatedPartyAddress, PartyAddressRequestError> |
fn to_dto(a : & PartyAddress) -> PartyAddressDto |
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, |
ListPartyAddressesQuery
Party-address admin REST router.
| Item |
|---|
pub struct ListPartyAddressesQuery |
NewPartyAddress
Party-address admin REST router.
| Item |
|---|
pub struct NewPartyAddress |
PartyAddressRequestError
Party-address admin REST router.
| Item |
|---|
pub enum PartyAddressRequestError |
TenantQuery
Organizations admin REST router.
| Item |
|---|
pub struct TenantQuery |
UpdatedPartyAddress
Party-address admin REST router.
| Item |
|---|
pub struct UpdatedPartyAddress |
api::persons_admin (other)
Persons admin REST router — the backend the staff-ui parties module has
| Item |
|---|
pub const MAX_PAGE_SIZE: u32 |
pub const DEFAULT_PAGE_SIZE: u32 |
fn opt(s : & str) -> Option <String> |
fn parse_lead_source(s : & str) -> Option <LeadSource> |
fn to_summary(p : & Person) -> PersonSummary |
fn to_detail(p : & Person) -> PersonDetail |
fn person_from_create(req : & CreatePersonRequest) -> Result <Person, PartyError> |
fn apply_update(p : & mut Person, req : & UpdatePersonRequest) -> Result <(), PartyError> |
fn clamp_paging(page : Option <u32>, page_size : Option <u32>) ->(u32, u32) |
fn page_offset(page : u32, page_size : u32) -> i64 |
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, |
ListPersonsQuery
Persons admin REST router — the backend the staff-ui parties module has
| Item |
|---|
pub struct ListPersonsQuery |
TenantQuery
Organizations admin REST router.
| Item |
|---|
pub struct TenantQuery |
api::relationships_admin (other)
Relationships admin REST router.
| Item |
|---|
pub const MAX_PAGE_SIZE: u32 |
pub const DEFAULT_PAGE_SIZE: u32 |
fn opt(s : & str) -> Option <String> |
fn to_dto(r : & PartyRelationship) -> RelationshipDto |
fn relationship_from_create(req : & CreateRelationshipRequest,) -> Result <PartyRelationship, PartyError> |
fn apply_update(r : & mut PartyRelationship, req : & UpdateRelationshipRequest) |
fn clamp_paging(page : Option <u32>, page_size : Option <u32>) ->(u32, u32) |
fn page_offset(page : u32, page_size : u32) -> i64 |
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, |
ListRelationshipsQuery
Relationships admin REST router.
| Item |
|---|
pub struct ListRelationshipsQuery |
TenantQuery
Organizations admin REST router.
| Item |
|---|
pub struct TenantQuery |
How to use it
No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.
Module structure
application_parties
apiapi::organizations_adminapi::party_places_adminapi::persons_adminapi::relationships_admin
flowchart TD n_application_parties["application_parties"] n_application_parties --> n_api["api"] n_api --> n_api__organizations_admin["organizations_admin"] n_api --> n_api__party_places_admin["party_places_admin"] n_api --> n_api__persons_admin["persons_admin"] n_api --> n_api__relationships_admin["relationships_admin"]
Public surface
`crate root`
| Item | What it is |
|---|---|
pub struct PartiesModule | — |
PartiesModule :: fn new() -> Self | — |
PartiesModule :: fn name(& self) -> & 'static str | — |
PartiesModule :: fn version(& self) -> & 'static str | — |
PartiesModule :: fn migrations(& self) -> Vec <MigrationSet> | — |
PartiesModule :: async fn migrate_pending(& self, pool : & PgPool) -> std::result::Result <u32, MigrationError> | — |
PartiesModule :: fn permission_codes(& self) -> Vec <String> | — |
`api`
| Item | What it is |
|---|---|
fn admin_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, | Admin router composing all parties admin sub-routers. |
`api::organizations_admin`
| Item | What it is |
|---|---|
pub const MAX_PAGE_SIZE: u32 | Largest page the list endpoint will serve, whatever the caller asks for. |
pub const DEFAULT_PAGE_SIZE: u32 | Page size used when the caller does not specify one. |
pub struct ListOrganizationsQuery | GET /organizations — tenant_id has no #serde(default) on purpose: an absent tenant must be a 400 from axum's Query rejection, not a silent Uuid::nil(). |
pub struct TenantQuery | `GET\ |
fn opt(s : & str) -> Option <String> | A denormalized contact column is "" when unset in identity-parties, but the wire DTO is Option<String> |
fn to_summary(o : & Organization) -> OrganizationSummary | Project an organization onto the list DTO. |
fn to_detail(o : & Organization) -> OrganizationDetail | Project an organization onto the detail/edit DTO. |
fn organization_from_create(req : & CreateOrganizationRequest,) -> Result <Organization, PartyError> | Build a new organization from a create request |
fn apply_update(o : & mut Organization, req : & UpdateOrganizationRequest) | Apply a partial update in place |
fn clamp_paging(page : Option <u32>, page_size : Option <u32>) ->(u32, u32) | Clamp caller-supplied paging into a served range |
fn page_offset(page : u32, page_size : u32) -> i64 | The OFFSET for a 1-based page at page_size |
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, | Organizations admin router |
`api::party_places_admin`
| Item | What it is |
|---|---|
pub struct ListPartyAddressesQuery | GET /party-addresses — tenant_id AND party_id are both required, no #serde(default), matching ListContactsQuery's/ ListRelationshipsQuery's contract exactly: a request for "every address in the tenant" with no anchor party isn't served by this admin surface |
pub struct TenantQuery | `GET\ |
pub enum PartyAddressRequestError | Errors raised before any query runs — either the domain crate's own FromStr validation (PartyPlaceError, reused rather than re-invented per Gate 0.5) or this router's own required-field/length checks (Gate 1.5.6 item 1, which the domain crate has no opinion on). |
pub struct NewPartyAddress | A validated create request, ready for repo::create_party_address_for_tenant. |
fn party_address_from_create(req : & CreatePartyAddressRequest,) -> Result <NewPartyAddress, PartyAddressRequestError> | Build + validate a create request |
pub struct UpdatedPartyAddress | Resolved fields for an update, ready for repo::update_party_address_for_tenant |
fn apply_update_fields(existing : & PartyAddress, req : & UpdatePartyAddressRequest,) -> Result <UpdatedPartyAddress, PartyAddressRequestError> | Resolve an update request against the existing row |
fn to_dto(a : & PartyAddress) -> PartyAddressDto | Project a party address onto the wire DTO. |
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, | Party-address admin router |
`api::persons_admin`
| Item | What it is |
|---|---|
pub const MAX_PAGE_SIZE: u32 | Largest page the list endpoint will serve, whatever the caller asks for. |
pub const DEFAULT_PAGE_SIZE: u32 | Page size used when the caller does not specify one. |
pub struct ListPersonsQuery | GET /persons — tenant_id has no #serde(default) on purpose: an absent tenant must be a 400 from axum's Query rejection, not a silent Uuid::nil(). |
pub struct TenantQuery | `GET\ |
fn opt(s : & str) -> Option <String> | A denormalized contact column is "" when unset in identity-parties, but the wire DTO is Option<String> |
fn parse_lead_source(s : & str) -> Option <LeadSource> | Parse a wire lead_source string into the typed enum |
fn to_summary(p : & Person) -> PersonSummary | Project a person onto the list DTO. |
fn to_detail(p : & Person) -> PersonDetail | Project a person onto the detail/edit DTO. |
fn person_from_create(req : & CreatePersonRequest) -> Result <Person, PartyError> | Build a new person from a create request |
fn apply_update(p : & mut Person, req : & UpdatePersonRequest) -> Result <(), PartyError> | Apply a partial update in place |
fn clamp_paging(page : Option <u32>, page_size : Option <u32>) ->(u32, u32) | Clamp caller-supplied paging into a served range |
fn page_offset(page : u32, page_size : u32) -> i64 | The OFFSET for a 1-based page at page_size |
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, | Persons admin router |
`api::relationships_admin`
| Item | What it is |
|---|---|
pub const MAX_PAGE_SIZE: u32 | Largest page the list endpoint will serve, whatever the caller asks for. |
pub const DEFAULT_PAGE_SIZE: u32 | Page size used when the caller does not specify one. |
pub struct ListRelationshipsQuery | GET /relationships — tenant_id AND party_id are both required, no #serde(default): a request for "every relationship in the tenant" with no anchor party isn't a query this admin surface serves (see repo::list_relationships_for_party_for_tenant's doc for why an anchor party is required, not optional). |
pub struct TenantQuery | `GET\ |
fn opt(s : & str) -> Option <String> | A blank title is "" in the model but None on the wire — same convention as organizations_admin::opt. |
fn to_dto(r : & PartyRelationship) -> RelationshipDto | Project a relationship onto the wire DTO. |
fn relationship_from_create(req : & CreateRelationshipRequest,) -> Result <PartyRelationship, PartyError> | Build a new relationship from a create request |
fn apply_update(r : & mut PartyRelationship, req : & UpdateRelationshipRequest) | Apply a partial update in place |
fn clamp_paging(page : Option <u32>, page_size : Option <u32>) ->(u32, u32) | Clamp caller-supplied paging into a served range. |
fn page_offset(page : u32, page_size : u32) -> i64 | The OFFSET for a 1-based page at page_size. |
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, | Relationships admin router |
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
identity_party_placesasparty_places | identity_party_placesasparty_places |
Boundary
Reaches into identity, platform.
Shares tier application with 120 other crates: application-agreements, application-ai, application-analytics, application-approvals, application-assessments, application-audit-log, application-auth, application-billing, … (120 total).
_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) | application |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/application/parties |
| Vocabulary in force (lexicon) | current |
Tier flow. Which tiers this crate's own edges cross.
flowchart LR n_application["application"] --> n_identity["identity"] n_application["application"] --> n_platform["platform"]
Dependencies
Runtime, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `application-core` | application | no | always |
| `identity-parties` | identity | no | always |
| `identity-party-places` | identity | no | always |
| `platform-dto` | platform | no | always |
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
async-trait | ^0.1 | — | no | always |
axum | ^0.7 | multipart | no | always |
serde | ^1 | derive | no | always |
sqlx | ^0.8 | runtime-tokio, postgres, chrono, uuid, json | no | always |
tracing | ^0.1 | — | no | always |
uuid | ^1 | v4, v7, serde, js | no | always |
Development, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `application-engine` | application | no | always |
| `application-geo` | application | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
chrono | ^0.4 | serde | no | always |
serde_json | ^1 | — | no | always |
tokio | ^1 | full | no | always |
tower | ^0.5 | — | no | always |
Build. None.
Depended on by. 10 workspace crates.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_application_auth["application-auth"] -->|uses| SELF n_application_billing["application-billing"] -->|uses| SELF n_application_calendar["application-calendar"] -->|uses| SELF n_application_calendar_recurrence["application-calendar-recurrence"] -->|uses| SELF n_application_catalog["application-catalog"] -->|uses| SELF n_application_encounters["application-encounters"] -->|uses| SELF n_application_identifiers["application-identifiers"] -->|uses| SELF n_application_messaging["application-messaging"] -->|uses| SELF n_application_party_discovery["application-party-discovery"] -->|uses| SELF n_application_planning["application-planning"] -->|uses| SELF SELF["application-parties"] SELF -->|development| n_application_engine["application-engine"] SELF -->|development| n_application_geo["application-geo"] SELF -->|runtime| n_application_core["application-core"] SELF -->|runtime| n_identity_parties["identity-parties"] SELF -->|runtime| n_identity_party_places["identity-party-places"] SELF -->|runtime| n_platform_dto["platform-dto"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.
Targets
| Kind | Name | Source |
|---|---|---|
| lib | application_parties | `src/lib.rs` |
| test | pg_forge_parties | `tests/pg_forge_parties.rs` |
| test | pg_party_addresses | `tests/pg_party_addresses.rs` |
Error model
| Error type | Named by |
|---|---|
PartyAddressRequestError | apply_update_fields, party_address_from_create |
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | yes |
| async runtime | none detected |
| database access | yes |
| network I/O | yes |
| unsafe code | none detected |
| environment variables | yes |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
| Variable | Read in |
|---|---|
CARGO_PKG_VERSION | src/lib.rs |
Related capabilities
10 workspace crates depend on this one: application-auth, application-billing, application-calendar, application-calendar-recurrence, application-catalog, application-encounters, application-identifiers, application-messaging, application-party-discovery, application-planning.
Verification
| Kind | Count |
|---|---|
| Unit tests | 87 |
| Integration tests | 31 |
| Examples | 0 |
| Doctests | 0 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
crate root | 1 | 0 | 0 |
api | 1 | 0 | 5 |
api::organizations_admin | 12 | 0 | 13 |
api::party_places_admin | 9 | 0 | 7 |
api::persons_admin | 13 | 0 | 13 |
api::relationships_admin | 11 | 0 | 13 |
What the tests establish, by name:
a_bare_person_insert_with_no_tenant_still_succeeds_via_the_shared_trigger—tests/pg_forge_parties.rscreate_organization_for_tenant_stores_the_party_with_the_right_tenant_and_name—tests/pg_forge_parties.rscreate_person_for_tenant_stores_the_party_with_the_right_tenant_and_name—tests/pg_forge_parties.rscreate_relationship_for_tenant_refuses_a_party_from_another_tenant—tests/pg_forge_parties.rscreate_relationship_for_tenant_succeeds_when_both_parties_are_in_the_tenant—tests/pg_forge_parties.rsfind_organization_by_id_for_tenant_enforces_tenant_isolation—tests/pg_forge_parties.rsfind_person_by_id_for_tenant_enforces_tenant_isolation—tests/pg_forge_parties.rsfind_relationship_by_id_for_tenant_enforces_tenant_isolation—tests/pg_forge_parties.rslist_relationships_for_party_for_tenant_only_returns_the_callers_tenant—tests/pg_forge_parties.rssearch_organizations_page_for_tenant_only_returns_the_callers_tenant—tests/pg_forge_parties.rssearch_persons_page_for_tenant_only_returns_the_callers_tenant—tests/pg_forge_parties.rssoft_delete_organization_for_tenant_removes_both_the_organization_and_the_party—tests/pg_forge_parties.rssoft_delete_person_for_tenant_removes_both_the_person_and_the_party—tests/pg_forge_parties.rssoft_delete_relationship_for_tenant_removes_it_from_lookups—tests/pg_forge_parties.rsupdate_organization_for_tenant_updates_both_organizations_and_the_denormalized_party_name—tests/pg_forge_parties.rsupdate_person_for_tenant_persists_date_of_death_and_the_full_lead_block—tests/pg_forge_parties.rsupdate_person_for_tenant_updates_both_persons_and_the_denormalized_party_name—tests/pg_forge_parties.rsupdate_relationship_for_tenant_can_change_the_type_but_never_the_endpoints—tests/pg_forge_parties.rsa_label_with_punctuation_and_unicode_round_trips_byte_for_byte—tests/pg_party_addresses.rsac1_create_writes_all_three_rows_and_get_returns_one_flattened_record—tests/pg_party_addresses.rsac2_filtering_by_role_returns_only_the_matching_address—tests/pg_party_addresses.rsac3_creating_a_second_primary_also_demotes_the_first—tests/pg_party_addresses.rsac3_set_primary_demotes_the_previous_primary_for_the_same_role—tests/pg_party_addresses.rsac4_another_tenants_id_is_invisible_to_read_update_and_delete—tests/pg_party_addresses.rsac5_soft_delete_removes_it_from_get_and_list—tests/pg_party_addresses.rsac6_a_failed_geo_places_insert_leaves_no_orphaned_geo_address—tests/pg_party_addresses.rsbilling_role_round_trips_through_the_full_stack_not_mailing—tests/pg_party_addresses.rsmigrate_pending_creates_the_three_tables—tests/pg_party_addresses.rsother_role_with_a_free_text_label_round_trips—tests/pg_party_addresses.rstwo_shipping_addresses_with_different_labels_are_both_legal—tests/pg_party_addresses.rs- _… 88 more_
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 46 | 53 |
Public modules with a //! block | 5 | 5 |
pie showData
title Public items with rustdoc
"Documented" : 46
"No rustdoc detected" : 7
Metrics
| Metric | Value |
|---|---|
| Rust source files | 6 |
| Source lines | 3685 |
| Code lines | 2957 |
| Public API items | 53 |
| Public modules | 5 |
| Tests | 118 |
| Examples | 0 |
| Cargo features | 0 |
| Direct runtime dependencies | 10 |
| Workspace reverse dependencies | 10 |
pie showData
title Public API by kind
"constant" : 6
"enum" : 1
"function" : 29
"method" : 6
"struct" : 11
pie showData
title Rust source composition
"Code" : 2957
"Blank or comment" : 728
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.