Nothing in the frontend parsed the backend error envelope, and nothing
anywhere handled 429 - a rate-limited backend surfaced as a generic failure
with no retry and no user-visible explanation. core/error-handling and
core/interceptors were empty directories.
- api-error.model.ts typed envelope per BACKEND-API-REFERENCE.md section 5,
plus a status-to-code fallback so a response with no
envelope still arrives as a usable ApiError
- api-error.mapper.ts total function: HTML bodies, empty bodies and
differently-shaped JSON all produce an ApiError rather
than throwing inside the error path
- api-error.interceptor bounded retry on 429 honouring Retry-After (seconds or
HTTP-date), idempotent methods only - replaying a POST
after a 429 can double-submit, and that call belongs to
the caller that knows whether it holds an idempotency key
- rate-limit-notifier signal-based state so the UI can say "throttled,
resumes in N seconds" instead of "something went wrong";
self-clearing, because a banner outliving the throttle
trains users to ignore it
A 429 carrying no delay hint defaults to a non-zero wait so callers cannot
busy-loop the endpoint that just asked them to stop.
14 mapper tests. Suite 115/115 green, boundaries pass, build clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- ADR-0001: decision to extract auth/payment into shared @marketplaces/* packages
- Scaffold packages/auth, packages/payment; @marketplaces/auth now holds the real
telegram (customer+admin QR/session) and ed25519 (future admin challenge/response)
auth implementation, pushed to sources.vitanova.network/sdarbinyan/vitanovaPackages
- Rewire ~30 call sites to import from @marketplaces/auth; delete migrated originals
from core/auth, core/admin-auth, services/, models/
- Replace environment coupling with AUTH_API_URL/TELEGRAM_BOT_USERNAME injection
tokens and isDevMode(); wired as file:packages/auth pending registry publish
- Add TRACK-S §8: bootstrap per-marketplace admin login + marketplace-scoped
sub-admin invite/role endpoints
- Build, arch:check:boundaries, and full test suite (103/103) all green
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ran via ng update @angular/core@22 @angular/cli@22 (schematics applied
automatically). TypeScript bumped 5.9.3 -> 6.0.3 as a required peer.
Migrations applied:
- provideHttpClient() calls gained withXhr() where HttpXhrBackend is used
(app.config.ts)
- optional-chaining expressions wrapped in $safeNavigationMigration()
(language-selector.component.html)
- nullishCoalescingNotNullable/optionalChainNotNullable extended
diagnostics disabled in tsconfig.app.json/tsconfig.spec.json (matches
the new stricter default the migration works around)
Next: ng update @angular/cdk@22, then verify tsc/build/tests.
Implements ADR-0002. MediaRepository is an abstract-class DI token (matching
the Ed25519VerificationService pattern in app.config.ts) bound to
MockMediaRepository, an IndexedDB-backed implementation storing blobs
directly with lazily-created/revoked object URLs. Swapping to a real
HttpMediaRepository later is a one-line provider change.
No UI yet (Sprint 4 Task 3).
- Project editor: persist draft to localStorage, restore on reload,
last-saved/draft-restored status indicators, section/whole-draft reset
with confirmation.
- Extract shared QR/polling/expiry engine from TelegramLoginComponent
(shared/qr-login) and reuse it for a new admin login flow.
- Admin authentication kept fully separate from customer session:
own cookie/localStorage keys, signals, guard, and header interceptor
(core/admin-auth).
- ?login=true / ?adminLogin=true open the respective login dialog for
manual testing.
- Ed25519 challenge/verify interfaces (fail-closed no-op binding) ready
for backend delivery.
- Document autosave/reset/admin-auth/QR-reuse/Ed25519 model and the
remaining full-field-coverage gap in docs/Project-Editor.md.