Compare commits

..

No commits in common. '6128922e80f78a784583a81d11e44e13d5f4ae5b' and '760aa0229e8fc1a82dabae20937820a19590c77e' have entirely different histories.

15
Jenkinsfile vendored

@ -4,6 +4,7 @@ pipeline {
environment {
DOCKER_HUB_USERNAME = 'aimodocker'
// This creates DOCKER_AUTH_USR and DOCKER_AUTH_PSW
DOCKER_AUTH = credentials('aimodocker')
IMAGE_NAME = 'lcca-service'
SERVICE_NAME = 'ahm-app'
@ -54,6 +55,13 @@ pipeline {
// }
// }
stage('Docker Login') {
steps {
// Fixed variable names based on the 'DOCKER_AUTH' environment key
sh "echo ${DOCKER_AUTH_PSW} | docker login -u ${DOCKER_AUTH_USR} --password-stdin"
}
}
stage('Build & Tag') {
steps {
script {
@ -67,14 +75,10 @@ pipeline {
}
}
stage('Docker Login & Push') {
stage('Push to Docker Hub') {
steps {
script {
def fullImageName = "${DOCKER_HUB_USERNAME}/${IMAGE_NAME}"
withCredentials([usernamePassword(credentialsId: 'aimodocker', passwordVariable: 'DOCKER_PSW', usernameVariable: 'DOCKER_USR')]) {
// Use single quotes to prevent Groovy from interpolating the secret in logs
sh 'echo $DOCKER_PSW | docker login -u $DOCKER_USR --password-stdin'
sh "docker push ${fullImageName}:${IMAGE_TAG}"
if (SECONDARY_TAG) {
@ -84,7 +88,6 @@ pipeline {
}
}
}
}
post {
always {

@ -33,23 +33,6 @@ async def get_yeardatas(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[AcquisitionCostDataPagination])
async def get_yeardatas_export_all(
db_session: DbSession,
common: CommonParameters,
):
"""Get all acquisition_cost_data for export."""
common["all"] = True
get_acquisition_cost_data = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
)
return StandardResponse(
data=get_acquisition_cost_data,
message="All Acquisition Cost Data retrieved successfully",
)
@router.get("/{acquisition_cost_data_id}", response_model=StandardResponse[AcquisitionCostDataRead])
async def get_acquisition_cost_data(db_session: DbSession, acquisition_cost_data_id: str):

@ -34,4 +34,13 @@ class AcquisitionCostDataPagination(Pagination):
class ListQueryParams(CommonParams):
pass
items_per_page: Optional[int] = Field(
default=5,
ge=1,
le=1000,
description="Number of items per page"
)
search: Optional[str] = Field(
default=None,
description="Search keyword"
)

@ -1,5 +1,5 @@
import logging
from typing import Annotated, List, Optional
from typing import Annotated, List
from sqlalchemy import desc, func, or_, Select
from sqlalchemy_filters import apply_pagination
@ -18,11 +18,9 @@ QueryStr = constr(pattern=r"^[ -~]+$", min_length=1)
def common_parameters(
db_session: DbSession, # type: ignore
current_user: Optional[str] = Query(None, alias="currentUser"), # type: ignore
current_user_snake: Optional[str] = Query(None, alias="current_user"), # type: ignore
current_user: QueryStr = Query(None, alias="currentUser"), # type: ignore
page: int = Query(1, gt=0, lt=2147483647),
items_per_page: Optional[int] = Query(None, alias="items_per_page", gt=-2, lt=2147483647),
items_per_page_camel: Optional[int] = Query(None, alias="itemsPerPage", gt=-2, lt=2147483647),
items_per_page: int = Query(5, alias="itemsPerPage", gt=-2, lt=2147483647),
query_str: QueryStr = Query(None, alias="q"), # type: ignore
filter_spec: QueryStr = Query(None, alias="filter"), # type: ignore
sort_by: List[str] = Query([], alias="sortBy[]"),
@ -30,23 +28,15 @@ def common_parameters(
all: int = Query(0),
# role: QueryStr = Depends(get_current_role),
):
# Support both snake_case and camelCase for pagination size
final_items_per_page = items_per_page_camel if items_per_page_camel is not None else (
items_per_page if items_per_page is not None else 5
)
# Support both snake_case and camelCase for current user
final_current_user = current_user or current_user_snake
return {
"db_session": db_session,
"page": page,
"items_per_page": final_items_per_page,
"items_per_page": items_per_page,
"query_str": query_str,
"filter_spec": filter_spec,
"sort_by": sort_by,
"descending": descending,
"current_user": final_current_user,
"current_user": current_user,
# "role": role,
"all": bool(all),
}

@ -62,23 +62,6 @@ async def get_equipments(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[EquipmentPagination])
async def get_equipments_export_all(
db_session: DbSession,
common: CommonParameters,
):
"""Get all equipment for export."""
common["all"] = True
equipment_data = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
)
return StandardResponse(
data=equipment_data,
message="All Equipment Data retrieved successfully",
)
@router.get("/maximo/{assetnum}", response_model=StandardResponse[List[dict]])
@ -228,18 +211,6 @@ async def get_calculated_top_10_replacement_priorities(db_session: DbSession, co
message="Top 10 Replacement Priorities Data retrieved successfully",
)
@router.get(
"/top-10-replacement-priorities-export-all",
response_model=StandardResponse[EquipmentTop10Pagination],
)
async def get_calculated_top_10_replacement_priorities_all(db_session: DbSession, common: CommonParameters):
common["all"] = True
equipment_data = await get_top_10_replacement_priorities(db_session=db_session, common=common)
return StandardResponse(
data=equipment_data,
message="All Replacement Priorities Data retrieved successfully",
)
@router.get(
"/top-10-economic-life",
response_model=StandardResponse[EquipmentTop10Pagination],
@ -253,18 +224,6 @@ async def get_calculated_top_10_economic_life(db_session: DbSession, common: Com
message="Top 10 Economic Life Data retrieved successfully",
)
@router.get(
"/top-10-economic-life-export-all",
response_model=StandardResponse[EquipmentTop10Pagination],
)
async def get_calculated_top_10_economic_life_all(db_session: DbSession, common: CommonParameters):
common["all"] = True
equipment_data = await get_top_10_economic_life(db_session=db_session, common=common)
return StandardResponse(
data=equipment_data,
message="All Economic Life Data retrieved successfully",
)
@router.get("/tree", response_model=StandardResponse[EquipmentRead])
async def get_equipment_tree():

@ -34,17 +34,9 @@ class EquipmentBase(DefaultBase):
updated_by: Optional[str] = Field(None)
class EquipmentMasterBase(DefaultBase):
id: Optional[UUID] = Field(None)
name: Optional[str] = Field(None)
parent_id: Optional[UUID] = Field(None)
equipment_tree_id: Optional[UUID] = Field(None)
category_id: Optional[UUID] = Field(None)
system_tag: Optional[str] = Field(None)
assetnum: Optional[str] = Field(None)
location_tag: Optional[str] = Field(None)
image_name: Optional[str] = Field(None)
description: Optional[str] = Field(None)
assetnum: Optional[str] = Field(None)
name: Optional[str] = Field(None)
class MasterBase(DefaultBase):
assetnum: Optional[str] = Field(None)
@ -170,5 +162,15 @@ class CountRemainingLifeResponse(DefaultBase):
critical: int
class ListQueryParams(CommonParams):
pass
items_per_page: Optional[int] = Field(
default=5,
ge=1,
le=1000,
description="Number of items per page",
alias="itemsPerPage"
)
search: Optional[str] = Field(
default=None,
description="Search keyword"
)

@ -31,8 +31,7 @@ class EquipmentMaster(Base, DefaultMixin):
system_tag = Column(String, nullable=True)
assetnum = Column(String, nullable=True)
location_tag = Column(String, nullable=True)
image_name = Column(String, nullable=True)
description = Column(String, nullable=True)
# Relationship definitions
# Define both sides of the relationship
# parent = relationship(

@ -28,21 +28,6 @@ async def get_all_equipment_master_tree(
data=equipment_masters, message="Data retrieved successfully"
)
@router.get("/export-all", response_model=StandardResponse[EquipmentMasterPaginated])
async def get_all_equipment_master_tree_export_all(
db_session: DbSession,
common: CommonParameters,
):
common["all"] = True
equipment_masters = await get_all_master(
db_session=db_session,
common=common,
)
return StandardResponse(
data=equipment_masters, message="All Equipment Master Data retrieved successfully"
)
@router.get(
"/{equipment_master_id}", response_model=StandardResponse[EquipmentMasterRead]

@ -46,4 +46,5 @@ class EquipmentMasterPaginated(Pagination):
class EquipmentMasterQuery(CommonParams):
parent_id : Optional[str] = None
items_per_page : Optional[int] = 5
search : Optional[str] = None

@ -32,23 +32,6 @@ async def get_yeardatas(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[ManpowerCostPagination])
async def get_yeardatas_export_all(
db_session: DbSession,
common: CommonParameters,
):
"""Get all manpower_cost_data for export."""
common["all"] = True
get_acquisition_cost_data = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
)
return StandardResponse(
data=get_acquisition_cost_data,
message="All Manpower Cost Data retrieved successfully",
)
@router.get("/{acquisition_cost_data_id}", response_model=StandardResponse[ManpowerCostRead])
async def get_acquisition_cost_data(db_session: DbSession, acquisition_cost_data_id: str):

@ -34,4 +34,5 @@ class ManpowerCostPagination(Pagination):
class QueryParams(CommonParams):
pass
items_per_page: Optional[int] = Field(5)
search: Optional[str] = Field(None)

@ -32,23 +32,6 @@ async def get_yeardatas(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[ManpowerCostPagination])
async def get_yeardatas_export_all(
db_session: DbSession,
common: CommonParameters,
):
"""Get all manpower_master_data for export."""
common["all"] = True
get_acquisition_cost_data = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
)
return StandardResponse(
data=get_acquisition_cost_data,
message="All Manpower Master Data retrieved successfully",
)
@router.get("/{acquisition_cost_data_id}", response_model=StandardResponse[ManpowerCostRead])
async def get_acquisition_cost_data(db_session: DbSession, acquisition_cost_data_id: str):

@ -33,4 +33,5 @@ class ManpowerCostPagination(Pagination):
items: List[ManpowerCostRead] = []
class QueryParams(CommonParams):
items_per_page: Optional[int] = Field(5)
search: Optional[str] = Field(None)

@ -1,9 +1,9 @@
from typing import Annotated, Optional, List
from fastapi import APIRouter, HTTPException, status, Query, Depends
from fastapi import APIRouter, HTTPException, status, Query
from sqlalchemy import Select
from .schema import QueryParams
from src.manpower_cost.schema import QueryParams
from .model import MasterData
from .schema import (
MasterDataPagination,
@ -25,7 +25,7 @@ router = APIRouter()
async def get_masterdatas(
db_session: DbSession,
common: CommonParameters,
params: Annotated[QueryParams, Depends()],
params: Annotated[QueryParams, Query()],
):
"""Get all documents."""
# return
@ -40,23 +40,6 @@ async def get_masterdatas(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[MasterDataPagination])
async def get_masterdatas_export_all(
db_session: DbSession,
common: CommonParameters,
):
"""Get all documents for export."""
common["all"] = True
master_datas = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
)
return StandardResponse(
data=master_datas,
message="All Master Data retrieved successfully",
)
@router.get("/{masterdata_id}", response_model=StandardResponse[MasterDataRead])
async def get_masterdata(db_session: DbSession, masterdata_id: str):

@ -2,8 +2,8 @@ from datetime import datetime
from typing import List, Optional
from uuid import UUID
from pydantic import BaseModel, Field, model_validator
from src.models import CommonParams, DefaultBase, Pagination
from pydantic import BaseModel, Field
from src.models import DefaultBase, Pagination
from src.auth.service import CurrentUser
@ -52,5 +52,13 @@ class MasterDataPagination(Pagination):
items: List[MasterDataRead] = []
class QueryParams(CommonParams):
pass
class QueryParams(BaseModel):
items_per_page: Optional[int] = Field(
5,
ge=1,
description="Items per page"
)
search: Optional[str] = Field(
None,
description="Search keyword"
)

@ -45,3 +45,9 @@ class QueryParams(CommonParams):
...,
description="Simulation identifier",
)
items_per_page: Optional[int] = Field(
5,
ge=1,
description="Items per page"
)
search: Optional[str] = Field(None)

@ -14,37 +14,6 @@ ALLOWED_MULTI_PARAMS = {
"exclude[]",
}
# Whitelist of ALL allowed query parameter names across the application.
# Any param NOT in this set will be rejected.
ALLOWED_QUERY_PARAMS = {
# CommonParameters (from database/service.py common_parameters)
"currentUser",
"page",
"itemsPerPage",
"q",
"filter",
"sortBy[]",
"descending[]",
"all",
# ListQueryParams / QueryParams used across routers
"items_per_page",
"search",
# equipment_master specific
"parent_id",
# masterdata_simulations / plant_transaction_data_simulations specific
"simulation_id",
# exclude
"exclude[]",
}
# Query params that are ONLY allowed for "write" operations (read operations use ALLOWED_QUERY_PARAMS).
# For GET/POST/PUT/etc, whitelisting still applies.
WRITE_METHOD_ALLOWED_PARAMS = {
# Only auth/session params are allowed in query for write methods.
# Data values (like simulation_id) must be in the JSON body for these methods.
"currentUser",
}
MAX_QUERY_PARAMS = 50
MAX_QUERY_LENGTH = 2000
MAX_JSON_BODY_SIZE = 1024 * 100 # 100 KB
@ -93,31 +62,31 @@ def has_control_chars(value: str) -> bool:
def inspect_value(value: str, source: str):
if XSS_PATTERN.search(value):
raise HTTPException(
status_code=422,
status_code=400,
detail=f"Potential XSS payload detected in {source}",
)
if SQLI_PATTERN.search(value):
raise HTTPException(
status_code=422,
status_code=400,
detail=f"Potential SQL injection payload detected in {source}",
)
if RCE_PATTERN.search(value):
raise HTTPException(
status_code=422,
status_code=400,
detail=f"Potential RCE payload detected in {source}",
)
if TRAVERSAL_PATTERN.search(value):
raise HTTPException(
status_code=422,
status_code=400,
detail=f"Potential Path Traversal payload detected in {source}",
)
if has_control_chars(value):
raise HTTPException(
status_code=422,
status_code=400,
detail=f"Invalid control characters detected in {source}",
)
@ -127,7 +96,7 @@ def inspect_json(obj, path="body"):
for key, value in obj.items():
if key in FORBIDDEN_JSON_KEYS:
raise HTTPException(
status_code=422,
status_code=400,
detail=f"Forbidden JSON key detected: {path}.{key}",
)
inspect_json(value, f"{path}.{key}")
@ -157,28 +126,12 @@ class RequestValidationMiddleware(BaseHTTPMiddleware):
if len(params) > MAX_QUERY_PARAMS:
raise HTTPException(
status_code=422,
status_code=400,
detail="Too many query parameters",
)
# -------------------------
# 2. Query param whitelist
# -------------------------
# For GET, we allow data parameters like page, search, etc.
# For POST, PUT, DELETE, PATCH, we ONLY allow auth/session params.
active_whitelist = ALLOWED_QUERY_PARAMS if request.method == "GET" else WRITE_METHOD_ALLOWED_PARAMS
unknown_params = [
key for key, _ in params if key not in active_whitelist
]
if unknown_params:
raise HTTPException(
status_code=422,
detail=f"Unknown query parameters are not allowed for {request.method} request: {unknown_params}",
)
# -------------------------
# 3. Duplicate parameters
# 2. Duplicate parameters
# -------------------------
counter = Counter(key for key, _ in params)
duplicates = [
@ -188,48 +141,12 @@ class RequestValidationMiddleware(BaseHTTPMiddleware):
if duplicates:
raise HTTPException(
status_code=422,
status_code=400,
detail=f"Duplicate query parameters are not allowed: {duplicates}",
)
# -------------------------
# 4. JSON body inspection & Single source enforcement
# Ensuring data comes from ONLY one source (Query OR Body).
# -------------------------
content_type = request.headers.get("content-type", "")
has_json_header = content_type.startswith("application/json")
# Read body now so we can check if it's actually empty
body = b""
if has_json_header:
body = await request.body()
# We consider it a "JSON body" source ONLY if it's not empty and not just "{}"
has_actual_json_body = has_json_header and body and body.strip() != b"{}"
# Check for data parameters in query (anything whitelisted as 'data' but not 'session/auth')
data_params_in_query = [
key for key, _ in params
if key in ALLOWED_QUERY_PARAMS and key not in WRITE_METHOD_ALLOWED_PARAMS
]
if has_actual_json_body:
# If sending actual JSON body, we forbid any data in query string (one source only)
if data_params_in_query:
raise HTTPException(
status_code=422,
detail=f"Single source enforcement: Data received from both JSON body and query string ({data_params_in_query}). Use only one source.",
)
# Special case: GET with actual body is discouraged/forbidden
if request.method == "GET":
raise HTTPException(
status_code=422,
detail="GET requests must use query parameters, not JSON body.",
)
# -------------------------
# 5. Query param inspection
# 3. Query param inspection
# -------------------------
pagination_size_keys = {"size", "itemsPerPage", "per_page", "limit", "items_per_page"}
for key, value in params:
@ -241,24 +158,16 @@ class RequestValidationMiddleware(BaseHTTPMiddleware):
try:
size_val = int(value)
if size_val > 50:
raise HTTPException(
status_code=422,
detail=f"Pagination size '{key}' cannot exceed 50",
)
raise HTTPException(status_code=400, detail=f"Pagination size '{key}' cannot exceed 50")
if size_val % 5 != 0:
raise HTTPException(
status_code=422,
detail=f"Pagination size '{key}' must be a multiple of 5",
)
raise HTTPException(status_code=400, detail=f"Pagination size '{key}' must be a multiple of 5")
except ValueError:
raise HTTPException(
status_code=422,
detail=f"Pagination size '{key}' must be an integer",
)
raise HTTPException(status_code=400, detail=f"Pagination size '{key}' must be an integer")
# -------------------------
# 6. Content-Type sanity
# 4. Content-Type sanity
# -------------------------
content_type = request.headers.get("content-type", "")
if content_type and not any(
content_type.startswith(t)
for t in (
@ -273,22 +182,32 @@ class RequestValidationMiddleware(BaseHTTPMiddleware):
)
# -------------------------
# 7. JSON body inspection & Re-injection
# 5. JSON body inspection
# -------------------------
if has_json_header:
if content_type.startswith("application/json"):
body = await request.body()
#if len(body) > MAX_JSON_BODY_SIZE:
# raise HTTPException(
# status_code=413,
# detail="JSON body too large",
# )
if body:
try:
payload = json.loads(body)
except json.JSONDecodeError:
raise HTTPException(
status_code=422,
status_code=400,
detail="Invalid JSON body",
)
inspect_json(payload)
# Re-inject body for downstream handlers
async def receive():
return {"type": "http.request", "body": body}
request._receive = receive # noqa: protected-access
return await call_next(request)

@ -2,7 +2,7 @@
from datetime import datetime
from typing import Generic, List, Optional, TypeVar
import uuid
from pydantic import BaseModel, Field, SecretStr, ConfigDict, model_validator
from pydantic import BaseModel, Field, SecretStr, ConfigDict
from sqlalchemy import Column, DateTime, String, func, event
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import Mapped, mapped_column
@ -100,29 +100,16 @@ class StandardResponse(BaseModel, Generic[T]):
class CommonParams(DefaultBase):
# This ensures no extra query params are allowed
current_user: Optional[str] = Field(None, alias="current_user")
currentUser: Optional[str] = Field(None, description="Alias for current_user")
current_user: Optional[str] = Field(None, alias="currentUser")
page: int = Field(1, gt=0, lt=2147483647)
items_per_page: int = Field(5, gt=-2, lt=2147483647, alias="items_per_page")
itemsPerPage: Optional[int] = Field(None, description="Alias for items_per_page")
items_per_page: int = Field(5, gt=-2, lt=2147483647, alias="itemsPerPage")
query_str: Optional[str] = Field(None, alias="q")
search: Optional[str] = Field(None, description="Search keyword")
filter_spec: Optional[str] = Field(None, alias="filter")
sort_by: List[str] = Field(default=[], alias="sortBy[]")
descending: List[bool] = Field(default=[], alias="descending[]")
exclude: List[str] = Field(default=[], alias="exclude[]")
sort_by: List[str] = Field(default_factory=list, alias="sortBy[]")
descending: List[bool] = Field(default_factory=list, alias="descending[]")
exclude: List[str] = Field(default_factory=list, alias="exclude[]")
all_params: int = Field(0, alias="all")
@model_validator(mode="before")
@classmethod
def resolve_aliases(cls, data: any) -> any:
if isinstance(data, dict):
if "itemsPerPage" in data and data["itemsPerPage"] is not None:
data.setdefault("items_per_page", data["itemsPerPage"])
if "currentUser" in data and data["currentUser"] is not None:
data.setdefault("current_user", data["currentUser"])
return data
# Property to mirror your original return dict's bool conversion
@property
def is_all(self) -> bool:

@ -1,4 +1,4 @@
from typing import Annotated, List, Optional
from typing import List, Optional
from uuid import UUID
from fastapi import APIRouter, HTTPException, Query, status
@ -16,7 +16,6 @@ from .schema import (
PlantFSTransactionDataRead,
PlantFSTransactionDataUpdate,
PlantFSChartData,
ListQueryParams,
)
from .service import create, delete, get, get_all, update, update_fs_charts_from_matrix, get_charts
@ -29,14 +28,15 @@ router = APIRouter()
async def list_fs_transactions(
db_session: DbSession,
common: CommonParameters,
params: Annotated[ListQueryParams, Query()],
items_per_page: Optional[int] = Query(5),
search: Optional[str] = Query(None),
):
"""Return paginated financial statement transaction data."""
records = await get_all(
db_session=db_session,
items_per_page=params.items_per_page,
search=params.search,
items_per_page=items_per_page,
search=search,
common=common,
)
@ -166,3 +166,8 @@ async def delete_fs_transaction(
await delete(db_session=db_session, fs_transaction_id=str(fs_transaction_id))
return StandardResponse(data=record, message="Data deleted successfully")

@ -4,7 +4,7 @@ from uuid import UUID
from pydantic import Field
from src.models import CommonParams, DefaultBase, Pagination
from src.models import DefaultBase, Pagination
class PlantFSTransactionDataBase(DefaultBase):
@ -100,11 +100,3 @@ class PlantFSChartData(DefaultBase):
bep_year: Optional[int] = Field(None, ge=0, le=9999)
bep_total_lcc: Optional[float] = Field(None, ge=0, le=1_000_000_000_000_000)
class ListQueryParams(CommonParams):
search: Optional[str] = Field(
default=None,
description="Search keyword",
)

@ -1,4 +1,4 @@
from typing import Annotated, Optional
from typing import Optional
from fastapi import APIRouter, HTTPException, status, Query
from .model import PlantMasterData
@ -7,7 +7,6 @@ from .schema import (
PlantMasterDataRead,
PlantMasterDataCreate,
PlantMasterDataUpdate,
ListQueryParams,
)
from .service import get, get_all, create, update, delete
@ -23,14 +22,15 @@ router = APIRouter()
async def get_masterdatas(
db_session: DbSession,
common: CommonParameters,
params: Annotated[ListQueryParams, Query()],
items_per_page: Optional[int] = Query(5),
search: Optional[str] = Query(None),
):
"""Get all documents."""
# return
master_datas = await get_all(
db_session=db_session,
items_per_page=params.items_per_page,
search=params.search,
items_per_page=items_per_page,
search=search,
common=common,
)
return StandardResponse(
@ -38,23 +38,6 @@ async def get_masterdatas(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[PlantMasterDataPagination])
async def get_masterdatas_export_all(
db_session: DbSession,
common: CommonParameters,
):
"""Get all documents for export."""
common["all"] = True
master_datas = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
)
return StandardResponse(
data=master_datas,
message="All Plant Master Data retrieved successfully",
)
@router.get("/{masterdata_id}", response_model=StandardResponse[PlantMasterDataRead])
async def get_masterdata(db_session: DbSession, masterdata_id: str):

@ -3,7 +3,7 @@ from typing import List, Optional
from uuid import UUID
from pydantic import Field
from src.models import CommonParams, DefaultBase, Pagination
from src.models import DefaultBase, Pagination
from src.auth.service import CurrentUser
@ -85,11 +85,3 @@ class PlantMasterDataRead(PlantMasterdataBase):
class PlantMasterDataPagination(Pagination):
items: List[PlantMasterDataRead] = []
class ListQueryParams(CommonParams):
search: Optional[str] = Field(
default=None,
description="Search keyword",
)

@ -1,4 +1,4 @@
from typing import Annotated, List, Optional
from typing import List, Optional
from fastapi import APIRouter, HTTPException, status, Query
from .model import PlantTransactionData
@ -10,7 +10,6 @@ from .schema import (
PlantTransactionDataCreate,
PlantTransactionDataUpdate,
PlantTransactionFSImport,
ListQueryParams,
)
from .service import (
get,
@ -34,13 +33,14 @@ router = APIRouter()
async def get_transaction_datas(
db_session: DbSession,
common: CommonParameters,
params: Annotated[ListQueryParams, Query()],
items_per_page: Optional[int] = Query(5),
search: Optional[str] = Query(None),
):
"""Get all transaction_data pagination."""
plant_transaction_data = await get_all(
db_session=db_session,
items_per_page=params.items_per_page,
search=params.search,
items_per_page=items_per_page,
search=search,
common=common,
)
# return
@ -49,23 +49,6 @@ async def get_transaction_datas(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[PlantTransactionDataPagination])
async def get_transaction_datas_export_all(
db_session: DbSession,
common: CommonParameters,
):
"""Get all transaction_data for export."""
common["all"] = True
plant_transaction_data = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
)
return StandardResponse(
data=plant_transaction_data,
message="All Plant Transaction Data retrieved successfully",
)
@router.get("/charts", response_model=StandardResponse[PlantChartData])
async def get_chart_data(db_session: DbSession, common: CommonParameters):
chart_data, bep_year, bep_total_lcc = await get_charts(

@ -3,7 +3,7 @@ from typing import Any, List, Optional
from uuid import UUID
from pydantic import Field
from src.models import CommonParams, DefaultBase, Pagination
from src.models import DefaultBase, Pagination
class PlantTransactionDataBase(DefaultBase):
@ -117,8 +117,3 @@ class PlantTransactionDataRead(PlantTransactionDataBase):
class PlantTransactionDataPagination(Pagination):
items: List[PlantTransactionDataRead] = []
class ListQueryParams(CommonParams):
pass

@ -1,4 +1,4 @@
from typing import Annotated, List, Optional
from typing import List, Optional
from uuid import UUID
from fastapi import APIRouter, HTTPException, status, Query
@ -11,7 +11,6 @@ from src.plant_transaction_data_simulations.schema import (
PlantTransactionDataSimulationsCreate,
PlantTransactionDataSimulationsUpdate,
PlantTransactionFSImportSimulations,
ListQueryParams,
)
from src.plant_transaction_data_simulations.service import (
get,
@ -35,15 +34,17 @@ router = APIRouter()
async def get_transaction_datas(
db_session: DbSession,
common: CommonParameters,
params: Annotated[ListQueryParams, Query()],
simulation_id: UUID = Query(..., description="Simulation identifier"),
items_per_page: Optional[int] = Query(5),
search: Optional[str] = Query(None),
):
"""Get all transaction_data pagination."""
plant_transaction_data = await get_all(
db_session=db_session,
items_per_page=params.items_per_page,
search=params.search,
items_per_page=items_per_page,
search=search,
common=common,
simulation_id=params.simulation_id,
simulation_id=simulation_id,
)
# return
return StandardResponse(
@ -51,25 +52,6 @@ async def get_transaction_datas(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[PlantTransactionDataSimulationsPagination])
async def get_transaction_datas_export_all(
db_session: DbSession,
common: CommonParameters,
simulation_id: UUID = Query(..., description="Simulation identifier"),
):
"""Get all transaction_data for export."""
common["all"] = True
plant_transaction_data = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
simulation_id=simulation_id,
)
return StandardResponse(
data=plant_transaction_data,
message="All Plant Transaction Data Simulations retrieved successfully",
)
@router.get("/charts", response_model=StandardResponse[PlantChartDataSimulations])
async def get_chart_data(
db_session: DbSession,

@ -3,7 +3,7 @@ from typing import Any, List, Optional
from uuid import UUID
from pydantic import Field
from src.models import CommonParams, DefaultBase, Pagination
from src.models import DefaultBase, Pagination
class PlantTransactionDataSimulationsBase(DefaultBase):
@ -140,11 +140,3 @@ class PlantTransactionDataSimulationsRead(PlantTransactionDataSimulationsBase):
class PlantTransactionDataSimulationsPagination(Pagination):
items: List[PlantTransactionDataSimulationsRead] = []
class ListQueryParams(CommonParams):
simulation_id: UUID = Field(
...,
description="Simulation identifier",
)

@ -1,4 +1,4 @@
from typing import Annotated, Optional
from typing import Optional
from fastapi import APIRouter, HTTPException, Query, status
@ -13,7 +13,6 @@ from src.simulations.schema import (
SimulationRead,
SimulationRunPayload,
SimulationUpdate,
ListQueryParams,
)
from src.simulations.service import create, delete, get, get_all, run_simulation, update
@ -25,33 +24,18 @@ async def get_simulations(
db_session: DbSession,
common: CommonParameters,
current_user: CurrentUser,
params: Annotated[ListQueryParams, Query()],
items_per_page: Optional[int] = Query(5),
search: Optional[str] = Query(None),
):
simulations = await get_all(
db_session=db_session,
items_per_page=params.items_per_page,
search=params.search,
items_per_page=items_per_page,
search=search,
common=common,
owner=current_user.name,
)
return StandardResponse(data=simulations, message="Data retrieved successfully")
@router.get("/export-all", response_model=StandardResponse[SimulationPagination])
async def get_simulations_export_all(
db_session: DbSession,
common: CommonParameters,
current_user: CurrentUser,
):
"""Get all simulations for export."""
common["all"] = True
simulations = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
owner=current_user.name,
)
return StandardResponse(data=simulations, message="All Simulations Data retrieved successfully")
@router.get("/{simulation_id}", response_model=StandardResponse[SimulationRead])
async def get_simulation(

@ -4,7 +4,7 @@ from uuid import UUID
from pydantic import Field
from src.models import CommonParams, DefaultBase, Pagination
from src.models import DefaultBase, Pagination
from src.masterdata_simulations.schema import MasterDataSimulationRead
from src.plant_transaction_data_simulations.schema import (
PlantTransactionDataSimulationsRead,
@ -51,11 +51,3 @@ class MasterDataOverride(DefaultBase):
class SimulationRunPayload(DefaultBase):
label: Optional[str] = Field(None)
overrides: List[MasterDataOverride] = Field(default_factory=list)
class ListQueryParams(CommonParams):
search: Optional[str] = Field(
default=None,
description="Search keyword",
)

@ -1,8 +1,8 @@
from typing import Annotated, Optional
from typing import Optional
from fastapi import APIRouter, Form, HTTPException, status, Query, UploadFile, File
from .model import UploadedFileData
from src.uploaded_file.schema import UploadedFileDataCreate, UploadedFileDataUpdate, UploadedFileDataRead, UploadedFileDataPagination, ListQueryParams
from src.uploaded_file.schema import UploadedFileDataCreate, UploadedFileDataUpdate, UploadedFileDataRead, UploadedFileDataPagination
from src.uploaded_file.service import get, get_all, create, update, delete
from src.database.service import CommonParameters, search_filter_sort_paginate
@ -20,13 +20,14 @@ router = APIRouter()
async def get_uploaded_files(
db_session: DbSession,
common: CommonParameters,
params: Annotated[ListQueryParams, Query()],
items_per_page: Optional[int] = Query(5),
search: Optional[str] = Query(None),
):
"""Get all uploaded files pagination."""
uploaded_files = await get_all(
db_session=db_session,
items_per_page=params.items_per_page,
search=params.search,
items_per_page=items_per_page,
search=search,
common=common,
)
# return
@ -35,23 +36,6 @@ async def get_uploaded_files(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[UploadedFileDataPagination])
async def get_uploaded_files_export_all(
db_session: DbSession,
common: CommonParameters,
):
"""Get all uploaded files for export."""
common["all"] = True
uploaded_files = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
)
return StandardResponse(
data=uploaded_files,
message="All Uploaded Files Data retrieved successfully",
)
@router.get("/{uploaded_file_id}", response_model=StandardResponse[UploadedFileDataRead])
async def get_uploaded_file(db_session: DbSession, uploaded_file_id: str):

@ -3,7 +3,7 @@ from typing import List, Optional
from uuid import UUID
from pydantic import Field
from src.models import CommonParams, DefaultBase, Pagination
from src.models import DefaultBase, Pagination
class UploadedFileDataBase(DefaultBase):
filename: str = Field(...)
@ -28,7 +28,3 @@ class UploadedFileDataRead(UploadedFileDataBase):
class UploadedFileDataPagination(Pagination):
items: List[UploadedFileDataRead] = []
class ListQueryParams(CommonParams):
pass

@ -1,8 +1,8 @@
from typing import Annotated, Optional
from typing import Optional
from fastapi import APIRouter, HTTPException, status, Query
from .model import Yeardata
from .schema import YeardataPagination, YeardataRead, YeardataCreate, YeardataUpdate, ListQueryParams
from .schema import YeardataPagination, YeardataRead, YeardataCreate, YeardataUpdate
from .service import get, get_all, create, update, delete
from src.database.service import CommonParameters, search_filter_sort_paginate
@ -17,13 +17,14 @@ router = APIRouter()
async def get_yeardatas(
db_session: DbSession,
common: CommonParameters,
params: Annotated[ListQueryParams, Query()],
items_per_page: Optional[int] = Query(5),
search: Optional[str] = Query(None),
):
"""Get all yeardata pagination."""
year_data = await get_all(
db_session=db_session,
items_per_page=params.items_per_page,
search=params.search,
items_per_page=items_per_page,
search=search,
common=common,
)
# return
@ -32,23 +33,6 @@ async def get_yeardatas(
message="Data retrieved successfully",
)
@router.get("/export-all", response_model=StandardResponse[YeardataPagination])
async def get_yeardatas_export_all(
db_session: DbSession,
common: CommonParameters,
):
"""Get all yeardata for export."""
common["all"] = True
year_data = await get_all(
db_session=db_session,
items_per_page=-1,
common=common,
)
return StandardResponse(
data=year_data,
message="All Year Data retrieved successfully",
)
@router.get("/{yeardata_id}", response_model=StandardResponse[YeardataRead])
async def get_yeardata(db_session: DbSession, yeardata_id: str):

@ -3,7 +3,7 @@ from typing import List, Optional
from uuid import UUID
from pydantic import Field, field_validator
from src.models import CommonParams, DefaultBase, Pagination
from src.models import DefaultBase, Pagination
class YeardataBase(DefaultBase):
@ -61,8 +61,3 @@ class YeardataRead(YeardataBase):
class YeardataPagination(Pagination):
items: List[YeardataRead] = []
class ListQueryParams(CommonParams):
pass

Loading…
Cancel
Save