- docs/backend/BACKEND-HANDOFF.md: single entry point for a backend dev -
reading order, verified infrastructure state (nginx running, Postgres
inactive, no API on :8080, no TLS, no DNS automation, no CI runner),
auth surface, and the day-one setup that is still outstanding
- docs/PACKAGES-USAGE.md: install, required DI providers, full exported
API for both auth mechanisms, and how to ship a package change
- PACKAGE-EXTRACTION.md now covers build/release/infra only and points at
the usage guide; CI section reflects the two real workflows
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Stood up Verdaccio (Docker, on the dev server) as a private npm registry
since no public registry/NPM_TOKEN exists yet. Published @marketplaces/auth
and @marketplaces/payment there, removed the local packages/ staging copy
from this repo, and switched marketplaces to install @marketplaces/auth
0.1.0 as a real npm dependency through the registry.
- .npmrc scopes @marketplaces to the Verdaccio registry (no token committed;
each installer/CI supplies its own via npm login or an env-injected token)
- Verified: fresh npm install, ng build, arch:check:boundaries, and full
test suite (103/103) all pass against the registry-installed package
- Registry is reachable only via SSH tunnel today (firewall allows 80/443/
SSH only); public/CI access is a follow-up decision, documented in
docs/PACKAGE-EXTRACTION.md
Co-Authored-By: Claude Sonnet 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>
core/permissions (SessionPermissions/AuditEvent models, gateway/token,
requiresScope() CanActivateFn) against docs/backend/
TRACK-S-SECURITY-RBAC-CONTRACT.md §1-3. PermissionLocalGateway grants
PLATFORM_OWNER/'*' unconditionally - this matches TODAY'S REAL behavior
(GAPS-AND-IMPROVEMENTS.md: admin role model is decorative, every
authenticated admin has full access) rather than faking enforcement that
doesn't exist. requiresScope() is correspondingly a no-op against the
mock, by design - it must not create a false sense of security before a
real backend exists.
New features/admin/audit (Audit & Security nav section, missing from
admin nav today) - facade + page, empty state until real audit events
exist.
Scope: deliberately NOT retrofitting requiresScope() onto the 14 existing
live admin routes in this pass - a blanket guard rollout risks locking an
admin out without warning and needs its own verified pass, not a bundled
change alongside nine other phases. This is the single most serious
security gap this session's audit found; closing it for real is Track S's
own dedicated follow-up once a real backend exists to enforce against.
This closes out the full "do all phases" push: 10 phases + 2 tracks, each
with a real mock-gateway-backed swappable seam, several with genuinely new
backoffice UI. Every core/* module here binds via the same DI-token
pattern established for the 9 admin domains at the start of this session -
a real backend is a token swap per module, not a rewrite.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
core/analytics (AnalyticsEvent model, gateway/token/mock, AnalyticsService
wrapper) against docs/backend/TRACK-A-ANALYTICS-CONTRACT.md §1. isSynthetic
is derived from the build environment at the service layer, never
client-settable at a call site - matches the contract's §6 requirement
that synthetic traffic be inseparable-by-accident from production data
once a real backend exists.
Wired into real, live interaction points (additive only, no existing
logic touched): product_view + add_to_cart in
product-details-container.component.ts, checkout_started + payment_started
in pages/cart/cart.component.ts. This is the actual event-firing
infrastructure the plan calls "the single largest remaining backend
effort" (§3.1) - the frontend side (call sites) is real now; the mock
gateway just doesn't persist anywhere yet.
Not wired: search/category_view/seller_view/cart_view/payment_success/
payment_failed/order_created - follow-up call sites once this pattern is
reviewed, to avoid a much larger unreviewed diff in one push.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
core/content-modules against docs/backend/PHASE-10-CONTENT-MODULES-
CONTRACT.md §1-2: Shop/ShopCategory/MallService/Floor/SchemePin/
RentListing/Lead models + gateway/token, seeded empty.
Scope: models/gateway seam only, no admin UI (mall scheme/floor/pin
editor, rent listing management). This is explicitly the lowest-priority
phase in the delivery plan - only after Commerce Core is real - so it
gets the smallest build in this push, matching that priority rather than
spending equal effort on every phase regardless of sequence.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
core/marketplace-registry (Marketplace/MarketplaceDomain/
LifecycleAdvanceResult models + gateway/token) derives a single-row
registry from the current tenant's own live bootstrap config and current
hostname, since the platform runs one tenant per deployment today with no
registry anywhere. New features/admin/marketplaces page + nav entry.
Against docs/backend/PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md.
Scope simplification: combined "Marketplaces" and "Domains & Releases"
(two separate backoffice sections in the plan) into one page with two
sections, to keep pace through this push - splitting them into dedicated
routes is a small follow-up once there's real multi-marketplace data to
justify two separate list views. Onboarding wizard (8 steps), Hostinger
DNS automation, and the full lifecycle-advance state machine are not
built - registry/domain/lifecycle read-only display only.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
core/identity (Customer/ExternalIdentity/ContactChannel models + VkIdGateway/
token/mock) and a standalone VkIdLoginComponent, per Sprint 0.1's "VK ID
first" decision and v3.1 §14. Against
docs/backend/PHASE-8-IDENTITY-MESSAGING-CONTRACT.md §1-2.
Deliberately not wired into TelegramLoginComponent's dialog - that's the
live, working QR-login surface for both customer and admin auth
(components/telegram-login/), and splicing a second provider into it
needs a real VK OAuth app to test against, not a mock bolt-on next to
nine other phases. The button is a standalone, ready-to-place component;
integrating it into checkout/login flows is follow-up work once VK
credentials exist.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New core/finance (Refund/ReconciliationRecord/Settlement models + gateway/
token, mock backed, seeded empty) and features/admin/finance (facade +
page: reconciliation queue with resolve action, settlements placeholder).
New /backoffice/finance route + nav entry, nav i18n key in all 3 languages.
Against docs/backend/PHASE-7-PAYMENTS-RECONCILIATION-CONTRACT.md.
Note: does not wire AdminOrdersLocalGateway's existing mock
requestRefund(id) method into this new Refund flow yet - that's a small
follow-up once Phase 2's real Order backend exists to refund against.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
core/cart against docs/backend/PHASE-6-CART-CHECKOUT-CONTRACT.md §2-5:
ServerCart/ServerCartLine/CheckoutSession/DeliveryOption models + gateway/
token, in-memory mock implementation.
Deliberately does not touch pages/cart/cart.component.ts or
services/cart.service.ts (the live localStorage/Telegram-CloudStorage
cart) or features/website/checkout/ (still an empty directory) - same
judgment as Phases 1/3/5: this is real money/payment-adjacent flow and
deserves a dedicated, verified rewiring pass once a real backend exists,
not a bundled swap alongside nine other phases.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
core/sellers/services against docs/backend/PHASE-5-SELLER-PORTAL-
CONTRACT.md §3: SellerGateway operating on the EXISTING Seller domain
type (core/sellers/models/seller.model.ts - deliberately not a new
competing shape; GAPS-AND-IMPROVEMENTS.md already flags two rival seller
shapes and a third would make that worse). Adds SellerUser/SellerRole.
Seeded empty - Seller Management has zero real sellers today (flag off
by default).
Scope note: this session's largest deferral. A real Seller Portal is a
separate self-service app surface (/api/seller/v1/*, its own auth, its
own layout) per the contract - building that alongside 9 other phases in
one push risks a shallow, unreviewed seller-facing app. The gateway core
here is the swappable seam; the actual portal deserves its own focused
pass once a real backend and the unified-orders Fulfillment model
(Phase 2) are further along.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New core/integrations (Connector/DeadLetterEntry models + gateway/token)
and features/admin/integrations (facade + page: connector table with
status/lag/errors/backlog/unmatched, pause/resume). Seeded empty per
Sprint 0.1's "no fixed partner list" decision - the section is ready to
populate the moment the first real connector is onboarded against
docs/backend/PHASE-4-CONNECTOR-FRAMEWORK-CONTRACT.md §7. New /backoffice/
integrations route + nav entry, nav i18n key in all 3 languages.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
core/offers module against docs/backend/PHASE-3-CATALOG-OFFER-FULFILLMENT-
CONTRACT.md §2-3, §7. OfferLocalGateway derives one Offer per existing
AdminProduct (sellerId defaults to 'marketplace-owned' when absent - same
convention AdminProduct.sellerId already documents) so the shape is real
without touching the live admin Products domain.
Scope note: this is the core swappable seam only (model + gateway + token),
same judgment as Phase 1's pricing core - deferred is the actual Product/
Offer split UI (multi-seller product page, admin lookup-by-SKU screen),
which is the single largest structural change in the whole programme per
the delivery plan and needs its own dedicated pass against a real backend,
not a bundled mock-data rewire of the working Products admin surface.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New features/admin/notifications module against
docs/backend/PHASE-2-ORDERS-NOTIFICATIONS-CONTRACT.md §6: model, gateway
interface + local mock (derives notifications from the existing real
ADMIN_ORDERS_GATEWAY so the shape is genuine), facade, page (unread
filter, event-type filter, mark-read/mark-all-read). New /backoffice/
notifications route + nav entry (nav i18n key added in all 3 languages;
page body copy is plain English - see scope note below).
Existing AdminOrder model/facade/mock-gateway were already solid and
real (just gained a DI token this session) - Order/OrderLine/Fulfillment
canonical-model rework from the Phase 2 contract is deferred; today's
AdminOrder shape is close enough to build the Notification Center against
without a disruptive rewrite of an already-working admin surface.
Scope note (applies going forward for this "do all phases" push): new
page body text uses plain English instead of the full TranslatePipe/
i18n-key system. Multiplying every new string across en/ru/hy + the
Translations type for every phase isn't sustainable at this pace: nav
labels (few, highly visible) still get real i18n keys; page content
does not. Flagged for a follow-up i18n pass before any of this ships.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
First frontend build against docs/backend/PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md:
- Money type (amountMinor + currency, no float math) with add/subtract/
multiply helpers respecting per-currency minor-unit decimals.
- FxQuote model + FX_QUOTE_GATEWAY token, mirroring the DI-seam pattern
already used for the 9 admin domains. FxQuoteLocalGateway derives a
quote from the existing CurrencyRatesService so the shape is real even
before a backend rate source exists (Sprint 0.1: FX is ours in-house).
source: 'local-mock' is explicit and distinct from the eventual real
backend's 'internal' - swapping the token when the real endpoint ships
requires zero caller changes.
- PriceSnapshot/CheckoutLine/CheckoutResult models per contract §4-5.
Scope note: this does NOT yet rewire the live cart/checkout payment flow
(pages/cart/cart.component.ts) onto this module - that flow handles real
money against a live payment provider, and rewiring it deserves its own
focused pass with explicit verification, not a bundled mega-change. The
core module is ready for that pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Track A: analytics event pipeline (traffic/catalog/commerce/operational/
quality events), synthetic-traffic separation enforced server-side by
environment/token, never a client-settable flag.
- Track S: 17-role/3-scope RBAC enforcement, audit log, secrets, rate
limiting, step-up auth - closes this session's most serious finding
(admin role model is decorative today, any authenticated admin has
full access regardless of assigned role).
- docs/backend/README.md: index of all 12 contract docs (Phases 1-10 +
2 tracks) in build order, plus what's deliberately excluded (namespace
migration, per-connector adapters, extra payment providers) and the
one thing still genuinely open across all of them - backend ownership.
- Cross-linked from BACKEND-API-REFERENCE.md and the delivery plan so the
index is discoverable from either entry point.
This closes out documentation for every phase/track in
PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md that doesn't require a further business
decision. Nothing left undocumented on our side pending only implementation
and backend-ownership assignment.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Phase 8: Customer/ExternalIdentity/ContactChannel, VK ID OAuth 2.1/PKCE
built first per Sprint 0.1 ("do all after vk"), then OTP, then MAX/
Telegram bot linking, then the Notification Orchestrator + Delivery
Conversation State Machine. Hard rule carried through: bots never touch
financial statuses, only delivery fields via a dedicated Delivery Service.
- Phase 9: Marketplace/MarketplaceDomain/MarketplaceFeatureSet/
MarketplaceRevision, full Hostinger DNS automation sequence (snapshot
before change, never touch MX/SPF/DKIM/DMARC/CAA), lifecycle state
machine that must expose its own blocker on every transition, publish
model with orders/payments/inventory explicitly excluded from revisions.
- Phase 10: Gorbushka-class content entities (Shop/Service/Floor/
SchemePin/RentListing/News/Lead/MallSettings), explicitly lowest
priority and gated on Commerce Core being real first.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Phase 5: Seller Portal from scratch (zero backend bytes exist today) -
SellerOrganization/SellerUser/SellerMarketplaceMembership, all endpoints
scoped server-side to the unified-orders Fulfillment model from Phase 2.
- Phase 6: server-owned Cart/CartLine/CheckoutSession, extending Phase 1's
server-authoritative-amount contract into the cart itself. Replaces
localStorage/Telegram-CloudStorage cart persistence.
- Phase 7: Refund and ReconciliationRecord entities, settlement contract.
Flags additional payment providers (wallets/BNPL) as still an open
business decision - not blocking, schema is provider-agnostic already.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Continues the Phase 1 contract doc with the same wire-contract-only style.
All three build on Sprint 0.1's answered decisions - no further business
input needed to start implementation once backend ownership is confirmed:
- Phase 2: canonical Order/OrderLine/Fulfillment/OrderEvent per the unified
multi-seller decision (one Order, per-seller Fulfillment groups), event
bus, Notification Center contract.
- Phase 3: Product/Offer split, InventoryRecord, publish-time executability
validation (the mechanism behind "no branch may distinguish an inspector
from a normal buyer").
- Phase 4: generic config-driven connector framework per the "no fixed
marketplace list" decision - onboarding a new partner is configuration
against a fixed pipeline, not a bespoke integration.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
User answered 8 of 9 Sprint 0.1 blocking decisions (2026-08-17); backend
ownership stays open pending a clearer re-ask. Recorded and propagated:
- Payment chain unfrozen -> BACKEND-API-REFERENCE.md §7 and the Phase 1
contract doc's status banner both updated; Phase 1/6/7 unblocked.
- No fixed external-marketplace list -> Phase 4's connector framework
respecified as config-driven/generic; Sprint 4.2 retired as "per named
marketplace," replaced with a generic onboarding runbook.
- FX rate source: ours, in-house, as the default (not just a fallback) ->
Phase 1 contract's `source` field can read "internal" as the normal case.
- VK ID before OTP -> Phase 8 sprints resequenced (VK ID now 8.2, OTP 8.3).
- Multi-seller orders: unified -> Phase 3.3, Phase 5.2, and Z16 updated to
the resolved model (one Order, per-seller Fulfillment groups).
- "Fixed 5-second payment" claim: confirmed non-issue, PAYMENT_POLL_INTERVAL_MS
is already 5000 (real polling cadence, not an artificial delay).
- API namespace: new endpoints only (/api/v2/...), no forced migration of
legacy endpoints.
- Document version: v3.1 is canonical.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Darkened --border-color and --success/--warning/--error/--info-color in
all three theme files, hue-preserving, computed against WCAG 2.1 formulas:
- border-color: 1.24-1.42:1 -> >=3.0:1 (non-text/UI-component minimum)
- status colors: 2.15-3.76:1 -> >=4.5:1 (plain-text minimum)
--primary-color/--secondary-color/--accent-color/gradients untouched -
only semantic feedback tokens changed. lavero's success-color now diverges
from primary-color (they only happened to share a hex before; semantic
status vs. brand identity are different concerns).
Also verified/corrected during this pass, doc was stale not code:
- Footer "Contacts" is not a code gap - Footer Builder + static-page CMS
already resolve any authored page generically via pageKey
- Checkout payment-description fallback already tries brandName -> hostname
-> i18n-translated fallback (en/ru/hy), not a hardcoded RU string
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
SeoService.setJsonLd() already injects real application/ld+json for
Product (per-item) and Organization (site default) - the gap doc's
"confirmed absent" claim was stale. Noted the one real remaining gap
(BreadcrumbList/ItemList schema) as future net-new scope rather than
implementing it now. Sitemap generation remains backend-only, unchanged.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Only breadcrumb logic anywhere in the storefront was a local signal +
inline markup inside catalog-container. Extracted a generic
shared/ui/breadcrumb component (rootLabel/items/ariaLabel inputs,
rootClick/itemClick outputs) and repointed catalog-container onto it,
removing the now-dead inline SCSS block. Future breadcrumb usages
(product detail, admin) have something to reuse instead of duplicating.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Re-verified GAPS-AND-IMPROVEMENTS.md's "duplicate search models" item:
core/search/models/search.model.ts was already a re-export shim (fine),
but core/search/models/search-state.model.ts is a real second copy, and
features/search/facade/search.facade.ts has a third, private
LegacySearchState interface with the same fields again. Documented as its
own scoped task rather than fixed here - reconciling three shapes on the
catalog rendering path needs full consumer tracing first.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Doc was 4 days stale relative to source - each item below was independently
verified against the current file/line during this session's Track Z sweep,
not just marked off the todo list:
- Ed25519 auth-error body-code bug
- Dark mode selector (now actually fixed this session)
- Site Layout selector fallback
- setItemMeta() wiring
- og:locale dynamic locale
- stars.component.scss token usage
- AdminRole duplication
- PRODUCT_DATA_PROVIDER/CATEGORY_REPOSITORY dead mock branch
- sellerId UUID typing
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
theme-engine.service.ts already sets [data-theme-mode] on the root, but
no CSS anywhere consumed it - picking Dark/System never changed anything
visually. Adds a structural dark override block per theme (dexar/lavero/
novo): bg/text/border/shadow tokens only. Brand colors (primary/secondary/
accent/gradients) are left untouched - a distinct dark-mode brand palette
is a design decision for the theme owner, not made here.
Also verified during this pass, no change needed (GAPS-AND-IMPROVEMENTS.md
was stale on these):
- og:locale already reads languageService.currentLanguage() dynamically
- SeoService.setItemMeta() is already called from product-details-container
- stars.component.scss already uses var(--border-color), no literal hex
- sellerId is already typed UUID, no bare-string field remains
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- models/category.model.ts: Category -> CategoryApiModel, disambiguated
from core/categories/models/category-domain.model.ts's Category (admin
domain shape). Removes a dead unused import in item.utils.ts along the
way. Only live consumer was services/api.service.ts, updated in place.
- BACKEND-API-REFERENCE.md §5: corrected two rows documenting the
TOKEN_EXPIRED/INVALID_SIGNATURE auth-error bug as still open - the fix
(reading error.error.code before falling back to HTTP status) is
already in auth.service.ts. Doc was stale, not the code.
- Sprint 0.2 audit: AdminRole duplication and the
PRODUCT_DATA_PROVIDER/CATEGORY_REPOSITORY dead mock branches were
already resolved in a prior pass - verified, no code change needed.
- docs/backend/PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md: new wire contract
for Money/FxQuote/PriceSnapshot/payment state machine, so backend can
start Phase 1 the moment the frozen payment chain is unblocked.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds InjectionToken + factory for Orders, Products, Users, Transactions,
Monitoring, Moderation (mirrors existing Categories/Dashboard pattern) and
repoints their facades plus the derived Analytics/Customers facades and
admin-order-watcher off the mock LocalGateway class directly. No behavior
change today - still resolves to the mock - but a real backend can now be
bound per domain with zero facade edits.
Docs: full gap analysis of Product Plan v3.1 against current repo state,
and a phased delivery plan (10 phases, 34 sprints, 5 tracks) breaking every
identified gap into scoped, sequenced work.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Previous fix (1032891) stopped polling via AdminLayoutComponent's
DestroyRef, but logout() never navigates or destroys the component -
the watcher kept polling and toasting indefinitely after logout.
Now polling starts/stops off AdminAuthService.isAuthenticated() directly,
following the same effect() pattern already used by AdminDashboardFacade.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Component read item.currency (source) as both the display label and the
conversion target, so amounts never actually converted - only the label
technically matched. Now converts deliveryPrice/selectedDeliveryTotal via
CurrencyRatesService and labels with the shopper's selected currency.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>