Skip to content
Non-Tech Founders

Building a Client Portal With AI in a Weekend

A real build timeline. Friday evening to Sunday afternoon. Lovable plus Supabase plus Clerk. What got built, what did not, what we added the following week.

By WitsCode10 min read

Every solo operator and agency owner hits the same wall around year two. Files ricochet through email attachments, status updates bury in Slack threads, invoices live on a different planet. The fix is a client portal. The objection used to be that building one meant a dev team, a three-month timeline, and a five-figure quote.

That math changed. Lovable for the frontend, Supabase for data and storage, Clerk for authentication. Together they make it possible to ship a branded, functional client portal in a single weekend. Not a polished SaaS product. A portal good enough to send to a real client on Monday.

This is a real build log. Friday evening to Sunday afternoon. Around fourteen hours of work. The scaffolding order that works, the three features that fit, the hardening pass that makes it safe to share, the honest cut list. At the end there is a repo template you can clone to skip the setup.

Why this stack, not the others

Before the timeline, a quick word on why these three tools. Bubble, Softr, Stacker all have advocates. SuperOkay and Copilot are turnkey. This stack wins for a weekend build because each tool does one thing well and stays out of the others' way.

Lovable generates a working Next.js app from a prompt. You describe your portal, it scaffolds routes, components, and layout. You iterate through chat rather than dragging elements around. The output is real code in a real Git repo, not a locked platform.

Supabase is a Postgres database with authentication, storage, and row-level security built in. For a portal, the row-level security matters more than anything. You want client A to only see client A's files, and you want that rule enforced at the database, not in application code you might forget to add.

Clerk handles authentication and user management. You could use Supabase Auth for this, and many builds do. Clerk wins because the hosted UI is better, invite flows are one line of code, and the admin dashboard is something you can hand to a non-technical partner without fear.

The combination is fast because each tool assumes the others exist. Lovable has templates that already wire Clerk and Supabase. Clerk publishes user IDs that Supabase RLS policies can consume directly. Nothing novel has to be built.

The Friday-evening scaffold

The single biggest mistake in a weekend build is treating Friday as a warm-up. Friday is load-bearing. If the scaffold is wrong, Saturday is spent debugging instead of shipping.

The right order is prompt, data, auth, seed. Do them in that sequence and the rest of the weekend has a chance.

The first ninety minutes belong to Lovable. Open a new project and write a dense prompt. Describe the portal as if briefing a junior developer. List the routes explicitly. A login page, a dashboard with a project list, a project detail view with tabs for files, messages, and status, a settings page for the client to change their own details. Describe the visual tone in one sentence. Say "clean, professional, minimal color" rather than "modern and sleek," which produces generic output. Paste a JSON example of the data shape you expect so the scaffolded components have realistic placeholder content.

Lovable will generate the whole thing in fifteen to twenty minutes. Resist the urge to edit code. Instead, use the chat to request changes. "Move the logout button from the sidebar to a user menu in the top right." "Convert the file list from cards to a table with columns for name, size, and date." Three or four of these prompts and the scaffold is close to what you want.

Around 7:30pm, switch to Supabase. Create a new project. Open the SQL editor and create five tables: clients, projects, messages, files, and status_updates. Each table has a clerk_user_id column that stores the Clerk user who owns or created the row. Turn on row-level security for every table. Write a policy on each table that says, in effect, "you can select a row only if its clerk_user_id matches the current authenticated user." That is the fence that stops client A from ever seeing client B's data, and it is enforced at the database level.

At 8:30pm, wire up Clerk. Install the Clerk Next.js SDK, wrap the app in <ClerkProvider>, add the middleware that protects the dashboard route. The important bit is piping the Clerk user ID into your Supabase calls so RLS works. Clerk exposes the user ID through a hook. Pass it into the Supabase client as the authenticated identity. Most of this is copy-paste from the Clerk and Supabase docs.

By 9:30pm, the scaffold is real. Log in with a test account. Confirm the dashboard loads. Confirm that logging out and visiting the dashboard URL directly redirects back to login. Seed one fake client and one fake project in Supabase. Reload the dashboard and see the project appear. Commit everything to Git. Go to bed. This is the hardest part and it is done.

Saturday feature sprint: three features, not thirty

Saturday is tempting. The scaffold works, you feel momentum, and the instinct is to list fifteen features and try to ship them all. This is how weekends die. Pick three features. Three is the maximum that fits in a Saturday with room for the things that always go wrong.

The three that matter for a portal v1 are file upload, project status, and messages. In that order, because file upload is the riskiest and if it breaks Saturday afternoon, you still have time to swap in something simpler.

File upload takes from 9am to 11:30am. Create a Supabase Storage bucket and set up policies that mirror the database RLS: a user can only read and write to a folder named after their own client ID. Add a drag-and-drop component to the project detail page. Lovable will scaffold the component in one prompt. Wire it to upload to Supabase Storage, then write a row into the files table with the storage path, file name, size, and owner. Set a hard limit of 25MB per file in the UI. Generate signed URLs when the client wants to download, not permanent public links.

Project status goes from noon to 2pm. A status_updates table, a form for the admin (you) to write updates, and a vertical timeline on the client's project page. One Lovable prompt handles the timeline component. This feature feels minor but is the single most valuable thing for a client. They stop emailing to ask "how's it going" because they can see.

Messages run from 2:30pm to 5:30pm. Per-project thread. A form to send, a list to display, both gated by the project's RLS. Store markdown and render it so links work. Real-time updates are optional. Skip them for v1 and refresh on send. Nobody will notice on a portal used twice a week.

Between 5:30 and 6pm, deploy. Vercel is fastest if Lovable has not already deployed for you. Log in from a fresh browser as the fake client. Something will break. It always does. Usually it is an environment variable, occasionally a redirect loop with Clerk, sometimes a Supabase policy that was too strict. Fix what is obvious and note the rest for Sunday.

Sunday hardening: auth edges and file upload limits

Sunday is not about new features. It is the difference between a demo and something you can send a paying client. If you skip Sunday, you have a tech demo. If you do Sunday, you have a portal.

Start with auth edges at 10am. Log in as the fake client and try to visit a URL for a project that belongs to another client. The RLS policy should return nothing. If it returns data, the policy is broken and must be fixed before anything else. Test the logout flow. Test the password reset flow through Clerk. Make sure that when a session expires, the user is redirected to login rather than seeing a blank page.

From 11:30am to 12:30pm, harden file uploads. The 25MB limit in the UI is not enough because any competent attacker can bypass the browser. Enforce the limit in a server-side API route or edge function. Add a content-type whitelist. Block executables, scripts, and anything that is not a document, image, or archive. Add a per-client storage quota. Five gigabytes is a reasonable default. This is also where you add virus scanning if the use case demands it, though for most agencies it does not.

From 12:30pm to 2pm, branding. Upload your logo to the sidebar and login page. Set the favicon. Configure the Clerk email domain so invite emails come from you and not from Clerk's default sender. Write a one-sentence welcome message on the dashboard. These are small changes that make the portal feel owned.

From 2pm to 3pm, error states. Empty file list, no messages yet, project not found, user has no projects, session timed out. Saturday builds skip these because there is always data in your test account. Sunday is when you find them.

The final hour is the invite flow. In Clerk, send a real invite to a real email address. Use a friend's email or a second account you control. Confirm the magic link works, the user lands on the dashboard, and they see only their own data. This end-to-end test is the single most important moment of the weekend. It is the thing that most tutorials skip and the thing that separates a project that works on your laptop from a project that works on someone else's.

By 4pm Sunday, a functional client portal exists.

What didn't ship, and why that is fine

Every honest build log has a cut list. These are the features that did not fit in the weekend and what to do about them.

Email notifications did not ship. Sending a transactional email when a client gets a new message or a status update is genuinely useful, but it requires a provider (Resend, Postmark, SendGrid), template design, and delivery testing. That is a three-hour task on its own. Defer to week 2. In the meantime, the portal works as a pull system rather than a push one. Clients check it when they remember to.

PDF invoice generation did not ship. The instinct was to generate branded PDF invoices inside the portal. Scope creep. The replacement is a Stripe payment link embedded on each project page. It does the job in thirty seconds instead of three hours and is arguably better because the client can pay with a card rather than mailing a check.

White-label subdomains per client did not ship. Giving each client clientname.yourportal.com requires DNS automation and a routing layer. Nice marketing, not a v1 requirement. Everyone uses the same domain and a client-specific login.

A polished mobile upload experience did not ship. The portal works on mobile because Lovable scaffolds responsive components, but drag-and-drop on mobile is awkward. Week 3 task.

Real-time updates did not ship. Messages refresh when you send. Supabase realtime is one line to enable, but testing it properly eats an hour, and for a portal used a few times a week, refresh-on-send is fine.

Week 2 additions, when the portal has been in real client hands for a few days: Resend for transactional email (two hours), a simple audit log table that records logins and downloads (one hour), and a one-line Stripe payment embed (fifteen minutes). None of these needed to be in v1.

The discipline that makes a weekend build work is writing the cut list before Saturday, not after Sunday. Decide what is not in scope and defend the scope when Saturday excitement hits.

The repo template

Rebuilding this from scratch every time is wasteful, so the version we use internally is saved as a template. It contains a Next.js 14 app with the router already set up, Clerk pre-wired including the middleware, a Supabase client with TypeScript types generated, the RLS policies for all five tables written as a migration file, and a seed script that creates one client and one project with sample data so the first login is not staring at empty tables.

The /prompts folder holds the Lovable prompts used to scaffold each of the three Saturday features, written as markdown. If you want to swap the messaging feature for a booking calendar, you edit the prompt and re-run Lovable rather than starting from zero. The README lists every environment variable you need, where to get it, and the shortest path to a working local dashboard. Expect twenty minutes from clone to login screen.

The template is not a product. It is a starting line. The point is that the scaffolding problem, the part that eats Friday evening, only needs to be solved once.

When to build it, when to hand it off

If you have a free weekend, comfort with a terminal, and a single client who needs a portal, build it. You will learn the stack, you will understand what to tweak when a client asks for something custom, and you will save four figures compared to outsourcing.

If you have three clients who all need portals, a fourth asking when theirs is ready, and a growing sense that the weekend you are about to spend building should be spent closing work, that is the moment to hand it off. A portal that exists on Monday earns its cost back faster than a portal that exists in four weekends.

WitsCode builds branded client portals on exactly this stack. Seven to ten days from kickoff to invited clients. Your logo, your domain, Clerk invite flow configured to send from your email, Supabase schema extended to match your workflow. The hardening pass is done by people who do it every week, not every weekend.

If you want the template and prompt library, or skip the weekend, book a portal build with WitsCode.

→ WitsCode client-portal build

Get weekly field notes.

Practical writing on shipping products, straight to your inbox. No spam.

Need help with this?

Custom Web Applications

We design and build web apps, MVPs, and SaaS products. Talk to us about what you are working on.

Talk to us

Want to discuss non-tech founders for your business?

Start a project and we'll talk through where you are, what's working, and the highest-leverage moves for the next 90 days.