Skip to content

feat: Implement middleware management controllers#199

Open
keshxvdayal wants to merge 9 commits into
devfrom
features/controller-implementation
Open

feat: Implement middleware management controllers#199
keshxvdayal wants to merge 9 commits into
devfrom
features/controller-implementation

Conversation

@keshxvdayal

@keshxvdayal keshxvdayal commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Detailed Implementation Plan

  1. Create Middleware Controller Module
    Implement pro_tes.api.middlewares.controllers to serve the middleware management API expected by FOCA/Connexion.

  2. Add Endpoint Handlers
    Implement handlers for:

    • GET /middlewares - List configured middlewares
    • POST /middlewares - Add a new middleware
    • GET /middlewares/{middleware_id} - Get middleware details
    • PATCH /middlewares/{middleware_id} - Update middleware configuration
    • DELETE /middlewares/{middleware_id} - Remove middleware
    • PUT /middlewares/reorder - Reorder the middleware stack
  3. Connect to FOCA Database Configuration
    Use the existing FOCA database wiring in config.yaml so the controller layer reads and writes from the taskStore.middlewares collection.

  4. Implement API Behavior
    Add the required runtime behavior for:

    • middleware creation with execution order assignment
    • partial updates for name/config fields
    • deletion by middleware ID
    • full stack reordering with ordered IDs
    • response shaping with API-friendly id fields
  5. Add Unit Tests
    Create controller tests using mongomock to validate:

    • create
    • list
    • get
    • update
    • delete
    • reorder
  6. Validate the Implementation
    Run the middleware controller test suite to confirm the controller layer works as expected.

  7. Document the Completion
    Add a short status note to the middleware docs so the API documentation reflects that subtask 2 is implemented and verified.

Summary by Sourcery

Implement controller layer and routing for middleware management APIs backed by the taskStore.middlewares collection.

New Features:

  • Expose CRUD and reordering endpoints for middlewares, including listing with pagination, creation with automatic ordering, retrieval by ID, partial updates, deletion, and stack reordering.

Enhancements:

  • Add a middleware API package and wire the controller module into the existing OpenAPI/FOCA configuration for runtime use.

Documentation:

  • Update middleware documentation with implementation status, code locations, and test command for the controller layer.

Tests:

  • Add unit tests for the middleware controllers covering list, create, get, update, delete, and reorder behaviors.

Copilot AI review requested due to automatic review settings June 18, 2026 02:45
@sourcery-ai

sourcery-ai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements a new middleware management controller layer backed by the FOCA MongoDB config, exposing CRUD and reordering endpoints plus basic pagination/sorting, and documents its implementation status.

Sequence diagram for ReorderMiddlewares runtime flow

sequenceDiagram
    actor Client
    participant Connexion
    participant Controllers as ReorderMiddlewares
    participant FlaskApp as current_app
    participant FOCA as foca_db
    participant Mongo as middlewares_collection

    Client->>Connexion: PUT /middlewares/reorder
    Connexion->>Controllers: ReorderMiddlewares(body)
    Controllers->>FlaskApp: _collection()
    FlaskApp->>FOCA: config.foca.db.dbs[taskStore]
    FOCA->>Mongo: collections[middlewares]
    Mongo-->>Controllers: collection_client

    Controllers->>Mongo: find({}, {_id})
    Mongo-->>Controllers: existing_ids
    Controllers-->>Controllers: [validate ordered_ids]

    loop for each id in ordered_ids
        Controllers->>Mongo: update_one({_id: oid}, {$set: {order, updated_at}})
        Controllers->>Mongo: find_one({_id: oid}, projection)
        Mongo-->>Controllers: middleware_doc
        Controllers-->>Controllers: _doc_to_response(middleware_doc)
    end

    Controllers-->>Connexion: {message, middlewares}
    Connexion-->>Client: 200 OK + body
Loading

File-Level Changes

Change Details Files
Introduce middleware controller module implementing CRUD, pagination, filtering, and reordering operations on the middlewares collection.
  • Add a private helper to access the FOCA-configured taskStore.middlewares collection from Flask current_app.
  • Normalize MongoDB documents to API responses by stripping _id and exposing it as string id.
  • Implement ListMiddlewares with optional source filtering, configurable sort field/order, and page/page_size validation plus pagination metadata.
  • Implement AddMiddleware to append a middleware at the end of the stack, computing order as max(existing)+1 and setting RFC3339 created_at/updated_at timestamps.
  • Implement GetMiddleware with ObjectId validation and NotFound handling.
  • Implement UpdateMiddleware to partially update only name and config, refreshing updated_at, and returning the updated document.
  • Implement DeleteMiddleware that validates the ID, deletes the document, and returns an empty body with HTTP 204 semantics.
  • Implement ReorderMiddlewares which validates that the provided ordered IDs set matches existing IDs, updates order and updated_at in bulk, and returns the reordered list.
pro_tes/api/middlewares/controllers.py
Create middleware API package and document that the controller layer is implemented and wired through OpenAPI/FOCA.
  • Add pro_tes.api.middlewares package with an __all__ re-export of the controllers module to support the x-openapi-router-controller reference.
  • Extend middleware documentation with an implementation status section pointing to the controller module, config wiring, and associated unit test command.
pro_tes/api/middlewares/__init__.py
docs/middleware.md

Possibly linked issues

  • #feat: Implement Controllers for Middleware Management API: PR implements the middleware management controllers, wiring, and tests described in the issue, though some validations remain pending.
  • #Dynamic Middleware Management API Implementation: The PR implements the middleware management API, persistence, and behavior exactly as requested in the issue.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In ListMiddlewares, consider validating sort_by and sort_order against a small allowlist of supported fields/directions so a bad query parameter doesn’t propagate as an unhandled database error.
  • In ReorderMiddlewares, the implementation performs one update_one and one find_one per middleware; you could reduce this N+1 pattern by using a bulk update and then a single sorted query to return the updated middlewares in the new order.
  • The timestamp formatting logic (datetime.now(...).replace(...).isoformat().replace(...)) is duplicated in several functions; extracting a small helper (e.g., utc_now_iso()) would make the code easier to maintain and avoid inconsistencies.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `ListMiddlewares`, consider validating `sort_by` and `sort_order` against a small allowlist of supported fields/directions so a bad query parameter doesn’t propagate as an unhandled database error.
- In `ReorderMiddlewares`, the implementation performs one `update_one` and one `find_one` per middleware; you could reduce this N+1 pattern by using a bulk update and then a single sorted query to return the updated middlewares in the new order.
- The timestamp formatting logic (`datetime.now(...).replace(...).isoformat().replace(...)`) is duplicated in several functions; extracting a small helper (e.g., `utc_now_iso()`) would make the code easier to maintain and avoid inconsistencies.

## Individual Comments

### Comment 1
<location path="pro_tes/api/middlewares/controllers.py" line_range="174-175" />
<code_context>
+
+    coll = _collection()
+    # Fetch existing ids
+    existing = list(coll.find({}, {"_id": True}))
+    existing_ids = {str(d["_id"]): d for d in existing}
+
+    if set(ordered_ids) != set(existing_ids.keys()):
</code_context>
<issue_to_address>
**suggestion:** The `existing_ids` mapping stores full docs but only keys are used; also the error message may not clearly surface invalid IDs.

Since only the keys are used later, `existing_ids` can just be a `set` of string IDs instead of a mapping to full documents. Also, when `ordered_ids` contains syntactically invalid IDs, the initial `set(ordered_ids) != set(existing_ids.keys())` check will fail with a generic mismatch message, and the more specific `Invalid id in ordered_ids` case is only reached later. If you care about clearer client feedback, consider validating that each `ordered_id` is a valid `ObjectId` string before the set comparison.

Suggested implementation:

```python
    coll = _collection()
    # Fetch existing ids
    existing = list(coll.find({}, {"_id": True}))
    existing_ids = {str(d["_id"]) for d in existing}

    # Validate that all provided ids are syntactically valid ObjectId strings
    for mid in ordered_ids:
        try:
            ObjectId(mid)
        except Exception:
            raise BadRequest(f"Invalid id in ordered_ids: {mid}")

    if set(ordered_ids) != existing_ids:
        raise BadRequest("`ordered_ids` must contain exactly all middleware ids")

```

```python
    # Apply new order
    updated_docs: List[Dict[str, Any]] = []
    now = datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
    for idx, mid in enumerate(ordered_ids):
        # At this point, all ids are known to be valid ObjectId strings
        oid = ObjectId(mid)

```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +174 to +175
existing = list(coll.find({}, {"_id": True}))
existing_ids = {str(d["_id"]): d for d in existing}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The existing_ids mapping stores full docs but only keys are used; also the error message may not clearly surface invalid IDs.

Since only the keys are used later, existing_ids can just be a set of string IDs instead of a mapping to full documents. Also, when ordered_ids contains syntactically invalid IDs, the initial set(ordered_ids) != set(existing_ids.keys()) check will fail with a generic mismatch message, and the more specific Invalid id in ordered_ids case is only reached later. If you care about clearer client feedback, consider validating that each ordered_id is a valid ObjectId string before the set comparison.

Suggested implementation:

    coll = _collection()
    # Fetch existing ids
    existing = list(coll.find({}, {"_id": True}))
    existing_ids = {str(d["_id"]) for d in existing}

    # Validate that all provided ids are syntactically valid ObjectId strings
    for mid in ordered_ids:
        try:
            ObjectId(mid)
        except Exception:
            raise BadRequest(f"Invalid id in ordered_ids: {mid}")

    if set(ordered_ids) != existing_ids:
        raise BadRequest("`ordered_ids` must contain exactly all middleware ids")
    # Apply new order
    updated_docs: List[Dict[str, Any]] = []
    now = datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
    for idx, mid in enumerate(ordered_ids):
        # At this point, all ids are known to be valid ObjectId strings
        oid = ObjectId(mid)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new FOCA/Connexion controller module to expose the Middleware Management API (CRUD + reorder) backed by the taskStore.middlewares MongoDB collection, and updates docs to reflect the new API layer.

Changes:

  • Implement pro_tes.api.middlewares.controllers with handlers for list/create/get/update/delete/reorder.
  • Add pro_tes.api.middlewares package initializer.
  • Update docs/middleware.md to describe implementation status and how to validate.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 8 comments.

File Description
pro_tes/api/middlewares/controllers.py New Mongo-backed controller functions implementing middleware management endpoints.
pro_tes/api/middlewares/init.py Declares the middlewares API package exports.
docs/middleware.md Documents controller implementation status and validation guidance.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pro_tes/api/middlewares/controllers.py Outdated
Comment thread pro_tes/api/middlewares/controllers.py
Comment on lines +94 to +99
# Insert
try:
res = coll.insert_one(doc)
except Exception as exc:
logger.exception("Failed to insert middleware")
raise
Comment thread pro_tes/api/middlewares/controllers.py Outdated
Comment on lines +136 to +146
update_fields["updated_at"] = datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
coll = _collection()
updated = coll.find_one_and_update(
{"_id": oid},
{"$set": update_fields},
projection={"_id": True, "name": True, "source": True, "order": True, "config": True, "created_at": True, "updated_at": True},
return_document=True,
)
if updated is None:
raise NotFound(f"Middleware with ID '{middleware_id}' not found")
return _doc_to_response(updated)
Comment thread pro_tes/api/middlewares/controllers.py Outdated
Comment thread pro_tes/api/middlewares/controllers.py Outdated
Comment thread docs/middleware.md Outdated
Comment on lines +35 to +39
def ListMiddlewares(page_size: int = 50,
page: int = 0,
sort_by: str = "order",
sort_order: str = "asc",
source: Optional[str] = None) -> Dict[str, Any]:
keshxvdayal and others added 8 commits June 18, 2026 08:24
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Keshav Dayal <115068840+keshxvdayal@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Keshav Dayal <115068840+keshxvdayal@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Keshav Dayal <115068840+keshxvdayal@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Keshav Dayal <115068840+keshxvdayal@users.noreply.github.com>
@keshxvdayal keshxvdayal self-assigned this Jun 18, 2026
@keshxvdayal keshxvdayal requested a review from uniqueg June 18, 2026 03:18
@keshxvdayal keshxvdayal changed the title Implement middleware management controllers feat:Implement middleware management controllers Jun 18, 2026
@keshxvdayal keshxvdayal changed the title feat:Implement middleware management controllers feat: Implement middleware management controllers Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants