Manage projects, members and services through the API
/api/v1/projects, /members and /services: create, list, show, update, delete and restore, with the panel's own rules — so the MCP server can load the collective's work, people and offer without anyone retyping them into forms. The MCP server picks the tools up from openapi.yaml. - Relations travel as ids and are replaced whole when sent, left alone when not: a project's technology_ids, service_ids and members with each one's role; a member's technology_ids; a service's technology_ids and project_ids. Record and relations are saved in one transaction. - Publishing stays a permission of its own. Without projects.publish or services.publish, published_at, unpublish_at and is_published are refused — the fields the panel disables for the same people. - MemberPolicy still lets someone edit their own profile. - Uploads accept `for: projects` and `for: members`, landing where the panel's own upload fields put them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,10 @@ declare(strict_types=1);
|
||||
namespace Tests\Feature\Api;
|
||||
|
||||
use App\Models\Category;
|
||||
use App\Models\Member;
|
||||
use App\Models\Page;
|
||||
use App\Models\Project;
|
||||
use App\Models\Service;
|
||||
use App\Models\Technology;
|
||||
use App\Models\User;
|
||||
use Database\Seeders\RolePermissionSeeder;
|
||||
@@ -66,6 +69,9 @@ class AdminApiContractTest extends TestCase
|
||||
'categories' => ['path' => '/v1/categories'],
|
||||
'users' => ['path' => '/v1/users'],
|
||||
'technologies' => ['path' => '/v1/technologies'],
|
||||
'projects' => ['path' => '/v1/projects'],
|
||||
'members' => ['path' => '/v1/members'],
|
||||
'services' => ['path' => '/v1/services'],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -75,6 +81,9 @@ class AdminApiContractTest extends TestCase
|
||||
$page = Page::factory()->create();
|
||||
$category = Category::factory()->create();
|
||||
$technology = Technology::factory()->create();
|
||||
$project = Project::factory()->create();
|
||||
$member = Member::factory()->create();
|
||||
$service = Service::factory()->create();
|
||||
|
||||
// One request, one documented path — the URL a real caller hits and
|
||||
// the path key that describes it, side by side rather than derived
|
||||
@@ -87,6 +96,12 @@ class AdminApiContractTest extends TestCase
|
||||
'category' => ["/v1/categories/{$category->id}", '/v1/categories/{category}'],
|
||||
'technologies' => ['/v1/technologies', '/v1/technologies'],
|
||||
'technology' => ["/v1/technologies/{$technology->id}", '/v1/technologies/{technology}'],
|
||||
'projects' => ['/v1/projects', '/v1/projects'],
|
||||
'project' => ["/v1/projects/{$project->id}", '/v1/projects/{project}'],
|
||||
'members' => ['/v1/members', '/v1/members'],
|
||||
'member' => ["/v1/members/{$member->id}", '/v1/members/{member}'],
|
||||
'services' => ['/v1/services', '/v1/services'],
|
||||
'service' => ["/v1/services/{$service->id}", '/v1/services/{service}'],
|
||||
'users' => ['/v1/users', '/v1/users'],
|
||||
'user' => ["/v1/users/{$this->caller->id}", '/v1/users/{user}'],
|
||||
'me' => ['/v1/me', '/v1/me'],
|
||||
|
||||
Reference in New Issue
Block a user