Synaplan
기업을 위한 오픈소스 AI 플랫폼
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 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.