Take over a site
Primer for a developer inheriting a Dropbits install. Site-specific URLs, accounts, and quirks stay in that site’s README (usually deployable/<id>/ or the install) — not in these product guides.
Owner chrome: Hub tour · Log in & roles · Entities & records. Deploy: Content-owned deploy.
Three trees
| Tree | What it is |
|---|---|
| Kernel | dropbits/ — PHP, packs, types, product docs. Code plane. |
| Site directory | site.json, themes/, optional import notes. Portable unit. |
| Content DB | data/site.db + data/uploads/ + secrets. Never executable. Tools only. |
Writes to pages, nav, entities, and users go through Toolbox tools (browser, CLI, or Assistant). Do not SQL-insert content.
First health check
From the kernel, with DROPBITS_SITE=<id> (discovery finds deployable/<id>/ or sites/<id>/):
php bin/site boot
php bin/site migrate --status # pending must be empty
php bin/site tool-run list_pages --role=admin
php bin/site tool-run list_entities --role=admin
php bin/site tool-run read_nav --role=admin --json='{"widget_id":"hub_menu"}'
Expect boot: ok, no pending migrations, guest pages 200, staff slugs (admin-users, …) 302 for guests. In-process HTTP (Router::handleHttp) is enough; do not hunt vhosts unless the URL itself is the bug.
Also confirm: grants_enabled, mail pack + data/mail.json if you need forgot-password, and that editor has edit on site plus view on public pages (re-apply set_page_visibility / set_widget_visibility public if an old import omitted the editor role).
Hub UX (editors and admins)
The sticky hub is grant-filtered. Usual structure slides: Pages, Entities, Site, Backup, LLM chat, Help. Records is a group of page links (not a dialog):
| Page | Typical visibility | Recipe / convention |
|---|---|---|
/admin-users | Admin | users_admin — login users table |
/account | Editors | users_admin — @me, no create |
/admin-<entity> | Editors or Admin | listing + hub_crud_pages |
Footer Log in is a login_chip chrome widget (users_admin places it).
Apply users admin on a non-live site:
php bin/site tool-run apply_recipe --role=admin --json='{"recipe":"users_admin"}'
Idempotent (only_missing for creates). Re-apply still runs patch_widget_config on users_list so auto_arm: true lands on widgets created before D46.
Linking extra CRUDs: create the page + listing, set visibility, then merge hub links — apply_recipe does that via nav.hub_crud_pages / hub_account_pages. Do not append staff slugs to main_nav.
Listing CRUDs should set detail: true. Staff-gated listings (admin/editors only) default auto_arm even when the config key is missing; public indexes stay unarmed until the Content handle. Recipes may still set auto_arm: true explicitly.
Mail and password reset
Forgot-password needs the mail pack enabled, a From address in data/mail.json, and a driver that is deliverable (log-only is refused on live). Reset links use canonical_host / SEO public_base_url or the current HTTP host. The admin demo user often has no email — invite named accounts instead.
Backup
Hub → Backup: rolling checkpoints (DB + user CSS) and SitePack ZIP. CLI: php bin/site backup --scope=full --out=PATH.zip. Content recover is the ZIP / install tarball, not theme git history.
Deploy
Routine ship is code + migrate. data/ stays on the install (CONTENT_OWNED=1). Do not --with-content unless you intend to overwrite editorial. Hotel / live URLs and host paths belong in the site README or gitignored host notes.
What to put where
| Generic (these docs) | This site’s README |
|---|---|
| Hub, roles, recipes, tools, deploy shape | Page map, entity names, known quirks |
users_admin, Records convention | Named accounts, public URL, mail driver |
| Kernel CLI | Import snapshots, FAU/WXR source |
Do not copy operator passwords or deploy.env into product git.