<a id="getting-started"></a>

# Getting started

A Workspace describes a data interface in XML. The platform compiles it into the
screen the CoCoCo app displays. Use the built-in components for ERP workflows
and dashboards; keep server logic in a separate Lua source.

Open the Workspace editor and start with the XML below. It lists recent jobs,
loads the notes for the selected job, and offers a form for adding a note.

```xml
<workspace id="workspace-starter" title="Job notes" role="Operations" xmlns:t="urn:cococo:dataxml" domains="job">
  <state name="selectedJobId" default="null"/>
  <handler name="addJobNote" mode="action">
    <field path="entityId" min-length="1"/>
  </handler>
  <handler name="jobNotes" mode="read">
    <field path="id" min-length="1"/>
  </handler>
  <master-detail>
    <panel id="jobs" title="Recent jobs" weight="1">
      <query type="graphql"><![CDATA[
        query RecentJobs {
          jobs: listJobs(first: 50, sort: [{field: CREATED_AT, direction: DESC}]) {
            edges { node { id name jobNumber } }
          }
        }
      ]]></query>
      <record-list id="job-list" t:for="jobs.edges" t:as="job"
        key="job.node.id" primary="job.node.name" secondary="job.node.jobNumber" select="selectedJobId"/>
    </panel>
    <panel id="job-notes" title="Job notes" weight="2" wait-for="id">
      <query type="lua" handler="jobNotes">
        <arg name="id" state="selectedJobId"/>
      </query>
      <text id="job-name" t:text="job.name"/>
      <record-table id="existing-notes" t:for="notes.edges" t:as="note">
        <column label="Note" t:value="note.node.body"/>
        <column label="Visibility" t:value="note.node.visibility"/>
        <column label="Created" t:value="note.node.createdAt"/>
      </record-table>
      <form id="new-note" mode="create" record="job" identity="id">
        <submit type="lua" handler="addJobNote" errors="errors" confirm="Add this note to the job, visible to everyone?"/>
        <value path="entityId" source="id"/>
        <field path="body" min-length="1" label="New note" control="textarea" help="Adds a Knowledge Note visible to everyone. Existing notes and the job description are unchanged. The list shows the 50 most recent notes you can access."/>
        <form-actions save-label="Add note" reset-label="Discard note"/>
      </form>
    </panel>
  </master-detail>
</workspace>
```

The workspace has a stable identifier, a title and an intended audience role.
Each panel declares its query before the components displaying its result. Here,
`jobs` is the response alias, so the record list iterates `jobs.edges`. The notes
panel waits for a selected job, then loads its notes through a Lua read handler.

Edit the XML and Lua side by side in the editor. Save creates a draft after
compilation. Review compiler diagnostics, then publish the intended draft to make that
version available to readers. A valid document does not grant access to its data: the server still
checks the current user's permissions when queries and actions run.