bradygaster/squad-places/binary-file-storage

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Pattern for storing and serving binary files (images, etc.) across both File and Blob storage backends

Install

npx vskill@latest install bradygaster/squad-places/binary-file-storage

SKILL.md

Context

When adding binary file support (images, attachments) to Squad Places, both FileStorageService and BlobStorageService must be extended consistently. The pattern applies to any new binary content type.

Patterns

Storage Interface

Add Save{Type}Async(Guid ownerId, Guid id, byte[] data, string contentType) and Get{Type}Async(Guid ownerId, Guid id) returning (byte[] Data, string ContentType)? to IBlobStorageService. Owner-scoped IDs enable natural data isolation.

FileStorageService
  • Store binary at {basePath}/{type}/{ownerId}/{id}{extension}
  • Store content type in a .meta sidecar file at {basePath}/{type}/{ownerId}/{id}.meta
  • Map content types to extensions in a switch expression
  • Create the top-level directory in InitializeAsync(); owner subdirectories created on-demand via Directory.CreateDirectory()
BlobStorageService
  • Use a dedicated container (e.g., images)
  • Blob path: {ownerId}/{id}{extension} — virtual folder structure
  • Set BlobHttpHeaders.ContentType on upload
  • For retrieval, search by prefix with GetBlobsAsync(BlobTraits, BlobStates, prefix, CancellationToken)
  • Create container in InitializeAsync()
API Pattern
  • POST /api/{type} — accept base64 body with owner ID, validate owner exists, store, return relative URL
  • GET /api/{type}/{ownerId}/{id} — serve with Results.File(data, contentType)
  • Inline upload on parent entity (e.g., ImageData on PublishArtifactRequest) as convenience
  • Only relative URLs — reject absolute http/https URLs to prevent SSRF and ensure all content is hosted
URL Security
  • Validate URLs with regex matching /api/{type}/{guid}/{guid} format
  • In HTML sanitizer, use FilterUrl event to strip non-relative src attributes rather than removing the tag entirely
  • This is more surgical than scheme-based allowlisting — permits relative paths without custom schemes
Dockerfile

Add the new data directory to the mkdir -p line.

Examples

See src/SquadPlaces.Data/FileStorageService.cs (SaveImageAsync/GetImageAsync) and src/SquadPlaces.Web/Api/ApiEndpoints.cs (image endpoints).

Anti-Patterns

  • Don't store binary data as base64 in JSON — decode to bytes first
  • Don't use GetBlobsAsync(prefix:) named parameter — the .NET 10 API requires positional args
  • Don't forget the .meta sidecar in file storage — without it, you can't serve with correct Content-Type

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
5

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/bradygaster/squad-places/binary-file-storage/badge)](https://verified-skill.com/skills/bradygaster/squad-places/binary-file-storage)

Something wrong with this skill or its page? Tell us.