- backend: user_avatar_objects binding (PG+SQLite), GC preserves avatar blobs, avatar service (EXIF-stripping WebP 128/512), public avatar read route - web: avatar upload/crop on profile, round avatar in header/members/comments/author - android: avatar upload/crop, round avatar on profile and albums header - openspec: add-user-avatar proposal/design/specs/tasks
23 lines
860 B
Go
23 lines
860 B
Go
package photos
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// objectKey builds an opaque, album-free storage key for a physical object.
|
|
// The key never encodes album, photo or any other metadata entity; the mapping
|
|
// between a key and its photo binding lives only in the metadata layer. The
|
|
// role segment is cosmetic (for debugging) and is not authoritative.
|
|
func objectKey(objectID, role, ext string) string {
|
|
if ext != "" && !strings.HasPrefix(ext, ".") {
|
|
ext = "." + ext
|
|
}
|
|
return fmt.Sprintf("objects/%s/%s%s", objectID, role, ext)
|
|
}
|
|
|
|
// ObjectKey exposes the opaque storage-key format for callers outside the
|
|
// photos package that need to create their own journaled objects (for example
|
|
// user avatars). The key stays entity-free; only the caller knows the binding.
|
|
func ObjectKey(objectID, role, ext string) string { return objectKey(objectID, role, ext) }
|