MIA Tips
Manager-led conversation for configuring tip-distribution rules. Not a separate app — it's a scoped route in the main Pivot frontend that talks to a context-specific Mia conversation.
Where it lives
- Frontend route:
/mia-tips→src/routes/MiaTips/ - Main shell:
src/routes/MiaTips/index.tsx(MiaTipsInner around line 110) - Context provider:
src/routes/MiaTips/MiaTipsContext.tsx - Chat hook:
src/routes/MiaTips/hooks/useMiaTipsChat.ts - Preview/simulation logic:
src/routes/MiaTips/logic/
Backend:
- API routes —
/companies/:id/ai-tips-rulesin thecompaniesmodule (functions/modules/companies/endpoints/apis/ai-tips-rules.router.ts). CRUD overAiTipsRules/{cid}/{ruleId}. - Conversation pipeline — shared with onboarding.
functions/pivotAiAgent/onboarding-pipeline.tshandles both, differentiated by aflowparameter. The 20-tool onboarding-pipeline set includes the four tip-rule tools listed below.
What kinds of rules
The system supports four shapes:
| Kind | Description |
|---|---|
percentage_tipout | "Servers tip out 3% of their tips to kitchen." |
pool_distribution | "All tips go to a pool, redistributed equally." |
fixed_tipout | "Add $5 per shift to support staff." |
conditional | "Apply rule X only when employee worked ≥ 7 hours." |
set_variable / custom | Escape hatches for one-off computations. |
System prompt
Built in src/routes/MiaTips/index.tsx. Bilingual (FR/EN, switched on user locale). Key constraints in the prompt:
- Must use the company's actual role names — generic role names are forbidden unless they happen to match.
- French uses "cotisation" (not "tip-out").
- Mia asks one question at a time, accumulates the rule shape, then calls
save_ai_tips_rule.
Tools Mia can call
save_ai_tips_rule— createupdate_ai_tips_rule— editdelete_ai_tips_rule— removelist_ai_tips_rules— list current rules (used at conversation start)
Rule shape (DTO)
{
variable: string, // snake_case identifier
priority: number, // lower = applied first; start at 100, increment by 10
explanation: string, // < 50 chars
variableLabelFr: string, // mandatory
variableLabelEn: string, // mandatory
rule: {
kind: 'percentage_tipout' | 'pool_distribution' | 'fixed_tipout'
| 'set_variable' | 'conditional' | 'custom',
sourceRoleIds?: string[],
targetRoleIds?: string[],
sourceEmployeeIds?: string[],
targetEmployeeIds?: string[],
sourceAll?: boolean,
targetAll?: boolean,
percent?: number,
basis?: 'tips' | 'sales',
fixedAmount?: number,
frequency?: 'per_shift' | 'per_day' | 'per_week',
minShiftHours?: number,
amountMode?: 'perEmployee' | 'split',
poolMode?: 'contribute' | 'draw',
distribution?: 'equal' | 'hours' | 'sales'
}
}
Storage
RTDB: AiTipsRules/{companyId}/{ruleId}.
The frontend simulates rule application on a test employee set to show the manager what each rule produces before committing. Simulation is purely client-side in src/routes/MiaTips/logic/.