TorbatYar/docs/architecture/published-resource-architecture.md
2026-07-28 20:39:10 +03:30

14 KiB
Raw Blame History

Published Resource Architecture

Platform-wide abstraction for anything that can be published publicly.
Normative decision: ADR-022
Experience ownership: ADR-016 · Roadmap: experience-roadmap.md
Contracts: published-resource-contracts.md

Status: Accepted · ARCHITECTURE COMPLETE (documentation freeze — no implementation in this patch).

Final freeze adds: Published Actions, Public Access Model, Universal Embed Architecture (additive, backward compatible).

1. Purpose

TorbatYar products publish many public surfaces (sites, pages, forms, menus, cards, events, …). Without a shared abstraction, each vertical and future product invents its own public identity, URL scheme, and cross-service coupling.

Published Resource is the official platform abstraction for every present and future public surface. All consumers (Payment, Communication, Short Link, QR, Analytics, CRM, verticals, future products) integrate via publish_id only — never via Experience (or other) internal tables.

2. Published Resource

A Published Resource represents anything that can be published publicly for a tenant.

Field Meaning
publish_id Stable public identity (UUID). Cross-service foreign key substitute.
tenant_id Owning tenant (ADR-003)
resource_type Extensible type key (string registry — not a closed enum in architecture)
resource_id Owning-service aggregate id (opaque to consumers)
canonical_url Canonical public URL path or absolute URL
publish_status Lifecycle: draft · published · unpublished · archived (extensible)
visibility e.g. public · unlisted · tenant_only (extensible)
owner_service Service that owns the aggregate (experience, hospitality, …)

Resource type registry (open)

Architecture must not hardcode a finite type list. Types are registered as string keys. Illustrative examples (non-exhaustive):

Example resource_type Typical owner
site experience
page experience
landing_page experience
form experience
survey experience
appointment experience
restaurant_menu hospitality (surface may publish via Experience)
product_catalog marketplace / ecommerce
campaign experience / marketing consumers
digital_business_card experience / future Torbat Card
event experience / future Torbat Event
booking_page experience / future Torbat Booking
future.* any registered service

Unlimited future types are allowed without ADR revision when they follow this contract.

3. Publish Target Registry

The Publish Target Registry is the logical catalog of all Published Resources.

Rules:

  1. Every publicly reachable surface that other services may attach to MUST have a registry entry with a publish_id.
  2. Registry entries are tenant-scoped.
  3. Consumers resolve and attach using publish_id (+ tenant_id for isolation checks).
  4. Registry ownership for Experience-authored surfaces is Experience (experience_db). Other owner services may publish their own surfaces into the same logical contract (API/events), never by writing Experience tables.
  5. No implementation in this documentation patch — schema, API, and migrations are deferred to future registered phases.

Logical record:

PublishTarget {
  publish_id
  tenant_id
  resource_type
  resource_id
  canonical_url
  publish_status
  visibility
  owner_service
  # optional metadata (locale, title_ref, …) — additive only
}

4. Independent Resources

The following Experience resource kinds MUST NOT require a parent Site or Page to exist or publish:

Resource Standalone publish Optional Site binding
Form Required Allowed
Survey Required Allowed
Appointment (appointment page / booking shell) Required Allowed

Rules:

  1. Forms, Surveys, and Appointments are first-class publishable resources.
  2. They may optionally belong to a Site (and/or Page) for composition.
  3. They must support standalone publishing with their own publish_id and canonical URL.
  4. UI and API designs must not force “create Site → create Page → attach Form” as the only path.

Sites and Pages remain publishable resources; independence applies to Form / Survey / Appointment aggregates specifically.

5. Cross-Service Integration Contracts

All integrations are documentation contracts only until a registered implementation phase.

Consumer Attachment Reference key
Payment (Torbat Pay) Paid form / appointment / booking / registration / event publish_id
Communication SMS/email/OTP/notify after submit or booking publish_id
Short Link Resolve short codes to public surfaces publish_id
QR Code Encode / resolve posters, tables, cards, events publish_id
Analytics Pageviews, conversions, funnels publish_id
CRM Lead capture / contact refs from public surfaces publish_id
Booking Scheduling refs attached to public bookable surfaces publish_id
Marketplace Catalog embed / campaign surfaces publish_id
Hospitality Menu / venue public surfaces publish_id
Delivery Campaign / logistics announcement surfaces publish_id
Loyalty Offer / card / campaign surfaces publish_id
Sports Center Membership / event / booking surfaces publish_id
Future services Any public attachment publish_id

Forbidden: consumers must not query Experience (or other) internal tables, import models, or store foreign primary keys as substitutes for publish_id when the public surface is the integration target.

Detail: published-resource-contracts.md.

6. Standard Public URL Patterns (Reserved)

Routing is not implemented in this patch. The following path prefixes are reserved for public resolution:

Prefix Intended use (illustrative)
/s/ Site / published site shell
/p/ Page / landing
/f/ Form
/survey/ Survey
/book/ Appointment / booking page
/menu/ Restaurant / digital menu surface
/card/ Digital business card
/event/ Event surface

Additional prefixes may be reserved later without breaking this architecture. Canonical URLs stored on the Publish Target Registry should align with these patterns when applicable.

7. Future Products

The following commercial products are architecture-reserved. They consume Published Resources; they never own Experience data:

Product Role
Torbat Link Short / branded link layer over Published Resources
Torbat QR QR issuance and resolution to publish_id
Torbat Card Digital business card surfaces
Torbat Booking Booking UX over appointment / bookable resources
Torbat Ticket Ticketing over event / paid registration resources
Torbat Event Event publishing and discovery
Torbat Learning Learning / knowledge page surfaces

These products integrate through API/Events + publish_id. Experience remains owner of page/site/theme/form aggregates it already owns (ADR-016).

8. Payment Integration

Payment (ADR-020, ADR-021) may attach to any Published Resource.

Examples: Paid Form · Paid Appointment · Paid Booking · Paid Registration · Paid Event.

Contract: Payment request / checkout session stores publish_id (and tenant_id). Payment must not own Experience aggregates or read experience_db.

9. Communication Integration

Communication (ADR-012) triggers may fire on Published Resource lifecycle or submission events.

Examples: SMS after submit · Email after booking · OTP · Notifications · Campaign messages.

Contract: templates and dispatches reference publish_id (plus channel/template keys owned by Communication). Providers remain Communication-owned.

Short Link ownership is reserved as a future/adjacent product capability (e.g. Torbat Link).

  • Short codes resolve to Published Resources via publish_id.
  • No direct dependency on Experience internals.
  • Experience must not embed a competing short-link engine as source of truth.

11. QR Integration

QR codes resolve to Published Resources via publish_id.

Examples: Restaurant Table · Business Card · Poster · Event · Form · Appointment.

QR issuance may live in a future Torbat QR product or vertical adapters; payload always targets the Publish Target Registry.

12. Analytics

Analytics (Experience shells and future platform analytics) record publish_id for public funnel metrics.

  • No ownership change: Experience analytics shells remain Experience-owned COUNT/local shells where already defined.
  • Cross-service analytics consumers also key off publish_id, not internal page/form table ids.

13. Ownership & Boundaries

Concern Owner
Publish Target Registry for Experience-authored surfaces Experience (experience)
Page / site / theme / template / form / survey / appointment shells Experience
Publishing, presentation, rendering metadata, embed metadata Experience
Published Action presentation bindings Experience (refs action_key)
Published Action business execution Owning service of the action
Public Access Policy metadata Experience
Authentication / SSO Identity / Core
Payment capture / ledger Payment
Membership gates Loyalty
OTP / messaging Communication
Menu/item catalog source of truth Hospitality
Product catalog source of truth Marketplace / Ecommerce
Media binaries File Storage
Short Link / QR issuance engines Reserved products
Public URL edge routing Platform edge / frontend (reserved patterns)
Builder UI Frontend (ADR-002)

All cross-service attachments continue to reference publish_id only.

14. Published Actions

Every Published Resource may expose zero or more Actions. Actions are service-independent contracts registered in an open Action Registry.

Field Meaning
action_key Open string key
display_name Label
owning_service Executes business logic
permission Invocation permission
capability Discovery key
feature_toggle Optional enablement
supported_resource_types Open type list

Illustrative keys (not closed): View, Submit, Book, Reserve, Pay, Donate, Register, Download, Open Chat, Send Message, Share, Copy Link, Generate QR, Scan QR, Call, Navigate, Add To Calendar, Automation Trigger, Webhook Trigger, …

Future services register new actions without modifying Experience. Normative contract: published-action-registry.md.

15. Public Access Model

A Public Access Policy may compose open strategies, including: Public, Private, Authenticated, Tenant Members, Role Based, Password Protected, OTP Protected, Paid Access, Invitation Only, Signed URL, Temporary Link, Expiration, Rate Limited, Geo Restricted (reserved), and future strategies.

Must not live in Experience Owner
Authentication Identity / Core
Payment unlock Payment
Membership evaluation Loyalty
OTP delivery Communication

Normative contract: public-access-contract.md.

16. Universal Embed Architecture

Published Resources may embed into external sites/apps. Reserved embed types (open): Iframe, JavaScript SDK, Widget, Popup, Inline, Modal, Floating Button, future types.

Embed contracts cover: responsive sizing, security/sandbox, origin validation, permission delegation, token passing, theming inheritance, analytics propagation (publish_id).

Normative contract: embed-contract.md.

17. Capability Discovery (additive, docs only)

Future /capabilities (or equivalent discovery) MAY advertise:

  • published_resources: true
  • published_actions: true (registry available)
  • public_access_policies: true
  • universal_embed: true
  • Open lists of known action_key / embed_type / access strategy keys

No API change in this patch — discovery additions are reserved for implementation phases.

18. Architecture Complete

With Published Resources, Publish Target Registry, Published Actions, Public Access Model, and Universal Embed Architecture documented and accepted under ADR-022, the Experience Platform architecture is ARCHITECTURE COMPLETE.

Remaining work is implementation (backend registry/APIs, frontend builders/public shells) in future registered phases — not architecture redesign.

19. Non-Goals (Architecture Patches)

  • No backend schema, migrations, or APIs
  • No frontend UI, embed SDK, or public routers
  • No Short Link / QR / Card / Booking product implementation
  • No changes to completed Experience phases 11.011.10 business code
  • No hardcoded closed enums of resource types, actions, access strategies, or embed types