feat: T4 waves 1-2 - rule configs, schema, suggestions core, season, rule forms
- Rule configs with typed parsers and registry; Berlin day helpers - Schema: T4 enums, Suggestion table, feed vocabulary (feedStatus as ColonyCondition with legacy text mapping), split queen source, varroa sample size; migration harness for data migrations - SuggestionsService: propose/refresh/resolve/obsolete/expire, accept/dismiss/reopen incl. bulk, lock order, concurrency e2e - SeasonService: phenology-based segments, inspection/varroa due dates, queen age; TimeEventsStep with JobPartialFailure - Frontend: per-rule settings forms with visible value sources Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
7097fcd97c
commit
d99a697739
116 files changed
+11239
-801
No files matched your search
@@ -0,0 +1,72 @@
|
||||
import type { AutomationTriggerType } from '../../../generated/prisma';
|
||||
import { RULE_CONFIG_PARSERS } from './rule-config.registry';
|
||||
|
||||
export interface RuleDefaults {
|
||||
config: Record<string, unknown>;
|
||||
actionTemplate: string;
|
||||
/** Rules without a sensible built-in setting start switched off. */
|
||||
active?: boolean;
|
||||
}
|
||||
|
||||
/** Texts of the rules that create a task; the new rules have none yet. */
|
||||
const ACTION_TEMPLATES: Record<AutomationTriggerType, string> = {
|
||||
QUEENLESS_NO_EGGS:
|
||||
'Kontrolle empfohlen: Königin nicht gesehen und keine Stifte vorhanden.',
|
||||
VARROA_THRESHOLD: 'Behandlung prüfen: Varroa-Schwellenwert überschritten.',
|
||||
FEED_STATUS_CRITICAL: 'Fütterung erforderlich: Futterstatus kritisch.',
|
||||
SWARM_MOOD_HIGH:
|
||||
'Schwarmkontrolle dringend: hohe Schwarmstimmung festgestellt.',
|
||||
COLONY_HEALTH_CRITICAL: 'Kontrolle erforderlich: Gesundheitsstatus kritisch.',
|
||||
STOCK_ITEM_LOW: 'Nachbestellung prüfen: Lagerartikel unter Mindestbestand.',
|
||||
// Not task-generating rules like the ones above - `active` here toggles
|
||||
// whether HoneyBatchesService/BottlingService auto-fill the batch/lot
|
||||
// number from `config.format` instead of requiring manual entry.
|
||||
HONEY_BATCH_NUMBER_FORMAT: '',
|
||||
BOTTLING_LOT_NUMBER_FORMAT: '',
|
||||
RAW_MATERIAL_LOT_NUMBER_FORMAT: '',
|
||||
PRODUCTION_BATCH_NUMBER_FORMAT: '',
|
||||
RAW_MATERIAL_LOW: 'Rohstoff unter Mindestmenge: Nachschub einplanen.',
|
||||
TREATMENT_FOLLOW_UP: 'Behandlungserfolg kontrollieren',
|
||||
FEEDING_FOLLOW_UP: 'Futterabnahme und Futtervorrat kontrollieren',
|
||||
INSPECTION_INTERVAL: '',
|
||||
QUEEN_CELLS_SWARM_CHECK: '',
|
||||
QUEEN_ACCEPTANCE_CHECK: '',
|
||||
SPLIT_SCHEDULE: '',
|
||||
COLONY_ENDED_CLEANUP: '',
|
||||
WITHDRAWAL_ENDED: '',
|
||||
HONEY_WATER_CONTENT: '',
|
||||
SEASON_AUTOPILOT: '',
|
||||
PHENOLOGY: '',
|
||||
};
|
||||
|
||||
// - RAW_MATERIAL_LOW: raw material lots carry no minimum of their own, so
|
||||
// the minimum per kind (config.minGrams) lives on the rule - and without
|
||||
// one there is nothing to compare, hence off by default.
|
||||
// - Follow-up checks: how many days after a treatment or feeding a check
|
||||
// makes sense depends on the product and the season, so there is no
|
||||
// built-in interval - the beekeeper switches the rule on and sets
|
||||
// config.dueInDays.
|
||||
const INACTIVE_BY_DEFAULT: ReadonlySet<AutomationTriggerType> = new Set([
|
||||
'RAW_MATERIAL_LOW',
|
||||
'TREATMENT_FOLLOW_UP',
|
||||
'FEEDING_FOLLOW_UP',
|
||||
]);
|
||||
|
||||
function defaultsOf(trigger: AutomationTriggerType): RuleDefaults {
|
||||
return {
|
||||
config: structuredClone(RULE_CONFIG_PARSERS[trigger].defaults) as Record<
|
||||
string,
|
||||
unknown
|
||||
>,
|
||||
actionTemplate: ACTION_TEMPLATES[trigger],
|
||||
...(INACTIVE_BY_DEFAULT.has(trigger) ? { active: false } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
/** The rule rows created on first use; the config is the parser's default. */
|
||||
export const DEFAULT_RULES: Record<AutomationTriggerType, RuleDefaults> =
|
||||
Object.fromEntries(
|
||||
(Object.keys(ACTION_TEMPLATES) as AutomationTriggerType[]).map(
|
||||
(trigger) => [trigger, defaultsOf(trigger)],
|
||||
),
|
||||
) as Record<AutomationTriggerType, RuleDefaults>;
|
||||
Reference in new issue
Block a user