Publish my App
Say "publish my app" and your App goes out on your own Domain, every Customer runs the newest build, and the last build stays ready to restore.
In the design, publishing releases your App on your own Domain, and every Customer runs the newest build. The last build stays, so one call puts it back.
| Before it runs | |
|---|---|
| Needs | An App, from Build my app, and a connected Domain, such as leaseclock.com |
| Who says yes | You. Your agent shows you what changed and waits for your Approval. |
| When it waits | A delay window of 1 business hour, in which a watcher can pause, redirect or cancel it |
| You leave the chat | Never |
What you get
In the design, one App.publish puts every set of screens on leaseclock.com live at once, over the one API.
| What you get | Is | |
|---|---|---|
| 1 | App at leaseclock.com/app, with one set of screens per Persona | App |
| 1 | screens for your own team at leaseclock.com/admin | Give my team an admin |
| 1 | sign-in, members and invoices for each Customer | Portal |
| 1 | API that every screen calls, the same one each Interface reads | Interface |
| 1 | newest build in every Customer's workspace, on its next request | Tenant |
| 1 | previous build kept, ready to restore | Version |
| 3 | renderings at each URL: HTML for people, JSON and Markdown for agents | Renderings |
| 1 | Event, App.published, for every Workflow that waits on it | Event |
A Customer sees leaseclock.com and its Brand on every screen, and never the platform's name.
Your agent does
In the design, your agent finds the App, shows you the change, and calls App.publish once you say yes.
Publish my app.
Put the new lease screens live.
Ship the app to every customer.{
"api": "https://api.sb/leaseclock.com",
"app": {
"$id": "https://api.sb/leaseclock.com/apps/app_1",
"$type": "App",
"kind": "app"
},
"action": {
"$id": "https://api.sb/leaseclock.com/actions/action_7",
"operation": "App.publish",
"status": "done"
},
"links": {
"self": "https://api.sb/leaseclock.com/actions/action_7"
}
}- Your agent reads the App with
Interface.list. - It shows you each screen that changed since the last build, such as a new
depositfield on theLeaseforms. - Once you approve, it calls
App.publish, and the Action waits out its delay window. - The new build serves at
leaseclock.com/app, and each Customer's Tenant runs it on its next request. - The previous Version stays, and
App.publishedfires.
A call without the scope to publish ends forbidden. A call on an App in a state that cannot publish ends refused, and the Action says why.
Change it
| Say | What your agent calls |
|---|---|
| "Preview it with one customer first." | Change.review on the preview, then Version.deploy for everyone |
| "Put the last build back." | Version.deploy with the previous Version, which App.publish kept |
| "Serve the app at /portal instead." | No call: mount: /portal in the App file, then App.publish |
Under the hood
| Part | Entries |
|---|---|
| Nouns | App, Version, Domain, Tenant, Change |
| Calls | Interface.list, App.publish |
| Events | App.published |
| Seat | The Engineering Lead approves App.publish |
| Systems | Sites |
| Depth | How an App is served, App previews and Versions |
Change what a screen shows
Say "show a renewal countdown on each lease" and a Component fills one named slot of a derived screen, while every other part keeps deriving.
What an App reads from a Noun: depth
Representation, field types, relationships, lifecycle states and Events: what an App draws from each fact a Noun declares, traced through one Lease.