kamau1's picture
fix: make user_id optional for self-service and auto-set before auth check; update schema, service, and docs
c5fdc5d

Inventory API - Field Agent Quick Reference

Base URL

/api/v1/inventory


Field Agent Endpoints

1. Get My Inventory Stats

GET /my-stats

Purpose: Dashboard stats for field agents

Response:

{
  "user_id": "uuid",
  "user_name": "John Doe",
  "total_assignments": 25,
  "active_assignments": 3,
  "returned_count": 18,
  "installed_count": 4,
  "consumed_count": 0,
  "by_item_type": {
    "tool": 1,
    "equipment": 2,
    "consumable": 0,
    "ppe": 0
  }
}

2. Get My Current Inventory

GET /my-inventory

Purpose: See what equipment I currently have (not returned/installed/consumed)

Response:

{
  "items": [
    {
      "id": "uuid",
      "unit_identifier": "ONT-12345",
      "equipment_type": "ONT",
      "equipment_name": "Huawei HG8546M",
      "item_type": "equipment",
      "issued_at": "2025-12-01T08:30:00Z",
      "days_issued": 5,
      "status": "issued",
      "is_active": true,
      "ticket_id": "uuid",
      "ticket_reference": "TKT-001",
      "region_name": "Nairobi West",
      "notes": "For installation at customer site"
    }
  ],
  "total": 3,
  "page": 1,
  "page_size": 100,
  "total_pages": 1
}

3. Get Available Inventory at Hub

GET /regions/{region_id}/available

Purpose: See what's available at my regional hub before going to collect

Response:

{
  "items": [
    {
      "id": "uuid",
      "equipment_type": "ONT",
      "equipment_name": "Huawei HG8546M",
      "item_type": "equipment",
      "quantity_available": 45.00,
      "quantity_allocated": 100.00,
      "quantity_issued": 55.00,
      "region_name": "Nairobi West",
      "allocated_date": "2025-11-15",
      "serial_numbers": [...]
    }
  ],
  "total": 5,
  "page": 1,
  "page_size": 100,
  "total_pages": 1
}

4. Record Collection from Hub

POST /assignments

Purpose: Record what I collected from the hub (self-service)

Request:

{
  "project_inventory_distribution_id": "uuid",
  "unit_identifier": "ONT-12345",
  "ticket_id": "uuid",
  "notes": "Collected for TKT-001"
}

Notes:

  • user_id is optional - auto-set to yourself for self-service
  • Field agents can only record for themselves (admins/PMs can specify user_id for others)
  • unit_identifier must be unique (serial number, box number, etc.)
  • ticket_id is optional - link to ticket if you know which job it's for

Response:

{
  "id": "uuid",
  "unit_identifier": "ONT-12345",
  "equipment_type": "ONT",
  "equipment_name": "Huawei HG8546M",
  "item_type": "equipment",
  "issued_at": "2025-12-01T10:30:00Z",
  "issued_by_user_id": "uuid",
  "status": "issued",
  "is_active": true,
  "days_issued": 0,
  "ticket_id": "uuid",
  "notes": "Collected for TKT-001"
}

5. Return Tool to Hub

POST /assignments/{assignment_id}/return

Purpose: Record tool return (for reusable tools only)

Request:

{
  "return_condition": "good",
  "return_notes": "Tool in good condition"
}

Valid conditions: good, damaged, lost, worn

Response:

{
  "id": "uuid",
  "unit_identifier": "DRILL-789",
  "equipment_type": "Drill",
  "item_type": "tool",
  "issued_at": "2025-11-28T08:00:00Z",
  "returned_at": "2025-12-01T17:00:00Z",
  "return_condition": "good",
  "is_returned": true,
  "status": "returned",
  "days_issued": 3
}

6. Mark Equipment as Installed

POST /assignments/{assignment_id}/install

Purpose: Mark equipment as installed at customer site (for equipment only)

Request:

{
  "ticket_id": "uuid",
  "installation_notes": "Installed at customer premises"
}

Response:

{
  "id": "uuid",
  "unit_identifier": "ONT-12345",
  "equipment_type": "ONT",
  "item_type": "equipment",
  "issued_at": "2025-12-01T08:30:00Z",
  "installed_at": "2025-12-01T14:30:00Z",
  "status": "installed",
  "is_active": false,
  "days_issued": 0,
  "ticket_id": "uuid"
}

7. Link Equipment to Ticket

POST /assignments/{assignment_id}/link-ticket?ticket_id={ticket_id}

Purpose: Link collected equipment to a specific ticket/job

Query Params:

  • ticket_id (required): UUID of ticket to link to

Response:

{
  "id": "uuid",
  "unit_identifier": "ONT-12345",
  "ticket_id": "uuid",
  "ticket_reference": "TKT-001",
  "status": "issued",
  "additional_metadata": {
    "linked_to_ticket_at": "2025-12-01T10:45:00Z",
    "linked_by_user_id": "uuid"
  }
}

8. List My Assignments (with filters)

GET /assignments?user_id={user_id}&status={status}&is_returned={bool}

Purpose: View assignment history with filters

Query Params:

  • page (default: 1)
  • page_size (default: 50, max: 100)
  • user_id (optional): Filter by user (field agents auto-filtered to self)
  • status (optional): issued, returned, installed
  • is_returned (optional): true or false
  • ticket_id (optional): Filter by ticket

Response:

{
  "items": [...],
  "total": 25,
  "page": 1,
  "page_size": 50,
  "total_pages": 1
}

Item Types & Workflows

Tool (Returnable)

  1. Collect from hub β†’ POST /assignments
  2. Use for job
  3. Return to hub β†’ POST /assignments/{id}/return

Equipment (Installable)

  1. Collect from hub β†’ POST /assignments
  2. Link to ticket β†’ POST /assignments/{id}/link-ticket
  3. Install at customer β†’ POST /assignments/{id}/install

Consumable (Single-use)

  1. Collect from hub β†’ POST /assignments
  2. Use up (no return needed)

PPE (Long-term)

  1. Collect from hub β†’ POST /assignments
  2. Keep for extended period

Error Responses

400 Bad Request:

{
  "detail": "No inventory available at this regional hub"
}

403 Forbidden:

{
  "detail": "Not authorized to record inventory collection at this region"
}

404 Not Found:

{
  "detail": "Assignment not found: {uuid}"
}

409 Conflict:

{
  "detail": "Unit ONT-12345 already assigned"
}


9. Initiate Transfer to Another Agent

POST /assignments/{assignment_id}/transfer

Purpose: Transfer equipment to another field agent (peer-to-peer)

Request:

{
  "to_user_id": "uuid",
  "transfer_reason": "Agent B needs ONT urgently, I have extra",
  "requires_approval": true,
  "transfer_latitude": -1.2921,
  "transfer_longitude": 36.8219,
  "notes": "Meeting at regional office"
}

Response:

{
  "id": "uuid",
  "from_assignment_id": "uuid",
  "from_user_id": "uuid",
  "to_user_id": "uuid",
  "unit_identifier": "ONT-12345",
  "transfer_reason": "Agent B needs ONT urgently, I have extra",
  "status": "pending",
  "requires_approval": true,
  "created_at": "2025-12-01T10:00:00Z"
}

10. Accept Transfer

POST /transfers/{transfer_id}/accept

Purpose: Accept equipment transfer from another agent

Response:

{
  "id": "uuid",
  "status": "completed",
  "to_assignment_id": "uuid",
  "accepted_by_to_user_at": "2025-12-01T10:30:00Z",
  "completed_at": "2025-12-01T10:30:00Z"
}

11. Get My Pending Transfers

GET /transfers/pending

Purpose: See transfers waiting for my acceptance

Response:

{
  "incoming": [
    {
      "id": "uuid",
      "from_user_name": "John Doe",
      "unit_identifier": "ONT-12345",
      "equipment_name": "Huawei HG8546M",
      "transfer_reason": "You need this for urgent job",
      "status": "approved",
      "created_at": "2025-12-01T09:00:00Z"
    }
  ],
  "outgoing": [
    {
      "id": "uuid",
      "to_user_name": "Jane Smith",
      "unit_identifier": "DRILL-789",
      "equipment_name": "Power Drill",
      "status": "pending",
      "created_at": "2025-12-01T08:00:00Z"
    }
  ]
}

Authorization

All endpoints require authentication. Field agents can only:

  • View their own assignments
  • Record their own collections
  • Return their own items
  • View available inventory at hubs in their project
  • Initiate transfers of their own equipment
  • Accept transfers sent to them

Admins/PMs can perform actions on behalf of any user and approve transfers.