The work before the walls go up.
Roughin is a production-oriented, mobile-first SaaS for solo contractors and tradespeople to manage clients, jobs, line items, invoices, photos, and subscription billing from the field with a simple dark industrial UI.
| Layer | Technology |
|---|---|
| Backend | FastAPI, SQLAlchemy 2.x async, Alembic, PostgreSQL |
| Auth | JWT access + refresh tokens |
| Payments | Stripe API + webhooks |
| File Storage | Cloudflare R2 (S3-compatible via boto3) |
| ReportLab | |
| Frontend | React 18, Vite, TailwindCSS, PWA |
| Runtime | Docker + docker-compose |
- Prerequisites: Docker, Docker Compose, Python 3.11+, Node 20+.
- Copy environment file values:
cp .env.example .env
- Start services:
docker-compose up --build
- Run first migration:
make migrate
- Optional seed via API by registering a user and creating demo entities.
| Variable | Purpose |
|---|---|
| APP_ENV | Runtime environment |
| SECRET_KEY | JWT signing key |
| ACCESS_TOKEN_EXPIRE_MINUTES | Access token lifetime |
| REFRESH_TOKEN_EXPIRE_DAYS | Refresh token lifetime |
| DATABASE_URL | Async PostgreSQL URL |
| STRIPE_SECRET_KEY | Stripe API key |
| STRIPE_WEBHOOK_SECRET | Stripe webhook signing secret |
| STRIPE_SOLO_PRICE_ID | Price ID for solo tier |
| STRIPE_PRO_PRICE_ID | Price ID for pro tier |
| R2_ENDPOINT_URL | R2 endpoint |
| R2_ACCESS_KEY_ID | R2 access key |
| R2_SECRET_ACCESS_KEY | R2 secret key |
| R2_BUCKET_NAME | Upload bucket name |
| R2_PUBLIC_URL | Public upload domain |
| VITE_API_BASE_URL | Frontend API base URL |
- Auth: /auth/register, /auth/login, /auth/refresh, /auth/logout
- Users: /users/me (GET/PATCH/DELETE)
- Clients: list/create/detail/update/delete + /clients/{id}/jobs
- Jobs: list/create/detail/update/delete + line-items/photos/estimate-pdf routes
- Invoices: list/create/detail/update + send/void/pdf
- Payments: list/detail
- Webhooks: /webhooks/stripe
- Stripe: /stripe/create-checkout-session, /stripe/portal
| Tier | Active Jobs | Clients | Payment Links | Photos | Price |
|---|---|---|---|---|---|
| free | 3 | 5 | No | No | $0 |
| solo | Unlimited | Unlimited | Yes | Yes | $29/mo |
| pro | Unlimited | Unlimited | Yes | Yes | $49/mo |
- Add
frontend/public/icons/icon-192.png(192x192 PNG) before deploying. - Add
frontend/public/icons/icon-512.png(512x512 PNG) before deploying. - Set all
.envvalues before running. - Configure Stripe webhook endpoint to point at
/api/v1/webhooks/stripe. - Create R2 bucket and set CORS policy to allow frontend origin.
Proprietary software. See LICENSE.
Developer: Outer Void / Justadudeinspace — theoutervoid@outlook.com — 2026.