Javis OS
Javis OS는 기업가를 돕는 에이전시 AI로, 업무를 지원하고 함께 성장합니다
배송 내용을 영어로 설명하거나 예약서를 업로드하세요
Describe a shipment in plain English or upload your booking sheet. SaathiFly checks ten pre-flight rules, explains every fix and recommends a carrier from the rate card.
비즈니스TypeScript · CSSGitHub @manavjain-cloud온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기AI shipment booking and pre-flight checker for Indian exporters (Gemini, Neon, Resend, Vercel)
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Live demo: https://saathifly.vercel.app (no login; the earlier addresses prefly-app.vercel.app and shipsaathi-mj-3d6b.vercel.app still work). Try the chat on New Shipment, or upload the sample workbook with planted mistakes on Upload Excel.
SaathiFly helps Indian manufacturers and sellers book pallet shipments from the UK to Germany, France and the Netherlands without the small mistakes that get goods held at customs or turned away at a warehouse.
SaathiFly does not book carriers. There's no carrier integration: a confirmed booking is the seller's confirmed proposal. The ten checks catch common mistakes. They are not a full customs, dangerous-goods or export-compliance review.
Seller chat ─┐ ┌─> Issue report (Red / Amber / review + fixes)
├─> one Booking model ─> validation engine ─┤
Excel upload ┘ (src/lib/domain) (pure TypeScript) └─> Carrier eligibility + priority ranking
│
seller review / edit / confirm <────┘ ──> optional email (Resend)
persisted in Neon Postgres (bookings, items, results, events)
| Layer | Where | Notes |
|---|---|---|
| Data model | src/lib/domain/types.ts | Both entry paths produce the same Booking. null = not provided, never a guess. |
| Parsing | normalize.ts, dates.ts, excel.ts | Same parsers for Excel cells, chat values and form edits. |
| Rules | validation.ts | One pure function per rule (ruleR01 … ruleR10), plus data-quality checks. |
| Prohibited goods | hazmat.ts (+ server/hazard-ai.ts) | Deterministic keyword screen. Gemini can only escalate an item to human review. |
| Carriers | carriers.ts | Route + pallet-weight filter, priority ranking, ties, balanced score. |
| Chat logic | conversation.ts | Applies the model's proposed changes, works out missing fields and next questions. |
| Gemini | server/llm.ts, server/extract.ts | Structured JSON output. Keys stay on the server. |
| API | src/app/api/* | Server re-validates everything. Client results are never trusted. |
| UI | src/app/*, src/components/* | Next.js 16 App Router, Tailwind v4. |
The rate card and rulebook live in src/data/rate-card.json and src/data/rulebook.json. They are generated from the supplied workbook (npm run extract:reference), not typed by hand. If an uploaded workbook includes a Carrier options sheet that differs from the template, its rates are used for that upload and the UI says so.
All numeric checks are deterministic code. None of them use AI judgement.
| Rule | Severity | Formula / logic |
|---|---|---|
| R-01 | Red | HS code digits (ignoring ., space, -) must be numeric and ≥ 6. Blank fails. A 5-digit code gets a note that Excel may have dropped a leading zero. |
| R-02 | Red | Let S = Σ(quantity × unit price). Pass when ` |
| R-03 | Red | For each item: units per carton × cartons = quantity (exact). |
| R-04 | Red | booking cartons = Σ item cartons (exact). |
| R-05 | Red | gross weight ÷ pallets ≤ max kg/pallet of the chosen carrier. Chosen = the seller's selected carrier, otherwise the carrier their priority picks from the route. If it fails, the fix offers the cheapest eligible alternative or the pallet count that would fit. Missing or zero pallets fail. |
| R-06 | Red | Keyword screen for lithium batteries, aerosols and flammable liquids, with negations ("non-flammable", "batteries not included") removed first. Clear hits are Red. Ambiguous ones (e.g. "battery", "perfume", "laptop", "spray") and anything Gemini flags become Needs review. They block dispatch until the seller confirms the item is safe. A Red hit can't be acknowledged away. |
| R-07 | Amber | gross weight ≥ Σ(unit weight × quantity). |
| R-08 | Amber | Destination type Warehouse ⇒ delivery appointment must be Yes. |
| R-09 | Amber | Every item has a country of origin. |
| R-10 | Amber | Ready date ≥ today, using the calendar date in Europe/London (goods are collected in the UK). Today itself passes. |
Booking status
The server refuses to confirm anything that is Blocked or Needs review.
gross ÷ pallets ≤ max weight per pallet.pallets × price per pallet (GBP, from the rate card).score = 0.40·cost + 0.30·speed + 0.30·reliability. Cost gets the biggest weight because on this rate card the faster services are also the more reliable ones, so equal weights would count that premium twice. For UK → Germany with 3 pallets: A 0.40, B 0.65, C 0.60.Requirements: Node 20+ (tested on Node 24), npm.
npm install
cp .env.example .env.local
Fill in .env.local:
| Variable | Needed for | Notes |
|---|---|---|
DATABASE_URL | saving bookings, reports, history | Neon pooled connection string |
GEMINI_API_KEY or OPENROUTER_API_KEY | chat, AI hazard review, plain-English summary | A Google AI Studio key calls Gemini directly. An OpenRouter key calls google/gemini-* through OpenRouter. |
GEMINI_MODEL | optional | Defaults: gemini-2.5-flash (Google) / google/gemini-3.5-flash (OpenRouter) |
RESEND_API_KEY | Without a verified domain, Resend only delivers to the Resend account owner's address. | |
RESEND_FROM | Defaults to SaathiFly <[email protected]> |
Create the tables (safe to re-run):
psql "$DATABASE_URL" -f db/schema.sql
psql "$DATABASE_URL" -f db/seed-carriers.sql
Start the dev server:
npm run dev
Other scripts:
npm test
npm run typecheck
npm run extract:reference
npx tsx scripts/make-sample.ts rebuilds public/templates/SaathiFly_Sample_With_Mistakes.xlsx, a demo upload with deliberate mistakes for every rule (sample input only, not real bookings).
The app degrades gracefully. Without Gemini, the chat says so and the editable form still works. Without a database, uploads are validated but not saved. Without Resend, email shows a clear "not configured" error.
/api/health reports which integrations are configured, without revealing any values.The app needs no login. All database access goes through server routes with input validation (zod), size limits and per-IP rate limits. No secrets reach the browser.
npm test runs 115 unit tests covering:
Checked by hand in the browser: a full chat booking including a mid-conversation weight change and "add a pallet", saving, confirming (and the server refusing a booking with a Red error), email failure feedback, uploading the sample workbook, and phone-width layout (375px) on every page with no sideways scroll.