fix post schema

This commit is contained in:
Evan Jarrett
2025-10-24 20:27:16 -05:00
parent 2a795ed5cd
commit 0c4d1cae8f
4 changed files with 27 additions and 18 deletions
+3 -3
View File
@@ -33,9 +33,9 @@ const holdDIDKey contextKey = "hold.did"
// These are set by main.go during startup and copied into NamespaceResolver instances.
// After initialization, request handling uses the NamespaceResolver's instance fields.
var (
globalRefresher *oauth.Refresher
globalDatabase storage.DatabaseMetrics
globalAuthorizer auth.HoldAuthorizer
globalRefresher *oauth.Refresher
globalDatabase storage.DatabaseMetrics
globalAuthorizer auth.HoldAuthorizer
globalReadmeCache storage.ReadmeCache
)
+1
View File
@@ -291,6 +291,7 @@ func (h *XRPCHandler) HandleNotifyManifest(w http.ResponseWriter, r *http.Reques
req.Repository,
req.Tag,
req.UserHandle,
req.UserDID,
manifestDigest,
totalSize,
)
+8 -8
View File
@@ -13,7 +13,7 @@ import (
// Includes facets for clickable mentions and links
func (p *HoldPDS) CreateManifestPost(
ctx context.Context,
repository, tag, userHandle, digest string,
repository, tag, userHandle, userDID, digest string,
totalSize int64,
) (string, error) {
now := time.Now()
@@ -30,7 +30,7 @@ func (p *HoldPDS) CreateManifestPost(
text := fmt.Sprintf("@%s just pushed %s\nDigest: %s Size: %s", userHandle, repoWithTag, digestShort, sizeStr)
// Create facets for mentions and links
facets := buildFacets(text, userHandle, repoWithTag, appViewURL)
facets := buildFacets(text, userHandle, userDID, repoWithTag, appViewURL)
// Create post struct with facets
post := &bsky.FeedPost{
@@ -60,19 +60,19 @@ func (p *HoldPDS) CreateManifestPost(
return postURI, nil
}
// formatDigest truncates digest to first 7 and last 7 chars
// Example: sha256:abc1234567890...fedcba9876543210 -> sha256:abc1234...9876543
// formatDigest truncates digest to first 10 chars
// Example: sha256:abc1234567890fedcba9876543210 -> sha256:abc1234567...
func formatDigest(digest string) string {
if !strings.HasPrefix(digest, "sha256:") {
return digest // Return as-is if not sha256
}
hash := strings.TrimPrefix(digest, "sha256:")
if len(hash) <= 14 {
if len(hash) <= 10 {
return digest // Too short to truncate
}
return fmt.Sprintf("sha256:%s...%s", hash[:7], hash[len(hash)-7:])
return fmt.Sprintf("sha256:%s...", hash[:10])
}
// formatSize converts bytes to human-readable format
@@ -98,7 +98,7 @@ func formatSize(bytes int64) string {
// buildFacets creates mention and link facets for rich text
// IMPORTANT: Byte offsets must be calculated for UTF-8 encoded text
func buildFacets(text, userHandle, repoWithTag, appViewURL string) []*bsky.RichtextFacet {
func buildFacets(text, userHandle, userDID, repoWithTag, appViewURL string) []*bsky.RichtextFacet {
facets := []*bsky.RichtextFacet{}
// Find mention: "@alice.bsky.social"
@@ -117,7 +117,7 @@ func buildFacets(text, userHandle, repoWithTag, appViewURL string) []*bsky.Richt
Features: []*bsky.RichtextFacet_Features_Elem{
{
RichtextFacet_Mention: &bsky.RichtextFacet_Mention{
Did: "", // Will be resolved by Bluesky from handle
Did: userDID,
},
},
},
+15 -7
View File
@@ -16,7 +16,7 @@ func TestFormatDigest(t *testing.T) {
{
name: "standard sha256 digest",
digest: "sha256:abc1234567890fedcba9876543210",
expected: "sha256:abc1234...6543210", // Last 7 chars of hash
expected: "sha256:abc1234567...", // First 10 chars
},
{
name: "short digest (no truncation)",
@@ -31,7 +31,7 @@ func TestFormatDigest(t *testing.T) {
{
name: "real sha256 digest",
digest: "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f",
expected: "sha256:e692418...7fc331f", // Last 7 chars are "7fc331f"
expected: "sha256:e692418e4c...", // First 10 chars
},
}
@@ -108,6 +108,7 @@ func TestBuildFacets(t *testing.T) {
name string
text string
userHandle string
userDID string
repoWithTag string
appViewURL string
wantFacets int // number of facets expected
@@ -116,6 +117,7 @@ func TestBuildFacets(t *testing.T) {
name: "standard post with mention and link",
text: "@alice.bsky.social just pushed myapp:latest\nDigest: sha256:abc...def Size: 12.2 MB",
userHandle: "alice.bsky.social",
userDID: "did:plc:alice123",
repoWithTag: "myapp:latest",
appViewURL: "https://atcr.io/r/alice.bsky.social/myapp",
wantFacets: 2,
@@ -124,6 +126,7 @@ func TestBuildFacets(t *testing.T) {
name: "no matches found",
text: "random text",
userHandle: "alice.bsky.social",
userDID: "did:plc:alice123",
repoWithTag: "myapp:latest",
appViewURL: "https://atcr.io/r/alice.bsky.social/myapp",
wantFacets: 0,
@@ -132,6 +135,7 @@ func TestBuildFacets(t *testing.T) {
name: "only mention found",
text: "@alice.bsky.social did something",
userHandle: "alice.bsky.social",
userDID: "did:plc:alice123",
repoWithTag: "myapp:latest",
appViewURL: "https://atcr.io/r/alice.bsky.social/myapp",
wantFacets: 1,
@@ -140,7 +144,7 @@ func TestBuildFacets(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
facets := buildFacets(tt.text, tt.userHandle, tt.repoWithTag, tt.appViewURL)
facets := buildFacets(tt.text, tt.userHandle, tt.userDID, tt.repoWithTag, tt.appViewURL)
if len(facets) != tt.wantFacets {
t.Errorf("buildFacets() returned %d facets, want %d", len(facets), tt.wantFacets)
@@ -183,10 +187,11 @@ func TestBuildFacets_ByteOffsets(t *testing.T) {
// Test that byte offsets are correctly calculated
text := "@alice.bsky.social just pushed myapp:latest"
userHandle := "alice.bsky.social"
userDID := "did:plc:alice123"
repoWithTag := "myapp:latest"
appViewURL := "https://atcr.io/r/alice.bsky.social/myapp"
facets := buildFacets(text, userHandle, repoWithTag, appViewURL)
facets := buildFacets(text, userHandle, userDID, repoWithTag, appViewURL)
if len(facets) != 2 {
t.Fatalf("expected 2 facets, got %d", len(facets))
@@ -235,10 +240,11 @@ func TestBuildFacets_UTF8Handling(t *testing.T) {
// Test with Unicode characters to ensure byte offsets work correctly
text := "@alice.bsky.social just pushed 🚀myapp:latest"
userHandle := "alice.bsky.social"
userDID := "did:plc:alice123"
repoWithTag := "🚀myapp:latest" // Note: emoji is multi-byte
appViewURL := "https://atcr.io/r/alice.bsky.social/myapp"
facets := buildFacets(text, userHandle, repoWithTag, appViewURL)
facets := buildFacets(text, userHandle, userDID, repoWithTag, appViewURL)
if len(facets) != 2 {
t.Fatalf("expected 2 facets, got %d", len(facets))
@@ -263,10 +269,11 @@ func TestBuildFacets_NoOverlap(t *testing.T) {
// Ensure facets don't overlap
text := "@alice.bsky.social just pushed myapp:latest"
userHandle := "alice.bsky.social"
userDID := "did:plc:alice123"
repoWithTag := "myapp:latest"
appViewURL := "https://atcr.io/r/alice.bsky.social/myapp"
facets := buildFacets(text, userHandle, repoWithTag, appViewURL)
facets := buildFacets(text, userHandle, userDID, repoWithTag, appViewURL)
if len(facets) != 2 {
t.Fatalf("expected 2 facets, got %d", len(facets))
@@ -287,6 +294,7 @@ func TestBuildFacets_RealWorldExample(t *testing.T) {
repository := "hsm-secrets-operator"
tag := "latest"
userHandle := "evan.jarrett.net"
userDID := "did:plc:pddp4xt5lgnv2qsegbzzs4xg"
digest := "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f"
totalSize := int64(12800000) // ~12.2 MB
@@ -297,7 +305,7 @@ func TestBuildFacets_RealWorldExample(t *testing.T) {
text := "@" + userHandle + " just pushed " + repoWithTag + "\nDigest: " + digestShort + " Size: " + sizeStr
appViewURL := "https://atcr.io/r/" + userHandle + "/" + repository
facets := buildFacets(text, userHandle, repoWithTag, appViewURL)
facets := buildFacets(text, userHandle, userDID, repoWithTag, appViewURL)
// Should have 2 facets: mention and link
if len(facets) != 2 {