I Built a Full-Stack Trading App Without Writing a Single Line of Code
How I used AI coding assistants to build TradingParadise, a complete options trading journal with Supabase backend, from idea to deployment.
I trade options as a side activity. I’ve used spreadsheets, Notion databases, and a couple of paid journaling tools. None of them fit how I actually think about my trades. So I decided to build my own.
The catch: I didn’t write any of the code myself. Every line of TypeScript, every SQL migration, every React component was generated by AI. I acted as the product owner and architect. The AI was the developer.
The result is TradingParadise, a full-stack options trading journal with portfolio management, dividend tracking, a live stock price feed, and a dashboard. About 49,000 lines of code across 265 files. It took roughly three weeks of evening sessions.
What I Built
The app covers my actual trading workflow:
- Trading Plans with structured sections for strategies, risk rules, market regimes, and daily checklists
- Trade Journal with inline editing, P/L calculations, grouping, sorting, and compliance tracking against plan rules
- Portfolio Holdings with buy/sell tracking, average cost calculation, and live price refresh
- Dividend Calendar showing projected monthly income based on holdings and yield
- Dashboard with monthly income summaries, per-plan analytics, and portfolio overviews
- Daily Notes with a rich text editor and screenshot capture
The tech stack: React 19, TypeScript, Tailwind CSS v4, Supabase (auth + Postgres + edge functions), Recharts, Zustand, React Router v7. Deployed as a static site with Supabase handling the backend.
The Process
I used Kiro, an AI-powered IDE, for the entire build. Kiro has a structured spec workflow that turned out to be the key differentiator from just chatting with an AI and hoping for the best.
Requirements Clarification
The first step for each major feature was writing requirements in plain language. I’d describe what I wanted as a trader, and the AI would formalize it into structured acceptance criteria.
For example, I said something like “I need to journal my options trades and track P/L.” The AI turned that into 17 specific acceptance criteria covering every field, every auto-calculation, every filter option. Things I hadn’t thought to specify got explicit rules: “THE Trade_Journal SHALL auto-calculate DTE as the number of calendar days between Open Date and Expiration Date.”
This back-and-forth was where most of the real thinking happened. The AI would propose acceptance criteria, I’d push back (“no, premium can be negative for debit spreads, you need to handle that”), and we’d iterate until the spec captured my actual workflow. The requirements doc for the core trading plan feature ended up with 18 requirements and over 100 acceptance criteria. That level of detail meant fewer surprises during implementation.
I ended up with four separate specs:
- Trading Plan App — the core journal, plan editor, reminders, and dashboard (18 requirements)
- Portfolio Management — holdings, brokerage import, transactions, performance metrics
- Default Options Strategies — a library of 20 pre-built strategy templates (Iron Condor, Covered Call, etc.)
- Dark Mode and Cloud Auth — Supabase auth integration and theming
Each spec was a separate conversation where I could focus on one domain at a time.
Design Phase
After requirements, the AI produced a design document. This is where architecture decisions got made: data models, component hierarchy, algorithms, database schema.
The design for the trading plan app proposed Dexie.js (IndexedDB) for local persistence. That was the AI’s suggestion based on the “offline-first” framing in my requirements. Later, when I decided I wanted cloud sync and multi-device access, we migrated to Supabase. The design doc made that migration tractable because the data models were already well-defined — we just swapped the persistence layer.
The portfolio management design included a full import pipeline architecture (file upload, format detection, parsing, de-duplication, preview, confirmation, persistence) with a strategy pattern for different brokerage formats. It defined a fingerprint-based de-duplication algorithm, specified how holdings would be computed from transactions, and laid out the component hierarchy. All before any code was written.
The design phase also produced “correctness properties” — formal statements about what the system should guarantee. Things like “for any valid openDate and expirationDate, DTE is non-negative and equals the calendar day difference” or “for any two transactions that differ in any fingerprint field, their fingerprints SHALL differ.” These became property-based tests during implementation.
Task Execution
The design doc fed into a task list — a dependency-ordered implementation plan with checkpoints. The trading plan app had 20 top-level tasks broken into 60+ subtasks, each referencing specific requirements for traceability.
The structure looked like:
- Project setup and types
- Checkpoint — verify tests pass
- Database layer and utilities
- Checkpoint
- State management
- Layout and navigation
- Plan Editor (9 subtasks covering each section)
- Checkpoint
- Trade Journal
- Portfolio Management
- Options Dashboard
Each task had clear inputs (which types, which requirements) and outputs (which files to create, which tests to write). The AI would execute a task, I’d review the result in the browser, and we’d move to the next one. The checkpoints forced us to stop and verify that everything still compiled and tests passed before building the next layer.
For large tasks, the AI would break them down further. “Implement Strategy Editor” became: create the component, capture all fields (name, classification, description, variants, entry criteria, management rules, profit targets, stop losses), validate at least one entry criterion and one management rule, create a StrategyCard for display, and wire it to the plan save flow.
This structured approach meant I could step away mid-feature and come back without losing context. The spec files acted as shared memory between sessions.
Iterative Refinement
The specs weren’t static. As I used the app, I’d discover things the original requirements missed.
The portfolio spec initially tied portfolios to plans with a foreign key. After using the app for a week, I realized that was wrong — a portfolio represents a brokerage account, and it exists independently of any yearly trading plan. That required a new migration (010_decouple_portfolio_from_plan.sql) and touching a dozen components. But because the change was well-defined (“make plan_id nullable on portfolios and journal_entries”), the AI could execute it cleanly.
Similarly, the journal originally auto-closed trades when you entered an exit price. In practice, I sometimes enter an exit price to see what the P/L would be before actually closing the position. So I changed the requirement: “Don’t auto-close. Let the user manually change status to Closed.” That was a two-file change once I articulated it clearly.
Bug Fixing Through Conversation
When something broke, I described the symptom. “P/L shows 6.55 but should be 1.45 when premium is -2.55 and exit is 4.” The AI would analyze the formula, explain the fix, and implement it.
Some bugs took multiple rounds. The date timezone issue was the most persistent — dates would shift back one day on refresh. JavaScript Date objects without a time component default to midnight UTC, which then shifts when displayed in local time. The fix was simple (append T12:00:00 to date strings) but finding the root cause required understanding the problem at a level the AI initially missed. This one came back three times in different forms before we stamped it out everywhere.
What Worked
Domain knowledge was the real bottleneck, not coding skill. I know options trading. I know what DTE means, how annualized return on risk should be calculated, why a debit spread has negative premium. The AI could generate React components all day, but it needed me to say “no, P/L for a credit trade is premium minus exit, but for a debit trade it’s premium plus exit.”
The spec workflow prevented scope creep. Without structured requirements, I would have wandered. Every feature started with “what exactly do I need?” before “how do I build it?” The specs acted as a contract between me (product owner) and the AI (developer). When I wanted to add dividend tracking, I described the requirement, the AI proposed a design, and we iterated before any code was written. Fewer rewrites.
Supabase as the backend meant I didn’t have to manage a server. Postgres, auth, row-level security, and edge functions out of the box. The AI generated all the SQL migrations and the RLS policies. I ran them in the dashboard. The edge function for stock quotes (proxying Yahoo Finance) was generated in one pass and deployed with a single CLI command.
Checkpoints caught regressions early. The task list had explicit “ensure all tests pass” checkpoints between feature groups. Broken imports or type errors got caught before they compounded. The AI would fix them immediately rather than building three more features on top of a broken foundation.
Inline editing over modal forms was a UX decision I made after using the app for a few days. Early versions had modal dialogs for editing trades. Clicking a cell and editing in place felt much better. The AI refactored the entire journal table in one pass.
What Didn’t Work (At First)
The AI over-engineers. Left unchecked, it would add abstractions I didn’t need. Custom hooks wrapping custom hooks. Generic components for things that only appear once. I had to repeatedly say “just put it in the component, I don’t need a separate file for this.”
State management decisions needed pushback. The AI defaulted to putting everything in Zustand stores. For some things (auth state, current plan) that made sense. For others (journal filter state that resets on navigation) it was overkill. I had to push toward local component state in several places.
The initial portfolio-plan coupling was a design mistake I only caught through usage. Portfolios represent brokerage accounts; they don’t belong to a yearly trading plan. The AI handled the decoupling refactor fine once I identified the problem, but it couldn’t have caught it on its own because it didn’t have the domain context of how traders think about accounts vs. plans.
Numbers
- ~49,000 lines of generated code
- 265 files committed
- 10 database migrations
- 1 Supabase edge function
- ~3 weeks of evening sessions (maybe 40-50 hours total)
- 0 lines of code I typed directly into a file
I typed plenty into the chat, though. Descriptions, corrections, bug reports, design decisions. The intellectual work was mine. The mechanical work of translating decisions into TypeScript was the AI’s.
Would I Do It Again?
Yes. For a personal tool where I’m the only user and I know the domain cold, this workflow is fast. I got a production app that fits my exact needs, with auth, a real database, and live market data. Building this with traditional development would have taken me months of evenings, not weeks.
The tradeoff: the codebase has some inconsistencies. Different components handle similar patterns in slightly different ways because they were generated in different sessions. If I were building something for a team, I’d want more upfront architecture decisions and stricter conventions. For a personal tool, it works.
If you trade options and want a journaling app that actually matches how options work (not just a generic trade log), the repo is at github.com/anuprk/TradingParadise. You’ll need your own Supabase project. The README has setup instructions.