Synaplan
Open-source AI platform for companies: self-hosted AI agents, GDPR-compliant chatbot widget, RAG knowledge base, WhatsApp and Outlook AI, MCP, multi-model routing. Docker, Kubernetes or hosted in Germ
G-Fast Workshop Portal - Estimate creation & approval
Translation pending
BusinessTypeScript · JavaScriptGitHub @Shoman98OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
Vehicle damage estimation platform for auto repair workshops. Built on top of the G-Fast shared analysis engine (@gfast/analysis-core).
Calls runAnalysisPipeline() from @gfast/analysis-core (wreck-vision shared module). This runs a 4-stage Gemini Vision analysis:
Cost: ~5 Gemini requests per analysis × image token cost (~$0.003 per analysis).
Located in server/index.js. Transforms raw pipeline output into workshop-ready format.
Important: To restart the backend without killing the frontend:Read the full README ↗Vehicle damage estimation platform for auto repair workshops. Built on top of the G-Fast shared analysis engine (@gfast/analysis-core).
Browser (React + Vite) Backend (Express) Shared Module
:3006 :3333 @gfast/analysis-core
│ │ │
│── POST /api/auth/login ───────►│ │
│── POST /api/analysis ──────────►── runAnalysisPipeline() ──►│
│ │◄── damages + hiddenDamage ──│
│ │── enrichAnalysisWithParts() │
│◄── damages + needs_check ─────│ │
│── POST /api/estimates ─────────►── Supabase DB │
│── GET /api/estimates/:id ─────►── Supabase DB │
| Layer | Tech |
|---|---|
| Frontend | React 18, Vite, TypeScript |
| Backend | Node.js, Express |
| Database | Supabase (PostgreSQL) |
| AI Analysis | Gemini Vision API via @gfast/analysis-core |
| Auth | JWT (8h expiry, auto-refresh) |
Calls runAnalysisPipeline() from @gfast/analysis-core (wreck-vision shared module). This runs a 4-stage Gemini Vision analysis:
| Stage | What it does |
|---|---|
| Stage 1 | Vehicle ID, photo quality, visible areas detection |
| Stage 2A | Damage pre-check (unbiased screener) |
| Stage 2B | Full damage scan — outputs damages + needs_check_parts |
| Stage 3 | Structural damage assessment (text-only) |
| Stage 4 | Hidden damage inference (AC condenser, radiator, etc.) |
Cost: 5 Gemini requests per analysis × image token cost ($0.003 per analysis).
Located in server/index.js. Transforms raw pipeline output into workshop-ready format.
runAnalysisPipeline() returns:
├── damages[] — all parts (confirmed + needs_check merged as recommendedDecision:'inspect')
├── needs_check_parts[] — explicit needs_check (if any)
└── hiddenDamageAssessment[] — Stage 4 hidden parts (radiator, AC condenser, etc.)
allParts = analysisData.damages
├── confirmedDamages = allParts WHERE recommendedDecision !== 'inspect'
└── needsCheckFromShared = allParts WHERE recommendedDecision === 'inspect'
hiddenDamageParts = hiddenDamageAssessment → mapped to needs_check format
allNeedsCheck = needsCheckFromShared + explicitNeedsCheck + hiddenDamageParts
lowercase → trim → replace special chars → snake_casePART_NAME_ALIASES (190+ aliases from @gfast/analysis-core) — e.g. front_bumper → upper_bumperPARTS_DATABASE (187 parts with EN/AR names, partId, category)Base rule: DAMAGE_TYPE_INDEX[damageType] < 4 → Repair
DAMAGE_TYPE_INDEX[damageType] >= 4 → Replace
Category overrides (highest priority):
airbags_safety, interior, mechanical, suspension → Always Replace
structural, chassis, chassis_structure → Always Repair
Any buckled damage → Always Repair
isUnmapped OR part_name_ar is null / قطعة غير معروفة{
"damages": [/* confirmed parts, mapped, enriched */],
"needs_check_parts": [/* uncertain + hidden parts, mapped, enriched */],
"vehicleInfo": { "year": 2020, "make": "Toyota", "model": "Camry" },
"timestamp": "2026-07-14T...",
"analysisSource": "@gfast/analysis-core (shared module)"
}
POST /api/auth/login with workshop_id + pinworkshops tablenode -e "import('bcrypt').then(b => b.default.hash('YOUR_PIN', 10).then(h => console.log(h)))"
INSERT INTO public.workshops (workshop_id, workshop_name, pin_hash, city, phone)
VALUES ('WS-001', 'اسم الورشة', '$2b$10$...hash...', 'المدينة', '05xxxxxxxx');
workshops
├── workshop_id TEXT PRIMARY KEY
├── workshop_name TEXT
├── pin_hash TEXT (bcrypt)
├── city TEXT
├── phone TEXT
└── is_active BOOLEAN
estimates
├── estimate_id UUID PRIMARY KEY
├── workshop_id TEXT → workshops
├── vehicle_year / make / model
├── status TEXT (draft | confirmed)
├── labors JSONB
└── confirmed_at TIMESTAMPTZ
estimate_parts
├── estimate_part_id UUID PRIMARY KEY
├── estimate_id UUID → estimates
├── part_name_en/ar TEXT
├── damage_type TEXT
├── confidence NUMERIC
├── severity_label TEXT (Repair | Replace)
└── price NUMERIC
estimate_audit_logs
├── log_id UUID PRIMARY KEY
├── estimate_id UUID → estimates
├── action_type TEXT
├── action_description_ar TEXT
├── field / old_value / new_value TEXT
└── created_at TIMESTAMPTZ
Damages section: Confirmed parts ≥ 70% confidence. User can:
Needs Check section: Parts < 70% confidence OR hidden damage from Stage 4. User can:
Labor section: 5 fixed labor types (ميكانيكا, سمكره, دهان, ايرباج, فك وتركيب) with price inputs. Repair-labeled damage parts auto-appear below as additional labor rows.
Total: إجمالي التكلفة = Replace parts cost + fixed labors + Repair parts cost
Add part manually: Arabic name + Repair/Replace + price
/report/:estimateId?public=true# Supabase
SUPABASE_URL=https://alyezrwvuzprmcaoirsb.supabase.co
SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_KEY=eyJ... # Service role key — bypasses RLS, backend only
# Gemini API
WORKSHOP_GEMINI_API_KEY=... # Overrides GEMINI_API_KEY used by shared module
# Auth
JWT_SECRET=...
PORT=3333
NODE_ENV=production
# Install dependencies
npm install
# Start backend (port 3333)
npm run server
# Start frontend (port 3006)
npm run dev
Important: To restart the backend without killing the frontend:
pkill -f "node server/index.js" && npm run server
Never use pkill -9 node — it kills Vite too.
| Decision | Reason |
|---|---|
@gfast/analysis-core shared module | Single source of truth — same prompts, PARTS_DATABASE, confidence rules as wreck-vision |
| Filter unmapped parts | Only show parts with valid Arabic names — no قطعة غير معروفة |
Include hiddenDamageAssessment in needs_check | Stage 4 hidden damage (radiator, AC condenser) was missing without this |
| Category-based severity overrides | Airbags/mechanical always Replace, structural always Repair — matches wreck-vision |
| Supabase service key (not anon key) | Bypasses RLS — used backend only, never exposed to browser |
| Manual workshop onboarding | Early adopter phase — admin inserts directly into Supabase |
PART_NAME_ALIASES from shared module | 190+ aliases stay in sync with wreck-vision automatically |
| Prices always 0 from analysis | Workshop mechanic inputs real prices manually on estimate page |