Feature: NamespacedProjectService application service As a developer maintaining the CleverAgents architecture I want the CLI layer to interact with projects only through NamespacedProjectService So that Architectural Invariant #3 (CLI → AppService → Domain) is enforced Background: Given a NamespacedProjectService with an in-memory database # ── Name parsing ────────────────────────────────────────────── Scenario: Parse a bare project name defaults to local namespace When I parse the project name "my-project" Then the NPS parsed namespace should be "local" And the NPS parsed name should be "my-project" And the NPS parsed server should be None Scenario: Parse a namespaced project name When I parse the project name "team/my-project" Then the NPS parsed namespace should be "team" And the NPS parsed name should be "my-project" Scenario: Parse a server-qualified project name When I parse the project name "dev:team/my-project" Then the NPS parsed namespace should be "team" And the NPS parsed name should be "my-project" And the NPS parsed server should be "dev" Scenario: Parse an invalid project name raises ValueError When I parse the invalid project name "123bad" Then the NPS should raise a ValueError Scenario: Parse a reserved namespace raises ValueError When I parse the invalid project name "system/bad" Then the NPS should raise a ValueError Scenario: Parse a provider namespace raises ValueError When I parse the invalid project name "openai/bad" Then the NPS should raise a ValueError # ── Validate project name ───────────────────────────────────── Scenario: Validate a valid project name succeeds When I validate the project name "valid-name" Then the validation should succeed Scenario: Validate an invalid project name raises ValueError When I validate the invalid project name "9invalid" Then the NPS should raise a ValueError # ── Create project ──────────────────────────────────────────── Scenario: Create a project with bare name When I create a project named "my-app" via the service Then the service should return a project with namespaced name "local/my-app" And the project should be persisted in the database Scenario: Create a project with explicit namespace When I create a project named "team/my-app" via the service Then the service should return a project with namespaced name "team/my-app" And the project should be persisted in the database Scenario: Create a project with description When I create a project named "my-app" with description "A test project" via the service Then the service should return a project with namespaced name "local/my-app" And the NPS project description should be "A test project" Scenario: Create a project with invalid name raises ValueError When I attempt to create a project named "123bad" via the service Then the NPS should raise a ValueError Scenario: Create a duplicate project raises DatabaseError Given a project "local/existing-app" already exists in the service When I attempt to create a duplicate project named "existing-app" via the service Then a database error should be raised # ── Get project ─────────────────────────────────────────────── Scenario: Get an existing project by namespaced name Given a project "local/get-test" already exists in the service When I get the project "local/get-test" via the service Then the service should return a project with namespaced name "local/get-test" Scenario: Get a nonexistent project raises NotFoundError When I attempt to get the project "local/nonexistent" via the service Then a NotFoundError should be raised # ── List projects ───────────────────────────────────────────── Scenario: List all projects returns all created projects Given a project "local/proj-a" already exists in the service And a project "local/proj-b" already exists in the service When I list all projects via the service Then the service project list should contain "local/proj-a" And the service project list should contain "local/proj-b" Scenario: List projects with namespace filter Given a project "local/proj-x" already exists in the service And a project "team/proj-y" already exists in the service When I list projects with namespace "team" via the service Then the service project list should contain "team/proj-y" And the service project list should not contain "local/proj-x" Scenario: List projects when empty returns empty list When I list all projects via the service Then the service project list should be empty # ── Delete project ──────────────────────────────────────────── Scenario: Delete an existing project Given a project "local/del-test" already exists in the service When I delete the project "local/del-test" via the service Then the delete should return True And the project "local/del-test" should not exist in the service Scenario: Delete a nonexistent project returns False When I delete the project "local/never-existed" via the service Then the delete should return False # ── project_to_dict ─────────────────────────────────────────── Scenario: project_to_dict returns spec-aligned keys Given a project "local/dict-test" already exists in the service When I convert the project "local/dict-test" to a dict via the service Then the dict should have key "namespaced_name" And the dict should have key "namespace" And the dict should have key "name" And the dict should have key "description" And the dict should have key "linked_resources" And the dict should have key "created_at" And the dict should have key "updated_at" Scenario: project_to_dict namespaced_name matches project Given a project "team/dict-ns" already exists in the service When I convert the project "team/dict-ns" to a dict via the service Then the dict value for "namespaced_name" should be "team/dict-ns" # ── CLI architectural invariant ─────────────────────────────── Scenario: CLI project create command does not import domain models directly When I inspect the project CLI create command source Then it should not contain a direct import of "cleveragents.domain.models.core.project"