Skip to content

feat: enforce supply chain stage transition validation and batch ownership checks #453

@Pcmhacker-piro

Description

@Pcmhacker-piro

Description

The updateBatch method in backend/controllers/batchController.js (line 173) blindly sets batch.currentStage = normalizedStage without any validation of whether the stage transition is legal according to the supply chain. A batch can jump directly from farmer to retailer without passing through mandi and transport. Additionally, there is no ownership check — any authenticated user can update any batch, despite the docstring claiming "Batch owner + stage transition authorized."

The valid stage order is: farmermanditransportretailer. Allowing arbitrary jumps undermines the entire farm-to-fork traceability promise.

Steps to Reproduce

  1. Login as any authenticated user (not necessarily the batch owner)
  2. Call PATCH /api/batches/BATCH000001 with { currentStage: "retailer" } on a batch that is still at farmer stage
  3. Observe the batch stage updates successfully despite skipping mandi and transport
  4. Login as a different unrelated user
  5. Observe they can also update any batch without ownership verification

Expected Behavior

  • Stage transition validation: The only valid transitions should be:
    • farmermandi
    • manditransport
    • transportretailer
  • Any other transition (skip, reverse, or jump to same stage) should return 400 Bad Request
  • Ownership check: Only the batch owner (farmer who created the batch) or an admin should be able to update a batch
  • Error messages: Clear error messages explaining why the transition is invalid

Implementation Hints

Add stage order constant to backend/constants/stages.js:

const STAGE_ORDER = [farmer, mandi, transport, retailer];

function isValidTransition(currentStage, newStage) {
  const currentIndex = STAGE_ORDER.indexOf(currentStage);
  const newIndex = STAGE_ORDER.indexOf(newStage);
  return newIndex === currentIndex + 1;
}

Update updateBatch in backend/controllers/batchController.js:

// Add after fetching the batch
if (!isValidTransition(batch.currentStage, normalizedStage)) {
  return res.status(400).json({
    message: `Invalid stage transition: cannot move from "${batch.currentStage}" to "${normalizedStage}". Valid next stage: "${getNextStage(batch.currentStage)}"`
  });
}

// Add ownership check
if (req.user.role !== admin && batch.farmerId !== req.user.id) {
  return res.status(403).json({
    message: "You do not own this batch"
  });
}

Affected Files

  • backend/controllers/batchController.js
  • backend/constants/stages.js (add transition validation)
  • backend/models/Batch.js (if adding stage order reference)

Labels

type:enhancement, level:intermediate, GSSoC-26

Metadata

Metadata

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions