Skip to content
Agentmart
Submit a tool

settings-system

Multi-tenant polymorphic settings system with agency-scoped records and global fallback chain.

Skill by ceilidhboy

IndexedMIT
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/ceilidhboy-settings-system

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Multi-tenant polymorphic settings system with agency-scoped records and global fallback chain. Create, read, update settings records. Use when working with App\Models\Setting, App\Enumerations\SettingType, the settings table migration, the polymorphic settings system, or the fallback chain (agency-specific → global default). Also use when integrating third-party services (Xero, Stripe, etc.) that need per-agency configuration storage.

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/settings-system

What's inside

Skill name
settings-system
Description
Multi-tenant polymorphic settings system with agency-scoped records and global fallback chain. Create, read, update settings records. Use when working with App\Models\Setting, App\Enumerations\SettingType, the settings table migration, the polymorphic settings system, or the fallback chain (agency-specific → global default). Also use when integrating third-party services (Xero, Stripe, etc.) that need per-agency configuration storage.
License
MIT
Instructions
78 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Settings System

## Quick Start

```php
use App\Enumerations\SettingType;

// Create a settings record (globally, for the system agency)
Setting::create([
    'agency_id' => Agency::SystemAgencyId,
    'type' => SettingType::XeroIntegration,
    'data' => ['key' => encrypt('value')],
]);

// Read with fallback chain (agency → global)
$setting = Setting::forAgency($agencyId, SettingType::XeroIntegration);
$data = $setting?->data;
```

## Model

`App\Models\Setting` extends `TenantModel`. Key details:

- `data` column is JSON, cast to `array` on read
- `$guarded = []` — all fields mass-assignable
- `TenantModel` auto-populates `agency_id` on create via `AgencyScoping` trait (can override by explicitly setting it)

## Fallback Chain Resolution

Settings resolve in priority order, returning the first match:

1. **Agency-specific** (`agency_id` = current agency)
2. **Global default** (`agency_id` = `Agency::SystemAgencyId`, which is 1)

Use `Setting::forAgency($agencyId, $type)` for this. To query a specific level directly, use `scopeOfType()` and/or `scopeForAgency()`.

## Composite Unique Constraint

The migration enforces `unique(agency_id, type)` — one record per setting type per agency. Use `updateOrCreate()` for upsert scenarios:

```php
Setting::updateOrCreate(
    ['agency_id' => $agencyId, 'type' => SettingType::XeroIntegration],
    ['data' => $payload],
);
```

## Data Payload & Encryption

- Only **secrets** (`access_token`, `refresh_token`, API keys) are encrypted via Laravel's `encrypt()`/`decrypt()`
- Non-sensitive fields (`expires_at`, `connected_at`, tenant IDs) are plaintext
- The `data` JSON column stores everything together

## Adding a New Setting Type

1. Add case to `App\Enumerations\SettingType`
2. Create/update a settings record via the model — no schema changes needed

## Creating Global vs Agency-Specific Records

When creating via `Setting::create()`, the `AgencyScoping` trait auto-sets `agency_id` to the current tenant. To create a global record (agency 1), explicitly set the agency_id:

```php
Setting::create([
    'agency_id' => Agency::SystemAgencyId, // must be explicit
    'type' => SettingType::XeroIntegration,
    'data' => [...],
]);
```

## See Also

- `docs/WIP/Mike/settings-system.md` — detailed human-readable documentation
- `app/Models/Setting.php` — model with scopes and helpers
- `app/Enumerations/SettingType.php` — enum of available setting types
- `database/migrations/2026_05_15_000000_create_settings_table.php` — table schema

From ceilidhboy/skills, MIT.

More from ceilidhboy/skills

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Jul 11, 2026 (3 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from ceilidhboy

Cite this page

settings-system skill. Agent Mart. https://agentmart.dev/skills/ceilidhboy-settings-system (last updated 2026-10-24)