Skip to content

[BE-92] Asset transfers with an approval workflow #1145

Description

@yusuftomilola

Overview

The frontend has a full transfers API layer (frontend/lib/query/queries/transfers.ts) including approve and reject actions, and a multisig_transfer Soroban contract exists — transfers with approval are a core workflow.

API contract: the frontend already calls these endpoints — see frontend/lib/api/ and frontend/lib/query/keys.ts. Match the paths exactly so the existing UI works without changes.

GET  /transfers                    list with filters
POST /transfers                    request a transfer
GET  /transfers/${id}
POST /transfers/${id}/approve
POST /transfers/${id}/reject
POST /assets/${id}/transfer         initiate from an asset

Tasks

  • Create the Transfer entity: assetId, fromDepartmentId/toDepartmentId, fromLocationId/toLocationId, fromUserId/toUserId, requestedByUserId, approverUserId, status (PENDING/APPROVED/REJECTED/CANCELLED/COMPLETED), reason, decisionNote, requestedAt, decidedAt.
  • Build the endpoints above with a pending-approvals inbox view.
  • Enforce that the requester cannot approve their own transfer.
  • On approval, atomically update the asset's department/location/assignee and write a history entry.
  • Move the asset to IN_TRANSIT while pending, if that suits the workflow — document the choice.
  • Prevent concurrent conflicting transfers for one asset.
  • Notify the approver on request and the requester on decision.
  • Generate a migration and write tests covering every state transition.

Acceptance Criteria

  • A transfer request, approval, and asset relocation work end to end.
  • Self-approval is refused.
  • Two simultaneous transfers of one asset cannot both complete.

Dependencies

Blocked by [BE-86], [BE-87], [BE-88].

Notes for Contributors

The backend is being rebuilt from a clean NestJS skeleton — backend/src/ currently contains only app.module.ts, app.controller.ts, app.service.ts, and main.ts. Follow standard NestJS module structure (module / controller / service / dto / entities) and register your module in app.module.ts. Comment below to be assigned.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions