← Back to directory

PRESENTATION-DRIVEN-OBJECT-EXPLORER.md

implementation/PRESENTATION-DRIVEN-OBJECT-EXPLORER.md · 5.9 KB · 2026-11-02 12:48

Presentation-Driven Generic Object Explorer

Status: Implemented, 2026-10-04 Scope: /objects/{id} ordinary-object path, presentation-driven rendering, no automatic relationship discovery

This document records the generic Object Explorer implementation slice. Its field-oriented renderer is one valid presentation composition, not a replacement for the global Object Presentation contract. The cross-cutting contract, binding semantics, authority boundary, renderable model and relationship to capability compositions are defined in Core Object Model and Authority; Views and Content owns the View/UI-specific mechanism.

Architectural Principle

Nothing becomes visible merely because it exists in the data graph. Every navigable relationship or object reference must be explicitly exposed by the presentation definition.

Design Pattern

/objects/{id}
     ↓
resolve object from repository
     ↓
resolve an optional Presentation Instance binding, then the applicable Business-scoped Presentation Definition
     ↓
project object using presentation.detail_fields
     ↓
render generic presentation
     ↓
Three rendering modes:
  ├── Primitive: Name: value
  ├── Object reference: <a href="/objects/{id}">Label</a>
  └── Collection: Name / ID / View (multiple entries)
     ↓
HTML output
     ↓
When user clicks object reference: /objects/{id} (same process with new object's presentation)

No Automatic Traversal

The old system would:

This violated the separation of:

New System

1. Presentation Definition Controls Visibility

2. Object References as Explicit Fields

3. Same Object, Multiple Presentations

   Data graph (one Campaign with 5 relationships):
   Campaign ─┬─ Goal
             ├─ Audience
             ├─ Content
             ├─ Response
             └─ Owner

   Presentation A: Goal, Audience, Content
   Presentation B: Goal, Audience, Response
   Presentation C: Goal (summary only)

   All three use the same underlying Campaign object; none creates a copied business Object.
   Same URL (/objects/{id}) with different view_id query params
   renders different interface.
   

Implementation Details

TargetHtmlBoundary::objectDetail()

Responsible for: 1. Resolving the object by ID 2. Resolving the optional Presentation Instance binding and Business-scoped Presentation Definition 3. Projecting the object using presentation.detail_fields 4. Passing the resulting projected field model to the thin renderer

Does NOT:

Shared `presentation.php` Template

Responsible for: 1. Rendering projected primitives as Name: value 2. Rendering object references as links to /objects/{id} 3. Rendering collections as lists of linked objects 4. Displaying state, type, and actions

Does NOT:

GenericObjectsExplorer (JSON API)

Separate responsibility from HTML rendering:

How to Add a Visible Relationship

To expose a relationship in a presentation:

1. Add to presentation's detail_fields array:

   {
     "name": "related_organization",
     "label": "Organization",
     "renderer": "object_reference"
   }
   

2. Ensure object_value contains the reference:

   {
     "related_organization": {
       "kind": "object_reference",
       "id": "org-uuid",
       "revision": 1
     }
   }
   

3. The view now shows it as a link:

   Organization: TechCorp Industries [link to /objects/org-uuid]
   

4. User clicks link:

Verification

Related Architecture Documents