Synaplan
기업을 위한 오픈소스 AI 플랫폼
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Simple estimating software for restoration contractors.
# Set DATABASE_URL in .env to your Neon connection string first (see below)
docker-compose up -d
# Frontend: http://localhost:3001
# Backend: http://localhost:8001
# API Docs: http://localhost:8001/api/docs
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
# Set DATABASE_URL in .env.local to your Neon connection string, then:
alembic upgrade head
# Run server
uvicorn main:app --reload --port 8001
cd frontend
npm install
npm run dev # http://localhost:3001
scopit/
├── backend/
│ ├── app/
│ │ ├── core/ # Config, database, security, storage
│ │ ├── common/ # Shared utilities
│ │ └── domains/ # Feature modules (DDD)
│ │ ├── auth/
│ │ ├── company/
│ │ ├── customer/
│ │ ├── estimate/
│ │ ├── invoice/
│ │ ├── line_item/
│ │ └── tools/ # PDF editor, packing, roof analyzer
│ ├── alembic/ # Database migrations
│ └── main.py
├── frontend/
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── pages/ # Page components
│ │ ├── services/ # API services
│ │ ├── stores/ # Zustand stores
│ │ ├── hooks/ # Custom hooks
│ │ └── types/ # TypeScript types
│ └── index.html
├── render.yaml # Render deployment blueprint
└── docker-compose.yml
| Layer | Technology |
|---|---|
| Frontend | React 18 + TypeScript, Vite 5, Ant Design 5, Zustand, TanStack Query |
| Backend | FastAPI, Python 3.11+, SQLAlchemy 2.0 (sync), Pydantic V2 |
| Database | PostgreSQL 15 (NeonDB) |
| File Storage | Local (dev) / Cloudflare R2 (production) |
| Auth | JWT (HS256), Google OAuth |
| WeasyPrint, PyPDF, ReportLab, pdf2image |
Users → Vercel (Frontend) → Render (Backend API) → NeonDB (PostgreSQL)
↕
Cloudflare R2 (Files)
| Service | Provider | URL |
|---|---|---|
| Frontend | Vercel | scopit.work |
| Backend | Render | api.scopit.work |
| Database | NeonDB | ep-xxx.neon.tech |
| Files | Cloudflare R2 | scopit-uploads bucket |
postgresql://user:[email protected]/scopit?sslmode=requireDATABASE_URL
in backend/.env.local (manual/uvicorn workflow) and in the root .env
(docker-compose workflow):
DATABASE_URL=postgresql://user:[email protected]/scopit?sslmode=require
Consider creating a separate Neon branch (e.g. dev) for local work so it
doesn't share data with production.# Dump local DB
pg_dump -U postgres -d scopit_local -Fc -f scopit_backup.dump
# Restore to NeonDB
pg_restore -h ep-xxx.neon.tech -U scopit -d scopit \
--no-owner --no-privileges scopit_backup.dump
scopit-uploadsAccount ID, Access Key ID, Secret Access Keyhttps://<ACCOUNT_ID>.r2.cloudflarestorage.com# Install rclone
# Configure rclone with R2 credentials, then:
rclone copy ./backend/uploads r2:scopit-uploads --progress
After migrating files, update file_path and thumbnail_path columns
in the database to use storage keys (strip the uploads/ prefix):
UPDATE pdf_documents
SET file_path = REPLACE(file_path, 'uploads/', ''),
thumbnail_path = REPLACE(thumbnail_path, 'uploads/', '')
WHERE file_path LIKE 'uploads/%';
UPDATE company_documents
SET file_path = REPLACE(file_path, 'uploads/', ''),
thumbnail_path = REPLACE(thumbnail_path, 'uploads/', '')
WHERE file_path LIKE 'uploads/%';
UPDATE sign_requests
SET signed_file_path = REPLACE(signed_file_path, 'uploads/', '')
WHERE signed_file_path LIKE 'uploads/%';
The backend deploys on Render's Docker runtime (not native Python) because
WeasyPrint (PDF generation) and pdf2image (PDF editor) require system libraries
— libpango/libcairo/libgdk-pixbuf and poppler-utils — that the native
runtime cannot install. These are provided by backend/Dockerfile. Database
migrations (alembic upgrade head) run automatically on every container start.
render.yaml blueprint (recommended — it creates the service as a
Docker web service), or create a Web Service manually:
./backend/Dockerfile./backendsync: false, so they must be filled in there):
DATABASE_URL (NeonDB connection string)CORS_ORIGINS (your Vercel URL, e.g. https://scopit.work)FRONTEND_URL, GOOGLE_REDIRECT_URIR2_ENDPOINT_URL, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEYGOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRETANTHROPIC_API_KEYapi.scopit.workFree plan note: The Item Recommender (semantic search) loads a sentence-transformers/torch model (~500MB–1GB RAM) that exceeds the free plan's 512MB limit, so
ITEM_RECOMMENDER_ENABLEDis set toFalseinrender.yaml. After upgrading to a paid plan (e.g. Starter) with more RAM — and providing theparsed_jsondataset — set it toTrueto enable the tool. The free plan also spins the service down after inactivity, causing a cold start (~30–60s) on the next request.
frontendVITE_API_URL=https://api.scopit.work/api
scopit.workscopit.work → CNAME → cname.vercel-dns.com
www.scopit.work → CNAME → cname.vercel-dns.com
api.scopit.work → CNAME → scopit-api.onrender.com
https://api.scopit.work/api/auth/google/callbackhttps://scopit.workENV=local
DEBUG=True
DATABASE_URL=postgresql://user:[email protected]/scopit?sslmode=require
SECRET_KEY=dev-secret-key
CORS_ORIGINS=http://localhost:3001
BETA_MODE=True
# File storage (default: local)
STORAGE_PROVIDER=local
STORAGE_BASE_DIR=uploads
# Item Recommender semantic search (heavy torch model).
# Set to False on memory-constrained hosts (e.g. Render free plan).
ITEM_RECOMMENDER_ENABLED=True
# Optional: use R2 locally
# STORAGE_PROVIDER=r2
# R2_ENDPOINT_URL=https://ACCOUNT_ID.r2.cloudflarestorage.com
# R2_ACCESS_KEY_ID=xxx
# R2_SECRET_ACCESS_KEY=xxx
# R2_BUCKET_NAME=scopit-uploads
VITE_API_URL=http://localhost:8001/api
| Property | Value |
|---|---|
| Primary | #111827 |
| Background | #f9fafb |
| Border | #e5e7eb |
| Headings | Plus Jakarta Sans |
| Body | Inter |
| Border Radius | 6px (buttons), 12px (cards) |
UI Library: Ant Design 5 with custom theme
# Backend
cd backend && pytest
# Frontend
cd frontend && npm test
Proprietary - All rights reserved.