Multi-Domain Projections
Every model property carries three independent projection configurations: persistence (how it is stored), search (how it is indexed), and API (how it is exposed). Each domain sees the same property through its own lens, controlled by profiles, without duplicating the definition.
A property in a data model does not exist in isolation. It has a physical representation in a database column, a search representation in an index field, and a public representation in an API contract. In most organisations, these three representations are defined separately by different teams using different tools. The database team writes DDL. The search team writes index mappings. The API team writes OpenAPI specs. Each definition is a copy, and each copy can drift from the others.
NeoArc eliminates this duplication by giving every model property three independent projection configurations. The property is defined once. Each domain reads it through its own projection lens. Profiles control how abstract types, naming conventions, and domain-specific behaviours are resolved. The result is three consistent outputs from one source of truth.
The Three Projections
The property table editor in NeoArc Studio offers four lens modes. The schema lens shows the base definition. The other three show how that definition projects into each domain.
How Projections Work
Concrete Example
Consider a createdDate property on a Customer entity with abstract type datetime.
| Domain | Profile Applied | Resolved Output |
|---|---|---|
| Persistence (SQL Server) | Database profile: SQL Server | Column: created_date, Type: DATETIME2, Nullable: false |
| Persistence (PostgreSQL) | Database profile: PostgreSQL | Column: created_date, Type: TIMESTAMPTZ, Nullable: false |
| Search (Elasticsearch) | Search profile: Elasticsearch | Field: createdDate, Type: date, Format: strict_date_optional_time, Sortable: yes |
| Search (Azure Cognitive Search) | Search profile: Azure Cognitive Search | Field: createdDate, Type: Edm.DateTimeOffset, Filterable: yes, Sortable: yes |
| API (Public REST) | API serialisation profile: camelCase + ISO 8601 | Field: createdDate, Format: 2026-03-05T00:00:00Z |
| API (Internal Batch) | API serialisation profile: snake_case + Unix | Field: created_date, Format: 1772006400 |
All six outputs derive from the same property. If the property is renamed, all six update. If the type is changed from datetime to date, each profile resolves the new abstract type to its domain-specific concrete type automatically.
Search Projection Details
The search projection is the richest of the three, reflecting the complexity of search index configuration.
| Category | Settings | Purpose |
|---|---|---|
| Query Behaviours | searchable, filterable, sortable, facetable, retrievable, highlightable, aggregatable, scoring enabled | Controls how the field participates in different query operations |
| Text Analysis | analyser, index analyser, search analyser, normaliser, synonym map, language | Configures tokenisation, stemming, and linguistic processing |
| Vector Search | dimensions, vector search profile, similarity metric (cosine, dot product, L2 norm) | Enables vector similarity search for embeddings and semantic search |
| Storage and Performance | stored, docValues, index enabled, norms, null value, term vector, nested flag | Fine-grained control over index storage and performance trade-offs |
| Sub-Fields | multi-field configuration with independent analysers | Allows a single property to be indexed multiple ways (e.g., keyword and full-text) |
| Per-Profile Overrides | profile-specific analyser, normaliser, and type overrides | Different search engines can use different analysis chains for the same property |
Intent Graph Integration
Each projection creates typed edges in the Architectural Intent Graph, enabling field-level traceability across all domains.
| Edge Type | From | To | Metadata |
|---|---|---|---|
| projects-to-db | Model property | Persistence projection node | Column name, column type |
| projects-to-search | Model property | Search projection node | Field name, search field type, key flag, search behaviours, analyser |
| projects-to-api | Model property | API projection node | Field name, read-only flag |
Unprojected Properties
Not every property needs to appear in every domain. A property might be stored in the database but excluded from the API (internal audit fields). A property might be exposed in the API but not indexed in search (large text fields). A property might exist only in search (computed relevance scores).
The Intent Graph service provides getUnprojectedProperties(entityId, domain, allPropertyIds) which identifies properties that are not projected to a specific domain. This is used by coverage reports to highlight potential gaps where a property exists in the model but has not been configured for a particular output channel.