# `brandAutomat` > **Source File**: [`src/automats/brandAutomat.js`](file:///home/seb/src/dashfront/src/automats/brandAutomat.js) > **Registration Key**: `'brand'` (`Automat.get('brand')` / `window.__AUTOMATS__.get('brand')`) --- ## 1. Overview & Purpose `brandAutomat` manages the active company's catalog brands (manufacturers). Brands are referenced by articles for catalog organization, filtering, and GPSR (General Product Safety Regulation) manufacturer compliance info. ### Core Responsibilities - **Company Scoping**: Caches all brands for the currently selected company. - **Alphabetical Sorting**: Automatically sorts brands by name using German (`'de'`) collation. - **Autonomous Bootstrap**: Automatically triggers `load()` when `authAutomat` enters `'authed'` with a selected company, and calls `reset()` when the session ends. - **Upsert Mutation**: Handles creating or updating a brand with immediate in-memory cache synchronization. --- ## 2. State Structure ```ts interface Brand { id: number | string; name: string; gsprpinfo?: string | null; [key: string]: any; } interface BrandState { /** Alphabetically sorted list of company brands. */ brands: Array; /** Async lifecycle status. */ status: 'idle' | 'loading' | 'succeeded' | 'failed'; /** Error message if loading failed. */ error: string | null; } ``` ### Initial State ```js const initialState = { brands: [], status: 'idle', error: null, }; ``` --- ## 3. Configuration & Options ```js new Automat(initialState, actions, { name: 'brand' }); ``` - **`name`**: `'brand'` - **`persist`**: `false` --- ## 4. Actions & Methods Access actions via `brandAutomat.actions.()`. ### `load(): Promise>` Fetches all brands for the current company via `GET /api/brand`. Sorts them by name, updates `status` to `'succeeded'`, and returns the array. If the request fails, sets `status` to `'failed'` and records `error`. ### `upsert(body: { name: string, gsprpinfo?: string }): Promise` Creates or updates a brand via `POST /api/brand/upsert`. Merges the updated brand into `state.brands`, re-sorts the list, updates state, and returns the modified brand object. ### `reset(): void` Resets the state back to `initialState` (`brands: []`, `status: 'idle'`, `error: null`). --- ## 5. Cross-Automat Subscriptions `brandAutomat` subscribes to `authAutomat` at module initialization: ```js authAutomat.subscribe((auth) => { const companyId = auth.user?.selectedCompanyId; if (auth.status === 'authed' && companyId) { void brandAutomat.actions.load(); } else if (auth.status === 'anon') { brandAutomat.actions.reset(); } }); ``` --- ## 6. Usage Examples ### A. React `PureComponent` Brand Selector Dropdown ```jsx import { PureComponent } from 'react'; import PropTypes from 'prop-types'; import brandAutomat from '../automats/brandAutomat'; export class BrandSelect extends PureComponent { static propTypes = { value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), onChange: PropTypes.func.isRequired, }; constructor(props) { super(props); this.state = { brands: brandAutomat.state.brands, status: brandAutomat.state.status, }; } componentDidMount() { this.unsub = brandAutomat.subscribe(this, ['brands', 'status']); if (this.state.status === 'idle') { brandAutomat.actions.load().catch(console.error); } } componentWillUnmount() { this.unsub?.(); } render() { const { brands, status } = this.state; const { value, onChange } = this.props; if (status === 'loading') { return ; } return ( ); } } ``` ### B. Creating or Updating a Brand ```js import brandAutomat from '../automats/brandAutomat'; async function handleSaveBrand(name, gsprpinfo) { try { const brand = await brandAutomat.actions.upsert({ name, gsprpinfo }); console.log('Saved brand:', brand); } catch (err) { console.error('Failed to save brand:', err); } } ``` --- ## 7. Best Practices & Gotchas 1. **Automatic Loading**: In normal usage, you rarely need to invoke `load()` manually; `authAutomat` triggers it as soon as the user logs in or switches company. 2. **Alphabetical Guarantee**: The `brands` array in state is guaranteed to be sorted alphabetically (`localeCompare` with German rules).