A core innovation within the OpenFaith platform is its Edge-Based Relationship Model. This approach moves beyond the often rigid, predetermined links found in traditional Church Management Systems (ChMS) by providing a flexible and universal way to define, query, and manage connections between any two entities in the system.
To ensure consistency and avoid ambiguity in directionality, OpenFaith uses a deterministic, convention-based rule for assigning sourceEntity and targetEntity in an Edge:
- Alpha Pattern Rule:
- Compare the first character of each entity's ID (or name, if preferred).
- If one entity's first letter falls in the range A–M (1–13), it is assigned as the
sourceEntity. If the other is in N–Z (14–26), it is thetargetEntity. - If both entities fall in the same alpha range (both A–M or both N–Z):
- Compare the full string values lexicographically (alphabetically). The entity with the lower value is the
sourceEntity, the other is thetargetEntity. - If the values are identical, allow self-linking where both
sourceEntityandtargetEntityare the same entity. This enables reflexive relationships.
- Compare the full string values lexicographically (alphabetically). The entity with the lower value is the
Example:
alice(A) andbob(B): Both A–M, so compare full string:alice<bob→aliceis source,bobis target.nancy(N) andbob(B):nancyis N–Z,bobis A–M →bobis source,nancyis target.zoe(Z) andyara(Y): Both N–Z, so compare full string:yara<zoe→yarais source,zoeis target.aliceandalice: Identical IDs →aliceis both source and target (self-linking).
Rationale:
- This approach is fully deterministic and does not require developers or users to remember or look up relationship directionality for each type.
- It works for any entity type and any relationship, making the system highly dynamic and scalable.
- It avoids ambiguity and ensures that the same pair of entities will always be stored in the same direction, regardless of who creates the edge.
- Self-linking support enables reflexive relationships where an entity can be related to itself (e.g., a person being their own emergency contact, a location being its own parent location).
Developer Note:
- When creating an edge, always apply the alpha pattern rule to determine which entity is the source and which is the target.
- This rule should be encapsulated in a utility function used throughout the codebase.
- Use the
EdgeDirectionSchemafrom@openfaith/dbwhich provides a robust, Effect-based implementation with proper error handling.
Example Usage (TypeScript):
import { Schema } from "effect";
import { EdgeDirectionSchema } from "@openfaith/db";
// Determine edge direction using the schema
const { source, target } = Schema.decodeUnknownSync(EdgeDirectionSchema)({
idA: "person_123",
idB: "group_456",
});
// Self-linking example
const selfLink = Schema.decodeUnknownSync(EdgeDirectionSchema)({
idA: "person_123",
idB: "person_123",
});
// Result: { source: 'person_123', target: 'person_123' }Legacy Example Utility Function (for reference):
function getEdgeDirection(
idA: string,
idB: string
): { source: string; target: string } {
const alphaRange = (id: string) => {
const c = id[0].toLowerCase();
return c >= "a" && c <= "m" ? "A-M" : "N-Z";
};
const rangeA = alphaRange(idA);
const rangeB = alphaRange(idB);
// Different ranges: A-M is source, N-Z is target
if (rangeA !== rangeB) {
return rangeA === "A-M"
? { source: idA, target: idB }
: { source: idB, target: idA };
}
// Same range: use full string comparison
if (idA < idB) return { source: idA, target: idB };
if (idB < idA) return { source: idB, target: idA };
// Self-linking: identical IDs
return { source: idA, target: idB };
}Most ChMS platforms define a fixed set of possible relationships: a Person can be in a Group; a Donation can be linked to a Person and a Fund; an Event can have Attendees (who are People). While these are essential, this fixed structure has limitations:
- Inflexibility: If you want to represent a relationship not explicitly designed into the ChMS, you often can't. For example:
- Linking a
PersontoGroupsthey might be suitable for based on interests or spiritual gifts. - Connecting a
MentoringPair(which might itself be aGroupor custom entity) consisting of twoPeople. - Relating a specific
Sermon(aDocumentorEventitem) to a set ofDiscussionQuestions(anotherDocumentor custom entity).
- Linking a
- Difficulty with Nuance: Standard links often lack the ability to store rich metadata about the relationship itself. For example, in a
PersontoGroupmembership:- What was the date they joined the group?
- What is their role within that specific group (e.g., "Leader," "Member," "Apprentice")?
- Is their membership "Active" or "Pending"? Traditional systems might add many specific columns to a join table, but this doesn't scale for arbitrary relationship types.
- Siloed Data: Because relationships are often hardcoded within modules, it can be difficult to see or query connections across different data domains in holistic ways.
OpenFaith introduces a generic Edge entity as a first-class citizen in its Canonical Data Model (CDM). An Edge represents a directed connection between two entities, along with a type and optional metadata describing the nature of that connection.
Edge Entity Schema (Key Fields):
orgId(The OpenFaith organization this link belongs to)sourceEntityId(ID of the starting entity of the relationship)sourceEntityTypeTag(The_tagof the source entity, e.g., "person", "group")targetEntityId(ID of the ending entity of the relationship)targetEntityTypeTag(The_tagof the target entity)relationshipType(A string defining the meaning of the connection, e.g., "member_of", "attended", "suitable_for_group", "mentors", "discussed_in_sermon")metadata(JSONB field to store arbitrary key-value pairs describing the relationship itself, e.g.,{ "role": "leader", "join_date": "2023-01-15", "status": "active" })- Auditing Timestamps & User Tracking:
createdAt,updatedAt,createdBy,updatedBy - Soft Delete:
deletedAt,deletedBy
Primary Key:
- The combination of (
orgId,sourceEntityId,targetEntityId,relationshipType) forms the composite primary key for the Edge table. There is no separateidfield.
-
Universal Connectivity:
- Any entity can be linked to any other entity. A
Personcan be linked to aGroupwith a "member_of" edge, but also to anotherPersonwith a "spouse_of" or "mentor_for" edge, or to aSkillentity (if you define one) with a "possesses_skill" edge. - Self-linking is supported, allowing entities to have reflexive relationships with themselves (e.g., a person being their own emergency contact, a location being its own parent location).
- This allows for emergent, graph-like data structures that can more accurately model real-world ministry relationships.
- Any entity can be linked to any other entity. A
-
Rich Relationship Context (Metadata on the Edge):
- The
metadatafield on theEdgeitself is powerful. For a "memberof" edge between aPersonand aGroup, themetadatacan store their role in that group, join date, custom notes about their involvement in _that specific group, etc., without cluttering thePersonorGroupentities. - This means the relationship itself carries its own descriptive data.
- The
-
Addressing Unmet Needs – Beyond Simple Membership:
- Prospective Links: You can now easily represent "Person A could be good for Group X" using an
EdgewithrelationshipType: "suitable_for_group"and perhapsmetadata: {"reason": "interest_in_topic_Y"}. This isn't about current membership but potential or suggested connections. - Custom Relationship Types: Churches can define their own
relationshipTypesto model specific ministry processes or connections unique to their context. - Inter-Module Connectivity: An
Edgecan connect anEventfrom the Schedule module to aFolderin the Collection module (relationshipType: "event_resources_in_folder"). - Reflexive Relationships: Self-linking enables modeling of reflexive relationships like "Person A is their own emergency contact" or "Organization X is a subsidiary of itself."
- Prospective Links: You can now easily represent "Person A could be good for Group X" using an
-
Enhanced Querying and Insights:
- While querying graph-like structures requires specific approaches (e.g., recursive queries, graph database capabilities if OpenFaith integrates one), the potential for insights increases dramatically.
- "Show me all People who
attendedEvent X and are also marked assuitable_for_groupY but are not yetmember_ofGroup Y." - "List all
Resources(e.g., articles, videos)tagged_with'Discipleship' that werediscussed_in_sermonby Pastor Z."
-
AI-First Enablement:
- LLMs can leverage this rich relational data. A query like "Find me potential mentors for John Doe who are skilled in 'leadership' and are part of the 'North Campus'" becomes answerable by an AI that can understand and traverse these
Edges and theirmetadata. - The
relationshipTypeandmetadataon edges provide crucial semantic context for AI reasoning.
- LLMs can leverage this rich relational data. A query like "Find me potential mentors for John Doe who are skilled in 'leadership' and are part of the 'North Campus'" becomes answerable by an AI that can understand and traverse these
(Person A) --member_of--> (Group X)metadata: {"role": "Leader", "join_date": "2022-08-01"}
(Person B) --suitable_for_group--> (Group Y)metadata: {"interest_level": "high", "suggested_by": "user_Z"}
(Sermon S1) --references_scripture--> (ScripturePassage P1)metadata: {"verse_start": "John 3:16", "verse_end": "John 3:17"}
(Event E1) --held_at--> (Location L1)(Document D1) --version_of--> (Document D0)metadata: {"version_number": 2, "change_summary": "Updated introduction"}
(Person A) --emergency_contact--> (Person A)(Self-linking)metadata: {"contact_type": "self", "notes": "Primary contact is self"}
(Organization O1) --parent_organization--> (Organization O1)(Self-linking)metadata: {"relationship_type": "self_governing", "established_date": "2020-01-01"}
- Query Performance: Heavily relying on
Edges means theEdgetable can grow very large. Efficient indexing onsourceEntityId,targetEntityId,relationshipType, and potentially fields within themetadatais critical. - Defining
relationshipTypes: Organizations will need a way to manage and understand therelationshipTypes they use. Some might be system-defined, others user-defined. - User Interface: Presenting and managing these flexible relationships in a user-friendly way is a UI/UX challenge.
- Alpha Pattern Enforcement: All edge creation and querying logic should use the
EdgeDirectionSchemafrom@openfaith/dbto ensure consistency. This schema provides robust error handling and supports self-linking. - Self-Linking Considerations: When implementing UI for self-linking relationships, ensure users understand that the source and target are the same entity, and provide appropriate validation and user feedback.
The Edge-based relationship model is a fundamental shift from the limitations of hardcoded links in many traditional ChMS. By treating relationships as first-class entities with their own types and metadata, OpenFaith provides a significantly more flexible, extensible, and powerful way to represent the complex web of connections inherent in ministry. The addition of self-linking support further enhances this flexibility by allowing entities to have reflexive relationships with themselves. This not only improves data modeling capabilities but also opens up new possibilities for advanced querying, insights, and AI-driven interactions with church data.