01
Two months ago, after successfully connecting with the backend, I published an article titled "With Supabase, Frontend Developers Can Instantly Become Fullstack (Tutorial Included)."

Two months later, it actually came true. I became fullstack.
But if you ask how much backend code I wrote?
Not a single line.
02
The code was written by Claude Code. But every decision was made by me.
These are two things I need to make clear.
Building a payment system isn't hard because of making code run — it's hard because you need to know where things will break, why they'll break, and where to look when they do. AI won't proactively tell you these things. I forced them out through real problems.
Here are 3 examples.
03
I questioned the database design.
One day I was looking at the database and found three fields in the profiles table specifically storing subscription status — subscription active, subscription plan, subscription expiry time. My first reaction was, "Can't all of this be queried from the subscriptions table? Why duplicate it here?"
I ran a test. Deleted an active subscription, then checked the profiles table. The subscription status still showed "active."
Data inconsistency.
Later I checked the code and confirmed these three fields weren't used anywhere in the entire project. Dead code. Their only effect was to give you wrong data at critical moments.
I didn't write the code that discovered this problem, but I saw where the problem was, confirmed it with actual testing, and eliminated it.
04
I overturned the technical solution from a product perspective.
When PayPal payment fails, AI's solution was: just log it, don't change subscription status, because PayPal will auto-retry.
I said no. "Payment failure should be past_due. What should be paid wasn't paid. That's a fact."
Then I laid out the complete status flow —
Payment fails → past_due → if continues unresolved → expired.
This isn't engineering thinking. It's product thinking.
The meaning of past_due status is to tell the user "you have an unpaid charge, go update your payment method."
If we wait until PayPal retries three times and fails before changing status, the user has no idea what's happening. By the time they receive the "subscription stopped" notification, it's too late, and the experience is terrible, right?
Technically the "retry mechanism" isn't wrong, but from a user experience standpoint "timely notification" is more important. That judgment was mine.
Later the business logic iterated once more, with past_due going directly to expired — but that's another story.
05
I chased one problem through three layers.
The upgrade/downgrade logic used an abstract scoring formula: tier x 10 + cycle (annual/monthly). So pro annual = 22 points, max monthly = 31 points, the system determined pro annual → max monthly as an "upgrade."
I looked at the interface and felt something was off.
"I selected pro annual, now I'm selecting max monthly, and the interface shows upgrade... that's not right, is it? Annual costs more, max monthly is clearly cheaper."
I didn't get fooled by the abstract scoring system. I went straight back to basic business intuition — the user is paying less money, so that's a downgrade. So I scrapped the entire scoring formula and changed it to directly compare actual prices.
But I didn't stop there.
I asked another layer, "What's the standard industry practice? Do they allow switching from annual to monthly mid-term?"
After researching, I found most SaaS don't allow switching from annual to monthly mid-term — annual has a discount, refund calculations are complex, payment platforms have issues with upgrades/downgrades. For me, the moment I understood was the moment to act, so I made the call and added a block.

Someone who just fixes bugs would stop at the second layer — price comparison logic fixed, done.
But the third layer is what truly matters — should this operation even be allowed?
This is a product strategy question, not a code question.
From my years of industry experience, strategy always determines execution, never the other way around. No matter how beautifully the code is written, if the direction is wrong, tear it all down and start over.
06
I want to say this proactively, without avoidance — these past two months, nearly all the code was written by Claude Code. It really did a lot of work for me.
But do I know why every line of code should be written that way? Yes. And when something breaks, do I know where to look? Yes. When encountering edge cases, can I judge how to handle them? Yes.
The old definition of "knowing backend" was being able to write code. I think that definition is changing — being able to judge, make decisions, get the system running, and find root causes when things break is the core. Code is just the execution layer.
I didn't write the code, but I directed the construction of the entire system. Like an architect who doesn't need to lay bricks himself, but needs to know why every wall is where it is, what happens if you remove it, and where to look if there's a foundation problem.
07
Two months ago I casually said "frontend can instantly become fullstack."
Now, it's come true.
I've known design since high school, I'm a frontend developer, and as a bug middleware, I understand aesthetics and user experience. I can make product decisions — something my managers often recognized when I worked at companies. I got the entire payment system running. I can handle server backend, learned Alibaba Cloud deployment in 2 days, and set up auto-deployment for 2 domains.
Next, I'm going to do something I've never done before — sell it.
The label "frontend" probably no longer defines me.