Between the idea and the app: a PRD
Before PFEx's first line of code there were documents. This is how I talked an idea through with AI into a PRD, split that PRD into components and milestones, and then built it week by week.
I wanted to build an app that treats one person's finances as a market. Before I touched a screen or a line of code, I did something else: I talked a vague idea through with AI until it became a document I could execute.
It starts with one idea
All I had at first was one sentence: bookkeeping apps hand you a list of transactions, and I want you to see your money the way you watch an index.
That sentence is a direction, not a requirement. It does not say what question the app answers, or what it refuses to do. So instead of writing code, I sat down and forced it into those sentences.
What the idea itself turned out to look like, I wrote up in the original concept piece. This one is only about how I turned it into an app, step by step.
Talking the requirements through with AI
I gave that sentence to the AI and went one round at a time. I did not ask "do you think this is good". I asked the details I could not answer myself. Three came up most: what question does it actually answer; in that securities vocabulary, which words really have to land in the data model and which are only for the screen; and what will it refuse to do.
The answers all became product decisions, and they are not the subject here. What mattered was the way I asked: it turned my "I think this is nice" into "this is the question I answer, and this is what I will not do".
Having AI write the PRD
Once the requirements were clear, I had the AI organise them into a PRD, doc/prd.md. It went through three rounds, and the last one rewrote it against the current implementation, replacing the two stitched-together drafts before it.
I only insisted on one thing: the PRD has to be a baseline I can compare against. Every task's acceptance criteria had to point back to one of its clauses.
Splitting the PRD into tasks
A PRD says what, not how to start. So I had the AI split it into tasks, which became doc/tasks.md, marked v1.0, dated 19 September 2026.
The split is by component, not by screen. Everything falls into four buckets: infrastructure (core and data), computation engines (pure Dart under domain/engine), UI components, and page modules. The direction between layers is fixed: pages depend only on engine interfaces, engines touch no IO, data implements repositories, and core is available to everyone.
I also wrote in a few hard rules to use as code-review gates. Two I still remember:
- the engine directory may not import drift, flutter or dart:io, so engines can be unit-tested on their own;
- every user-facing string must come from the localisation files, no hard-coding.
Then milestones. The whole thing was laid out as 12 weeks, M0 to M11, one theme each: infrastructure and data, the core transaction flow, the engine cluster, then the market UI, review, the status system, bilingual, the remaining pages, a releasable MVP, Japanese and Korean, AI reports, and finally polish and store submission.
For every task I required four things: which component it belongs to, which task it depends on, which PRD clause its acceptance criteria map to, and what test closes it out. Only with all four is a task genuinely independently buildable and independently acceptable.
Building it milestone by milestone
With the task table in hand, the rest was moving week by week. I had the AI take one task from a milestone at a time, delivering the code and the tests together, per the conventions above.
Take the engine week. I wrote the acceptance criteria and the test requirement first: empty account, negative balance and transactions spanning days all had to be covered. The AI then delivered the engine and its unit tests against that standard. Because the engine is a pure function that touches no IO, those cases ran directly as unit tests.
Later the AI wrote pages, components, localisation copy, and unit tests. At the end of each week I checked the acceptance criteria myself and sent back whatever did not match. In this workflow the AI produced a lot, but the standard for "is this right" was always the clauses I had written into the documents first.
What I learned
Looking back, the rounds I spent on requirements at the very start paid for themselves, and they paid off in the process:
- requirements written as acceptable clauses gave the AI a standard to check against instead of guessing;
- writing down what the app refuses to do kept the AI from quietly adding things while it split the tasks;
- tasks written as "component plus dependency plus acceptance plus test" are what made week-by-week independent delivery possible;
- when a document changes, the latest version is the one that counts, and the AI starts from it every time.
Ideas are easy to have; a document you can accept is not. Between the two sit the rounds I spent at the start, talking it through with the AI.