The Freelance Operating System.
Run your freelance business like a 10-person agency — proposals, contracts, GST invoices, milestone workspaces, time tracking, and magic-link client portals, all unified in a single dark-mode operating system.
Features · Quick Start · Docker · Architecture · Contributing
Indian solo freelancers juggle 4–6 disconnected tools: a spreadsheet for clients, Google Docs for proposals, a separate invoicing app, manual time tracking, and WhatsApp for client communication. 7obits collapses that entire stack into one opinionated dashboard that covers the full client lifecycle — from first contact to signed proposal to delivered project to paid invoice.
- 💸 Missed revenue → unbilled time and forgotten follow-ups become impossible to lose.
- 🎩 Unprofessional client experience → magic-link portals, e-signatures, and branded PDFs.
- 🧾 GST compliance friction → 18% GST, GSTIN, and INR-first pricing are first-class, not afterthoughts.
| Module | What it does |
|---|---|
| CRM | Track clients through a lead → active → past → lost lifecycle. |
| Proposals | Scoped proposals with line items, tech-stack blocks, and e-signature acceptance. Accepting a proposal auto-promotes it to a project. |
| Projects | Milestone- and task-based project workspaces with client sign-off. |
| Time Tracking | A global timer (persisted across the dashboard) with billable/non-billable entries. |
| Invoicing | GST-compliant, INR-first invoices with sequential numbering and PDF export. |
| Client Portals | Public, zero-login magic-link portals for proposals and invoices. |
| PDF Generation | Server-rendered invoice and tech-spec PDFs via @react-pdf/renderer. |
- Framework: Next.js 14 (App Router, Server Actions)
- Language: TypeScript
- Database & Auth: Supabase (Postgres + Row Level Security + SSR auth)
- Styling: Tailwind CSS with CSS-variable design tokens (dark mode default)
- Data fetching: TanStack Query + Next.js Server Actions
- State: Zustand
- Email: Resend
- Monorepo: Turborepo + pnpm workspaces
7obits/
├── apps/
│ └── web/ # Next.js 14 app (@7obits/web) — the only active app
├── packages/
│ ├── db/ # Supabase client factories + generated types (@7obits/db)
│ └── ui/ # Shared UI primitives (@7obits/ui)
├── supabase/
│ ├── config.toml # Local Supabase config
│ └── migrations/ # SQL schema, RLS policies, and DB functions
├── docs/ # PRD, spec, and design docs
├── Dockerfile # Production image for apps/web
└── docker-compose.yml # One-command local stack
- Node.js 20+
- pnpm 9+ (
npm install -g pnpm) - A Supabase project (or the Supabase CLI for local dev)
- A Resend API key (for transactional email)
git clone https://github.com/jinia101/7obits.git
cd 7obits
pnpm installcp .env.local.example apps/web/.env.localFill in apps/web/.env.local:
| Variable | Description |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Your Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Supabase anon/public key |
SUPABASE_SERVICE_ROLE_KEY |
Supabase service-role key (server only) |
NEXT_PUBLIC_APP_URL |
App base URL, e.g. http://localhost:3000 |
RESEND_API_KEY |
Resend API key for proposal/invoice emails |
RESEND_FROM_EMAIL |
Verified sender, e.g. noreply@yourdomain.com |
Using the Supabase CLI:
supabase db push # applies everything in supabase/migrationspnpm devOpen http://localhost:3000.
The repository ships a production-ready multi-stage Dockerfile (Next.js standalone output) and a docker-compose.yml.
# NEXT_PUBLIC_APP_URL is baked in at build time so link-share thumbnails use
# absolute image URLs — set it to your production domain.
docker build --build-arg NEXT_PUBLIC_APP_URL=https://your-domain.com -t 7obits .
docker run --rm -p 3000:3000 --env-file apps/web/.env.local 7obits# Reads apps/web/.env.local
docker compose up --buildThe app will be available at http://localhost:3000.
All commands run from the repo root:
pnpm dev # Start every package in dev mode (Turbo)
pnpm build # Build all packages
pnpm lint # Lint all packages
# Scope to the web app only:
pnpm --filter @7obits/web dev
pnpm --filter @7obits/web build
pnpm --filter @7obits/web lint| Group | Paths | Notes |
|---|---|---|
(marketing) |
/ |
Public landing page |
(auth) |
/login, /signup |
No sidebar |
(dashboard) |
/dashboard, /clients, /proposals, /projects, /time, /invoices, /settings |
Protected, sidebar layout |
portal/ |
/portal/invoice/[uuid], /portal/proposal/[id] |
Public, no-auth client portals |
api/ |
PDF generation + logging | @react-pdf/renderer routes |
Mutations use Next.js Server Actions (not REST routes). Each route follows the pattern:
page.tsx— server component, fetches initial data via@7obits/db/server*View.tsx/*Client.tsx— client component, receives data as propsactions.ts—"use server"mutation functionsuse*.tshooks — TanStack Query wrappers for cache invalidation
Supabase SSR handles auth via edge middleware (apps/web/middleware.ts), which verifies the session cookie and redirects accordingly. Use @7obits/db/server in server components/actions and @7obits/db/browser in client components.
Design tokens are CSS custom properties in app/globals.css. Dark mode is the default; light mode is applied via the .light class on <html>. Reference token names in Tailwind classes (e.g. bg-[var(--color-bg-surface)]) — never hardcode hex values.
See docs/ for the full PRD, spec, and design documentation.
Open Graph and Twitter Card metadata is defined in apps/web/app/layout.tsx. Whenever the site URL is shared (Slack, WhatsApp, iMessage, LinkedIn, Discord, X, …), the hero screenshot (apps/web/public/image.png) renders as the thumbnail.
Note: Next.js evaluates
metadataBaseat build time, so setNEXT_PUBLIC_APP_URLto your production domain when building for deploy — otherwise the absolute image URL falls back tohttps://7obits.com.
Contributions are welcome! Please read the Contributing Guide and our Code of Conduct before opening a pull request. To report a security vulnerability, see SECURITY.md.
Distributed under the MIT License.