left4me/docs/superpowers/plans/2026-05-06-server-port-constraint.md

4.8 KiB

Server Port Constraint Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Ensure servers cannot share the same port by enforcing uniqueness at the database level and handling the constraint violation in the web UI.

Architecture: We will add a unique constraint to the Server.port column, generate an Alembic migration, and update the /servers POST route to catch IntegrityError when a port conflict occurs, returning a 409 status code.

Tech Stack: Python, Flask, SQLAlchemy, Alembic, Pytest


Task 1: Add Unique Constraint to Server Port

Files:

  • Modify: l4d2web/models.py

  • Modify: l4d2web/routes/server_routes.py

  • Create: l4d2web/alembic/versions/XXXX_make_server_port_unique.py (via alembic)

  • Step 1: Update the database model

Update l4d2web/models.py to add unique=True to the port column on the Server model.

class Server(Base):
    __tablename__ = "servers"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False)
    blueprint_id: Mapped[int] = mapped_column(ForeignKey("blueprints.id"), nullable=False)
    name: Mapped[str] = mapped_column(String(128), unique=True, nullable=False)
    port: Mapped[int] = mapped_column(Integer, unique=True, nullable=False)
    # ... rest of the columns
  • Step 2: Generate the Alembic migration

Run: PYTHONPATH=. alembic -c l4d2web/alembic.ini revision --autogenerate -m "make server port unique" Expected: Creates a new migration file in l4d2web/alembic/versions/

  • Step 3: Update application logic

Update l4d2web/routes/server_routes.py to catch the IntegrityError when creating a server.

from sqlalchemy.exc import IntegrityError
# ... other imports

@bp.post("/servers")
@require_login
def create_server() -> Response:
    # ... existing user check and payload extraction

    with session_scope() as db:
        blueprint = db.scalar(
            select(BlueprintModel).where(
                BlueprintModel.id == int(payload["blueprint_id"]),
                BlueprintModel.user_id == user.id,
            )
        )
        if blueprint is None:
            return Response("blueprint not found", status=404)

        server = Server(
            user_id=user.id,
            blueprint_id=blueprint.id,
            name=str(payload["name"]),
            port=int(payload["port"]),
            desired_state="stopped",
            actual_state="unknown",
            last_error="",
        )
        db.add(server)
        
        try:
            db.flush()
        except IntegrityError:
            db.rollback()
            return Response("port already in use", status=409)
            
        server_id = server.id

    if json_response:
        return jsonify({"id": server_id}), 201
    return redirect(f"/servers/{server_id}")
  • Step 4: Commit
git add l4d2web/models.py l4d2web/routes/server_routes.py l4d2web/alembic/versions/
git commit -m "feat: enforce unique port constraint on servers"

Task 2: Write Verification Tests

Files:

  • Modify: l4d2web/tests/test_servers.py

  • Step 1: Write the failing test

Add a test case to l4d2web/tests/test_servers.py that verifies the unique port constraint.

def test_create_server_duplicate_port(client, auth, db_session):
    auth.login()
    
    # First, create a blueprint
    response = client.post(
        "/blueprints",
        data={"name": "my-blueprint", "arguments": "[]", "config": "[]"},
    )
    assert response.status_code == 302
    
    # Then create the first server
    response = client.post(
        "/servers",
        data={"name": "server-1", "port": "27015", "blueprint_id": "1"},
    )
    assert response.status_code == 302
    
    # Try to create a second server with the same port
    response = client.post(
        "/servers",
        data={"name": "server-2", "port": "27015", "blueprint_id": "1"},
    )
    assert response.status_code == 409
    assert b"port already in use" in response.data
    
    # Verify the second server was not created
    from l4d2web.models import Server
    servers = db_session.query(Server).all()
    assert len(servers) == 1
    assert servers[0].name == "server-1"
  • Step 2: Run test to verify it passes

Run: pytest l4d2web/tests/test_servers.py -v Expected: PASS (It passes because we implemented the code in Task 1. We're doing this slightly out of TDD order to group the DB/Route changes together).

  • Step 3: Commit
git add l4d2web/tests/test_servers.py
git commit -m "test: add test for duplicate port constraint"