erp_be/src/docs/assets-routes.yaml

932 lines
39 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

tags:
- name: Assets
components:
schemas:
AssetsCreateBody:
type: object
required: [asset_name, item_category_id, item_subcategory_id, location_id]
properties:
asset_name: { type: string, example: 'CNC Lathe Machine' }
item_category_id: { type: integer, example: 1 }
item_subcategory_id: { type: integer, example: 1 }
location_id: { type: integer, example: 1, description: 'Location id (plant or warehouse)' }
brand_model: { type: string }
manufacturer: { type: string }
serial_number: { type: string }
part_number: { type: string }
department_id: { type: integer, nullable: true }
location_detail: { type: string }
assigned_to_user_id: { type: integer, nullable: true }
maintenance_incharge_user_id: { type: integer, nullable: true, description: 'User responsible for periodic maintenance checklist' }
maintenance_frequency_in_days: { type: integer, nullable: true, example: 30, description: 'Days between maintenance checklists' }
maintenance_checklist_json:
type: array
nullable: true
description: 'Checklist TEMPLATE stored on the asset. Unique by label (case-insensitive). No `key` field.'
items:
type: object
required: [label]
properties:
label: { type: string, example: 'Check CO2 level' }
required: { type: boolean, example: true }
vendor_id: { type: integer, nullable: true }
po_id: { type: integer, nullable: true }
grn_id: { type: integer, nullable: true }
grn_item_id: { type: integer, nullable: true }
commencement_date: { type: string, format: date, nullable: true, description: 'Asset usage start date — used for depreciation (falls back to purchase_date)' }
purchase_date: { type: string, format: date, nullable: true }
purchase_cost: { type: number, example: 850000 }
useful_life_years: { type: integer, example: 10 }
depreciation_method: { type: string, enum: [SLM, WDV, CUSTOM], example: SLM }
depreciation_rate: { type: number, nullable: true, example: 10, description: 'Required for CUSTOM; auto-calculated for SLM/WDV when omitted' }
salvage_value: { type: number, example: 50000, description: 'Salvage amount. Send this OR salvage_percentage (not both required).' }
salvage_percentage: { type: number, example: 5, description: 'Salvage as % of purchase_cost (0100). If both sent, percentage wins and amount is derived.' }
warranty_expiry_date: { type: string, format: date, nullable: true }
condition: { type: string, enum: [NEW, GOOD, FAIR, POOR] }
status: { type: string, enum: [IN_USE, IDLE, UNDER_MAINTENANCE, DISPOSED, SCRAPPED] }
qr_code_value: { type: string }
disposal_date: { type: string, format: date, nullable: true }
disposal_reason: { type: string }
disposal_value: { type: number }
remarks: { type: string }
is_active: { type: boolean }
AssetsUpdateBody:
type: object
minProperties: 1
properties:
asset_name: { type: string }
item_category_id: { type: integer }
item_subcategory_id: { type: integer }
location_id: { type: integer }
brand_model: { type: string }
manufacturer: { type: string }
serial_number: { type: string }
part_number: { type: string }
department_id: { type: integer, nullable: true }
location_detail: { type: string }
assigned_to_user_id: { type: integer, nullable: true }
maintenance_incharge_user_id: { type: integer, nullable: true }
maintenance_frequency_in_days: { type: integer, nullable: true }
maintenance_checklist_json:
type: array
nullable: true
items:
type: object
required: [label]
properties:
label: { type: string }
required: { type: boolean }
vendor_id: { type: integer, nullable: true }
po_id: { type: integer, nullable: true }
grn_id: { type: integer, nullable: true }
grn_item_id: { type: integer, nullable: true }
commencement_date: { type: string, format: date, nullable: true }
purchase_date: { type: string, format: date, nullable: true }
purchase_cost: { type: number }
useful_life_years: { type: integer }
depreciation_method: { type: string, enum: [SLM, WDV, CUSTOM] }
depreciation_rate: { type: number, nullable: true }
salvage_value: { type: number }
salvage_percentage: { type: number, description: 'Salvage as % of purchase_cost (0100)' }
warranty_expiry_date: { type: string, format: date, nullable: true }
condition: { type: string, enum: [NEW, GOOD, FAIR, POOR] }
status: { type: string, enum: [IN_USE, IDLE, UNDER_MAINTENANCE, DISPOSED, SCRAPPED] }
qr_code_value: { type: string }
disposal_date: { type: string, format: date, nullable: true }
disposal_reason: { type: string }
disposal_value: { type: number }
remarks: { type: string }
is_active: { type: boolean }
DepreciationCalculateBody:
type: object
required: [depreciation_method]
properties:
depreciation_method: { type: string, enum: [SLM, WDV, CUSTOM] }
depreciation_rate: { type: number, nullable: true }
purchase_cost: { type: number, example: 850000 }
salvage_value: { type: number, example: 50000 }
salvage_percentage: { type: number, example: 5, description: 'Optional; if sent with/without salvage_value, % wins when both present' }
useful_life_years: { type: integer, example: 10 }
commencement_date: { type: string, format: date, description: 'Preferred depreciation start date' }
purchase_date: { type: string, format: date }
as_of_date: { type: string, format: date }
MaintenanceLogCreateBody:
type: object
required: [performed_date, checklist_json]
properties:
performed_date: { type: string, format: date }
next_due_date: { type: string, format: date, nullable: true, description: 'Optional override; defaults to performed_date + frequency' }
remarks: { type: string }
checklist_json:
type: array
minItems: 1
items:
type: object
required: [label, status]
properties:
label: { type: string, example: 'Check CO2 level' }
status: { type: string, enum: [OK, NOT_OK, NA] }
remarks: { type: string, nullable: true }
TransferAssetBody:
type: object
required: [transfer_date]
properties:
transfer_date: { type: string, format: date }
to_location_id: { type: integer, nullable: true }
to_department_id: { type: integer, nullable: true }
to_user_id: { type: integer, nullable: true }
reason: { type: string }
description: At least one of to_location_id, to_department_id, to_user_id is required
AmcContractBody:
type: object
required: [vendor_id, start_date, end_date]
properties:
vendor_id: { type: integer, example: 1 }
contract_no: { type: string, example: AMC-2026-001 }
contract_type: { type: string, enum: [COMPREHENSIVE, LABOUR_ONLY, PARTS_ONLY, PREVENTIVE_ONLY] }
start_date: { type: string, format: date }
end_date: { type: string, format: date }
renewal_date: { type: string, format: date, nullable: true }
annual_cost: { type: number, example: 50000 }
payment_frequency: { type: string, enum: [MONTHLY, QUARTERLY, HALF_YEARLY, ANNUAL] }
service_frequency: { type: string, enum: [MONTHLY, QUARTERLY, HALF_YEARLY, ANNUAL], nullable: true }
visits_per_year: { type: integer, nullable: true, example: 4 }
contact_person: { type: string }
contact_phone: { type: string }
contact_email: { type: string, format: email }
scope_of_work: { type: string }
exclusions: { type: string }
remarks: { type: string }
is_active: { type: boolean }
AmcContractUpdateBody:
type: object
minProperties: 1
properties:
vendor_id: { type: integer }
contract_no: { type: string }
contract_type: { type: string, enum: [COMPREHENSIVE, LABOUR_ONLY, PARTS_ONLY, PREVENTIVE_ONLY] }
start_date: { type: string, format: date }
end_date: { type: string, format: date }
renewal_date: { type: string, format: date, nullable: true }
annual_cost: { type: number }
payment_frequency: { type: string, enum: [MONTHLY, QUARTERLY, HALF_YEARLY, ANNUAL] }
service_frequency: { type: string, enum: [MONTHLY, QUARTERLY, HALF_YEARLY, ANNUAL], nullable: true }
visits_per_year: { type: integer, nullable: true }
contact_person: { type: string }
contact_phone: { type: string }
contact_email: { type: string, format: email }
scope_of_work: { type: string }
exclusions: { type: string }
remarks: { type: string }
is_active: { type: boolean }
AmcRenewBody:
type: object
required: [start_date, end_date]
properties:
start_date: { type: string, format: date }
end_date: { type: string, format: date }
vendor_id: { type: integer }
contract_no: { type: string }
contract_type: { type: string, enum: [COMPREHENSIVE, LABOUR_ONLY, PARTS_ONLY, PREVENTIVE_ONLY] }
renewal_date: { type: string, format: date, nullable: true }
annual_cost: { type: number }
payment_frequency: { type: string, enum: [MONTHLY, QUARTERLY, HALF_YEARLY, ANNUAL] }
service_frequency: { type: string, enum: [MONTHLY, QUARTERLY, HALF_YEARLY, ANNUAL], nullable: true }
visits_per_year: { type: integer, nullable: true }
contact_person: { type: string }
contact_phone: { type: string }
contact_email: { type: string, format: email }
scope_of_work: { type: string }
exclusions: { type: string }
remarks: { type: string }
ServiceVisitBody:
type: object
required: [visit_type, visit_date]
properties:
visit_type: { type: string, enum: [PREVENTIVE, BREAKDOWN, INSPECTION, INSTALLATION, CALIBRATION, OTHER] }
visit_date: { type: string, format: date }
amc_contract_id: { type: integer, nullable: true }
complaint_no: { type: string, example: CMP-001 }
complaint_date: { type: string, format: date, nullable: true }
complaint_desc: { type: string }
engineer_name: { type: string }
engineer_phone: { type: string }
vendor_id: { type: integer, nullable: true }
work_done: { type: string }
parts_replaced: { type: string }
next_service_date: { type: string, format: date, nullable: true }
status: { type: string, enum: [SCHEDULED, IN_PROGRESS, COMPLETED, CANCELLED, PENDING_PARTS] }
downtime_hours: { type: number, example: 2.5 }
service_cost: { type: number, example: 1500 }
is_under_amc: { type: boolean }
asset_condition_after: { type: string, enum: [GOOD, FAIR, POOR, NEEDS_REPLACEMENT], nullable: true }
remarks: { type: string }
ServiceVisitUpdateBody:
type: object
minProperties: 1
properties:
visit_type: { type: string, enum: [PREVENTIVE, BREAKDOWN, INSPECTION, INSTALLATION, CALIBRATION, OTHER] }
visit_date: { type: string, format: date }
amc_contract_id: { type: integer, nullable: true }
complaint_no: { type: string }
complaint_date: { type: string, format: date, nullable: true }
complaint_desc: { type: string }
engineer_name: { type: string }
engineer_phone: { type: string }
vendor_id: { type: integer, nullable: true }
work_done: { type: string }
parts_replaced: { type: string }
next_service_date: { type: string, format: date, nullable: true }
status: { type: string, enum: [SCHEDULED, IN_PROGRESS, COMPLETED, CANCELLED, PENDING_PARTS] }
downtime_hours: { type: number }
service_cost: { type: number }
is_under_amc: { type: boolean }
asset_condition_after: { type: string, enum: [GOOD, FAIR, POOR, NEEDS_REPLACEMENT], nullable: true }
remarks: { type: string }
ServiceVisitStatusBody:
type: object
required: [status]
properties:
status: { type: string, enum: [SCHEDULED, IN_PROGRESS, COMPLETED, CANCELLED, PENDING_PARTS] }
remarks: { type: string }
InsurancePolicyBody:
type: object
required: [policy_no, insurer_name, policy_start_date, policy_end_date]
properties:
policy_no: { type: string, example: POL-2026-001 }
insurer_name: { type: string, example: 'ICICI Lombard' }
insurer_branch: { type: string }
insurer_contact: { type: string }
insurer_phone: { type: string }
insurer_email: { type: string, format: email }
policy_type: { type: string, enum: [FIRE_AND_ALLIED, MACHINERY_BREAKDOWN, COMPREHENSIVE, THIRD_PARTY, VEHICLE, OTHER] }
sum_insured: { type: number, example: 1000000 }
annual_premium: { type: number, example: 25000 }
policy_start_date: { type: string, format: date }
policy_end_date: { type: string, format: date }
renewal_date: { type: string, format: date, nullable: true }
is_auto_renewal: { type: boolean }
premium_paid: { type: boolean }
premium_paid_date: { type: string, format: date, nullable: true }
remarks: { type: string }
is_active: { type: boolean }
InsurancePolicyUpdateBody:
type: object
minProperties: 1
properties:
policy_no: { type: string }
insurer_name: { type: string }
insurer_branch: { type: string }
insurer_contact: { type: string }
insurer_phone: { type: string }
insurer_email: { type: string, format: email }
policy_type: { type: string, enum: [FIRE_AND_ALLIED, MACHINERY_BREAKDOWN, COMPREHENSIVE, THIRD_PARTY, VEHICLE, OTHER] }
sum_insured: { type: number }
annual_premium: { type: number }
policy_start_date: { type: string, format: date }
policy_end_date: { type: string, format: date }
renewal_date: { type: string, format: date, nullable: true }
is_auto_renewal: { type: boolean }
premium_paid: { type: boolean }
premium_paid_date: { type: string, format: date, nullable: true }
remarks: { type: string }
is_active: { type: boolean }
InsuranceRenewBody:
type: object
required: [policy_start_date, policy_end_date]
properties:
policy_start_date: { type: string, format: date }
policy_end_date: { type: string, format: date }
policy_no: { type: string }
insurer_name: { type: string }
insurer_branch: { type: string }
insurer_contact: { type: string }
insurer_phone: { type: string }
insurer_email: { type: string, format: email }
policy_type: { type: string, enum: [FIRE_AND_ALLIED, MACHINERY_BREAKDOWN, COMPREHENSIVE, THIRD_PARTY, VEHICLE, OTHER] }
sum_insured: { type: number }
annual_premium: { type: number }
renewal_date: { type: string, format: date, nullable: true }
is_auto_renewal: { type: boolean }
premium_paid: { type: boolean }
premium_paid_date: { type: string, format: date, nullable: true }
remarks: { type: string }
AssetAttachmentResponse:
type: object
properties:
id: { type: string, example: '1' }
asset_id: { type: string, example: '1' }
attachment_type:
type: string
enum: [DOCUMENT, PHOTO, WARRANTY, INVOICE, AMC_CONTRACT, SERVICE_REPORT, INSURANCE_POLICY, OTHER]
example: DOCUMENT
amc_contract_id: { type: string, nullable: true, example: '1' }
service_visit_id: { type: string, nullable: true, example: '1' }
insurance_id: { type: string, nullable: true, example: '1' }
file_name: { type: string, example: 'warranty-card.pdf' }
file_type: { type: string, example: 'application/pdf' }
file_size: { type: integer, example: 245760 }
uploaded_by_user:
type: object
nullable: true
properties:
id: { type: string }
full_name: { type: string }
employee_code: { type: string, nullable: true }
created_at: { type: string, format: date-time }
paths:
/assets/options:
get:
tags: [Assets]
summary: All asset module dropdown options in one call
description: Returns contract_types, visit_types, policy_types, conditions, statuses, frequencies, etc.
responses:
'200':
description: Options fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/contract-types:
get:
tags: [Assets]
summary: AMC contract type dropdown options
responses:
'200':
description: Contract types fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/visit-types:
get:
tags: [Assets]
summary: Service visit type dropdown options
responses:
'200':
description: Visit types fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/policy-types:
get:
tags: [Assets]
summary: Insurance policy type dropdown options
responses:
'200':
description: Policy types fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/conditions:
get:
tags: [Assets]
summary: Asset condition dropdown options
responses:
'200':
description: Asset conditions fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/statuses:
get:
tags: [Assets]
summary: Asset status dropdown options
responses:
'200':
description: Asset statuses fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/payment-frequencies:
get:
tags: [Assets]
summary: AMC payment frequency dropdown options
responses:
'200':
description: Payment frequencies fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/service-frequencies:
get:
tags: [Assets]
summary: AMC service frequency dropdown options
responses:
'200':
description: Service frequencies fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/visit-statuses:
get:
tags: [Assets]
summary: Service visit status dropdown options
responses:
'200':
description: Visit statuses fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/visit-conditions-after:
get:
tags: [Assets]
summary: Asset condition after visit dropdown options
responses:
'200':
description: Visit condition options fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/depreciation-methods:
get:
tags: [Assets]
summary: List depreciation method dropdown options (SLM, WDV, CUSTOM)
responses:
'200':
description: Depreciation methods fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/depreciation/calculate:
post:
tags: [Assets]
summary: Preview depreciation calculation for selected method/rate
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/DepreciationCalculateBody' }
responses:
'200':
description: Depreciation calculated
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/alerts/expiry:
get:
tags: [Assets]
summary: Expiry alerts (AMC, Insurance, Warranty)
parameters:
- { name: days, in: query, schema: { type: integer, example: 30 } }
- { name: type, in: query, schema: { type: string, enum: [AMC, INSURANCE, WARRANTY] } }
- { name: page, in: query, schema: { type: integer } }
- { name: limit, in: query, schema: { type: integer } }
responses:
'200':
description: Expiry alerts fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/alerts/service:
get:
tags: [Assets]
summary: Service due/overdue alerts
parameters:
- { name: status, in: query, schema: { type: string, enum: [OVERDUE, DUE_THIS_WEEK, DUE_THIS_MONTH, UPCOMING] } }
- { name: page, in: query, schema: { type: integer } }
- { name: limit, in: query, schema: { type: integer } }
responses:
'200':
description: Service alerts fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/maintenance/my:
get:
tags: [Assets]
summary: List assets assigned to me as maintenance incharge
description: |
Returns assets where `maintenance_incharge_user_id` equals the logged-in user.
Use `due_only=true` to show only assets whose next checklist is due/overdue.
Each asset includes a `maintenance` summary (`is_due`, `next_due_date`, `checklist`, etc.).
parameters:
- { name: page, in: query, schema: { type: integer } }
- { name: limit, in: query, schema: { type: integer } }
- { name: search, in: query, schema: { type: string } }
- { name: due_only, in: query, schema: { type: boolean } }
- { name: status, in: query, schema: { type: string } }
- { name: location_id, in: query, schema: { type: integer } }
- { name: is_active, in: query, schema: { type: boolean } }
responses:
'200':
description: Maintenance assets fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/export:
get:
tags: [Assets]
summary: Export assets CSV (same filters as list)
description: |
Requires `ASSET` → `export`. Returns CSV (opens in Excel).
No `id` column; date/datetime values formatted as `dd-mm-yyyy hh:mm`.
parameters:
- { name: search, in: query, schema: { type: string } }
- { name: status, in: query, schema: { type: string } }
- { name: condition, in: query, schema: { type: string } }
- { name: item_category_id, in: query, schema: { type: integer } }
- { name: item_subcategory_id, in: query, schema: { type: integer } }
- { name: location_id, in: query, schema: { type: integer } }
- { name: department_id, in: query, schema: { type: integer } }
- { name: maintenance_incharge_user_id, in: query, schema: { type: integer } }
- { name: due_only, in: query, schema: { type: boolean }, description: 'When true, only assets whose maintenance is due/overdue' }
- { name: is_active, in: query, schema: { type: boolean } }
responses:
'200':
description: CSV export
content:
text/csv:
schema: { type: string }
/assets:
get:
tags: [Assets]
summary: List assets
description: >
Each item includes purchase_cost, current_value (book value after depreciation),
and a depreciation summary object (method, rate, annual, accumulated, book_value, years_elapsed).
parameters:
- { name: page, in: query, schema: { type: integer } }
- { name: limit, in: query, schema: { type: integer } }
- { name: search, in: query, schema: { type: string } }
- { name: status, in: query, schema: { type: string } }
- { name: condition, in: query, schema: { type: string } }
- { name: item_category_id, in: query, schema: { type: integer } }
- { name: item_subcategory_id, in: query, schema: { type: integer } }
- { name: location_id, in: query, schema: { type: integer } }
- { name: department_id, in: query, schema: { type: integer } }
- { name: maintenance_incharge_user_id, in: query, schema: { type: integer } }
- { name: due_only, in: query, schema: { type: boolean } }
- { name: is_active, in: query, schema: { type: boolean } }
responses:
'200':
description: Assets fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
post:
tags: [Assets]
summary: Create asset
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/AssetsCreateBody' }
responses:
'201':
description: Asset created
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
tags: [Assets]
summary: Get asset (includes depreciation summary)
responses:
'200':
description: Asset fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
put:
tags: [Assets]
summary: Update asset
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/AssetsUpdateBody' }
responses:
'200':
description: Asset updated
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
delete:
tags: [Assets]
summary: Soft delete asset
responses:
'200':
description: Asset deleted
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/transfer:
post:
tags: [Assets]
summary: Transfer asset
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/TransferAssetBody' }
responses:
'200':
description: Asset transferred
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/transfer-history:
get:
tags: [Assets]
summary: Asset transfer history
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: Transfer history fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/maintenance-logs:
get:
tags: [Assets]
summary: List maintenance checklist logs for an asset
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: page, in: query, schema: { type: integer } }
- { name: limit, in: query, schema: { type: integer } }
responses:
'200':
description: Maintenance logs fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
post:
tags: [Assets]
summary: Submit a maintenance checklist (incharge only)
description: |
Only the asset's `maintenance_incharge_user_id` may submit.
Required checklist labels from `maintenance_checklist_json` must be present with status OK/NOT_OK/NA.
`next_due_date` defaults to performed_date + maintenance_frequency_in_days.
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/MaintenanceLogCreateBody' }
responses:
'201':
description: Checklist submitted
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
'403': { description: Not the maintenance incharge }
/assets/{id}/maintenance-logs/{logId}:
get:
tags: [Assets]
summary: Get a maintenance log by id
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: logId, in: path, required: true, schema: { type: string } }
responses:
'200':
description: Maintenance log fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
delete:
tags: [Assets]
summary: Soft-delete a maintenance log (incharge only)
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: logId, in: path, required: true, schema: { type: string } }
responses:
'200':
description: Maintenance log deleted
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{assetId}/attachments:
get:
tags: [Assets]
summary: List asset attachments
parameters:
- { name: assetId, in: path, required: true, schema: { type: string, example: '1' } }
responses:
'200':
description: Attachments fetched
content:
application/json:
schema:
allOf:
- { $ref: '#/components/schemas/ApiResponse' }
- type: object
properties:
data:
type: array
items: { $ref: '#/components/schemas/AssetAttachmentResponse' }
'404': { description: Asset not found }
post:
tags: [Assets]
summary: Upload asset attachment
description: Multipart upload. Optional fields link file to AMC, service visit, or insurance policy.
parameters:
- { name: assetId, in: path, required: true, schema: { type: string, example: '1' } }
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required: [file]
properties:
file:
type: string
format: binary
attachment_type:
type: string
enum: [DOCUMENT, PHOTO, WARRANTY, INVOICE, AMC_CONTRACT, SERVICE_REPORT, INSURANCE_POLICY, OTHER]
default: DOCUMENT
amc_contract_id: { type: integer, nullable: true }
service_visit_id: { type: integer, nullable: true }
insurance_id: { type: integer, nullable: true }
responses:
'201':
description: Attachment uploaded
content:
application/json:
schema: { $ref: '#/components/schemas/ApiResponse' }
'400': { description: Invalid attachment_type or missing file }
'404': { description: Asset or linked record not found }
/assets/{assetId}/attachments/{attachmentId}:
get:
tags: [Assets]
summary: Get asset attachment metadata
parameters:
- { name: assetId, in: path, required: true, schema: { type: string, example: '1' } }
- { name: attachmentId, in: path, required: true, schema: { type: string, example: '1' } }
responses:
'200':
description: Attachment fetched
content:
application/json:
schema: { $ref: '#/components/schemas/ApiResponse' }
'404': { description: Not found }
delete:
tags: [Assets]
summary: Delete asset attachment
parameters:
- { name: assetId, in: path, required: true, schema: { type: string, example: '1' } }
- { name: attachmentId, in: path, required: true, schema: { type: string, example: '1' } }
responses:
'200':
description: Attachment deleted
content:
application/json:
schema: { $ref: '#/components/schemas/ApiResponse' }
'404': { description: Not found }
/assets/{assetId}/attachments/{attachmentId}/download:
get:
tags: [Assets]
summary: Download asset attachment file
parameters:
- { name: assetId, in: path, required: true, schema: { type: string, example: '1' } }
- { name: attachmentId, in: path, required: true, schema: { type: string, example: '1' } }
responses:
'200':
description: File download
content:
application/octet-stream:
schema: { type: string, format: binary }
'404': { description: Not found }
/assets/{id}/amc:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
tags: [Assets]
summary: List AMC contracts for asset
responses:
'200':
description: AMC contracts fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
post:
tags: [Assets]
summary: Create AMC contract
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/AmcContractBody' }
responses:
'201':
description: AMC contract created
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/amc/{contractId}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: contractId, in: path, required: true, schema: { type: string } }
get:
tags: [Assets]
summary: Get AMC contract
responses:
'200':
description: AMC contract fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
put:
tags: [Assets]
summary: Update AMC contract
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/AmcContractUpdateBody' }
responses:
'200':
description: AMC contract updated
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/amc/{contractId}/renew:
patch:
tags: [Assets]
summary: Renew AMC contract
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: contractId, in: path, required: true, schema: { type: string } }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/AmcRenewBody' }
responses:
'200':
description: AMC renewed
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/service-visits:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
tags: [Assets]
summary: List service visits
parameters:
- { name: status, in: query, schema: { type: string } }
- { name: visit_type, in: query, schema: { type: string } }
responses:
'200':
description: Service visits fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
post:
tags: [Assets]
summary: Log service visit
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/ServiceVisitBody' }
responses:
'201':
description: Service visit created
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/service-visits/{visitId}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: visitId, in: path, required: true, schema: { type: string } }
get:
tags: [Assets]
summary: Get service visit
responses:
'200':
description: Service visit fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
put:
tags: [Assets]
summary: Update service visit
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/ServiceVisitUpdateBody' }
responses:
'200':
description: Service visit updated
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/service-visits/{visitId}/status:
patch:
tags: [Assets]
summary: Update service visit status
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: visitId, in: path, required: true, schema: { type: string } }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/ServiceVisitStatusBody' }
responses:
'200':
description: Status updated
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/insurance:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
get:
tags: [Assets]
summary: List insurance policies
responses:
'200':
description: Insurance policies fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
post:
tags: [Assets]
summary: Create insurance policy
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/InsurancePolicyBody' }
responses:
'201':
description: Insurance policy created
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/insurance/{policyId}:
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: policyId, in: path, required: true, schema: { type: string } }
get:
tags: [Assets]
summary: Get insurance policy
responses:
'200':
description: Insurance policy fetched
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
put:
tags: [Assets]
summary: Update insurance policy
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/InsurancePolicyUpdateBody' }
responses:
'200':
description: Insurance policy updated
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }
/assets/{id}/insurance/{policyId}/renew:
patch:
tags: [Assets]
summary: Renew insurance policy
parameters:
- { name: id, in: path, required: true, schema: { type: string } }
- { name: policyId, in: path, required: true, schema: { type: string } }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/InsuranceRenewBody' }
responses:
'200':
description: Insurance renewed
content: { application/json: { schema: { $ref: '#/components/schemas/ApiResponse' } } }