6.0 KiB
6.0 KiB
Dashfront Automats Documentation
This directory contains reference documentation for all state automats in dashfront (src/automats/), powered by react-automat.
Architecture Overview
In dashfront, state is managed outside the React component lifecycle using Automats. An Automat is an observable, fine-grained state store living in module scope.
Core Principles
- Module Scope: State persists across route changes and component mount/unmount cycles.
- Synchronous Reads: Components read state synchronously in their
constructor(or initial state) — zero loading flicker or blank frames. - Fine-Grained Subscriptions: React
PureComponentinstances subscribe incomponentDidMountwith selector functions or key lists, skipping unnecessary re-renders. - Explicit Cleanup: Every subscription returns an
unsub()function called incomponentWillUnmount(). - No Context / No Hooks in PureComponents: Automats bypass React Context providers and hooks, eliminating reconciliation cascades.
- Automatic Coordination: Domain and configuration automats subscribe to
authAutomatto automatically bootstrap on login, switch data when the active company changes, and reset on logout.
Domain & Data Model Guides
- Artikeltypen-Matrix: Spezifikation und Matrix für non-standard Artikeltypen (Stückliste, Variations-Vater, Variations-Kind, Varianten-Baum).
Automats Directory
| Automat | State File | Documentation | Description |
|---|---|---|---|
artikelAutomat |
src/automats/artikelAutomat.js |
artikelAutomat.md | Cache and reactive distributor for single article detail payloads (GET /api/article/:sku) with inflight request deduplication. |
authAutomat |
src/automats/authAutomat.js |
authAutomat.md | Manages authentication lifecycle, session bootstrap, Google One Tap login, and multi-tenant company selection. |
brandAutomat |
src/automats/brandAutomat.js |
brandAutomat.md | Company-scoped catalog brands / manufacturers list (GET /api/brand, upsert). Auto-loads on company auth. |
categoryAutomat |
src/automats/categoryAutomat.js |
categoryAutomat.md | Hierarchical category tree (id → node map), route view article automats, tree ordering, drag-and-drop moves, and image uploads. |
companyAutomat |
src/automats/companyAutomat.js |
companyAutomat.md | Active company configuration, tax rates (standard, reduced), root category ID, and company profile info. |
deliveryEditorAutomat |
src/automats/deliveryEditorAutomat.js |
deliveryEditorAutomat.md | Multi-line inbound delivery editor, OCR/PDF receipt reconciliation, supplier article auto-matching, and draft badge tracking. |
navigationAutomat |
src/automats/navigationAutomat.js |
navigationAutomat.md | Tracks and restores last visited article SKU and delivery paths across top-level section navigation. |
posterminalAutomat |
src/automats/posterminalAutomat.js |
posterminalAutomat.md | Point-of-Sale hardware terminals and enabled category assignments per terminal. |
supplierAutomat |
src/automats/supplierAutomat.js |
supplierAutomat.md | Company-scoped supplier directory (GET /api/supplier, create, update, delete) with inflight deduplication. |
unitAutomat |
src/automats/unitAutomat.js |
unitAutomat.md | Standard units of measure (Stück, kg, Liter, etc.) for the active company (GET /api/unit, upsert, delete). |
userSettingsAutomat |
src/automats/userSettingsAutomat.js |
userSettingsAutomat.md | Client-side user UI preferences (e.g. viewer docking position). Persisted to IndexedDB (persist: true). |
Canonical PureComponent Consumption Pattern
import { PureComponent } from 'react';
import { artikelAutomat, createArticleSelector, getArticle } from '../automats';
class ArticleHeader extends PureComponent {
constructor(props) {
super(props);
// 1. Synchronous read — no initial flash of empty state
this.state = {
article: getArticle(props.sku),
};
}
componentDidMount() {
// 2. Subscribe with fine-grained selector
this.unsub = artikelAutomat.subscribe(this, createArticleSelector(this.props.sku));
}
componentDidUpdate(prevProps) {
// 3. Re-subscribe if props change
if (prevProps.sku !== this.props.sku) {
this.unsub?.();
this.setState({ article: getArticle(this.props.sku) });
this.unsub = artikelAutomat.subscribe(this, createArticleSelector(this.props.sku));
}
}
componentWillUnmount() {
// 4. Always unsubscribe
this.unsub?.();
}
render() {
const { article } = this.state;
if (!article) return <div>Lädt...</div>;
return <h1>{article.name}</h1>;
}
}
Debugging
All registered automats are available on window.__AUTOMATS__ and accessible via Automat.get(name). In development mode, the docked AutomatInspector (src/devtools/AutomatInspector.jsx) renders live state, subscriber counts, and action triggers.