Synaplan
开源 AI 软件平台,面向企业:自托管 AI 代理,符合 GDPR 的聊天机器人小部件,RAG 知识库,WhatsApp 与 Outlook AI,MCP,多模型路由。支持 Docker、Kubernetes 或在 Germ 托管。
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
A Tamil Nadu Factories Act compliance app for factory owners — worker attendance, statutory compliance forms, wage rate management, and payroll.
• Frontend: Expo/React Native + TypeScript (mobile/)
• Backend: FastAPI + SQLAlchemy + Postgres (backend/)
See SPEC.md, BUILD_PLAN.md, DATA_MODEL.md, PHASE2_BACKLOG.md, and PHASE3_STATUTORY_FORMS_PLAN.md for feature-level design history.
Production readiness push (Day 1 / Day 2 / Day 3)
Store submission is deliberately deferred to Day 3 so Days 1–2 can focus on fully building, wiring, and testing everything else.查看完整 README ↗A Tamil Nadu Factories Act compliance app for factory owners — worker attendance, statutory compliance forms, wage rate management, and payroll.
mobile/)backend/)See SPEC.md, BUILD_PLAN.md, DATA_MODEL.md, PHASE2_BACKLOG.md, and PHASE3_STATUTORY_FORMS_PLAN.md for feature-level design history.
Store submission is deliberately deferred to Day 3 so Days 1–2 can focus on fully building, wiring, and testing everything else.
Done:
https://labourlens-backend.onrender.com), HTTPS confirmed valid, real signup → login → mark-attendance round trip confirmed against the live deploymentJWT_SECRET/ENCRYPTION_KEY generated and loaded into Render's env vars (never committed)Still open — reminder to pick this up during Day 2:
Known deploy gotchas (already fixed, documented here in case they recur elsewhere):
pydantic-core — pinned via a PYTHON_VERSION=3.12.7 env var.OCR_WARM_UP=false. The Aadhaar-scan feature itself may still be memory-tight on the free tier when actually invoked; revisit if that becomes a real blocker.Block 1 — Observability:
sentry-sdk (backend) + @sentry/react-native (mobile); instrument key events in PostHog (worker registered, attendance marked, form downloaded/emailed, wage rate set).Block 2 — Billing groundwork + localization:
6. Start Razorpay merchant signup (2–4 business day KYC — the longest external clock on the whole list).
7. Integrate Razorpay SDK in sandbox/test mode; build the subscription-tier selection UI.
8. Test: full test-mode transaction with Razorpay's test card, confirm webhook fires and subscription status updates in the DB. Pending after Day 2: real KYC approval.
9. Stand up react-i18next; translate Home, Login, Dashboard into Tamil.
10. Test: device locale set to Tamil, walk those 3 screens, confirm no English fallback / no clipping. Pending after Day 2: remaining ~15 screens (deliberately not machine-translated without native-speaker review).
Block 3 — Push notifications, production build, automated tests:
11. Wire Expo push notification infrastructure (device token registration, test-push path).
12. Test: real push to a real device via expo push:send, confirm receipt backgrounded and killed.
13. Run the first production EAS build (binary only — store submission stays Day 3).
14. Test: install the production build (not Expo Go) on a real device, walk the full golden path (login, mark attendance, download a form, set a wage rate).
15. Set up Maestro with 4 smoke flows: login, mark attendance, download a form, add a worker.
16. Test: Maestro suite passes against the production build; confirm it fails loudly on a deliberately broken flow.
App Store / Play Store submission only.
Integration layer for ZKTeco fingerprint devices, built and fully tested without physical hardware. The device-connection logic is isolated behind one interface (biometric.BaseConnector) so switching from mock data to a real device is a config change, not a code change.
What's built:
biometric_devices, device_user_mapping, biometric_punches, biometric_consents; workers.numeric_employee_code (doubles as the device's User ID for the common case).MockConnector / ZKTecoConnector, selected via BIOMETRIC_CONNECTOR env var (mock default, or zkteco).biometric_sync.py): resolves punches to workers (mapping, else direct employee-code match), dedups on (device_id, raw_device_user_id, timestamp), writes attendance through the same shared attendance_service.upsert_attendance used by manual marking (never a parallel path), and never overwrites a manually-marked day.last_synced_at, 30-minute stale threshold, unmapped-punch and pending-sync counts surfaced in the admin/mobile UI; every attendance record shows its source (Biometric — device — timestamp or Manual override — supervisor — reason), never a bare tick.BiometricConsent record captured in Worker Details onboarding; enrollment (device mapping) is server-side blocked with a 422 if consent hasn't been captured yet — not just a UI checkbox.backend/verify_biometric_sync.py — normal sync, duplicate punch (no double-insert), unmapped device_user_id (flagged, not dropped, doesn't crash), backlogged/out-of-order timestamps landing on the correct date, manual-override protection, connection timeout / partial read / device-busy handling. All passing against MockConnector.Mocked vs. real:
| Piece | Status |
|---|---|
| Data model, migrations | Real — same schema used for mock and real punches |
| Sync/mapping/dedup/attendance-writing logic | Real — identical code path for both connectors |
MockConnector | Fully real, used for all current testing (default_mock_batch(): normal in/out pairs, one unmapped ID, one backlogged pair) |
ZKTecoConnector | Structurally complete (pyzk connect → disable_device() → get_attendance() → get_users() reconcile → enable_device()/disconnect, TCP/UDP + comm password, timeout/busy/partial-read handling) but never run against a real device |
pyzk dependency | Commented out in backend/requirements.txt (lazy-imported only if ZKTecoConnector is actually selected) |
Checklist for the first real-device integration test:
pyzk==0.9 in backend/requirements.txt, pip install, set BIOMETRIC_CONNECTOR=zkteco.force_udp is needed for that model).ZKTecoConnector sends (int-cast) — mismatches fail silently on some firmware.pyzk's actual punch_type codes for this specific device model match the assumed in/out mapping — ZKTeco firmware isn't fully consistent across models here.source="device", resolves to the correct worker, and a verification punch round-trip confirms it's not a "wrong Ramesh" (id collision).disable_device() / enable_device() and memory-clear-after-confirmed-write behave correctly on the real unit — this can only be verified against real firmware, not mocked.verify_biometric_sync.py's scenarios manually against the real device: unmapped ID, duplicate punch, connection drop mid-sync, backlogged punches from being briefly offline.