# CreditFair Project - Architecture & Concepts Guide ## Introduction This README serves as the central documentation for the CreditFair project, detailing the structural paradigms, implemented features, and software design principles governing both the **Python FastAPI Backend** and the **Flutter Frontend**. This guide is intended to align all team members, ensuring that continuous development naturally follows the established core concepts without accumulating technical debt. --- ## 🏗️ Core Architecture: Clean Architecture & Domain-Driven Design (DDD) The project adopts a Clean Architecture approach, strictly separating the software into distinct, independent layers. Dependencies point inwards towards the Domain. 1. **Domain Layer** (`domain/`): The core of the business logic containing `entities` and abstract `interfaces`. It has zero external dependencies (no frameworks, no DB logic). 2. **Application Layer** (`application/`): Contains the business rules via `use_cases`. These classes orchestrate the data flow to and from the Domain Layer using the interfaces. 3. **Infrastructure Layer** (`infrastructure/`): The "outer ring" housing technical details. It holds the concrete implementations of database access (Repositories), third-party services, and external APIs. 4. **Presentation Layer** (`presentation/`): Exposes the underlying application to external clients. In the backend, this is where HTTP REST APIs and FastAPI router bindings live. In the frontend, this comprises your mobile/web UI screens. ### Why Clean Architecture? - **Separation of Concerns:** Business logic lives entirely isolated from technical implementation details. - **Maintainability:** You can easily swap out a database (e.g., from SQLite to PostgreSQL) or UI framework with zero changes required in your business logic. - **Testability:** Complete isolation simplifies Mocking for Unit Tests. --- ## 🛠️ Design Patterns Leveraged - **Repository Pattern (Backend):** Abstracts direct database operations (e.g., `user_repository.py`), providing simple collections of domain objects. We strictly code against repository *interfaces*, never direct ORM objects in our use cases. - **Dependency Injection (Backend & Frontend):** Instead of instantiating dependencies (like a DB connection) internally, they are injected from the outside. - *Backend:* Utilizes FastAPI's `Depends` system to inject configured repositories into Use Cases safely per request. - *Frontend:* Utilizes `Riverpod` (`application/providers`) for safe state sharing and object injection across the app. - **Use Case Pattern / Command Pattern:** Every distinct feature (e.g., `authenticate_user.py`, `authenticate_microsoft.py`) is encapsulated in a dedicated, single-purpose class. - **Singleton Pattern:** Used sparingly but effectively for centralized settings/configuration (`config/settings.py`) and loggers (`core/logger.py`). --- ## 🧱 SOLID Principles in Practice To ensure the system allows for flexible extension, the codebase revolves entirely around the SOLID principles: 1. **S - Single Responsibility Principle (SRP)** *Rule:* A class should have one, and only one, reason to change. *Example in our code:* FastAPI routers only handle HTTP request parsing and generic responses. All complex business rules are strictly confined to their respective `src/application/use_cases/`. Database interaction solely belongs in `infrastructure`. 2. **O - Open/Closed Principle (OCP)** *Rule:* Software entities should be open for extension but closed for modification. *Example in our code:* When adding a new login provider (like Google or Apple), you won't modify the existing core authentication logic. Instead, you develop a new Use Case mapped to existing abstract authentication interfaces. 3. **Liskov Substitution Principle (LSP)** *Rule:* Derived classes must be perfectly substitutable for their base classes. *Example in our code:* The system expects an interface (`UserRepositoryInterface`). Any concrete class we pass, whether a SQL DB implementation or a Mock Memory implementation during testing, will execute flawlessly without producing unhandled exceptions or violating interface contracts. 4. **I - Interface Segregation Principle (ISP)** *Rule:* Prefer multiple, focused, and specialized client-specific interfaces over massive, monolithic, general-purpose ones. *Example in our code:* Repositories are cleanly structured around bounded contexts resulting in narrow interfaces in `domain/interfaces/`. 5. **D - Dependency Inversion Principle (DIP)** *Rule:* High-level modules must NOT depend on low-level modules; both must rely upon abstractions. *Example in our code:* The Use Case `authenticate_user.py` implicitly relies on the abstract `UserRepositoryInterface`. It understands absolutely *nothing* regarding *how* the `User` was ultimately fetched—the `infrastructure` deals with that. --- ## 🚀 Module Development Guidelines for Team Members When assigning new tasks to the team (e.g., adding a `LoanManagement` module), strictly adhere to the flow below to respect the existing concepts: ### Backend (Python/FastAPI) Workflow **Never mix HTTP logic with Business rules!** 1. **Domain:** Start centrally. Define the strictly-typed Pydantic schemas or standard Dataclasses in `src/domain/entities/`. 2. **Interface:** Write abstract base classes defining contract methods in `src/domain/interfaces/`. 3. **Infrastructure:** Fulfill the contract. Write the factual database engine transaction logic inheriting your interface inside `src/infrastructure/repositories/`. 4. **Use Case:** Code the orchestration inside `src/application/use_cases/`. Ensure it takes your repository **interface** as an injected argument. 5. **Presentation:** Finally, bind your Use Case to a FastAPI Router inside `src/presentation/api/v1/`, parsing the payload and executing your abstracted Use Case. ### Frontend (Flutter) Workflow **Never place Networking inside the UI!** 1. **API/Infrastructure (`lib/infrastructure/api/`)**: Encapsulate all raw HTTP communication, utilizing `dio` and models for structured API responses. 2. **State Management (`lib/application/providers/`)**: Handle the business logic and app-wide state changes here using `Riverpod`. 3. **Presentation (`lib/presentation/screens/`)**: Code the visual components. UI widgets must unconditionally remain "dumb" – they simply *watch* providers for state changes and reflect that state. --- ## 🔄 Final Remarks By rigorously maintaining these functional boundaries, our application stays heavily decoupled, highly cohesive, easily maintainable, and infinitely testable. Welcome to the codebase, and happy coding!