Topolo Docs Topolo Platform
Open workspace

Rename a Consent project or change its workspace default

Apply a reviewed project metadata change and reconcile true-only default promotion, sequential writes and uncertain read-back.

Outcome

Rename one Consent project, make it the workspace default, or both. This is a project metadata mutation with possible sequential partial effects.

Action: app_topolo_consent.projects.update.

PATCH /api/projects/{projectKey}

Before you start

Verify original production credential, organization, exact Consent workspace grant and target projectKey. Discover its current name/default/status from authorized projects.list, keeping the200-row bound and normalized fallback fields in mind. A project key/id is not a workspace grant; bind the actual canonical workspace separately.

Requires app_topolo_consent.workspace:write plus read_write-or-higher verified workspace access. Explicitly approve the rename and/or workspace-default change before a real mutation. Retain the original name and actual prior default project identity for any conditional compensation.

The target must be reachable and non-archived. This action updates a Consent project inside a workspace; it does not rename an Auth workspace, change organization context or grant access. Synthetic fixture examples below are unrun and authorize no mutation.

Request and field behavior

FieldMeaning
projectKeyRequired actual reachable project key; not a workspace id.
nameOptional; trimmed nonblank text renames. Whitespace has no rename effect.
isDefaultOnly true promotes. false does not clear the default.

Discover the current action and validate the approved input before execution. Inspect the plan with the original verified workspace bound separately; confirmation must cover the actual rename/default effects. No guessed workspace or fixture id should be executed.

Input accepts projectKey plus optional name:string and isDefault:boolean. Source trims name; whitespace becomes no rename. Only literal isDefault:true promotes. false does not unset an existing default. If there is neither a nonblank trimmed name nor true promotion, source returns400 project_update_empty even though projectKey-only/false/whitespace inputs can satisfy the declared JSON Schema.

When a nonblank name is supplied, the handler updates name and updated_at by the resolved project id. Project key, workspace id, stored configuration and SDK key are not changed by this handler. It does not refresh public config cache or send notifications.

Promotion first clears is_default and updates timestamps on every sibling project row in the same workspace, then sets the target default and its updated_at. These are separately awaited SQL writes, without a transaction, revision precondition or compare-and-swap shown here. A partial failure or concurrent update may leave an intermediate state; one HTTP failure is not proof that nothing changed.

A rename plus promotion is likewise sequential. Repeating the same values is not an idempotent no-op: timestamps can change and siblings may be touched again. Never issue parallel retries or assume an operation key is supported by this input.

Success is {project:<complete normalized project projection or null>}, read again after the writes. It is not generic data/id/success. The immediate read-back can reflect concurrent work, and a disappeared row may yield project:null. Treat null or a mismatch as unresolved rather than silently calling the operation complete.

Read-back fields are id,key,workspaceId,name,isDefault,tenantId,authOrgId,tenantName,environment,mode,status,configJson,updatedAt,archivedAt,notificationUserId. configJson stays a string. Projection can fill legacy/default values; it is not independent proof that every field was persisted unchanged or that a downstream site adopted a new name/default.

Complete worked responses

Rename using trimmed input

Complete synthetic/unrun HTTP200 projection. Assumes original read_write/write grant, active reachable fixture project, successful name write and the shown immediate normalized read-back. All ids/config are fictional; no project mutation was executed.

Input:

{
  "projectKey": "project_fixture_docs",
  "name": "  Renamed fixture  "
}

Response:

{
  "project": {
    "id": "project_record_fixture",
    "key": "project_fixture_docs",
    "workspaceId": "ws_consent_fixture",
    "name": "Renamed fixture",
    "isDefault": false,
    "tenantId": "org_record_fixture",
    "authOrgId": "org_fixture",
    "tenantName": "Fixture organization",
    "environment": "production",
    "mode": "global",
    "status": "active",
    "configJson": "{}",
    "updatedAt": "2026-10-20T08:01:00.000Z",
    "archivedAt": null,
    "notificationUserId": null
  }
}

Compare the trimmed name and unchanged target identity. A display rename does not rotate a key or prove downstream adoption.

False does not clear the default

Complete synthetic/unrun HTTP400 source branch. Assumes all prior Auth/workspace/project/storage checks pass and no name is supplied. This input is schema-valid; it is not a captured response.

Input:

{
  "projectKey": "project_fixture_docs",
  "isDefault": false
}

Response:

{
  "error": "project_update_empty"
}

Correct the intended operation. Do not retry false to unset the default; that operation is not provided by this input.

Refuse an archived target

Complete synthetic/unrun HTTP409 source branch. Assumes original authority and reachable stored project whose status is archived. That status is external fixture state, not an input flag.

Input:

{
  "projectKey": "project_fixture_docs",
  "name": "Renamed fixture"
}

Response:

{
  "error": "project_archived"
}

Preserve the refusal. Restoring a project is a separate approved admin-level operation, not an automatic rename workaround.

Verify and recover

Compare actual project.key/id/workspaceId, returned name/default and updatedAt with the intended record and current authorized context. Verify the actual stored state through projects.list when present in its bounded result. A missing target from the first200 does not establish deletion; null read-back is UNKNOWN.

For promotion, reconcile both the intended default and prior default within the same workspace. Check relevant siblings rather than assuming target success proves all concurrent/default transitions were atomic. Do not use the organization id as a workspace binding.

After an interrupted/uncertain call, read current project/default state before considering another write. Reconcile source partial effects, timestamps and intervening owner work; preserve unresolved outcomes instead of blindly repeating the mutation.

Only with current authorization and current-state reconciliation, use the same action with the reviewed previous nonblank name or isDefault:true on the actual previously-default project. These are separate compensating writes, not an exact rollback: original timestamps are not restored, sibling changes/concurrent work may differ, an archived prior default may be refused, and isDefault:false cannot recreate a prior no-default state. Do not overwrite another owner’s intervening changes or invent direct SQL cleanup.

Refusals

400 / project_update_empty: Provide a reviewed nonblank name or true default promotion; false/whitespace/projectKey alone do not request a change.

403 / organization_context_required: Reconcile intended original organization; do not broaden principal.

404 / project_not_found: Reconcile the real key in original organization AND verified workspace; listing omissions are bounded.

409 / project_archived: Preserve archived state; restoration requires separate explicit authority.

503 / database_unavailable: Control storage absent; preserve actual error evidence. For any failure after writes began, reconcile partial state before retry.

Shared authentication/workspace/permission failures precede the handler; retain the actual carrier/request evidence. SQL exceptions need actual shared-runtime evidence, not an invented guaranteed carrier. No live mutation was captured here.

Change log

  • 2026-10-21: Added exact trim/true-only semantics, non-archived project scope, sequential promotion/partial-effect behavior, complete unrun responses and conditional compensation rather than exact rollback. Source-serving association remains unknown.