SharedLedger Journey Part 1: From Zero to Phoenix
posted by donghyun
last updated
13 min read
π The Context: Berlin, New Life, New Needs
September 2025, I moved to Berlin. New city, new life, and new finances to manage with my partner. Using both EUR (Euro) and KRW (Korean Won) simultaneously, existing expense tracking apps couldnβt meet our needs:
- Multi-currency support (EUR β KRW real-time conversion)
- Shared ledger concept (for couples)
- Transaction categorization
- Monthly/annual summaries and analysis
At the same time, I wanted to explore the AI coding tools space deeply.
βSo, why not build it myself? With AI tools.β
π€ Why AI-Assisted Development?
This project started with AI coding tool experimentation in mind from the beginning:
- Test Claude Codeβs real-world project capabilities
- Identify strengths and limitations of AI tools
- Learn effective AI utilization patterns
- Validate AI tool viability in the Elixir/Phoenix ecosystem
π‘ Honest Expectations Setup
What you should know before starting:
This is NOT a story where βAI perfectly built everything.β The reality:
- β My Role: Architecture design, planning, decision making, extensive refactoring, fixing broken implementations
- π€ Claude Codeβs Role: Code generation, boilerplate creation, initial feature implementation
- β° Time Reality: ~30% planning, ~40% AI-assisted coding, ~30% refactoring/fixing what AI messed up
AI tools are powerful, but especially with specialized frameworks like Ash Framework, they required significant corrections and improvements. This series covers that realistic journey.
π§ Technology Choices
Why Elixir?
Elixir is my favorite language, but recently Iβve been using other languages at work, which made me crave an Elixir project even more. Since I consider myself an Elixir expert, I was curious how well I could validate the Elixir code Claude Code generates.
Why Phoenix LiveView?
Iβm still not sure if Phoenix LiveView can build complex SPA-level services. There are many inconveniences, and itβs actively evolving, so Iβm constantly catching up. Iβm genuinely curious if LiveView will one day perfectly replace frontend development.
Why Ash Framework?
Ash Framework has been really hot lately, but the learning curve is steep. As always, using a powerful framework means giving up some freedom. For this project, I was particularly curious how well Claude Code could handle Ash.
Key Decision: PostgreSQL (not ETS/SQLite)
- Initial plan: SQLite for MVP
- Reality: Switched to PostgreSQL early
- Reason: Production-ready from day one
π Project Initialization
Day 1: Setting Up
-
Documentation phase with Claude (17+ files, ~5,500 lines):
Architecture Documents (in
docs/architecture/):-
DOMAIN_MODEL.md(1,066 lines) - Defined 4 domains (Identity, Accounts, Ledger, Currency) -
UI_COMPONENTS.md(1,026 lines) - Complete UI spec based on Atomic Design -
API_SPECIFICATION.md(645 lines) - LiveView event contracts -
DATABASE_DESIGN.md(489 lines) - Complete schema structure -
ASH_FRAMEWORK_ANALYSIS.md(355 lines) - Ash framework evaluation and usage strategy -
SYSTEM_ARCHITECTURE.md(292 lines) - Layered architecture and patterns
Project Documents (in
docs/):-
REQUIREMENTS_SPECIFICATION.md(815 lines) - Functional/non-functional requirements -
PROJECT_PLAN.md(572 lines) - MVP β Phase 2 β Phase 3 roadmap -
TECHNICAL_SPECIFICATION.md- Implementation details -
CLAUDE.md(229 lines) - AI assistant guide - Plus: PROJECT_STATUS, DEPLOYMENT_OPERATIONS_GUIDE, DATA_FLOW_INTEGRATION
-
-
Project initialization:
-
mix phx.new shared_ledger -
mix igniter.installfor Ash Framework and dependencies
-
π First Lesson with Claude Code
Day 1: Perfect Planning
Before actually running mix new to generate code, I focused on creating proper documentation. Using the expertise I gained from company projects, I started creating essential documents with Claudeβs help. The more thorough you are here, the less unnecessary effort later.
Good documentation means:
- β AI understands my architectural intent
- β Generates code with consistent patterns
- β Doesnβt repeat the same mistakes
But there was a trapβ¦
Day 2: Collision with Reality
# Code perfectly planned on Day 1
changeset = Ash.Changeset.for_action(User, :create, %{})
form = to_form(changeset) # π₯ Protocol error!
Error message: Protocol Phoenix.HTML.FormData not implemented for Ash.Changeset
Even with perfect documentation, special Ash Framework integration issues couldnβt be prevented. New documents were created that day:
-
DEVELOPMENT_CONVENTIONS.md- Ash+Phoenix patterns -
ADR-005: Ash-Phoenix Form Integration- Why we did it this way
Two types of documentation:
- Proactive (Day 1) - Documentation that prevents problems
- Reactive (Day 2) - Documentation that solves and records problems
AI Agents constantly and unintentionally embed information that differs from what I want, so I needed to carefully review documentation and continuously update it.
Lesson: Documentation is not one-and-done. It must be living documentation.
ποΈ Architecture Planning
Domain Contexts
Initial planning led to 4 main contexts:
- Identity - Users, authentication, sessions
- Accounts - Shared accounts, memberships, roles
- Ledger - Transactions, categories, summaries
- Currency - Exchange rates, conversions
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Phoenix UI β
β (LiveView Components) β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Domain Layer β
β Identity β Accounts β Ledger β Currency β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β Ash Resources Layer β
β (Declarative definitions + Actions) β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
β PostgreSQL β
βββββββββββββββββββββββββββββββββββββββββββββββββββ
π€ Architecture Decision Challenges
Initial state: I was confident in Elixir, but domain modeling and relationship design were areas with many concerns, so I decided to follow Claudeβs concrete and comprehensive design this time.
Core mistake: Uncritically accepting βit sounds logical so it must be right.β
Major cases:
- 4-domain structure β Week 5 domain boundary refactoring
-
Many-to-many + RBAC β Implemented without understanding
manage_relationshipβ 2 weeks debugging - SQLite β Forced PostgreSQL migration (Day 7)
- 403 Forbidden β 404 NotFound (security issue)
Pattern: Claude suggests β βSounds goodβ β Implement β Discover problems β Refactoring
Time Cost: 10 hours architecture review vs. 3-4 weeks fixing later (1:20~30 ratio)
Lesson: AI knows patterns. But it doesnβt know my problem, trade-offs, security implications. βAI presents options. I decide.β
β Part 2 covers domain design details
π Initial Feature Planning
MVP Scope (Week 1 Planning)
Must Have:
- β User authentication (email/password)
- β Create/join shared accounts
- β Add transactions (amount, category, date, note)
- β Multi-currency support (EUR, KRW)
- β Basic transaction list view
- β Monthly summary
Nice to Have (Later):
- β Budget tracking
- β Recurring transactions
- β Advanced analytics
- β Mobile app (PWA instead)
π‘ Lesson: Pattern Pollution
The most dangerous pattern when working with AI: Bad code snowballing
Scenario: Big feature request (500 lines) β Mostly working β Skip detailed review due to laziness β 10 lines of bad code hidden β Claude learns it β Repeats in next feature.
Real Example:
-
Week 1: Direct
Ash.Queryusage in Transaction LiveView (no review) - Week 2-3: Category, Summary LiveView β Same pattern copied
-
Week 5:
git grep "Ash.Query"β Found 12 files β 2 weeks refactoring
Another example: Using Decimal instead of Money β Spreads to all calculations β Loss of currency information.
Key points:
- βWorking β Rightβ
- One mistake = 12 bugs
- Review 30 min vs. Refactoring 2 weeks (1:40 ratio)
Solution:
- Detailed review mandatory even for big features
- Fix wrong patterns immediately (not later)
- Record anti-patterns in CLAUDE.md
-
Periodic audits (
git grepforbidden patterns)
β Part 4 covers refactoring in detail
π― Documentation-Driven Development
One of the best decisions: Creating comprehensive documentation for Claude Code.
Files created:
-
CLAUDE.md- Project-specific guidelines -
AGENTS.md- Phoenix/LiveView/Elixir rules (later) -
ASH_DEVELOPMENT_GUIDE.md- Ash framework patterns -
ASH_LIVEVIEW_STRICT_RULES.md- Quick checklist
π Why This Mattered
ROI: 12-16 hours documentation vs. 30-40 hours saved (~2-3x)
Effects:
- Claude follows consistent patterns
- Reduces repeated mistakes
- Enables multitasking (documentation replaces me)
Trade-offs:
- Takes significant time to write documentation
- Requires continuous updates
- Claude sometimes ignores documentation
Conclusion: Complex frameworks (Ash, LiveView) require documentation. Simple projects donβt need it.
π Development Workflow Setup
Tools & Environment
# Docker for PostgreSQL
docker-compose up -d postgres
# Development commands (Makefile)
make dev-setup # First time
make dev # Daily use
make test # Run tests
make format # Code formatting
π€ Workflow with Claude Code
Established pattern:
-
Feature start: Create branch β Provide context to Claude (
DOMAIN_MODEL.md, etc.) - During work: Immediate review, stop on pattern violations, check compile at each step
- Iteration: Average 3-4 times (Direct Ash β Domain functions β Authorization β Error handling)
- Commit: Reject Claudeβs commit message suggestions, write my own
Role division:
- Claude: Boilerplate, repetitive CRUD, test drafts
- Me: Architecture decisions, complex business logic
Key point: Use as pair programmer, but I make final decisions.
π First Week Results
By the end of first week (Sep 11-18):
β
Project initialized
β
Ash framework integrated
β
Basic domain structure defined
β
SQLite setup (later migrated to PostgreSQL)
β
Initial documentation written
β
Core features implemented (but needed fixes)
β οΈ Many compilation errors to resolve
Git commits tell the story:
dd3de03 - docs: Add comprehensive Ash framework implementation
4377a84 - docs: Add complete Ash framework architecture
b010fc3 - feat: Implement core MVP features with Ash
394878a - feat: Implement Phoenix LiveView UI
π‘ Key Insight
Planning saved time:
- Documentation first: 48 hours total investment
- Without documentation (estimated): 60+ hours (architecture refactoring, repeated mistakes)
- Saved: ~20%
More importantly: Correct structure, consistent patterns, less technical debt.
However: Documentation couldnβt prevent everything. Week 5-6 needed 26 refactoring commits. AI-generated code still requires review and refactoring.
π¬ Whatβs Next?
In Part 2, weβll dive into:
- Implementing the four domain contexts with Ash
- Resource definitions and relationships
- Authorization setup (RBAC)
- Testing in IEx before touching LiveView
- Lessons learned about guiding Claude with Ash patterns