- Datenmodell: Tenant.tier (Default PROFI), lotseChatSeats, lotseChatHardLimit;
Tabelle lotse_chat_seats (RLS, TENANT_MODELS, pii-fields), Index für die
Monatszählung der Chat-Nachrichten (Migration 20260921100000_pakete)
- src/lib/plans.ts: Stufenregeln, 150 Chats je Platz, Mehrverbrauch in 100er-Paketen
- src/server/plan.ts: effektive Freischaltung = Stufe UND TenantModule, genutzt von
requireModule, assertModuleEnabled, API, Sync (Offline-Op → rejected mit Klartext),
Navigation, isLotseEnabled und planningAccess (Planung nur in Profi)
- Lotse-Chat: Platzprüfung (no_seat), Testphase ohne Platz, Kontingent mit
hartem Limit (quota_exhausted); Platzvergabe durch den Mandanten-Admin
- Betreiber: Stufe/Plätze/hartes Limit im Mandantendetail mit Bestätigung
und Plattform-Audit, Verbrauch laufender Monat/Vormonat, Stufe als Badge
- Demo-Seed: demo = Profi mit 3 Plätzen, demo2 = Basis
- Tests: test-pakete-{rules,gates,seats}
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
94 lines
5.0 KiB
JSON
94 lines
5.0 KiB
JSON
{
|
||
"tier": {
|
||
"BASIS": "Basic",
|
||
"PROFI": "Profi"
|
||
},
|
||
"colTier": "Package",
|
||
"notInTier": "Profi package only",
|
||
"profiHint": {
|
||
"title": "Included in the Profi package",
|
||
"text": "This function is part of the Profi package. Your company uses the Basic package – please contact your Craftvia representative to upgrade."
|
||
},
|
||
"admin": {
|
||
"title": "Package & Lotse chat",
|
||
"sub": "Package of the company, chat seats for technicians and usage in the current month",
|
||
"package": "Package",
|
||
"trial": "Trial (all functions)",
|
||
"packageReadOnly": "The provider sets the package and the number of chat seats. Here you assign the purchased seats to your technicians and team leads.",
|
||
"basisHint": "Lotse and the Lotse chat are included in the Profi package. Assigned seats and chat histories are kept and available again after switching to Profi.",
|
||
"seatsTitle": "Chat seats",
|
||
"seatsCount": "{assigned} of {purchased} seats assigned",
|
||
"trialSeats": "During the trial all technicians and team leads may use the Lotse chat – no seats need to be assigned (quota: {perSeat} chats per person and month).",
|
||
"noSeatsBought": "No chat seats purchased yet. The provider books seats for your company.",
|
||
"overbooked": "More seats assigned than purchased ({purchased}). Only the seats assigned first are valid – please revoke seats.",
|
||
"noFieldUsers": "No active users with a field role (technician, team lead).",
|
||
"seatAssigned": "Seat assigned",
|
||
"seatOverbooked": "Above the seat number",
|
||
"seatNone": "No seat",
|
||
"assign": "Assign seat",
|
||
"revoke": "Revoke seat",
|
||
"assignLabel": "Assign chat seat to {name}",
|
||
"revokeLabel": "Revoke chat seat from {name}",
|
||
"saved": "Chat seat saved.",
|
||
"usageTitle": "Usage {month}",
|
||
"usageText": "{used} of {quota} chats",
|
||
"quotaRule": "Quota: {perSeat} chats per assigned seat and month, shared by the company (basis: {basis}). One chat is one message to the Lotse.",
|
||
"warn80": "{percent} % of the monthly quota are used.",
|
||
"exhausted": "The monthly quota is used up. Further chats are billed as overage in packs of {pack}.",
|
||
"hardLimitReached": "The monthly quota is used up. The Lotse chat is blocked until the end of the month (hard limit).",
|
||
"overage": "Overage: {overage} chats – equals {packs, plural, one {# pack} other {# packs}} of {pack} chats.",
|
||
"perUserCaption": "Chats per user in the current month",
|
||
"perUserName": "User",
|
||
"perUserChats": "Chats",
|
||
"errors": {
|
||
"no_seats_left": "All purchased seats are assigned. Please revoke a seat first or book more seats with the provider.",
|
||
"not_eligible": "This person cannot get a chat seat (no active field role).",
|
||
"not_in_plan": "The Lotse chat is included in the Profi package.",
|
||
"disabled": "Lotse is switched off for this company.",
|
||
"forbidden": "You are not allowed to do this.",
|
||
"trial_expired": "Trial expired – read-only access.",
|
||
"failed": "Could not save."
|
||
}
|
||
},
|
||
"platform": {
|
||
"title": "Package & Lotse chat",
|
||
"tier": "Package",
|
||
"trialProfi": "Trial = Profi",
|
||
"seats": "Chat seats",
|
||
"seatsValue": "{assigned} assigned / {purchased} purchased",
|
||
"hardLimit": "Hard limit",
|
||
"hardLimitOn": "on – blocked at the quota",
|
||
"hardLimitOff": "off – overage is counted",
|
||
"rule": "{perSeat} chats per assigned seat and month (tenant timezone); overage in packs of {pack}.",
|
||
"currentMonth": "Current month · {month}",
|
||
"previousMonth": "Previous month · {month}",
|
||
"chats": "{used} of {quota} chats",
|
||
"overage": "Overage {overage} chats → {packs, plural, one {# pack} other {# packs}} of {pack}",
|
||
"noOverage": "No overage",
|
||
"edit": "Change package …",
|
||
"editTitle": "Change package & chat seats",
|
||
"editText": "The change applies immediately to all users of the tenant and is logged in the platform audit.",
|
||
"tierHint": {
|
||
"BASIS": "Without AI and planning: no Lotse, no planning board/live situation, no billing overview, no emergency service, no order import.",
|
||
"PROFI": "All functions incl. planning, billing overview, emergency service, import and Lotse."
|
||
},
|
||
"downgradeHint": "Switching to Basic keeps all data, only access ends. Back on Profi everything is available again.",
|
||
"seatsInput": "Purchased chat seats",
|
||
"seatsHint": "The tenant admin assigns the seats to users with a field role.",
|
||
"hardLimitInput": "Hard limit",
|
||
"hardLimitHint": "When the monthly quota is used up the chat is blocked instead of counting overage.",
|
||
"confirm": "I checked the impact and confirm the change.",
|
||
"submit": "Save",
|
||
"submitting": "Saving …",
|
||
"close": "Close",
|
||
"saved": "Package saved.",
|
||
"errors": {
|
||
"confirm_required": "Please confirm the change.",
|
||
"invalid_input": "Please check the input (seats 0–1000).",
|
||
"tenant_archived": "The tenant is archived.",
|
||
"platform_admin_required": "Only full administrators may change the package.",
|
||
"failed": "Could not save."
|
||
}
|
||
}
|
||
}
|