FreelanceDesk
A client-management portal that centralizes clients, projects, messages, files, and invoices for freelancers.
- Role
- Solo developer
- Status
- Active development
Overview
FreelanceDesk is a client-management portal built for freelancers. A freelancer (the admin) manages clients, projects, messages, files, and invoices in one place, and each client logs in to a scoped view of only the information that belongs to them. It's a solo project, currently in active development, with the core product architecture and major workflows already built.
Problem
Freelancers commonly manage clients, project status, messages, files, and invoices across disconnected tools — a mix of email, spreadsheets, chat apps, and file-sharing links. FreelanceDesk centralizes those workflows into a single client portal.
Architecture
The app is built on Next.js (App Router) and React with TypeScript, backed by Supabase for Postgres, authentication, and file storage. Tailwind CSS and shadcn/ui handle the UI layer, and it deploys to Vercel.
There are two roles: admin and client. The admin manages everything; each client sees only their own projects, messages, files, and invoices.
Role-Based Access, Enforced at the Data Layer
The admin/client split isn't just a UI concern — a client shouldn't be able to reach another client's data even by manipulating a request directly. So authorization is enforced at the database layer with Postgres Row Level Security in Supabase, not only by hiding UI elements for the wrong role.
That meant thinking carefully about the relationships between users/profiles, clients, projects, messages, files, and invoices, and writing RLS policies keyed off those relationships rather than trusting the client to only ask for its own data. The tradeoff is real: RLS makes the system safer, but it also makes the database policies — and debugging when a query doesn't return the rows you expect — more complicated than an app that only checks permissions in application code.
Admin-Provisioned Accounts
Clients don't self-register. The flow is: the admin creates or invites a client, the client receives access, and the client logs in. That matches how freelancers actually work, and it fits the product better than open registration would.
The tradeoff is that account invitation, initial-password handling, and password recovery all need to be designed deliberately rather than relying on a generic sign-up form — that onboarding flow is one of the pieces I'm still refining before calling the product production-ready.
Keeping the MVP Focused
Messaging, invoicing, notifications, realtime updates, and file management can each expand into their own product. Rather than trying to rebuild Slack, Stripe, Dropbox, and project-management software all at once, I focused first on the core client-portal workflow — clients, projects, and the data tying them together — and treated the rest as subsystems to deepen individually afterward: build the core product first, then improve the pieces.
Server vs. Client Responsibilities
Using the Next.js App Router meant deciding, for every piece of functionality, whether it belonged on the server or the client — authenticated data access, mutations, session handling, which Supabase client to use where, and where authorization checks actually get enforced. Getting that split right is what makes the RLS-backed authorization model hold together end to end, rather than just listing "Next.js" as a technology.
File Storage and Access
Files belong to a specific project and need to be visible only to the people who should see them. That meant designing how file metadata — who uploaded it, which project it belongs to — is stored in the database alongside the actual file in Supabase Storage, and writing storage policies that check project ownership the same way the database RLS policies do.
Invoicing and Payment Workflow
Creating an invoice is the easy part. A reliable payment workflow is not: it means tracking payment state, handling asynchronous confirmation from a payment provider, and planning for webhooks, failed payments, retries, and keeping the payment provider and the local database in sync. This is the least-finished part of FreelanceDesk — the invoicing feature exists, but I wouldn't describe the payment flow as production-ready yet.
Outcome
FreelanceDesk is a working full-stack MVP that centralizes client, project, messaging, file, and invoicing workflows while enforcing role-based access through application logic and database security. It's the project I point to when I want to show I can work across the whole stack — database, authentication, backend/server logic, frontend, and deployment — not just isolated backend endpoints.