fix(api): reclaim stale domain claims with neutral conflicts - #446
Conversation
Preserve global one-owner uniqueness with an atomic conditional upsert. Reclaim never-verified pending/failed claims after seven days, rotate claim identity, and avoid disclosing other projects in conflict errors. Document the lifecycle and cover tenant isolation, deadlines, and concurrent adds. JSON-path hardening from #441 remains unchanged. Co-Authored-By: Duyet Le <me@duyet.net> Co-Authored-By: duyetbot <bot@duyet.net>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Reviewer's GuideThis PR preserves database-enforced one-domain/one-project ownership while moving domain creation to an atomic guarded upsert. It returns neutral errors for claims owned by other projects, reclaims never-verified pending or failed claims after seven days using rotated identity and verification credentials, adds extensive concurrency and lifecycle regression coverage, and documents the resulting API and ownership rules. Sequence diagram for atomic custom-domain claimingsequenceDiagram
participant Client
participant API
participant DomainsService
participant Database
Client->>API: POST /api/v1/projects/:projectId/domains
API->>DomainsService: createDomain(db, projectId, domain)
DomainsService->>Database: insert(...).onConflictDoUpdate(...).returning(...)
alt New domain or reclaimable unverified claim
Database-->>DomainsService: claimed id
DomainsService-->>API: verification instructions
API-->>Client: 201 Created
else Active claim in requesting project
DomainsService->>Database: select own claim
Database-->>DomainsService: matching claim
DomainsService-->>API: DOMAIN_EXISTS
API-->>Client: 409 DOMAIN_EXISTS
else Claim owned by another project or protected claim
DomainsService->>Database: select own claim
Database-->>DomainsService: no matching claim
DomainsService-->>API: DOMAIN_UNAVAILABLE
API-->>Client: 409 DOMAIN_UNAVAILABLE
end
State diagram for custom-domain claim lifecyclestateDiagram-v2
[*] --> pending: createDomain
pending --> verified: verification succeeds
pending --> failed: verification fails
failed --> verified: verification succeeds
pending --> pending: retry verification
failed --> failed: retry verification
pending --> pending: reclaim after 7 days
failed --> pending: reclaim after 7 days
verified --> [*]: owner removes domain
pending --> pending: replacement gets new ID, token, timestamps
failed --> pending: SSL disabled and credentials rotated
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Summary
Validation
Closes #436
Do not merge this PR as part of this task. Release-please #442 is untouched.
Co-Authored-By: Duyet Le me@duyet.net
Co-Authored-By: duyetbot bot@duyet.net
🤖 Generated with Claude Code
Summary by Sourcery
Harden custom-domain claims by neutralizing cross-project conflicts and safely reclaiming stale unverified ownership after seven days.
Bug Fixes:
DOMAIN_UNAVAILABLEerrors.Enhancements:
Documentation:
Tests:
Chores: