Javis OS
Javis OS는 기업가를 돕는 에이전시 AI로, 업무를 지원하고 함께 성장합니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Internal tool for GMR: equipment/inventory tracking, face-scan attendance, car booking, leave requests, project & wiring-diagram management — plus a LINE bot for borrowing items, attendance reminders, and approvals on the go.
| Layer | Choice |
|---|---|
| Framework | Next.js 16.2.6 (App Router, Server Actions) |
| UI | React 19, Tailwind CSS 4 |
| Database | PostgreSQL — Prisma ORM 6.19.3 (@prisma/adapter-pg) |
| Auth | NextAuth v5 (beta), Credentials provider (username + bcrypt password) |
| Face recognition | face-api.js (client-side, browser) |
| Diagrams / circuit sandbox | @xyflow/react (React Flow) |
| File storage | Vercel Blob (@vercel/blob) |
| Tests | Vitest |
| Chat bot | LINE Messaging API webhook |
| AI (LINE bot only) | Groq API (qwen/qwen3.8-27b, OpenAI-compatible endpoint) |
| Hosting | Vercel |
⚠️ Next.js 16 renamed
middleware.ts→proxy.ts. This repo already usesproxy.ts— don't add amiddleware.tsfile, the two conflict and crash the dev server.
npm install
npx prisma generate
npm run dev
Open http://localhost:3000. You'll need a .env file (see below) — ask an
admin for one, or set up your own dev database (Neon free tier works fine).
All of these live in .env (gitignored, never commit real values). Ask an
admin for the real .env, or fill in your own for local dev:
| Variable | Purpose |
|---|---|
DATABASE_URL | Pooled Postgres connection string (used at runtime) |
DIRECT_URL | Unpooled connection string (required by prisma migrate) |
AUTH_SECRET | NextAuth session encryption secret |
BLOB_STORE_ID, BLOB_READ_WRITE_TOKEN | Vercel Blob storage (asset/vehicle/check-in photos) |
LINE_CHANNEL_SECRET | LINE webhook signature verification |
LINE_CHANNEL_ACCESS_TOKEN | LINE push/reply message API auth |
CRON_SECRET | Shared secret so only Vercel Cron / the external pinger can trigger /api/cron/* |
GROQ_API_KEY | Powers the LINE bot's free-form Q&A + borrow-intent extraction — get one free at console.groq.com/keys |
⚠️ Local dev vs. production are separate databases. DATABASE_URL in
.env points at a local/dev Neon branch by default. The real production
database (used by the deployed app) is a separate Prisma Postgres instance —
its connection string is commented out at the top of .env. To run any
script against production, override DATABASE_URL/DIRECT_URL for that one
command only, e.g. (PowerShell):
$env:DATABASE_URL = '<production connection string>'; npx prisma studio
Never edit DATABASE_URL itself to point at production — too easy to forget
to change it back.
| Command | What it does |
|---|---|
npm run dev | Start the Next.js dev server |
npm run build | prisma migrate deploy && prisma generate && next build — used by Vercel |
npm start | Run the production build locally |
npm run lint | ESLint |
npm test | Run the Vitest suite (lib/*.test.ts) |
npx prisma studio — GUI to browse/edit every table in the browser
(http://localhost:5555). Defaults to the local dev DB; override
DATABASE_URL first to point it at production (see above). The
in-app "delete row" button has a known client-side bug (Cannot find module error) — prefer the script below instead of clicking Delete in
Studio.node scripts/delete-user.js <username> — deletes one user by
username, including everything that cascades (check-ins, loans, leave
requests, car bookings). If the user owns an Equipment Template, Wiring
Diagram, or Project, delete/reassign those first — the database blocks
the user delete otherwise rather than silently destroying real work. Same
local-by-default / override-for-production rule as above.Schema lives in prisma/schema.prisma. To change it:
npx prisma migrate dev --name <description> # writes + applies a migration locally
Then apply the same migration to production (production does not
auto-migrate on deploy — next build's prisma migrate deploy step runs,
but has occasionally not taken effect reliably, so always double check):
$env:DATABASE_URL = '<prod>'; $env:DIRECT_URL = '<prod>'; npx prisma migrate deploy
On Windows, npx prisma generate can fail with EPERM: operation not permitted, rename ... query_engine-windows.dll.node if a dev server is
already running and holding the file lock. This is harmless — the client's
generated TypeScript types still update; only the (unchanged) native engine
binary fails to re-stage. Safe to ignore, or stop the dev server first if
it bothers you.
⚠️ After any schema change, restart npm run dev if it was already
running. Node caches the old @prisma/client module in memory — the
prisma generate step updates the files on disk, but a dev server started
before that won't see the new model/fields until restarted, and will
throw Unknown field '...' errors on any query touching them.
Three roles, enforced in auth.config.ts (page-level) and inside each
Server Action (data-level — belt and suspenders):
/inventory: create/edit/
delete assets, adjust quantity)./users (manage accounts, roles, registered
faces) and /attendance (HR data across all employees, CSV export).| Route | What it's for |
|---|---|
/checkin | Face-scan check-in/out kiosk (liveness check: head-turn detection) |
/attendance | Admin-only attendance table, customizable columns, CSV export |
/inventory, /catalog | Equipment stock management / employee-facing browse & borrow |
/my-loans | An employee's currently-borrowed items |
/carbook | Vehicle booking, admin approval |
/leave | Leave requests, admin approval |
/projects, /work-schedule | Project tracking and scheduling — projects can have images, PDFs, and 3D/CAD files (STEP, STL, OBJ, IGES) attached, up to 50MB each |
/diagrams, /circuit | Wiring diagram templates + free-form circuit sandbox (React Flow) |
/users | Admin-only: accounts, roles, face registration |
/dashboard | Overview landing page |
Webhook: app/api/line/webhook/route.ts. Employees link their account once
(1:1 chat only, username + password) via lib/line.ts, then can:
"ยืม สว่าน 2", or just
"ขอสว่านหน่อย" and the bot asks what's missing next), with tap-to-pick
Quick Reply buttons when a name matches multiple items.lib/lineAssistant.ts.AI model: Groq (qwen/qwen3.8-27b, OpenAI-compatible chat completions
API) — chosen over Gemini's free tier, which caps at 20 requests/day.
/api/cron/cleanup-checkin-photos — runs once daily via
vercel.json (Vercel Hobby plan allows one cron schedule). Purges
check-in webcam snapshots to bound storage growth (the CheckIn record
itself is kept — attendance math needs it)./api/cron/checkin-reminders — needs to run every few minutes, which
Hobby's cron doesn't support. Triggered instead by an external pinger
(cron-job.org) hitting the endpoint every 5 minutes with an
Authorization: Bearer <CRON_SECRET> header. Handles the 15-min warning,
8-hour OT prompt, and the midnight auto-checkout/re-ask described above.Both routes check CRON_SECRET so they can't be triggered by anyone who
just finds the URL.
Push to main → Vercel auto-deploys. npm run build runs
prisma migrate deploy first, but this has occasionally not applied
migrations reliably on Vercel's build — after any schema change, verify (or
manually re-run prisma migrate deploy against production, see above)
rather than assuming it worked.
All check-in/attendance/leave/booking timestamps are stored as UTC instants
but every display and business-hour calculation pins Asia/Bangkok
explicitly (lib/datetime.ts) — the production server itself runs in UTC,
so anything using the ambient server timezone shows times ~7 hours off.
Always use the helpers in lib/datetime.ts rather than raw
toLocaleString()/Date timezone-dependent calls.
docker compose --env-file .env.production build
docker compose --env-file .env.production up -d
docker compose logs -f app
docker compose down