Skip to content

Overview

Projects within a resolved organization. Every route here carries {org}, so ResolveTenantFilter has already resolved + access-checked it before any action runs — dispatched commands/queries always use ResolvedOrgId, never the raw route string. {project} (get/update/delete) is resolved key-or-guid, scoped to the resolved org, via ResolveProjectIdAsync — same addressing pattern as OrganizationsController uses for {org}. Writes (create/update/delete) require at least Member (RequireRole); a Viewer attempting one gets a 403 forbidden envelope.