Files

80 lines
2.7 KiB
Go

package pds
import (
"context"
"fmt"
"log/slog"
"time"
"atcr.io/pkg/atproto"
"github.com/ipfs/go-cid"
)
const (
// CaptainRkey is the fixed rkey for the captain record (singleton)
CaptainRkey = "self"
)
// CreateCaptainRecord creates the captain record for the hold (first-time only).
// This will FAIL if the captain record already exists. Use UpdateCaptainRecord to modify.
func (p *HoldPDS) CreateCaptainRecord(ctx context.Context, ownerDID string, public bool, allowAllCrew bool, enableBlueskyPosts bool) (cid.Cid, error) {
captainRecord := &atproto.CaptainRecord{
Type: atproto.CaptainCollection,
Owner: ownerDID,
Public: public,
AllowAllCrew: allowAllCrew,
EnableBlueskyPosts: enableBlueskyPosts,
DeployedAt: time.Now().Format(time.RFC3339),
}
// Use repomgr.PutRecord - creates with explicit rkey, fails if already exists
recordPath, recordCID, err := p.repomgr.PutRecord(ctx, p.uid, atproto.CaptainCollection, CaptainRkey, captainRecord)
if err != nil {
return cid.Undef, fmt.Errorf("failed to create captain record: %w", err)
}
slog.Info("Created captain record",
"path", recordPath,
"cid", recordCID.String())
return recordCID, nil
}
// GetCaptainRecord retrieves the captain record
func (p *HoldPDS) GetCaptainRecord(ctx context.Context) (cid.Cid, *atproto.CaptainRecord, error) {
// Use repomgr.GetRecord - our types are registered in init()
// so it will automatically unmarshal to the concrete type
recordCID, val, err := p.repomgr.GetRecord(ctx, p.uid, atproto.CaptainCollection, CaptainRkey, cid.Undef)
if err != nil {
return cid.Undef, nil, fmt.Errorf("failed to get captain record: %w", err)
}
// Type assert to our concrete type
captainRecord, ok := val.(*atproto.CaptainRecord)
if !ok {
return cid.Undef, nil, fmt.Errorf("unexpected type for captain record: %T", val)
}
return recordCID, captainRecord, nil
}
// UpdateCaptainRecord updates the captain record (e.g., to change public/allowAllCrew/enableBlueskyPosts settings)
func (p *HoldPDS) UpdateCaptainRecord(ctx context.Context, public bool, allowAllCrew bool, enableBlueskyPosts bool) (cid.Cid, error) {
// Get existing record to preserve other fields
_, existing, err := p.GetCaptainRecord(ctx)
if err != nil {
return cid.Undef, fmt.Errorf("failed to get existing captain record: %w", err)
}
// Update the fields
existing.Public = public
existing.AllowAllCrew = allowAllCrew
existing.EnableBlueskyPosts = enableBlueskyPosts
recordCID, err := p.repomgr.UpdateRecord(ctx, p.uid, atproto.CaptainCollection, CaptainRkey, existing)
if err != nil {
return cid.Undef, fmt.Errorf("failed to update captain record: %w", err)
}
return recordCID, nil
}