{
 "note": "These are categories, not products. The same connector shape has been built against the common hosted CRMs and against a plain database, against the common marketing platforms, and against the common file stores. What changes between products is the field names and the rate limit, not the direction of the arrows or the read only list.",
 "centre": {
  "id": "os",
  "label": "The company system",
  "sub": "Rules, assembly, checks"
 },
 "nodes": [
  {
   "id": "crm",
   "label": "A CRM",
   "sub": "The customer record",
   "examples": "A hosted CRM, or a database the company owns",
   "reads": [
    "Account, tier, plan, renewal date",
    "Open tickets and severity",
    "Lifetime value and products",
    "Flags such as a pricing dispute",
    "Consent and contact details"
   ],
   "writes": [
    "A note on the account saying what was sent, or refused, and which rule fired"
   ],
   "readOnly": false,
   "readOnlyNote": null,
   "guard": "The write is one note per decision. Nothing else on the record is ever changed by the system."
  },
  {
   "id": "marketing",
   "label": "A marketing platform",
   "sub": "Sending and lists",
   "examples": "A hosted marketing platform, or the mail service already in place",
   "reads": [
    "Send history and the date of the last contact",
    "Consent state",
    "Bounce and unsubscribe events"
   ],
   "writes": [
    "The assembled message, with the constraints already applied",
    "The suppression, when a rule refuses"
   ],
   "readOnly": false,
   "readOnlyNote": null,
   "guard": "The platform never receives a message the rules did not clear. Refusals are pushed as suppressions, not silently dropped."
  },
  {
   "id": "files",
   "label": "A file store",
   "sub": "Approved assets and documents",
   "examples": "A shared drive, an object store, or a document library",
   "reads": [
    "Approved logos, images, and templates",
    "The asset index and its status field"
   ],
   "writes": [
    "Generated documents, into one dated output folder"
   ],
   "readOnly": false,
   "readOnlyNote": null,
   "guard": "The system writes only inside the output folder. It has no permission to change or delete an approved asset."
  },
  {
   "id": "warehouse",
   "label": "A data warehouse",
   "sub": "Reporting truth",
   "examples": "A warehouse or a reporting database",
   "reads": [
    "Revenue and order history",
    "The published price list",
    "Ticket volumes by severity"
   ],
   "writes": [],
   "readOnly": true,
   "readOnlyNote": "Read only on purpose. The warehouse is where the business agrees what happened, so nothing that composes text is allowed to write to it.",
   "guard": "Connection is read only at the credential, not just by convention."
  },
  {
   "id": "hosting",
   "label": "A hosting layer",
   "sub": "Where pages are published",
   "examples": "A managed host, a static host, or a CDN",
   "reads": [
    "The live page inventory and the last publish date"
   ],
   "writes": [
    "A page or a document, published to a preview address for a person to approve"
   ],
   "readOnly": false,
   "readOnlyNote": null,
   "guard": "Publishing to a live address is a separate, human step. The system can only reach the preview address."
  },
  {
   "id": "chat",
   "label": "A chat tool",
   "sub": "Where people are asked",
   "examples": "The team chat tool already in use",
   "reads": [
    "Who is on duty, and the approval thread"
   ],
   "writes": [
    "The request for a decision, with the record and the rule quoted",
    "The result once a person answers"
   ],
   "readOnly": false,
   "readOnlyNote": null,
   "guard": "Every refusal that names a person becomes a message here. That is how a stop turns into somebody doing something."
  }
 ],
 "legend": [
  [
   "reads",
   "The system reads from this system"
  ],
  [
   "writes",
   "The system writes to this system, inside a named boundary"
  ],
  [
   "read-only",
   "Deliberately read only. No credential exists that could write"
  ]
 ]
}