Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions content/docs/configure/localization.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: Localization
description: Set the tenant-wide timezone, language, country, and date, time, and number formats that every rendered value inherits.
---

# Localization

Localization sets the **tenant-level defaults** for how ObjectOS interprets
time, chooses a message catalog, and renders dates, numbers, and currency.
These values are the fallback for the whole workspace — individual users can
override their own language in their [Account](/docs/use/profile), but the
defaults you set here apply to everyone who has not.

Open **Setup → Configuration → Localization**. The page is split into two
sections: **Region** and **Formats**.

## Region

Region controls how ObjectOS resolves *meaning* — which timezone anchors
relative-time calculations, which locale drives formatting, and which country
the deployment reports as its home.

| Setting | Default | Drives |
|---|---|---|
| `Default timezone` | `UTC` | IANA zone for `today()` / `daysFromNow`, analytics date buckets, and rendered datetimes |
| `Default language` | `English (US)` | BCP-47 locale for message catalogs and number/date formatting |
| `Default country` | `US` | ISO 3166-1 alpha-2 code (e.g. `US`, `GB`, `CN`) |

> **Timezone is not cosmetic.** It is the anchor for every relative-time
> expression and for the buckets analytics rolls records into. Changing it
> shifts what "today" means across the tenant — set it once, deliberately.

`Default timezone` is a dropdown of IANA zones (`UTC`, `America/New_York`,
`Asia/Shanghai`, and so on). `Default language` selects the locale whose
message catalog and formatting rules the UI falls back to. `Default country`
is a free-text field that expects a two-letter ISO code.

## Formats

Formats control *presentation* — how an already-resolved value is written out.
They do not change stored data, only how it is displayed.

| Setting | Default | Example |
|---|---|---|
| `Date format` | ISO | `2026-06-17` |
| `Time format` | 24-hour | `14:30` |
| `Number format` | comma / dot | `1,234.56` |
| `Currency` | — | Currency symbol and placement for money fields |

Each is a dropdown. Pick the presentation your users expect; the underlying
timestamps and numbers are stored in a canonical form and only formatted at
render time.

## Tenant defaults vs. user overrides

Everything on this page is a **tenant default**. When a user sets their own
language in **Account**, that choice wins for that user's session and rendered
UI; users who leave their preference unset inherit the `Default language` you
configure here. Timezone, country, and format defaults apply tenant-wide.

## Where to go next

| Task | Page |
|---|---|
| Change branding, feature flags, and other tenant settings | [System Settings](/docs/configure/system-settings) |
| Configure a user's personal language override | [Your profile](/docs/use/profile) |
| Set up transactional email delivery | [Email](/docs/configure/email) |
| Return to the administration overview | [Configure](/docs/configure) |
2 changes: 1 addition & 1 deletion content/docs/configure/meta.de.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"title": "Konfigurieren",
"defaultOpen": false,
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "api-access", "webhooks", "email"]
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "localization", "notifications", "api-access", "webhooks", "email"]
}
2 changes: 1 addition & 1 deletion content/docs/configure/meta.es.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"title": "Configurar",
"defaultOpen": false,
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "api-access", "webhooks", "email"]
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "localization", "notifications", "api-access", "webhooks", "email"]
}
2 changes: 1 addition & 1 deletion content/docs/configure/meta.fr.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"title": "Configurer",
"defaultOpen": false,
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "api-access", "webhooks", "email"]
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "localization", "notifications", "api-access", "webhooks", "email"]
}
2 changes: 1 addition & 1 deletion content/docs/configure/meta.ja.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"title": "設定",
"defaultOpen": false,
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "api-access", "webhooks", "email"]
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "localization", "notifications", "api-access", "webhooks", "email"]
}
2 changes: 1 addition & 1 deletion content/docs/configure/meta.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"title": "Configure",
"defaultOpen": false,
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "api-access", "webhooks", "email"]
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "localization", "notifications", "api-access", "webhooks", "email"]
}
2 changes: 1 addition & 1 deletion content/docs/configure/meta.ko.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"title": "설정",
"defaultOpen": false,
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "api-access", "webhooks", "email"]
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "localization", "notifications", "api-access", "webhooks", "email"]
}
2 changes: 1 addition & 1 deletion content/docs/configure/meta.zh-Hans.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"title": "配置",
"defaultOpen": false,
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "api-access", "webhooks", "email"]
"pages": ["index", "users", "runtime", "data-sources", "authentication", "permissions", "storage", "ai", "mcp", "system-settings", "localization", "notifications", "api-access", "webhooks", "email"]
}
120 changes: 120 additions & 0 deletions content/docs/configure/notifications.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
title: Notifications
description: Configure how ObjectOS routes events into user inboxes — subscriptions, per-user preferences, and render templates.
---

# Notifications

This page covers the **administrator side** of notifications: how events become
messages, and the three system-managed objects you use to route and render
them. For the recipient's view of the inbox — reading and muting notifications —
see [Notifications](/docs/use/notifications) under *Use*.

## The notification pipeline

A notification is not a single record. It flows through four stages:

```text
emit() → Notification Event → routed by Subscription + Preference + Template → Inbox Message
```

1. **`emit()`** — Application code raises an event (an approval submitted, a
record shared, an invitation sent).
2. **Notification Event** (`sys_notification`) — Each `emit()` writes one
ingress row. This is the diagnostic log of *what happened*, before any
delivery decision. See [Audit Logs](/docs/operate/audit-logs) for how to
read it.
3. **Routing** — For each event, ObjectOS resolves who should be notified
(**Subscriptions**), whether each recipient allows that topic on that channel
(**Preferences**), and how the message should be rendered (**Templates**).
4. **Inbox Message** (`sys_inbox_message`) — The materialized, per-user result
the recipient actually sees in their inbox.

Preferences, Subscriptions, and Templates are the admin/system-side
configuration. Inbox Messages are the user-side output.

### How routing resolves

For a single event, the three objects each answer one question:

| Object | Question it answers |
|---|---|
| Notification Subscription | *Who is interested?* — which principals stand subscribed to the topic |
| Notification Preference | *Does this recipient allow it here?* — the per-user mute/allow for the topic and channel |
| Notification Template | *How is it written?* — the subject and body to render for the recipient's channel and locale |

Only when a recipient is subscribed **and** their preference for the
topic/channel is enabled does a template render and an inbox message
materialize. All three objects are seeded and maintained by the platform, so
the list views mostly show system-generated rows.

## Notification Preferences

At **Setup → Configuration → Notification Preferences** (`sys_notification_preference`).

Per-user × topic × channel toggle (mute/allow), with admin-global defaults. A
preference decides whether a given recipient receives a given topic on a given
channel.

| Field | Purpose |
|---|---|
| `user_id` | The principal the preference belongs to |
| `topic` | Notification topic (e.g. `project.digest`) |
| `channel` | Delivery channel (in-app, email, …) |
| `enabled` | Boolean — allow or mute this topic/channel for the user |
| `digest` | Batching cadence for the topic |
| `quiet_hours` | JSON window during which delivery is suppressed |
| `created_at` / `updated_at` | Audit timestamps |

> Entries appear automatically when their source action first runs (for
> example *Submit for Approval*, *Share*, or *Invite*) — you rarely create
> preference rows by hand. Use the list to adjust admin defaults or mute a
> noisy topic.

## Notification Subscriptions

At **Setup → Configuration → Notification Subscriptions** (`sys_notification_subscription`).

A **standing subscription** of a principal (role, team, or user) to a
notification topic. Subscriptions answer *who is interested* in a topic before
per-user preferences filter delivery.

| Field | Purpose |
|---|---|
| `topic` | The topic being subscribed to |
| `principal` | Role, team, or user that receives the topic |
| `enabled` | Boolean — activate or pause the subscription |

## Notification Templates

At **Setup → Configuration → Notification Templates** (`sys_notification_template`).

A per **(topic × channel × locale)** render template. Templates turn an event
payload into the subject and body a recipient reads, in their locale and for
their channel.

| Field | Purpose |
|---|---|
| `topic` | Topic this template renders |
| `channel` | Channel the rendered output targets |
| `locale` | Locale of this rendering (matched to the recipient) |
| `version` | Template version number |
| `subject` | Rendered title |
| `body` | Message body (markdown) |
| `format` | Output format for the body |
| `is_active` | Boolean — whether this template is used for rendering |

These objects are **system-managed**: rows are seeded by the platform and the
capabilities you run, so most of your work is editing template content or
toggling `is_active`, `enabled`, and preference defaults rather than creating
records from scratch.

## Where to go next

| Task | Page |
|---|---|
| Configure the email channel used for delivery | [Email](/docs/configure/email) |
| Diagnose events with the ingress log and audit trail | [Audit Logs](/docs/operate/audit-logs) |
| See the recipient's inbox experience | [Notifications](/docs/use/notifications) |
| Set locale defaults that templates match against | [Localization](/docs/configure/localization) |
| Return to the administration overview | [Configure](/docs/configure) |
25 changes: 25 additions & 0 deletions content/docs/configure/system-settings.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,31 @@ Customer-facing settings usually include:
| AI providers | Model provider, API key, budget limits |
| SSO | OIDC provider settings and test connection |

## Branding

At **Setup → Configuration → Branding**. These settings control the workspace's
display identity — its name, logo, and colours.

| Setting | Notes |
|---|---|
| `Workspace name` | Required. The name shown across the UI (default `ObjectStack`) |
| `Support email` | Address surfaced to users for help (e.g. `support@example.com`) |
| `Default theme` | `Match system`, `light`, or `dark` |
| `Accent colour` | Hex colour with a picker (default `#6366f1`) |
| `Logo URL` | URL of the workspace logo |

## Feature flags

At **Setup → Configuration → Feature Flags** `[Beta]`. Toggle experimental and
beta features for this workspace — grouped as **Productivity** (AI Assistant,
Kanban swimlanes) and **Collaboration** (Realtime cursors, Inline comments).
Each is a tenant-level UI switch.

> **Beta features may change without notice.** Pin a flag with an environment
> variable (e.g. `OS_FEATURE_FLAGS_AI_ENABLED=true`) to lock it for the whole
> deployment. Because environment overrides are locked, the `OS_FEATURE_FLAGS_*`
> vars take precedence over the UI toggles.

## Secrets

Password and credential fields should be encrypted by the settings
Expand Down
126 changes: 126 additions & 0 deletions content/docs/operate/audit-logs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
title: Audit Logs
description: Read the immutable audit trail and diagnostics logs that record every change, sign-in, and emitted event on your deployment.
---

# Audit Logs

The audit log is the immutable record of what happened on your deployment: who
changed what, when, and from where. This page is the deep reference for the
diagnostics surfaces under **Setup → Diagnostics**. For the operator overview of
logs, metrics, and request identity, see
[Observability](/docs/operate/observability).

> These surfaces require the `manage_platform_settings` permission.

Reach for the audit log when you need to prove or investigate:

- permission-sensitive changes;
- settings and configuration changes;
- user and session activity;
- integration and automation activity;
- denied-access analysis.

## Audit Logs

At **Setup → Diagnostics → Audit Logs** (`sys_audit_log`). The object is
**read-only and immutable** — an append-only trail of platform events. You can
filter, group, and inspect rows, but nothing can edit or delete them from the
Console.

### Preset views

The list opens with tabs that filter by action category:

| View | Shows |
|---|---|
| `Recent` | All events, newest first |
| `Writes` | Create / update / delete actions |
| `Auth` | Sign-in, sign-out, and authentication events |
| `Config` | Settings and configuration changes |

### Columns and fields

The default columns are `Timestamp`, `Action` (a coloured pill —
create / update / …), `Object`, `Record ID`, and `Actor`. The footer shows the
total record count (e.g. *36 records*).

Each row carries the full field set:

| Field | Meaning |
|---|---|
| `created_at` | When the event was recorded |
| `action` | The operation (create, update, delete, auth, …) |
| `user_id` | Lookup to the acting User |
| `actor` | Textual actor identity |
| `object_name` | The object the event touched (e.g. `sys_user`) |
| `record_id` | The affected record |
| `old_value` | Prior value (textarea) |
| `new_value` | New value (textarea) |
| `ip_address` | Source IP of the request |
| `user_agent` | Client user agent |
| `tenant_id` | Owning tenant |
| `metadata` | Additional structured context |

> The `Config` view is the fastest way to answer "who changed this setting?" —
> it narrows the trail to configuration actions before you start reading rows.

### Reading a change

For write actions, the interesting detail is the before/after. Open a row's
`⋮` menu to expand `old_value` and `new_value` and see exactly what changed on
that record. The `Object` and `Record ID` columns tell you *what* was touched;
`old_value`/`new_value` tell you *how*; `actor`, `ip_address`, and `user_agent`
tell you *who* and *from where*.

> For regulated environments, back the immutability up at the storage layer —
> make the table append-only at the database and define a retention policy.

## Notification Events

At **Setup → Diagnostics → Notification Events** (`sys_notification`). This is
the **ingress log of the notification system** — one row per `emit()`, written
before any delivery decision. Use it to diagnose why a notification did or did
not reach an inbox; the routing and materialization that follow are documented
in [Notifications](/docs/configure/notifications).

Preset views are `Recent` and `By Topic`. Default columns: `Topic` (e.g.
`project.digest`), `Severity` (an info/warn/… pill), `Actor`, `Source Object`,
and `Created At`.

| Field | Meaning |
|---|---|
| `topic` | The emitted topic |
| `payload` | Event payload (JSON) |
| `severity` | Severity level |
| `dedup_key` | Key used to collapse duplicate emits |
| `source_object` | Object that raised the event |
| `source_id` | Record that raised the event |
| `actor_id` | Principal that triggered the emit |
| `created_at` | When the event was ingested |

The `dedup_key` collapses duplicate emits, and `payload` carries the raw event
context that templates render from. Because this log sits *upstream* of routing,
a row here with no matching inbox message usually means a subscription or
preference filtered the event out — check
[Notifications](/docs/configure/notifications) when a user reports a missing
alert.

Downstream, each event is materialized into per-user inbox messages
(`sys_inbox_message`) — the recipient's view lives under
[Notifications](/docs/use/notifications).

## Sessions

At **Setup → Diagnostics → Sessions**. Sessions lists active and recent
sign-in sessions, so you can investigate a user's activity or revoke access.
Pair it with the `Auth` audit view when reviewing a sign-in incident.

## Where to go next

| Task | Page |
|---|---|
| Operator overview of logs, metrics, and request identity | [Observability](/docs/operate/observability) |
| Understand how notifications are routed and rendered | [Notifications](/docs/configure/notifications) |
| Harden a deployment before go-live | [Production Readiness](/docs/operate/production) |
| Return to the operations overview | [Operate](/docs/operate) |
Loading
Loading