Skip to content

feat: create repository layer for loans, transactions, notifications, and liquidity modules #118

Description

@Josue19-08

🔖 Title

Create missing repository layer for loans, transactions, notifications, and liquidity


📄 Description

The architecture defines `src/database/repositories/` as the data access abstraction layer. Only 3 repositories exist (`users`, `sessions`, `merchants`). The four remaining domain services call `supabaseService.getClient()` and inline raw Supabase queries directly inside business logic:

  • `src/modules/loans/loans.service.ts` — raw queries against `loans`, `loan_payments`, `loan_installments` tables
  • `src/modules/transactions/transactions.service.ts` — raw queries against `transactions` table
  • `src/modules/notifications/notifications.service.ts` — raw queries against `notifications` table
  • `src/jobs/transaction-status-checker/transaction-status-checker.processor.ts` — raw queries against `transactions` and `loans` tables (duplicated from the service)

This means:

  • Supabase table names are magic strings scattered across business logic
  • Services cannot be unit-tested without mocking the entire Supabase client
  • Query optimizations (field selection, indexes, caching hints) have no single place to live

✅ Tasks to complete

  • Create `src/database/repositories/loans.repository.ts` — encapsulate all `loans`, `loan_payments`, and `loan_installments` queries; expose typed methods (`findById`, `findByUser`, `createLoan`, `updateStatus`, `recordPayment`)
  • Create `src/database/repositories/transactions.repository.ts` — encapsulate `transactions` queries from both `transactions.service.ts` and `transaction-status-checker.processor.ts`; expose `findPending`, `findByHash`, `updateStatus`, `deleteOlderThan`
  • Create `src/database/repositories/notifications.repository.ts` — encapsulate `notifications` queries; expose `findByUser`, `countUnread`, `markAsRead`, `markAllAsRead`, `create`
  • Create `src/database/repositories/liquidity.repository.ts` — encapsulate any DB-backed liquidity metadata queries from `liquidity.service.ts`
  • Refactor `src/modules/loans/loans.service.ts` — inject `LoansRepository`; remove all direct Supabase calls
  • Refactor `src/modules/transactions/transactions.service.ts` — inject `TransactionsRepository`
  • Refactor `src/modules/notifications/notifications.service.ts` — inject `NotificationsRepository`
  • Refactor `src/jobs/transaction-status-checker/transaction-status-checker.processor.ts` — inject `LoansRepository` and `TransactionsRepository`; remove duplicated raw queries
  • Update unit tests for all affected services to mock repositories instead of the Supabase client

📚 Documentation/context for AI

(This link never should removed)
https://github.com/TrustUp-app/TrustUp-API/tree/main/docs

Reference implementation:

  • `src/database/repositories/users.repository.ts` — use this as the pattern to follow
  • `src/database/repositories/sessions.repository.ts`

🗒️ Additional notes

  • Each repository should be decorated with `@Injectable()` and registered in its module's `providers` array
  • Repositories must only interact with Supabase — no business logic, no external service calls
  • All repository methods should return typed results matching the DB schema interfaces in `src/database/types/`
  • After refactor, each service's unit test should mock only the repository, not the Supabase client directly

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions