Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
226175d678 |
3422
Cargo.lock
generated
Normal file
3422
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
edition = "2024"
|
||||||
|
name = "web"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
fathom-function = { git = "ssh://git@github.com/fathom-io/pipeline-calculations.git", branch = "FTHM-12741/adnoc-ingestion" }
|
||||||
|
pipeline-application = { git = "ssh://git@github.com/fathom-io/pipeline-calculations.git", branch = "FTHM-12741/adnoc-ingestion" }
|
||||||
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
|
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread"] }
|
||||||
|
uuid = { version = "1" }
|
||||||
65
README.md
65
README.md
@ -1,2 +1,65 @@
|
|||||||
# 08f878c1b6e94e1f8838ea45e762c598
|
# Creation of an ILI report
|
||||||
|
|
||||||
|
A function that will create a ILI report asset and sequence.
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
- `org_id`: as string which should be a valid `uuid` for the organization
|
||||||
|
- `project_id`: the id of the data project where the pipeline data is found
|
||||||
|
- `pipeline_id`: a `array` each item of which should be a valid uuid for a pipeline.
|
||||||
|
- `date`: a `string` formatted as an ISO date representing the date of the
|
||||||
|
inspection.
|
||||||
|
- `vendor_name`: a `string` the company who conducted the ILI inspection
|
||||||
|
- `report_type`: a `string` the type of the report possible values:
|
||||||
|
- `final`
|
||||||
|
- `preliminary`
|
||||||
|
- `inspection_type`: a `string` the type of technology used possible values:
|
||||||
|
- `mfl`
|
||||||
|
- `tfi`
|
||||||
|
- `ut`
|
||||||
|
- `emat`
|
||||||
|
- `caliper`
|
||||||
|
- `combo_mfl_and_tfi`
|
||||||
|
- `combo_mfl_and_ut`
|
||||||
|
- `combo_mfl_and_ec`
|
||||||
|
- `file_details`: a `array` of file detail objects
|
||||||
|
- `pipebody_tolerances`: an `object` representing the tolerances for the pipebody
|
||||||
|
- `haz_tolerances`: an `object` representing the tolerances for the heat affected zone (HAZ)
|
||||||
|
|
||||||
|
## Creating the function on the platform
|
||||||
|
|
||||||
|
To create this function on the platform using the `cli` set up the port forwarding as shown in README.
|
||||||
|
|
||||||
|
Then run the following command to create the function.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run functions create \
|
||||||
|
-f functions/ili_creation \
|
||||||
|
-d "Processes an ILI file and create the sequences and assets associated with that report" \
|
||||||
|
-i org_id=string \
|
||||||
|
-i project_id=string \
|
||||||
|
-i pipeline_id=string \
|
||||||
|
-i date=string \
|
||||||
|
-i vendor_name=string \
|
||||||
|
-i report_type=string \
|
||||||
|
-i inspection_type=string \
|
||||||
|
-i file_details=object \
|
||||||
|
-i pipebody_tolerances=object \
|
||||||
|
-i haz_tolerances=object
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing the function locally
|
||||||
|
|
||||||
|
You can run and test the function locally by running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can check it work with `curl` as follows
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl localhost:8080 -d $(jq '. | tojson' functions/ili_creation/example_input.json)
|
||||||
|
```
|
||||||
|
|||||||
245
example_input.json
Normal file
245
example_input.json
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
{
|
||||||
|
"date": "Fri Feb 01 2002",
|
||||||
|
"file_details": [
|
||||||
|
{
|
||||||
|
"fileId": "a2e8295f-3547-47b1-92ae-d5446b081eee",
|
||||||
|
"revisionId": "2c68f624-2e9b-4c4a-90e0-d0243bd5c541"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"haz_tolerances": {
|
||||||
|
"axial_grooving": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"axial_slotting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"circumferential_grooving": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"circumferential_slotting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pinhole": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 2
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pitting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"sensitivity": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inspection_type": "mfl",
|
||||||
|
"pipebody_tolerances": {
|
||||||
|
"axial_grooving": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.2
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 13
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"axial_slotting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.19
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"circumferential_grooving": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.13
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 13
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 15
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"circumferential_slotting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.13
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 13
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 19
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.15
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 19
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 19
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pinhole": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.2
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pitting": {
|
||||||
|
"depth": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 0.13
|
||||||
|
},
|
||||||
|
"length": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 13
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"inputType": "number",
|
||||||
|
"value": 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"org_id": "2cbfe270-d195-48ad-aed1-24145924635c",
|
||||||
|
"pipeline_id": [
|
||||||
|
"01966d47-1d4c-7751-a1f1-0617caa3a00d"
|
||||||
|
],
|
||||||
|
"project_id": "680b61b0aedd6f9e639d8699",
|
||||||
|
"report_type": "final",
|
||||||
|
"vendor_name": "ILI-Ros"
|
||||||
|
}
|
||||||
191
src/main.rs
Normal file
191
src/main.rs
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
use fathom_function::{
|
||||||
|
chrono::NaiveDate,
|
||||||
|
forms::{TableCellValue, deserialize_date},
|
||||||
|
tracing,
|
||||||
|
};
|
||||||
|
use pipeline_application::application::{
|
||||||
|
Application, DimensionClass, InlineInspection, InspectionType, ReportType,
|
||||||
|
Tolerance as ApplicationTolerance, ToleranceAdjustment, ToolTolerances,
|
||||||
|
uom::si::{f64::Length, length::millimeter},
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[fathom_function::function]
|
||||||
|
async fn ili_creation(input: Input) -> Result<Output, String> {
|
||||||
|
let reports_details = input.report_details;
|
||||||
|
let tolerances = input.tolerances;
|
||||||
|
let app = Application::new_from_compile_env(input.org_id, input.project_id).unwrap();
|
||||||
|
|
||||||
|
for (pipeline_id, file_details) in input.pipeline_id.into_iter().zip(input.file_details) {
|
||||||
|
app.process_ili_report(
|
||||||
|
pipeline_id,
|
||||||
|
file_details.file_id,
|
||||||
|
&tolerances,
|
||||||
|
&reports_details,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
tracing::error!(%pipeline_id, ?err, "Error running ili calculations");
|
||||||
|
format!("{err:?}")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
Ok(Output {
|
||||||
|
status: "Success".to_owned(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct Output {
|
||||||
|
status: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Input {
|
||||||
|
org_id: Uuid,
|
||||||
|
project_id: String,
|
||||||
|
pipeline_id: Vec<Uuid>,
|
||||||
|
file_details: Vec<FileDetails>,
|
||||||
|
#[serde(flatten)]
|
||||||
|
report_details: InspectionReportDetails,
|
||||||
|
#[serde(flatten)]
|
||||||
|
tolerances: CombineTolerances,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct CombineTolerances {
|
||||||
|
haz_tolerances: Tolerances<HazTolerance>,
|
||||||
|
pipebody_tolerances: Tolerances<Tolerance>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Tolerances<T> {
|
||||||
|
general: T,
|
||||||
|
pitting: T,
|
||||||
|
axial_grooving: T,
|
||||||
|
circumferential_grooving: T,
|
||||||
|
pinhole: T,
|
||||||
|
axial_slotting: T,
|
||||||
|
circumferential_slotting: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Tolerance {
|
||||||
|
depth: TableCellValue,
|
||||||
|
length: TableCellValue,
|
||||||
|
width: TableCellValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct HazTolerance {
|
||||||
|
sensitivity: TableCellValue,
|
||||||
|
#[serde(flatten)]
|
||||||
|
tolerance: Tolerance,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tolerance {
|
||||||
|
fn to_tolerance(&self, haz_tolerances: &HazTolerance) -> Option<ApplicationTolerance> {
|
||||||
|
Some(ApplicationTolerance::new(
|
||||||
|
Option::<f64>::try_from(&haz_tolerances.sensitivity).ok()??,
|
||||||
|
Option::<ToleranceAdjustment>::from(&haz_tolerances.tolerance)?,
|
||||||
|
Option::<ToleranceAdjustment>::from(self)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct InspectionReportDetails {
|
||||||
|
#[serde(deserialize_with = "deserialize_date")]
|
||||||
|
date: NaiveDate,
|
||||||
|
vendor_name: String,
|
||||||
|
report_type: ReportType,
|
||||||
|
/// The inspection type and technology used.
|
||||||
|
inspection_type: InspectionType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&CombineTolerances> for ToolTolerances {
|
||||||
|
fn from(value: &CombineTolerances) -> Self {
|
||||||
|
[
|
||||||
|
(
|
||||||
|
DimensionClass::General,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.general
|
||||||
|
.to_tolerance(&value.haz_tolerances.general),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::Pitting,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.pitting
|
||||||
|
.to_tolerance(&value.haz_tolerances.pitting),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::AxialGrooving,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.axial_grooving
|
||||||
|
.to_tolerance(&value.haz_tolerances.axial_grooving),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::CircumferentialGrooving,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.circumferential_grooving
|
||||||
|
.to_tolerance(&value.haz_tolerances.circumferential_grooving),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::Pinhole,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.pinhole
|
||||||
|
.to_tolerance(&value.haz_tolerances.pinhole),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::AxialSlotting,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.axial_slotting
|
||||||
|
.to_tolerance(&value.haz_tolerances.axial_slotting),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
DimensionClass::CircumferentialSlotting,
|
||||||
|
value
|
||||||
|
.pipebody_tolerances
|
||||||
|
.circumferential_slotting
|
||||||
|
.to_tolerance(&value.haz_tolerances.circumferential_slotting),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|(dc, tol)| tol.map(|tol| (dc, tol)))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Tolerance> for Option<ToleranceAdjustment> {
|
||||||
|
fn from(value: &Tolerance) -> Self {
|
||||||
|
Some(ToleranceAdjustment {
|
||||||
|
depth: Option::<f64>::try_from(&value.depth).ok()??,
|
||||||
|
width: Length::new::<millimeter>(Option::<f64>::try_from(&value.width).ok()??),
|
||||||
|
length: Length::new::<millimeter>(Option::<f64>::try_from(&value.length).ok()??),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&InspectionReportDetails> for InlineInspection {
|
||||||
|
fn from(value: &InspectionReportDetails) -> Self {
|
||||||
|
Self {
|
||||||
|
date: value.date,
|
||||||
|
vendor_name: value.vendor_name.to_owned(),
|
||||||
|
report_type: value.report_type,
|
||||||
|
inspection_type: value.inspection_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FileDetails {
|
||||||
|
pub file_id: Uuid,
|
||||||
|
pub revision_id: Uuid,
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user