# Published Resource — Integration Contracts

> **Documentation contracts only.** No APIs or schemas are implemented by this document.  
> Architecture: [published-resource-architecture.md](../architecture/published-resource-architecture.md) · [ADR-022](../architecture/adr/ADR-022.md)

All contracts are **versioned conceptually** as `published-resource.v1`, with additive companions:

| Contract | Version | Path |
| --- | --- | --- |
| Published Resource | `published-resource.v1` | this file |
| Published Action Registry | `published-action.v1` | [published-action-registry.md](published-action-registry.md) |
| Public Access | `public-access.v1` | [public-access-contract.md](public-access-contract.md) |
| Universal Embed | `universal-embed.v1` | [embed-contract.md](embed-contract.md) |

Implementations MUST accept unknown additive JSON fields. Breaking changes require a new major contract version and a registered phase.

---

## 1. Identity

| Field | Type | Rules |
| --- | --- | --- |
| `publish_id` | UUID | Stable; never reused after delete/archive policy |
| `tenant_id` | UUID | Mandatory isolation key |
| `resource_type` | string | Open registry key |
| `resource_id` | UUID / opaque string | Owner-service aggregate id |
| `canonical_url` | string | Absolute or path; aligns with reserved prefixes when applicable |
| `publish_status` | string | Extensible lifecycle |
| `visibility` | string | Extensible visibility |
| `owner_service` | string | Service id (`experience`, `hospitality`, …) |

Consumers **MUST** store and pass `publish_id` (+ validate `tenant_id`). Consumers **MUST NOT** persist Experience internal table names or require joins into `experience_db`.

---

## 2. Event payload fragment (conceptual)

When a Published Resource is created, published, unpublished, or archived, owner services SHOULD include:

```json
{
  "publish_id": "uuid",
  "tenant_id": "uuid",
  "resource_type": "form",
  "resource_id": "uuid",
  "canonical_url": "/f/{slug-or-id}",
  "publish_status": "published",
  "visibility": "public",
  "owner_service": "experience"
}
```

Event type names remain owner-prefixed (e.g. `experience.*`, `hospitality.*`). This fragment is the cross-service attachment key.

---

## 3. Consumer attachment contracts

### 3.1 Payment (Torbat Pay)

| Concern | Contract |
| --- | --- |
| Attach paid checkout | Payment request / session references `publish_id` |
| Examples | Paid Form, Paid Appointment, Paid Booking, Paid Registration, Paid Event |
| Forbidden | Reading Experience form/page tables |

### 3.2 Communication

| Concern | Contract |
| --- | --- |
| Triggers | After submit / booking / OTP / notify / campaign |
| Reference | `publish_id` + Communication `template_key` / channel |
| Forbidden | Embedding SMS providers in Experience; using Experience rows as contact source of truth |

### 3.3 Short Link

| Concern | Contract |
| --- | --- |
| Resolve | Short code → `publish_id` → canonical URL |
| Ownership | Reserved (e.g. future Torbat Link) |
| Forbidden | Hard dependency on Experience internals |

### 3.4 QR Code

| Concern | Contract |
| --- | --- |
| Encode / resolve | QR payload → `publish_id` |
| Examples | Table, card, poster, event, form, appointment |
| Ownership | Reserved (e.g. future Torbat QR) and/or vertical adapters |

### 3.5 Analytics

| Concern | Contract |
| --- | --- |
| Metrics key | `publish_id` |
| Notes | Experience local analytics shells unchanged in ownership |

### 3.6 CRM / Booking / Marketplace / Hospitality / Delivery / Loyalty / Sports Center / Future

| Concern | Contract |
| --- | --- |
| Attachment | Entity or session refs may cite `publish_id` for the public surface |
| Data ownership | Vertical owns its catalog/order/member aggregates; Experience owns its page/form shells |

---

## 4. Standalone Form / Survey / Appointment

Contractual requirements for Experience (future implementation phases):

1. Creating a Form, Survey, or Appointment page **MUST NOT** require an existing Site or Page.
2. Optional `site_id` / `page_id` binding is allowed.
3. Publishing MUST allocate a `publish_id` and registry entry usable by Payment/Communication/Link/QR/Analytics.

---

## 5. Reserved URL prefixes

| Prefix | Example resource types |
| --- | --- |
| `/s/` | site |
| `/p/` | page, landing_page |
| `/f/` | form |
| `/survey/` | survey |
| `/book/` | appointment, booking_page |
| `/menu/` | restaurant_menu |
| `/card/` | digital_business_card |
| `/event/` | event |

Routing not implemented here.

---

## 6. Capability discovery additions (reserved)

Future discovery responses MAY include additive keys (no API change in this docs patch):

```json
{
  "published_resources": true,
  "published_actions": true,
  "public_access_policies": true,
  "universal_embed": true
}
```

Action keys, access strategies, and embed types remain open registries advertised by owning services.

---

## 7. Related Documents

- [Published Resource Architecture](../architecture/published-resource-architecture.md)
- [ADR-022](../architecture/adr/ADR-022.md)
- [Published Action Registry](published-action-registry.md)
- [Public Access Contract](public-access-contract.md)
- [Embed Contract](embed-contract.md)
- [Payment Contracts](payment-contracts.md)
- [Services Contracts](services-contracts.md)
- [Experience Roadmap](../experience-roadmap.md)
