Skip to content

feat: F-037 provider showcase — photo, logo, portfolio, QR code - #179

Merged
ogdevlabs merged 13 commits into
mainfrom
feat/F-037-provider-showcase
Sep 30, 2026
Merged

ogdevlabs merged 13 commits into
mainfrom
feat/F-037-provider-showcase

Conversation

@ogdevlabs

@ogdevlabs ogdevlabs commented Sep 30, 2026 •

Copy link
Copy Markdown
Owner

F-037 — Provider Showcase ("Mi vitrina")

A provider photo, a logo, a portfolio of up to 20 images, and a shareable QR code, all served by the Provider service.

Backend

  • AgendaBuddy.Library/Showcase/ + Media/, handlers in AgendaBuddy.Provider.Core/Showcase/, routes in Showcase/Media/GoModule.cs. New Gateway allowlist rows: /api/v1/showcase, /api/v1/media, /api/v1/go.
  • Every upload is re-encoded to an sRGB JPEG plus a thumbnail, which strips EXIF/GPS and defeats polyglots. Size limits are checked from the header before decoding.
  • No public image URL (ADR-069). The authenticated media route answers 404 for every reason a caller is refused.
  • /api/v1/go/{code} is the only anonymous route (ADR-070). Known, unknown and malformed codes get identical answers; it redirects only to an https store URL and keeps an anonymous per-platform counter.
  • Moderation is report + customer hide + operator takedown (ADR-072). Account erasure removes every showcase row and the provider's blobs; MediaSweeper cleans up detached uploads.
  • Aspire: AddAzureStorage("storage").AddBlobs("media") — Azurite locally, managed identity in the cloud.

Mobile

  • Mi vitrina authoring: photo/logo, tagline/about, portfolio editor (cover, reorder, captions, remove with undo), and QR + share (link, story/post/card images).
  • Customer side: showcase page, open by scan or typed code, report, hide/unhide ("Proveedores ocultos").
  • Entry points from the directory, appointment, booking, messages, dashboard and profile. Camera/photo permissions and privacy/terms clauses.

Checked by hand on the iOS simulator

Every flow above except the camera QR scan, which the simulator cannot do. Defects found and fixed in 22d5d36:

  • Multi-photo add silently added nothing. MAUI's MaximumWidth/MaximumHeight swallow a compression failure without completing the pick. The picker now returns originals, and the app resizes them itself.
  • Signing out left each tab's pages on screen. The next account opened More onto the previous account's Profile. Every tab is now reset to its root on sign-in, guarded by SignInResetsTabStacksTest.
  • A literal {0} rendered through x:Static, now guarded by StaticStringPlaceholderTest. Two Spanish labels were truncated.

Gates (local)

Suite Result
Backend slnf 1339 passed
Integration 448 passed
Mobile (MobileWorkloads=false) 1298 passed, 7 skipped
dotnet format --verify-no-changes clean
net10.0-android build 0 errors
dotnet list package --vulnerable none

Before release

  • deploy.yml with provision: true (new storage account).
  • Set Showcase:Go:AppStoreUrl, Showcase:Go:PlayStoreUrl, Showcase:ReportEmail.
  • Lawyer review of the new privacy/terms clauses.
  • Physical-device check: camera, QR scan, share sheet.

🤖 Generated with Claude Code

ogdevlabs and others added 13 commits September 30, 2026 10:12
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… layout

Route builders, wire models, error mapping and EN/es-MX copy for the
provider showcase and media routes, with the Maui-free pieces tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ing, messages, dashboard and profile

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s clauses

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nk button

Gender-neutral copy guard, icon-only button descriptions, pinned showcase
actions, and view-model tests for the directory, message, dashboard and
profile entry points.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blob-backed media pipeline (re-encode to JPEG, header-checked limits),
authenticated media route, showcase read/write handlers, anonymous /go
store redirect, reports, customer hide, operator takedown, erasure of
showcase rows and blobs, hourly detached-media sweep. Gateway allowlist
rows for /showcase, /media and /go; Azure Storage (Azurite locally) in
the AppHost. Unit, integration, OpenAPI and Bruno updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Multi-photo add silently added nothing on iOS: MediaPicker's MaximumWidth/
  MaximumHeight route every result through MAUI's compression inside an async
  callback that swallows a failure without completing the pick. The picker now
  returns originals and EncodeAsync downsizes them itself.
- Sign-out left every tab's pushed pages in place, so the next account on the
  device opened More onto the previous account's Profile (email, avatar,
  provider rows). UpdateForRoleAsync, the one step every sign-in passes
  through, now pops every tab to its root first.
- "Tu código: {0}" rendered its placeholder literally through x:Static;
  StaticStringPlaceholderTest now fails on any format placeholder in a string
  a view binds statically.
- Mi vitrina: edit buttons stacked (Spanish labels truncated at half width),
  code label hidden with a hint until a code exists; share-format buttons no
  longer clip "Publicación".
- CLAUDE.md test counts: 1339 backend, 448 integration, 1305 mobile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ogdevlabs ogdevlabs changed the title feat(F-037): provider-showcase feat: F-037 provider showcase — photo, logo, portfolio, QR code Sep 30, 2026
@ogdevlabs
ogdevlabs marked this pull request as ready for review September 30, 2026 22:06
@ogdevlabs
ogdevlabs merged commit 3b073f7 into main Sep 30, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant