Skip to main content

Projects Service

Overview

The Projects Service handles purchase order (PO) creation and tracking for active construction projects. It supports six PO types with vendor-specific workflows and approval chains.

Base URL

http://localhost:5002/api

Authentication

Cookie: sAccessToken=...; sRefreshToken=...

Purchase Order Types

🧊

Concrete

Mix design, cubic yards, delivery schedule

📦

Material

General materials and supplies

🚚

Rental

Equipment rentals with duration

🤝

Subcontract

External services and labor

🔌

Pump

Concrete pumping services

⚙️

Miscellaneous

General costs and fees

PO Workflow

🔍 Click diagram to expand

Base Operations

List Purchase Orders

GET /api/purchase-orders
Cookie: sAccessToken=...; sRefreshToken=...

Roles: OPS, PM, ACCOUNTING, ADMIN

Query Parameters:

  • projectId - Filter by project
  • status - Filter by status
  • type - Filter by PO type
  • vendorId - Filter by vendor

Get Purchase Order

GET /api/purchase-orders/:id
Cookie: sAccessToken=...; sRefreshToken=...

Roles: OPS, PM, ACCOUNTING, ADMIN


Update Purchase Order

PUT /api/purchase-orders/:id
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"scopeId": "new-uuid",
"notes": "Updated notes"
}

Roles: OPS, ADMIN


Delete Purchase Order

DELETE /api/purchase-orders/:id
Cookie: sAccessToken=...; sRefreshToken=...

Roles: OPS, ADMIN

warning

Only POs with status PENDING_RECEIPT can be deleted.

PO Type Endpoints

Concrete PO

POST /api/purchase-orders/concrete
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"projectId": "uuid",
"vendorId": "uuid",
"scopeId": "uuid",
"concreteType": "3000 PSI",
"mixIds": "MIX-001",
"cubicYards": 45.5,
"slumpSize": 4,
"spacing": "Continuous",
"desiredDelivery": "2025-11-20T08:00:00Z",
"notes": "Foundation pour"
}

Required Fields:

  • concreteType, mixIds, cubicYards, slumpSize, spacing, desiredDelivery

Vendor Type: CONCRETE


Material PO

POST /api/purchase-orders/material
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"projectId": "uuid",
"vendorId": "uuid",
"scopeId": "uuid",
"desiredDelivery": "2025-11-20T08:00:00Z",
"notes": "Lumber delivery"
}

Required Fields:

  • desiredDelivery

Vendor Type: MATERIAL


Rental PO

POST /api/purchase-orders/rental
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"projectId": "uuid",
"vendorId": "uuid",
"scopeId": "uuid",
"equipmentType": "Skid Steer - Daily",
"duration": 5,
"desiredDelivery": "2025-11-20T08:00:00Z",
"notes": "Site work"
}

Required Fields:

  • equipmentType, duration, desiredDelivery

Vendor Type: EQUIPMENT


Subcontract PO

POST /api/purchase-orders/subcontract
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"projectId": "uuid",
"vendorId": "uuid",
"scopeId": "uuid",
"subType": "Pier Drilling",
"quantity": 100,
"uom": "LF",
"desiredDelivery": "2025-11-20T08:00:00Z",
"notes": "Drilled piers"
}

Required Fields:

  • subType, quantity, uom, desiredDelivery

Vendor Type: SUBCONTRACTOR

Units: EA, LF, SF, CY, HR, DAY, etc.


Pump PO

POST /api/purchase-orders/pump
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"projectId": "uuid",
"vendorId": "uuid",
"scopeId": "uuid",
"pumpType": "Alamo City - 32 Meter",
"desiredDelivery": "2025-11-20T08:00:00Z",
"notes": "Foundation pour"
}

Required Fields:

  • pumpType, desiredDelivery

Vendor Type: PUMP


Miscellaneous PO

POST /api/purchase-orders/misc
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: application/json

{
"projectId": "uuid",
"vendorId": "uuid",
"specifyScope": "Foundation, Grade Beam",
"notes": "General project costs"
}

Optional Fields:

  • specifyScope - Multi-select from project scopes
  • notes

Vendor Type: MISC

Receipt Management

Upload Receipt

POST /api/purchase-orders/:id/receipt
Cookie: sAccessToken=...; sRefreshToken=...
Content-Type: multipart/form-data

[Upload image file]

Roles: OPS, ADMIN

Requirements:

  • Max size: 10MB
  • Formats: JPEG, PNG
  • Storage: Google Cloud Storage

Updates status from PENDING_RECEIPT to WITH_RECEIPT.


Get Receipt

GET /api/purchase-orders/:id/receipt
Cookie: sAccessToken=...; sRefreshToken=...

Roles: OPS, PM, ACCOUNTING, ADMIN


Delete Receipt

DELETE /api/purchase-orders/:id/receipt
Cookie: sAccessToken=...; sRefreshToken=...

Roles: OPS, ADMIN

Updates status back to PENDING_RECEIPT.

Bids Integration

Get Equipment Types

GET /api/purchase-orders/integration/equipment-types
Cookie: sAccessToken=...; sRefreshToken=...

Cached: 1 hour


Get Subcontractor Types

GET /api/purchase-orders/integration/subcontractor-types
Cookie: sAccessToken=...; sRefreshToken=...

Cached: 1 hour


Get Pump Catalog

GET /api/purchase-orders/integration/pump-catalog
Cookie: sAccessToken=...; sRefreshToken=...

Cached: 1 hour

Status Transitions

Current StatusAllowed ActionsNext Status
PENDING_RECEIPTUpload receipt, Update, DeleteWITH_RECEIPT
WITH_RECEIPTPM assign cost codesALLOCATED
WITH_RECEIPTPM rejectREJECTED_BY_PM
ALLOCATEDAccounting approveCOMPLETE
ALLOCATEDAccounting rejectREJECTED_BY_ACCT
REJECTED_BY_PMOPS fix and re-uploadWITH_RECEIPT
REJECTED_BY_ACCTPM review and fixALLOCATED

Vendor Type Validation

Each PO type requires specific vendor types:

PO TypeRequired Vendor Type
CONCRETECONCRETE
MATERIALMATERIAL
RENTALEQUIPMENT
SUBCONTRACTSUBCONTRACTOR
PUMPPUMP
MISCMISC
warning

Creating a PO with wrong vendor type returns error: "Selected vendor is not a [type] supplier"

Role-Based Access

RolePermissions
OPSCreate, update, upload receipts
PMApprove/reject, assign cost codes
ACCOUNTINGReconcile, approve/reject
ADMINFull access