data/ — versioned reference data
This directory holds the reference data of the apxtri core (options, apidoc
configuration). It is versioned in the apxtri repository so that every town boots
with the same data and so that a change can be rolled out to every namespace by a
plain git pull followed by setup/update.sh.
Nothing in here is user data. Persons, messages, clients, missions and any other
runtime content are never committed here: --capture excludes the
donotupdate items from the policy, and per-tribe mirrors only touch object
directories declared (present) in the tribe's own {tribe}/data/objects.
Two layers
TOWN layer (apxtri/data/) is applied to the town and every runtime
namespace, driven by the policy file data/sync-policy.json. Each entry maps a
data/<key> subtree to a runtime path and decides how it is handled:
| Entry | Action | Applies to |
|---|---|---|
apidoc |
sync-data |
town only (rendered, apply-only) |
objects/options/itm |
replace |
town + all tribes (fan-out), with donotupdate: ["profil_*"] |
replace semantics (fan-out): a file not in donotupdate is added if missing
and overwritten if present. A donotupdate item (e.g. a tribal profil_*) is
seeded when missing but never overwritten once it exists, and it is never
captured back into apxtri/data/. A data/ subtree with no policy entry is
left alone.
TRIBE layer ({tribe}/data/) is a full mirror of the tribe's own namespace,
with no per-tribe policy. Only object directories declared in the tribe
repository ({tribe}/data/objects/<obj>/itm/) are mirrored; set --tribe <name>
manages them in both directions. Protected user objects (persons, mails,
mailboxes, clients, ...) are hard-skipped as a safety net.
The tribe's profil_* is seeded at tribe creation and owned by the tribe: it
lives in the tribe namespace, is versioned by the tribe git, and is never written
by the town layer. The town layer runs last during an update so town-owned
replace items keep the final word.
Layout
apxtri/data/
├── sync-policy.json # TOWN layer policy (actions, scope, donotupdate)
├── objects/
│ └── options/
│ └── itm/*.json # reference option values (profil_*, country_*...)
├── apidoc/apxtri/ # apidoc config templates, rendered at install
└── wwws/newwebapp/ # on-demand templates, never applied by update
Usage
The single entry point is setup/sync-data.sh:
# TOWN layer — apply committed data to town + all tribes (done by update.sh)
setup/sync-data.sh --apply --tribe apxtri
# Capture tested town data back into apxtri/data/ (done by gitpush.sh)
setup/sync-data.sh --capture --tribe apxtri
# TRIBE layer — mirror the edifiance namespace from/to its own repository
setup/sync-data.sh --apply --tribe edifiance
setup/sync-data.sh --capture --tribe edifiance
# Preview without writing, or restrict to matching filenames
setup/sync-data.sh --apply --tribe apxtri --dry-run
setup/sync-data.sh --capture --tribe edifiance --limit 'profil_*'
--delete is never used: files present in a namespace but absent from the
repository are left untouched. Index directories (idx/) are never touched — the
runtime rebuilds them on start.
Workflow
Town reference data is edited in the running instance, where it can be tested, then captured and pushed:
# 1. Edit / test in {DATAPATH}/{TOWN}/objects/options/itm/
# 2. Capture (called automatically by gitpush.sh)
setup/sync-data.sh --capture --tribe apxtri
# 3. Review, commit and push
git add data/
git commit -m "data: update country options"
gitpush.sh patch
Tribal reference data follows the same loop from the tribe repository:
# from {NODEPATH}/edifiance: edits to profil_* live in the tribe namespace,
# captured by gitpush --tribe edifiance into edifiance/data/objects/
cd /opt/apxtowns/dev.zero/edifiance
SYNC_LIMIT='profil_*' /opt/apxtowns/dev.zero/apxtri/setup/gitpush.sh patch --tribe edifiance
On every other instance, setup/update.sh pulls and applies both layers.