# CreditFair Migration Workshop Guide ## Overview We are migrating the CreditFair platform from a Laravel (PHP) monolith to: - **Flutter** — new cross-platform frontend - **FastAPI (Python)** — new backend with Clean Architecture This guide is your starting point for the workshop. Read it fully before writing any code. --- ## Repos & Paths | Repo | Path | Your Role | |------|------|-----------| | Original Laravel app (READ ONLY) | `/Users/creditfair/Sites/creditfair` | Reference only | | Flutter frontend | `/Users/creditfair/Sites/creditfair_flutter_frontend/app` | Migrate screens | | Python backend | `/Users/creditfair/Sites/creditfair_python_backend` | Migrate API endpoints | --- ## Setup (Do This First) ### 1. Clone & Branch ```bash # Flutter frontend cd /Users/creditfair/Sites/creditfair_flutter_frontend git checkout main && git pull git checkout -b feature// # example: git checkout -b feature/priya/disbursements-screen # Python backend cd /Users/creditfair/Sites/creditfair_python_backend git checkout main && git pull git checkout -b feature// # example: git checkout -b feature/arjun/loan-management-api ``` ### 2. Set Up Python Backend ```bash cd /Users/creditfair/Sites/creditfair_python_backend source venv/bin/activate pip install -r requirements.txt # if any new packages uvicorn src.main:app --reload --port 8000 ``` API docs available at: http://localhost:8000/docs ### 3. Set Up Flutter Frontend ```bash cd /Users/creditfair/Sites/creditfair_flutter_frontend/app flutter pub get flutter run -d chrome # or: flutter run -d macos ``` --- ## How to Use Claude Code for Migration Claude Code is your AI pair programmer. It has already read the entire codebase and knows: - The architecture patterns (Clean Architecture, DDD, SOLID) - The coding conventions for both Flutter and Python - What has already been migrated - Where to find the original Laravel code to migrate from ### Starting a Claude Session ```bash cd /Users/creditfair/Sites/creditfair_python_backend # for backend work # OR cd /Users/creditfair/Sites/creditfair_flutter_frontend/app # for frontend work claude # opens Claude Code ``` Claude automatically loads `CLAUDE.md` — this file contains the full architecture guide. ### Effective Prompts for Migration Work Claude works best with specific, contextual prompts. Use these patterns: **For backend features:** ``` Migrate the loan hypothecation flow from the Laravel backend to FastAPI. The original code is in /Users/creditfair/Sites/creditfair/app/Method/ Read the relevant Laravel files first, understand the business logic, then implement it following our Clean Architecture pattern (domain → interface → repository → use case → router). ``` **For frontend screens:** ``` Create a Disbursements screen in Flutter. Look at the existing ApplicationsScreen for the pattern to follow. Connect it to a new DisbursementApi class that calls GET /api/v1/disbursements. Follow the Riverpod provider pattern from the existing providers. ``` **For understanding existing code:** ``` Read /Users/creditfair/Sites/creditfair/app/Http/Controllers/ApiController.php and explain what the disbursement-related methods do, then help me plan the migration to Python. ``` ### What Claude Knows (Auto-Loaded via CLAUDE.md) - Full layer structure of both repos - Step-by-step guides for adding new features - SOLID principles with code examples - Naming conventions and file structure - Which Laravel files correspond to each feature area - What's been migrated and what hasn't --- ## Architecture Quick Reference ### Python Backend Layers ``` src/ ├── domain/entities/ ← Pure dataclasses (no framework) ├── domain/interfaces/ ← Abstract contracts (ABCs) ├── application/use_cases/ ← Business logic orchestration ├── infrastructure/ │ ├── models/ ← SQLAlchemy ORM models │ └── repositories/ ← DB access implementing interfaces └── presentation/api/v1/ ← FastAPI routers + Pydantic schemas ``` **Add a new feature in this order:** entity → interface → repository → use case → router ### Flutter Frontend Layers ``` lib/ ├── infrastructure/api/ ← Dio HTTP clients (one per domain) ├── application/providers/ ← Riverpod state management └── presentation/screens/ ← UI widgets (watches providers) ``` **Add a new screen in this order:** API class → Riverpod provider → Screen widget → Route --- ## Implemented API Endpoints (Backend) | Method | Path | Description | Permission Required | |--------|------|-------------|---------------------| | POST | `/api/v1/auth/login` | Email/password login → JWT | — | | GET | `/api/oauth/microsoft` | Initiate Microsoft OAuth | — | | GET | `/api/oauth/microsoft/callback` | MS OAuth callback → JWT (with RBAC role embedded) | — | | GET | `/api/v1/applications` | List loan applications | `applications.view` | | GET | `/api/v1/applications/{id}` | Get application by ID | `applications.view` | | PATCH | `/api/v1/applications/{id}` | Partial update application | `applications.edit` | | GET | `/api/v1/rbac/roles` | List roles | `rbac.view` | | POST | `/api/v1/rbac/roles` | Create role | `rbac.manage` | | GET | `/api/v1/merchants` | List merchants (paginated) | `merchants.view` | | GET | `/api/v1/merchants/{id}` | Get merchant by ID | `merchants.view` | | POST | `/api/v1/merchants` | Create merchant | `merchants.manage` | | PUT | `/api/v1/merchants/{id}` | Update merchant | `merchants.manage` | | DELETE | `/api/v1/merchants/{id}` | Delete merchant | `merchants.delete` | | GET | `/api/v1/merchants/{id}/locations` | List merchant locations | `merchants.view` | | POST | `/api/v1/merchants/{id}/locations` | Add merchant location | `merchants.manage` | | PUT | `/api/v1/merchants/locations/{id}` | Update location | `merchants.manage` | | GET | `/api/v1/merchant-categories` | List merchant categories | `merchants.view` | | GET | `/api/v1/merchants/{id}/products` | List products for merchant | `products.view` | | POST | `/api/v1/merchants/{id}/products` | Create product | `products.manage` | | PUT | `/api/v1/merchants/{id}/products/{pid}` | Update product | `products.manage` | | DELETE | `/api/v1/merchants/{id}/products/{pid}` | Delete product | `products.manage` | | GET | `/api/v1/merchants/{id}/offers` | List active offers for product linking | `products.view` | | POST | `/api/v1/products/{id}/link-offers` | Link offers to a product | `products.manage` | | **GET** | **`/api/v1/merchant/offers/{merchant_id}`** | **List all offers for a merchant (with audit log + disbursement phases)** | **`merchants.view`** | | **DELETE** | **`/api/v1/merchant/offers/{offer_id}`** | **Soft-delete a merchant offer** | **`merchants.delete`** | | **POST** | **`/api/v1/merchant-categories/`** | **Create a new merchant category with verification script** | **`merchants.create`** | | **GET** | **`/api/v1/merchant-categories/{id}/script`** | **Fetch the current verification script for a category** | **`merchants.view`** | | **PUT** | **`/api/v1/merchant-categories/{id}/script`** | **Update (or create) a verification script; archives old to logs table** | **`merchants.edit`** | | **GET** | **`/api/v1/kw-capping/`** | **List all KW capping tiers with max approved loan values** | **`merchants.view`** | | **PUT** | **`/api/v1/kw-capping/`** | **Batch-update max_approved_value for KW tiers** | **`merchants.edit`** | | **GET** | **`/api/v1/legal-charges/`** | **List all legal-charges rules (one per merchant category)** | **`merchants.view`** | | **PUT** | **`/api/v1/legal-charges/`** | **Upsert legal-charges rules for a set of merchant categories** | **`merchants.edit`** | | **GET** | **`/api/v1/merchant-category-mails/`** | **List all merchant category mail entries (id + email)** | **`merchants.view`** | | **GET** | **`/api/v1/merchant-category-mails/{id}`** | **Get a single mail entry with its linked category IDs** | **`merchants.view`** | | **POST** | **`/api/v1/merchant-category-mails/`** | **Create a new mail ↔ category mapping** | **`merchants.edit`** | | **PUT** | **`/api/v1/merchant-category-mails/{id}`** | **Update the category list for an existing mail entry** | **`merchants.edit`** | | GET | `/health` | Health check | — | > **Merchant Offers endpoints** were added in the `merchant-offers` merge. They return each offer enriched with its `offer_log` (from `merchant_offers_lock` table) and `disbursement_phases` (from `disbursement_offers` table). > **Create Merchant Category endpoint** (bold above) was added in the `Migration-workshop` branch. It writes to `merchant_category` and `merchant_category_scripts` tables. Requires `merchants.create` permission. The Flutter dialog (in `merchants_screen.dart`) replaces the old `#createCategory` modal — it includes a multi-line script editor with an `@tag` inserter dropdown so operators can place dynamic placeholders (e.g. `@Customer Name`, `@Tenure`) into the verification script. > **Merchant Category Mail endpoints** (bold above) were added in the `Migration-workshop` branch. They operate on the `merchant_category_common_mail` table (column `merchant_category_list` stores category IDs as a comma-separated string, e.g. `"1,3,7"`). The Flutter dialog (`update_category_mail_dialog.dart`) replaces the old Laravel mail page — it shows a dropdown of existing mail entries, auto-loads their linked categories as pre-ticked `FilterChip` widgets, and supports creating a brand-new mail entry inline. Requires `pydantic[email]` (`email-validator`) to be installed for `EmailStr` validation on the create endpoint. --- ## Feature Assignment Tracker Use this to coordinate who is working on what. Update your assignment before starting. ### Python Backend Tasks | Feature | Complexity | Assigned To | Status | |---------|-----------|-------------|--------| | Merchant offers list + soft-delete | Medium | — | ✅ Done | | Create Merchant Category (with verification script) | Low | — | ✅ Done | | Edit Verification Script (get + upsert with audit log) | Medium | — | ✅ Done | | Update Merchant Category Mail (list + get + create + update) | Low | — | ✅ Done | | Update KW Capping Cost for solar (list + bulk update) | Low | — | ✅ Done | | Update Legal Charges (list + upsert per category) | Low | — | ✅ Done | | Application creation/submission | Medium | | Not started | | Document upload (S3) | High | | Not started | | OTP verification (Exotel) | Medium | | Not started | | Payment webhooks (Razorpay) | High | | Not started | | ABFL loan hypothecation | High | | Not started | | Avanse integration | High | | Not started | | Email notifications | Low | | Not started | | Excel export | Medium | | Not started | | Advanced filtering/search | Medium | | Not started | | Background jobs (Celery) | High | | Not started | | Application status workflow | Medium | | Not started | | Payout/disbursement flow | High | | Not started | ### Flutter Frontend Tasks | Feature | Complexity | Assigned To | Status | |---------|-----------|-------------|--------| | Auth token persistence | Low | | Not started | | Riverpod auth provider | Medium | | Not started | | Disbursements screen | Medium | | Not started | | Analytics/Reports screen | Medium | | Not started | | Merchants screen — list + filters + pagination | Medium | — | ✅ Done | | Merchants "More Details" → Create Merchant Category | Low | — | ✅ Done | | Merchants "More Details" → Edit Verification Script | Medium | — | ✅ Done | | Merchants "More Details" → Update Merchant Category Mail | Low | — | ✅ Done | | Merchants "More Details" → Update KW Capping Cost for Solar | Low | — | ✅ Done | | Merchants "More Details" → Update Legal Charges | Low | — | ✅ Done | | Document upload UI | High | | Not started | | OTP verification UI | Medium | | Not started | | Search & filters on app list | Medium | | Not started | | Notification bell | Low | | Not started | | Application submission flow | High | | Not started | | EMI/Payment schedule view | Medium | | Not started | | Export button (PDF/Excel) | Low | | Not started | --- ## Key Reference Files in the Original Laravel App When migrating any feature, **always read the original code first**. | Feature Area | Laravel Location | |-------------|-----------------| | All API routes | `/Users/creditfair/Sites/creditfair/routes/api.php` | | Admin routes | `/Users/creditfair/Sites/creditfair/routes/admin.php` | | Main API controller (huge) | `/Users/creditfair/Sites/creditfair/app/Http/Controllers/ApiController.php` | | Database table schemas | `/Users/creditfair/Sites/creditfair/database/migrations/` | | ABFL integration | `/Users/creditfair/Sites/creditfair/app/ABFL/` | | Avanse integration | `/Users/creditfair/Sites/creditfair/app/Avanse/` | | OTP / Exotel | `/Users/creditfair/Sites/creditfair/app/Exotel/` | | Payment / Payout | `/Users/creditfair/Sites/creditfair/app/Payout/` | | Email templates | `/Users/creditfair/Sites/creditfair/app/Mail/` | | Background jobs | `/Users/creditfair/Sites/creditfair/app/Jobs/` | | Business logic methods | `/Users/creditfair/Sites/creditfair/app/Method/` | | UI views (for Flutter reference) | `/Users/creditfair/Sites/creditfair/resources/views/` | --- ## SOLID Rules (Follow These Always) | Principle | In Python | In Flutter | |-----------|-----------|------------| | **Single Responsibility** | One use case = one feature | One screen = one purpose | | **Open/Closed** | New feature = new use case class | New screen = new file | | **Liskov Substitution** | Any repo impl works interchangeably | Any provider can be mocked | | **Interface Segregation** | Focused interfaces per domain | Separate API class per domain | | **Dependency Inversion** | Use cases depend on interfaces | Screens depend on providers | --- ## Anti-Patterns to Avoid ### Python - Never write DB queries in a route handler - Never import SQLAlchemy models in use cases - Never put business logic in `presentation/` layer - Never skip the interface — always code against the ABC ### Flutter - Never call `Dio` directly from a screen widget - Never define `Provider` inside a screen file - Never use `setState` when a Riverpod provider exists for the same state - Never hardcode colors — use `AppTheme.*` --- ## Git Workflow ```bash # After completing a feature git add src/domain/entities/loan.py src/application/use_cases/get_loan.py # be specific git commit -m "feat: add loan management use case and API endpoint" git push origin feature// # Create a PR on GitHub — tag the feature lead for review ``` **Branch naming:** `feature//` **Commit style:** `feat:`, `fix:`, `refactor:`, `chore:` prefix --- ## Troubleshooting ### Python backend won't start ```bash source venv/bin/activate pip install -r requirements.txt cp .env.example .env # fill in DB credentials ``` ### Flutter can't connect to backend - Ensure backend is running: `curl http://localhost:8000/health` - Check base URL in `lib/infrastructure/api/auth_api.dart` = `http://127.0.0.1:8000` - For web: CORS is already configured on the backend ### "Import not found" in Python Make sure you are running from the repo root: ```bash cd /Users/creditfair/Sites/creditfair_python_backend # NOT from src/ subfolder ``` ### Claude gives wrong architecture Claude loads `CLAUDE.md` automatically. If it suggests something that violates the patterns, say: > "That violates our Clean Architecture. Please check CLAUDE.md and follow the correct layer structure." --- ## Questions? Ask the feature lead. For Claude-specific issues, prefix your message with: "According to CLAUDE.md..."