From 4cf981eb659fb69b13a0fa04f78a266c61ce644d Mon Sep 17 00:00:00 2001 From: wiIliu Date: Wed, 18 Mar 2026 23:56:48 -0400 Subject: [PATCH 1/5] added pagination to get orders cmds --- orders_service/app/api/v1/health.py | 2 -- orders_service/app/api/v1/orders.py | 8 +++++--- orders_service/app/db_logic/crud.py | 11 ++++++++--- orders_service/app/schemas/order.py | 3 +++ 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/orders_service/app/api/v1/health.py b/orders_service/app/api/v1/health.py index cad2247..a370486 100644 --- a/orders_service/app/api/v1/health.py +++ b/orders_service/app/api/v1/health.py @@ -19,8 +19,6 @@ def get_health_db(db: Annotated[Session, Depends(get_db)]): try: db.execute(text("SELECT 1")) print("✅ DB connection OK") - finally: - db.close() return {"status": "OK"} @router.get("/db/orders") diff --git a/orders_service/app/api/v1/orders.py b/orders_service/app/api/v1/orders.py index a3e8805..eeb5ecd 100644 --- a/orders_service/app/api/v1/orders.py +++ b/orders_service/app/api/v1/orders.py @@ -19,9 +19,11 @@ def post_order(order : OrderCreate, db: Annotated[Session, Depends(get_db)]): @router.get("/", response_model=OrderListResponse) def get_orders(db: Annotated[Session, Depends(get_db)], name: str | None = None, - product: str | None = None): - orders = crud.get_orders(db ,name, product) - return {"items": orders} + product: str | None = None, + offset: int = 0, + limit: int = 10): + orders, total = crud.get_orders(db ,name, product, offset, limit) + return {"items": orders, "total": total, "limit": limit, "offset": offset} @router.get("/{order_id}", response_model=OrderResponse) def get_order_from_id(order_id: int, db: Annotated[Session, Depends(get_db)]) -> OrderResponse: diff --git a/orders_service/app/db_logic/crud.py b/orders_service/app/db_logic/crud.py index 0421df2..0e0775c 100644 --- a/orders_service/app/db_logic/crud.py +++ b/orders_service/app/db_logic/crud.py @@ -20,8 +20,11 @@ def get_order_by_id(db: Session, order_id: int): return db.query(Order).filter(Order.id == order_id).first() -# TODO: implement pagination -def get_orders(db: Session, name: str | None = None, product: str | None = None): +def get_orders(db: Session, + name: str | None = None, + product: str | None = None, + offset=0, + limit=10): query = db.query(Order) if name: @@ -29,7 +32,9 @@ def get_orders(db: Session, name: str | None = None, product: str | None = None) if product: query = query.filter(Order.product == product) - return query.all() + orders = query.offset(offset).limit(limit).all() + total = query.count() + return orders, total def delete_by_id(db: Session, order_id: int): diff --git a/orders_service/app/schemas/order.py b/orders_service/app/schemas/order.py index a4d7c0c..12d605a 100644 --- a/orders_service/app/schemas/order.py +++ b/orders_service/app/schemas/order.py @@ -23,6 +23,9 @@ class OrderResponse(OrderBase): class OrderListResponse(BaseModel): items: list[OrderResponse] + total: int + limit: int + offset: int class OrderUpdate(BaseModel): name: str | None = Field(default=None, min_length=2) From 3b5fb2914664c5e0c8d66c37c9fb0e383bcc99a0 Mon Sep 17 00:00:00 2001 From: wiIliu Date: Thu, 19 Mar 2026 00:16:05 -0400 Subject: [PATCH 2/5] added tests for pagination --- .../tests/unit/crud/orders_table_test.py | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/orders_service/tests/unit/crud/orders_table_test.py b/orders_service/tests/unit/crud/orders_table_test.py index 345ff2d..834902f 100644 --- a/orders_service/tests/unit/crud/orders_table_test.py +++ b/orders_service/tests/unit/crud/orders_table_test.py @@ -57,55 +57,77 @@ def test_get_order_by_id_not_found(db: Session) -> None: def test_get_orders_all(db: Session) -> None: OrderFactory.create_batch(50) - retrieved_orders = crud.get_orders(db=db) - assert len(retrieved_orders) == 50 + orders, total = crud.get_orders(db=db, limit=50) + assert len(orders) == 50 + assert total == 50 + +def test_get_orders_paginated_fetches_all(db: Session) -> None: + OrderFactory.create_batch(25) + page_size = 10 + offset = 0 + all_orders = [] + + while True: + orders, total = crud.get_orders(db, limit=page_size, offset=offset) + all_orders.extend(orders) + offset += page_size + if offset >= total: + break + + assert len(all_orders) == 25 + assert len(set(order.id for order in all_orders)) == 25 def test_get_orders_empty_db(db: Session) -> None: - retrieved_orders = crud.get_orders(db=db) - assert retrieved_orders == [] + orders, total = crud.get_orders(db=db) + assert orders == [] + assert total == 0 def test_get_orders_by_name(db: Session) -> None: target = "target_customer" OrderFactory.create_batch(15, name="buffer customer") OrderFactory.create_batch(10, name=target) - retrieved_orders = crud.get_orders(db=db, name=target) - assert len(retrieved_orders) == 10 - assert all(order.name == target for order in retrieved_orders) + orders, total = crud.get_orders(db=db, name=target) + assert len(orders) == 10 + assert total == 10 + assert all(order.name == target for order in orders) def test_get_orders_by_product(db: Session) -> None: target = "target_product" OrderFactory.create_batch(15, product="buffer product") OrderFactory.create_batch(10, product=target) - retrieved_orders = crud.get_orders(db=db, product=target) - assert len(retrieved_orders) == 10 - assert all(order.product == target for order in retrieved_orders) + orders, total = crud.get_orders(db=db, product=target) + assert len(orders) == 10 + assert total == 10 + assert all(order.product == target for order in orders) def test_get_orders_by_all_filters(db: Session) -> None: target_name = "target_customer" target_product = "target_product" - + OrderFactory.create_batch(5, name="temp customer", product="temp product") OrderFactory.create_batch(10, name=target_name, product="temp product 2") OrderFactory.create_batch(12, name="temp customer 2", product=target_product) OrderFactory.create_batch(6, name=target_name, product=target_product) - retrieved_orders = crud.get_orders(db=db, name=target_name, product=target_product) - assert len(retrieved_orders) == 6 - assert all(order.name == target_name for order in retrieved_orders) - assert all(order.product == target_product for order in retrieved_orders) + orders, total = crud.get_orders(db=db, name=target_name, product=target_product) + assert len(orders) == 6 + assert total == 6 + assert all(order.name == target_name for order in orders) + assert all(order.product == target_product for order in orders) def test_get_orders_by_filters_no_match(db: Session) -> None: target_name = "target_customer" target_product = "target_product" - + OrderFactory.create_batch(5, name="temp customer", product="temp product") OrderFactory.create_batch(10, name=target_name, product="temp product 2") OrderFactory.create_batch(12, name="temp customer 2", product=target_product) - retrieved_orders = crud.get_orders(db=db, name=target_name, product=target_product) - assert retrieved_orders == [] + orders, total = crud.get_orders(db=db, name=target_name, product=target_product) + assert orders == [] + assert total == 0 From e571bb88b157cd9e809055982f1eabfd313efa1a Mon Sep 17 00:00:00 2001 From: wiIliu Date: Thu, 19 Mar 2026 00:16:25 -0400 Subject: [PATCH 3/5] removed redundancy from health endpoint O-S --- orders_service/app/api/v1/health.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/orders_service/app/api/v1/health.py b/orders_service/app/api/v1/health.py index a370486..4c894d5 100644 --- a/orders_service/app/api/v1/health.py +++ b/orders_service/app/api/v1/health.py @@ -18,14 +18,15 @@ def get_health(): def get_health_db(db: Annotated[Session, Depends(get_db)]): try: db.execute(text("SELECT 1")) - print("✅ DB connection OK") - return {"status": "OK"} + return {"status": "OK"} + except Exception as e: + return {"status": "ERROR", "detail": str(e)} + @router.get("/db/orders") def get_health_orders(db: Annotated[Session, Depends(get_db)]): try: - r = db.execute(text("SELECT * FROM orders")).fetchall() - print("Data output: ", r) - finally: - db.close() - return {"status": "OK"} + db.execute(text("SELECT * FROM orders")).fetchall() + return {"status": "OK"} + except Exception as e: + return {"status": "ERROR", "detail": str(e)} From 26bcd38adfbfd0d34b9039c7f5fb0af266b3eaa1 Mon Sep 17 00:00:00 2001 From: wiIliu Date: Thu, 19 Mar 2026 00:18:10 -0400 Subject: [PATCH 4/5] linting --- orders_service/app/db_logic/crud.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/orders_service/app/db_logic/crud.py b/orders_service/app/db_logic/crud.py index 0e0775c..a1928f5 100644 --- a/orders_service/app/db_logic/crud.py +++ b/orders_service/app/db_logic/crud.py @@ -20,7 +20,7 @@ def get_order_by_id(db: Session, order_id: int): return db.query(Order).filter(Order.id == order_id).first() -def get_orders(db: Session, +def get_orders(db: Session, name: str | None = None, product: str | None = None, offset=0, @@ -39,7 +39,7 @@ def get_orders(db: Session, def delete_by_id(db: Session, order_id: int): try: - result = get_order_by_id(db, order_id) + result = get_order_by_id(db, order_id) if not result: return None db.delete(result) From 48632b60c128956a15de980f89388ae715b877e9 Mon Sep 17 00:00:00 2001 From: wiIliu Date: Thu, 19 Mar 2026 00:20:58 -0400 Subject: [PATCH 5/5] lint --- orders_service/tests/unit/crud/orders_table_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/orders_service/tests/unit/crud/orders_table_test.py b/orders_service/tests/unit/crud/orders_table_test.py index 834902f..0b5d1e1 100644 --- a/orders_service/tests/unit/crud/orders_table_test.py +++ b/orders_service/tests/unit/crud/orders_table_test.py @@ -1,4 +1,4 @@ -from sqlalchemy.orm import Session +from sqlalchemy.orm import Session from orders_service.app.db_logic import crud from orders_service.app.models.order import Order @@ -6,7 +6,7 @@ from orders_service.tests.factories.order_factory import OrderFactory -### CREATE TESTS ### +### CREATE TESTS ### def test_create_order(db: Session) -> None: data: Order = OrderFactory.build() new_order = OrderCreate( @@ -200,7 +200,7 @@ def test_delete_by_id(db: Session, fixture_order: Order) -> None: result = crud.delete_by_id(db, order_id=fixture_order.id) assert result assert result.id == fixture_order.id - + deleted = db.query(Order).filter(Order.id == fixture_order.id).first() assert deleted is None