use-case:agencies

Every client portal, documented and comparable.

Setting up a client portal is a checklist and a person clicking through it, rebuilt for every client. Kalup turns each portal into files you can read, document and compare. Keep one repo per client.

the cast, and the sheet it came from
one mould per clientKALUPFIG. 3 · THE FLEETSCALE 1:1 · SHEET 3 OF 4
flow:daily

From an existing portal to a documented one.

Start from what the client already has. Nothing here writes to a portal.

  1. 01

    Pull the client portal into files

    0.2
    $ kalup pull
    Brings the objects, groups and properties of an existing portal into config. Nothing to write by hand.
  2. 02

    Write the data dictionary

    0.2
    $ kalup docs
    A Markdown data dictionary generated from the files, so the documentation is never older than your files.
  3. 03

    See what has not been promoted

    0.2
    $ kalup compare sandbox production
    Shows what a colleague built in the sandbox and has not moved to production yet, edits included.
  4. 04

    Know what changed since last time

    0.2
    $ kalup snapshot --target production
    Saves a scoped observation of the configuration, with what could not be read listed. Compare against it later to see what changed in the portal since.
  5. 05

    Reuse a setup across clients

    0.2
    $ kalup add ../blueprints/renewals-1.0.0.json
    Blueprints: a versioned setup you add to each client repo. kalup blueprint upgrade merges a new version into each and keeps the client's own changes. No portal changes until someone plans and applies.
compare:sandbox/production

What your colleague built, and never moved.

Compare takes two sides, each a target, a snapshot file or your config, and lists the differences in the same shape as a plan.

acme-crm · zsh
$ kalup compare sandbox production
a: target sandbox, portal 1111111
b: target production, portal 2222222
3 equal, 1 differ, 1 only in a, 0 only in b, 0 unmanaged, 0 unknown, 0 excluded
differs: property:companies/billing_status
  add options[PAST DUE]: null -> {"value":"PAST DUE","label":"Past due","hidden":false,"description":""}
only in a: property:companies/renewal_date
$ 
docs/data-dictionary.md
<!-- an excerpt of kalup docs output -->
# acme\-crm data dictionary

Source: the config files.

## companies

### Properties

| Internal name | Key | Label | Type | Field type | Group | Managed or reference | Codec | Required | Description |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| billing\_status | billingStatus | Billing status | enumeration | select | billing | managed | enum | no |  |
| renewal\_date | renewalDate | Renewal date | date | date | billing | managed | date | no |  |
One repo per client
acme-crm/             one repo per client
  kalup.config.ts     targets: sandbox 1111111, production 2222222
  kalup/objects/      companies.ts, deals.ts, subscription.ts
  .kalup/snapshots/   production/20260901T090000000Z.json
scope:out

What Kalup does not do for you.

Knowing where it stops is part of trusting what it does.

  • It does not move records.

    Setting up a portal moves configuration only. Contacts, companies and deals stay where they are.

  • A snapshot is not a backup.

    A snapshot is a scoped observation of the configuration, with what could not be read listed. It holds no record values, and nothing restores from it.

  • It does not click through the UI for you.

    Record page layouts, saved views and conditional property logic have no public API. The plan says so, and a person makes those changes. Printed steps for them come later.

kalup:init

Start with one portal.

kalup init pins a target, writes the files and runs the first pull. Nothing is written to the portal.