# Company, Home Content, and Managed Settings

Phase 7 provides a governed company profile, a revisioned home-page CMS, and an
allow-listed typed settings registry. All administration endpoints require a
recent password confirmation in addition to the relevant database permission.

## Company profile

The `primary` company profile is a singleton selected by its stable
`profile_key`. It holds public identity and contact fields; credentials and
provider secrets do not belong in this table. Updates require `company.manage`,
use `lock_version` optimistic concurrency, and append a before/after audit event.
A stale form is rejected without partially changing the profile.

## Home-page revisions

The home page owns ordered relational revisions and sections. Section keys and
their display order are defined in `config/content.php`; arbitrary section keys
are not accepted at the HTTP boundary.

The publication lifecycle is:

```text
draft <-> scheduled -> published -> superseded
```

- Draft and scheduled revisions are editable. Saving a scheduled revision keeps
  its schedule.
- At most one editable revision is produced through the application service.
  Scheduling a new revision returns any previous scheduled revision to draft.
- Publishing locks the home-page row, supersedes the prior live revision, and
  makes the selected revision live in one transaction.
- Published and superseded revisions are immutable. A new draft is cloned from
  the live revision for subsequent changes.
- A page-level `lock_version` rejects stale saves, schedules, publications, and
  draft creation.

`content:publish-due` publishes due scheduled revisions. The scheduler invokes
it every minute with overlap protection and a cross-node server lock. The public
home route reads only a `published` revision, filters disabled sections before
rendering, and shows a safe fallback until the first publication.

Call-to-action URLs must be root-relative or HTTPS. Labels and URLs must be
provided together. Blade escapes all managed content by default.

## Managed settings

`config/managed-settings.php` is the authoritative allow-list. Each entry has a
stable qualified key, label, type, sensitivity flag, and default. The database
stores the scope and key separately and supports string, integer, boolean, and
JSON serialization.

Every setting has an independent optimistic `version`. An update transaction
checks every submitted version before committing, skips unchanged entries, and
audits only the qualified keys that changed. Values are never included in the
settings audit event.

Sensitive settings are stored only in `encrypted_value` using Laravel's
application encryption; `value` remains null. They are never returned by the
read model. A blank sensitive field preserves the existing value. Operators
must treat `APP_KEY` and its rotation history as recovery-critical because loss
of the key makes encrypted settings unreadable.

## Permissions and audit actions

- `company.manage`: view and update the company profile.
- `home.manage`: view, edit, schedule, publish, and clone home revisions.
- `settings.manage`: view and update managed settings.

The module records company updates, revision creation/update/scheduling/
publication, and changed setting keys. Scheduled system publication records a
null actor while preserving the same audit trail.

## Operational verification

- Run `php artisan content:publish-due` to verify or manually recover scheduled
  publication.
- Confirm `php artisan schedule:list` includes the minute-level publisher.
- Alert when the command fails, a scheduled revision remains overdue, or the
  public page has no published revision after launch approval.
- MySQL 8 CI remains authoritative for row-lock and unique-index behavior.
