Synaplan
開源 AI 平台,供企業使用:自行託管的 AI 代理、符合 GDPR 的聊天機器人小工具、RAG 知識庫、WhatsApp 與 Outlook AI、MCP、多模型路由。Docker、Kubernetes 或託管於 Germ
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Live: https://fairshift-five.vercel.app · Prompt Wars 2026 · UN SDG 8 (Decent work)
Construction sites and college campuses run their workforce on paper registers. The register belongs to the boss, so pay is opaque, complaints get traced, and hazards are ignored until someone is hurt. FairShift makes the worker's phone a second register: their own copy of hours, pay math and the status of every report, in Tamil.
UN SDG 8, Decent work and economic growth (targets 8.5 equal pay, 8.8 labour rights and safe work). Persona: a daily-wage or contract worker (mason, helper, security guard, housekeeping) who speaks Tamil, uses a low-end Android phone and has no say over the paper register. Second persona: the site admin who needs to see hazards and overwork early.
lib/rules.ts): wage
basis, overtime thresholds, hazard categories, severity floors, feedback themes. The same report or the same 12-hour
shift gives a different, correct result on a construction site and on a college campus.lib/assistant.ts turns each person's own context into ranked next
steps, each with the rule behind it (see How FairShift decides below).| Screen | What it does | Code |
|---|---|---|
Landing page / | Live Shift Receipt hero, key figures, problem → features story, worker tiles, rule-pack comparison | app/page.tsx |
Worker app /w/[id] | Key figures and the worker's own rest flags; weekly pay receipt with overtime bars and Tamil read-aloud; Voice Hazard recorder; "Speak up (sealed)" | app/w/[id]/page.tsx, components/HazardReporter.tsx, components/SpeakButton.tsx |
Admin dashboard /admin?site= | Key figures, hazard-resolution gauge, crew hours chart, worker × day heatmap, filterable live hazards (cards on phones), attention list, Sealed Voice, crew pay table with CSV export | app/admin/page.tsx, components/LiveWidgets.tsx, components/Kpi.tsx |
| Shift assistant | Worker: "What to do next" in English + Tamil, read aloud. Admin: ranked "Do this first" | lib/assistant.ts, app/w/[id]/page.tsx, components/LiveWidgets.tsx |
| Live data | One poller for the whole dashboard (4s, 204 when unchanged, paused when hidden) | components/live.tsx |
| Shared UI | One look on all three screens: top bar, cards, key figures, status pills | components/TopBar.tsx, components/Card.tsx, components/Kpi.tsx, components/StatusBadge.tsx |
| API | Hazards POST/GET/PATCH and Sealed Voice in one route (shares one in-memory store) | app/api/hazards/route.ts, lib/store.ts |
| Rules (tested) | Pay, fatigue, severity floor, Sealed Voice grouping, site totals and CSV, rule packs, rate limit | lib/pay.ts, lib/fatigue.ts, lib/severity.ts, lib/sealed.ts, lib/crew.ts, lib/rules.ts, lib/ratelimit.ts |
| AI | Gemini, schema-constrained JSON, temperature 0, falls back across models on quota errors | lib/ai.ts |
| Who | Context | Decision (most urgent first) | Why it is shown |
|---|---|---|---|
| Worker | 7+ days in a row | Act now: ask for a day off | 7+ days without rest is HIGH |
| Worker | Over 60h (or 48h) in 7 days | Act now (or Check): ask for shorter shifts | Over 48h/week is overtime; over 60h is HIGH |
| Worker | Under 10h between shifts | Check: start later tomorrow | At least 10h rest between shifts |
| Worker | Any overtime | Check: pay slip shows the overtime amount | Over 8h/day or 48h/week is paid at 2× |
| Worker | None of the above | All good | Within the site's rule pack |
| Admin | Open HIGH hazard | 1. Fix it (oldest first) | Safety first |
| Admin | Report Gemini could not read | 2. Read the original report | Never lose a report |
| Admin | Worker with a HIGH fatigue flag | 3. Take the flag's action | Overwork before feedback |
| Admin | Open MEDIUM hazard, unlocked Sealed Voice theme, WARN flag, LOW hazard | 4–7, in that order | Lower risk |
The same report or shift gives a different, correct decision under each site's rule pack. Tested in
tests/assistant.test.ts.
lib/seed.ts).| Worker pain | FairShift feature | Code | SDG 8 target |
|---|---|---|---|
| Pay and overtime are opaque | Shift Receipt: day-by-day hours, regular × rate, overtime × 2 × rate, total owed, read aloud in Tamil | lib/pay.ts, app/w/[id]/page.tsx | 8.5 equal pay, 8.8 labour rights |
| Workers and admins don't know what to act on first | Shift assistant: ranked next steps from each person's own records, each with its rule | lib/assistant.ts | 8.8, 8.5 |
| Hazards ignored, reporters identified | Voice Hazard: speak or type in Tamil → Gemini → HIGH card on the admin board → Acknowledged → Fixed → status read aloud on the worker's phone. No reporter identity stored | app/api/hazards/route.ts, lib/ai.ts, lib/severity.ts, components/HazardReporter.tsx | 8.8 safe working environments |
| Overwork goes unseen | Attention list: explainable fatigue flags with an action ("13 days without rest: schedule a day off") | lib/fatigue.ts, app/admin/page.tsx | 8.8, 8.5 |
AI listens, rules decide. Gemini only converts speech/text into structured JSON (schema-constrained, temperature 0, validated with zod). Money and alerts are plain functions with unit tests. Gemini never touches a rupee, and it can raise a hazard's severity but never lower it below the rule pack's floor.
| Construction site | College campus | |
|---|---|---|
| Wage basis | daily (Rs 700/day) | monthly (Rs 15,000) |
| Overtime | 2× beyond 8h/day or 48h/week | 2× beyond 8h/day or 48h/week |
| Hazard categories | fall from height, scaffolding, electrical, no PPE, heat stress | electrical, lab chemical, fire exit blocked, structural damage, slippery floor |
| Severity floor (HIGH) | fall from height, electrical | electrical, fire exit blocked |
A hospital or factory is one more entry in lib/rules.ts. Defaults are illustrative; verify the applicable state
rule before using real figures. Under this pack a 12-hour guard shift is worth two 8-hour days of pay.
Worker phone (/w/[id]) Admin (/admin?site=...)
record / type / poll status poll every 4s (204 when unchanged)
\ /
Next.js 16 on Vercel: /api/hazards (POST, GET, PATCH)
lib/* pure functions (pay, fatigue, severity, rules)
lib/ai.ts -> Gemini API (Flash-Lite, falls back across models on quota errors), server-only key
npm install
cp .env.example .env.local # set GEMINI_API_KEY (server-only, never NEXT_PUBLIC_)
npm run dev
npm test # Vitest (46 tests): pay, fatigue, severity, sealed, assistant, crew, format, rate limit
npm run lint
Deploy: push to main; Vercel builds it. GEMINI_API_KEY is set as a Vercel sensitive environment variable.
Demo workers (fictional): Murugan and Selvi (construction), Ravi and Lakshmi (college).
.env* is gitignored.429 + Retry-After), which also protects the Gemini
quota. The limiter key lives in memory for the window only and is never logged or stored with a report.frame-ancestors 'none', nosniff, Referrer-Policy: no-referrer, Permissions-Policy: microphone=(self).aria-pressed and a visible
timer (keyboard-usable), severity is icon + word + color, overtime bars use a stripe pattern, lang="ta" on Tamil
text, role="status" / aria-live for updates. Read-aloud only uses a Tamil voice; it hides rather than reading
Tamil with an English voice./, /admin and /w/murugan, mobile and desktop. Layouts verified
at 1440px and 390px with no horizontal scrolling; on phones the hazard table becomes cards so actions stay on screen.lib/ai.ts falls through several models on 429s. Google may use submitted content to improve its products; a production deployment should use a
paid tier or Vertex AI.