Files
at-container-registry/pkg/atproto/endpoints.go

292 lines
11 KiB
Go

// Package atproto provides constants for XRPC endpoint paths used throughout ATCR.
//
// This package serves as a single source of truth for all XRPC endpoint URLs,
// preventing typos and making refactoring easier. All endpoint paths follow the
// XRPC/Lexicon naming convention: /xrpc/{namespace}.{method}
package atproto
// Hold service multipart upload endpoints (io.atcr.hold.*)
//
// These endpoints handle OCI blob uploads to hold services (BYOS storage).
const (
// HoldInitiateUpload starts a new multipart upload session.
// Method: POST
// Request: {"digest": "sha256:..."}
// Response: {"uploadId": "..."}
HoldInitiateUpload = "/xrpc/io.atcr.hold.initiateUpload"
// HoldGetPartUploadURL gets a presigned URL or endpoint info for uploading a specific part.
// Method: POST
// Request: {"uploadId": "...", "partNumber": 1}
// Response: {"url": "...", "method": "PUT", "headers": {...}}
HoldGetPartUploadURL = "/xrpc/io.atcr.hold.getPartUploadUrl"
// HoldUploadPart handles direct buffered part uploads (alternative to presigned URLs).
// Method: PUT
// Headers: X-Upload-Id, X-Part-Number
// Body: raw part data
// Response: {"etag": "..."}
HoldUploadPart = "/xrpc/io.atcr.hold.uploadPart"
// HoldCompleteUpload finalizes a multipart upload and moves blob to final location.
// Method: POST
// Request: {"uploadId": "...", "digest": "sha256:...", "parts": [{...}]}
// Response: {"status": "completed", "digest": "..."}
HoldCompleteUpload = "/xrpc/io.atcr.hold.completeUpload"
// HoldAbortUpload cancels a multipart upload and cleans up temporary data.
// Method: POST
// Request: {"uploadId": "..."}
// Response: {"status": "aborted"}
HoldAbortUpload = "/xrpc/io.atcr.hold.abortUpload"
// HoldNotifyManifest notifies hold about a manifest upload for layer tracking and Bluesky posting.
// Method: POST
// Request: {"repository": "...", "tag": "...", "userDid": "...", "userHandle": "...", "manifest": {...}}
// Response: {"success": true, "layersCreated": 5, "postCreated": true, "postUri": "at://..."}
HoldNotifyManifest = "/xrpc/io.atcr.hold.notifyManifest"
// HoldGetLayersForManifest returns layer records for a specific manifest.
// Method: GET
// Query: manifest={at-uri}
// Response: {"layers": [{...}]}
HoldGetLayersForManifest = "/xrpc/io.atcr.hold.getLayersForManifest"
// HoldGetImageConfig returns the OCI image config record for a manifest.
// Method: GET
// Query: digest={manifest-digest}
// Response: ImageConfigRecord JSON
HoldGetImageConfig = "/xrpc/io.atcr.hold.image.getConfig"
// HoldGetQuota returns storage quota information for a user.
// Method: GET
// Query: userDid={did}
// Response: {"userDid": "...", "uniqueBlobs": 10, "totalSize": 1073741824}
HoldGetQuota = "/xrpc/io.atcr.hold.getQuota"
// HoldExportUserData exports all user data from a hold service (GDPR compliance).
// Method: GET
// Response: JSON containing all user data stored by the hold
HoldExportUserData = "/xrpc/io.atcr.hold.exportUserData"
// HoldDeleteUserData deletes all user data from a hold service (GDPR compliance).
// Method: DELETE
// Response: {"success": true, "crew_deleted": bool, "layers_deleted": int, "stats_deleted": int}
HoldDeleteUserData = "/xrpc/io.atcr.hold.deleteUserData"
)
// Hold service crew management endpoints (io.atcr.hold.*)
//
// These endpoints manage access control for hold services via crew membership.
const (
// HoldRequestCrew requests crew membership for a hold service.
// Method: POST
// Request: OAuth-authenticated request with DPoP
// Response: {"status": "pending"|"approved"}
HoldRequestCrew = "/xrpc/io.atcr.hold.requestCrew"
// HoldSubscribeScanJobs subscribes to scan jobs via WebSocket (scanner → hold).
// Method: GET (WebSocket upgrade)
// Query: cursor={lastSeq}
// Auth: Shared secret (query param or header)
// Response: Stream of scan job events (JSON)
HoldSubscribeScanJobs = "/xrpc/io.atcr.hold.subscribeScanJobs"
)
// ATProto sync endpoints (com.atproto.sync.*)
//
// Standard AT Protocol synchronization endpoints for PDS interoperability.
const (
// SyncGetBlob retrieves a blob (or presigned URL) from a repository.
// Method: GET
// Query: did={did}&cid={cid}&method={GET|HEAD}
// Response: {"url": "..."} or blob data
SyncGetBlob = "/xrpc/com.atproto.sync.getBlob"
// SyncGetRepo downloads a full repository or diff as a CAR file.
// Method: GET
// Query: did={did}&since={rev}
// Response: CAR file (application/vnd.ipld.car)
SyncGetRepo = "/xrpc/com.atproto.sync.getRepo"
// SyncGetRecord retrieves a specific record as part of a repository sync.
// Method: GET
// Query: did={did}&collection={collection}&rkey={key}
// Response: Record data
SyncGetRecord = "/xrpc/com.atproto.sync.getRecord"
// SyncListBlobs lists blob CIDs for an account.
// Method: GET
// Query: did={did}&since={since}&limit={limit}&cursor={cursor}
// Response: {"cids": ["..."], "cursor": "..."}
SyncListBlobs = "/xrpc/com.atproto.sync.listBlobs"
// SyncListRepos lists all repositories on a PDS.
// Method: GET
// Response: {"repos": [{...}]}
SyncListRepos = "/xrpc/com.atproto.sync.listRepos"
// SyncListReposByCollection lists all repositories that have records in a specific collection.
// Method: GET
// Query: collection={collection}&limit={limit}&cursor={cursor}
// Response: {"repos": [{"did": "..."}], "cursor": "..."}
SyncListReposByCollection = "/xrpc/com.atproto.sync.listReposByCollection"
// SyncSubscribeRepos subscribes to real-time repository events via WebSocket.
// Method: GET (WebSocket upgrade)
// Response: Stream of #commit events
SyncSubscribeRepos = "/xrpc/com.atproto.sync.subscribeRepos"
// SyncGetRepoStatus gets the hosting status for a repository.
// Method: GET
// Query: did={did}
// Response: {"did": "...", "active": true, "rev": "..."}
SyncGetRepoStatus = "/xrpc/com.atproto.sync.getRepoStatus"
// SyncGetLatestCommit gets the current commit CID and revision for a repository.
// Method: GET
// Query: did={did}
// Response: {"cid": "...", "rev": "..."}
SyncGetLatestCommit = "/xrpc/com.atproto.sync.getLatestCommit"
// SyncGetHostStatus gets the hosting/crawl status for a hostname on a relay.
// Method: GET
// Query: hostname={hostname}
// Response: {"hostname": "...", "active": true, "seq": 123}
SyncGetHostStatus = "/xrpc/com.atproto.sync.getHostStatus"
// SyncRequestCrawl requests a relay to crawl a PDS.
// Method: POST
// Request: {"hostname": "hold01.atcr.io"}
// Response: {}
SyncRequestCrawl = "/xrpc/com.atproto.sync.requestCrawl"
)
// ATProto server endpoints (com.atproto.server.*)
//
// Standard AT Protocol server management and authentication endpoints.
const (
// ServerGetServiceAuth gets a service auth token for inter-service communication.
// Method: GET
// Query: aud={serviceDID}&lxm={lexicon}
// Response: {"token": "..."}
ServerGetServiceAuth = "/xrpc/com.atproto.server.getServiceAuth"
// ServerDescribeServer returns server metadata and capabilities.
// Method: GET
// Response: {"did": "...", "availableUserDomains": [...]}
ServerDescribeServer = "/xrpc/com.atproto.server.describeServer"
// ServerCreateSession creates a new session with identifier and password.
// Method: POST
// Request: {"identifier": "...", "password": "..."}
// Response: {"accessJwt": "...", "refreshJwt": "...", "did": "...", "handle": "..."}
ServerCreateSession = "/xrpc/com.atproto.server.createSession"
// ServerRefreshSession refreshes an existing session using a refresh token.
// Method: POST
// Headers: Authorization (Bearer <refreshJwt>)
// Response: {"accessJwt": "...", "refreshJwt": "...", "did": "...", "handle": "..."}
ServerRefreshSession = "/xrpc/com.atproto.server.refreshSession"
// ServerGetSession validates a session and returns the current session info.
// Method: GET
// Headers: Authorization (Bearer or DPoP), DPoP (if using DPoP)
// Response: {"did": "...", "handle": "..."}
ServerGetSession = "/xrpc/com.atproto.server.getSession"
)
// ATProto repo endpoints (com.atproto.repo.*)
//
// Standard AT Protocol repository management endpoints.
const (
// RepoDescribeRepo describes a repository's structure and metadata.
// Method: GET
// Query: repo={did}
// Response: {"did": "...", "handle": "...", "collections": [...]}
RepoDescribeRepo = "/xrpc/com.atproto.repo.describeRepo"
// RepoPutRecord creates or updates a record in a repository.
// Method: POST
// Request: {"repo": "...", "collection": "...", "rkey": "...", "record": {...}}
// Response: {"uri": "...", "cid": "..."}
RepoPutRecord = "/xrpc/com.atproto.repo.putRecord"
// RepoGetRecord retrieves a record from a repository.
// Method: GET
// Query: repo={did}&collection={collection}&rkey={key}
// Response: {"uri": "...", "cid": "...", "value": {...}}
RepoGetRecord = "/xrpc/com.atproto.repo.getRecord"
// RepoListRecords lists records in a collection.
// Method: GET
// Query: repo={did}&collection={collection}&limit={limit}&cursor={cursor}
// Response: {"records": [...], "cursor": "..."}
RepoListRecords = "/xrpc/com.atproto.repo.listRecords"
// RepoDeleteRecord deletes a record from a repository.
// Method: POST
// Query: repo={did}&collection={collection}&rkey={key}
// Response: {}
RepoDeleteRecord = "/xrpc/com.atproto.repo.deleteRecord"
// RepoUploadBlob uploads a blob to a repository (standard ATProto endpoint).
// Method: POST
// Body: blob data
// Response: {"blob": {"$type": "blob", "ref": {...}, "mimeType": "...", "size": ...}}
// Note: For OCI container layer uploads, ATCR uses io.atcr.hold.* multipart endpoints instead.
RepoUploadBlob = "/xrpc/com.atproto.repo.uploadBlob"
)
// ATProto identity endpoints (com.atproto.identity.*)
//
// Standard AT Protocol identity resolution endpoints.
const (
// IdentityResolveHandle resolves a handle to a DID.
// Method: GET
// Query: handle={handle}
// Response: {"did": "did:plc:..."}
IdentityResolveHandle = "/xrpc/com.atproto.identity.resolveHandle"
)
// Hold billing/tier endpoints (io.atcr.hold.*)
//
// These endpoints manage billing tiers on hold services.
const (
// HoldUpdateCrewTier updates a crew member's tier. Only accepts requests from the trusted appview.
// Method: POST
// Request: {"userDid": "did:...", "tierRank": 0}
// Response: {"tierName": "deckhand"}
HoldUpdateCrewTier = "/xrpc/io.atcr.hold.updateCrewTier"
// HoldListTiers lists the hold's available tiers with storage quotas and features.
// Method: GET
// Response: {"tiers": [{"name": "deckhand", "quotaBytes": 5368709120, "quotaFormatted": "5.0 GB", "scanOnPush": false}]}
HoldListTiers = "/xrpc/io.atcr.hold.listTiers"
)
// Appview metadata endpoint (io.atcr.*)
const (
// AppviewGetMetadata returns appview branding and configuration metadata.
// Method: GET
// Response: {"clientName": "...", "clientShortName": "...", "faviconUrl": "...", "registryDomains": [...]}
AppviewGetMetadata = "/xrpc/io.atcr.getMetadata"
)
// Bluesky app endpoints (app.bsky.actor.*)
//
// Bluesky-specific actor/profile endpoints.
const (
// ActorGetProfile retrieves an aggregated profile for an actor.
// Method: GET
// Query: actor={did|handle}
// Response: {"did": "...", "handle": "...", "displayName": "...", "postsCount": ...}
ActorGetProfile = "/xrpc/app.bsky.actor.getProfile"
// ActorGetProfiles retrieves aggregated profiles for multiple actors.
// Method: GET
// Query: actors={did|handle}&actors={did|handle}...
// Response: {"profiles": [{...}, {...}]}
ActorGetProfiles = "/xrpc/app.bsky.actor.getProfiles"
)