19 Commits

Author SHA1 Message Date
sdarbinyan
d27c10dd17 feat: start @marketplaces/payment implementation
package.json already had @marketplaces/payment added (uncommitted) when this
started. Wired it in.

- app.config.ts: provideMarketplacesPayment(). apiUrl is environment.qrApiUrl
  with its trailing /api stripped - found and fixed a real bug while wiring
  this: qrApiUrl already ends in /api, and the package's default
  paymentsPath is '/api/v1/payments', so passing qrApiUrl unchanged would
  have silently doubled the path to .../api/api/v1/payments. Confirmed by
  reading the package's baseUrl() concatenation directly, not guessed.
  marketplaceDomain is a plain closure (not TenantResolverService) since
  provideMarketplacesPayment runs outside the injector.

- cart.component.ts: createPaymentIntent() and startPolling() now go through
  MARKETPLACES_PAYMENT_GATEWAY instead of api.service.ts's
  createPaymentIntent/checkCartPaymentStatus/checkCartCardPaymentStatus (our
  own earlier inferred contract, now superseded by the package's real,
  published one - POST/GET {qrApiUrl}/api/v1/payments). Deliberately did NOT
  swap to the package's own <mp-payment> UI component - that has a different
  UX paradigm entirely (window.open for redirects instead of an iframe
  popup, client-side QR generation instead of an external image service) and
  replacing the existing, already-tested 769-line popup state machine
  wholesale is a separate, much larger change than "wire the new package
  in." Only the I/O layer moved; the surrounding state machine (paymentStatus,
  checkoutInFlight, timeout/success/error handling, bank-iframe UX) is
  untouched.

  Response shape differs from the legacy provider: the package's
  PaymentStatus is a fixed union (created/pending/authorized/paid/failed/
  cancelled/expired), not a free-form string+code pair - simplified the
  status-check conditionals accordingly and added 'authorized' as a second
  success state (PaymentResult's own status union), which the legacy check
  didn't have. The package also carries no TTL/expiry field on its response,
  unlike the legacy provider's qrTTL - polling duration now falls back to
  PAYMENT_MIN_POLL_SECONDS alone; flagged in a comment.

- api.service.ts's createPaymentIntent and its QrCreateResponse-based
  resolvePaymentQrId/resolvePaymentQrUrl/resolvePaymentLink/
  resolveBankPaymentUrl helpers are now dead code. Left in place rather than
  deleted in the same pass that adds a new external dependency, so a revert
  doesn't also need to resurrect deleted code.

Verified: production build succeeds, 247/247 unit tests, arch:check clean.

E2E: 2 of 7 tests currently fail
(checkout-request-shape.spec.ts, checkout-idempotent-click.spec.ts), and
this is disclosed honestly rather than hidden. Root cause, confirmed by
tracing real network requests: the customer-session cookie fake these tests
rely on stops working somewhere between the cookie being demonstrably
present in the browser (context.cookies(), and document.cookie read from a
plain page on the same origin) and Angular's own AuthService reading it -
the session-check request never fires at all. This reproduces with or
without this session's payment changes (checkout-idempotent-click.spec.ts
doesn't touch payment creation and fails the same way), so it is not a
regression introduced here, but it is unresolved. Tried switching
context.addCookies from {domain,path} to {url} form (the standard fix for
this class of Playwright cookie issue) - did not fix it, kept anyway as the
more correct form. Documented as a known, unresolved issue directly in both
spec files and e2e/README.md rather than deleting or silently marking the
tests skip - the request-shape assertions those tests make are still
correct, they are just currently unverifiable through this harness.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 09:37:16 +04:00
sdarbinyan
21443d34a0 feat: stand up E2E harness, fix a real bootstrap bug it found
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Track Q Q1/Q4 (docs/PRODUCT-PLAN-v3.1-DELIVERY-PLAN.md). No E2E existed
before this. Playwright chosen - no existing test runner preference, and it
needs zero extra infra beyond the dev server this repo already has.

- playwright.config.ts, package.json e2e/e2e:ui/e2e:report scripts
- e2e/smoke.spec.ts       app boots, no console errors (network 404s from the
                          absent backend are filtered - expected, not a bug)
- e2e/currency-switch.spec.ts   Track Q Q4: switching currency must change
                          the displayed price VALUE, not just the label next
                          to it. Written specifically so the upcoming
                          checkout money-truth rewrite (frontend backlog
                          F10-F16, which replaces client-side FX math with a
                          server-computed total) has a regression net under
                          it before that rewrite starts.

The first run found a real, current bug: @marketplaces/auth ships plain tsc
output (dist/index.js), not Angular Package Format, so it carries no compiled
Ivy DI metadata. Any class-based provider from it - not just the Ed25519
Noop stub, AuthService itself hit the same failure - forces Angular to
JIT-compile at runtime, which throws immediately when @angular/compiler
isn't loaded. That breaks app bootstrap outright, for real users, not just
this test.

Fixed here with the minimum honest scope:
- src/main.ts: import '@angular/compiler' before bootstrap, so JIT works
  everywhere the package is injected, not just at one call site
- src/app/app.config.ts: useFactory instead of useClass for the Noop
  Ed25519 provider, since it has zero constructor deps and doesn't need
  Angular to derive metadata for it at all
- angular.json: raised the initial-bundle hard-error budget 1.5MB -> 1.8MB,
  because the compiler import made a correct build refuse to complete. A
  build that fails outright is worse than a bundle that's honestly larger
  than it should be.

The real fix belongs in the vitanovaPackages auth repo: publish via
ng-packagr so consumers get Ivy-compiled output and none of this is
necessary. Do not remove the compiler import until that ships - see the
comment left in main.ts.

Also fixed a genuine test defect while getting this to a real green: the
page renders duplicate .currency-option elements (desktop/mobile variants of
the same selector), so the first attempt at this test clicked into a hidden
duplicate and silently no-opped. Scoped the click to .currency-dropdown.open
and added an explicit poll for the DOM to reflect the new currency before
reading it back, rather than trusting a fixed timeout.

Verified: 3/3 E2E green, 115/115 unit tests green, arch:check clean,
production build succeeds.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 13:46:43 +04:00
sdarbinyan
551a22a245 fix: install shared packages over git, unbreaking CI
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
The Verdaccio registry introduced earlier is unreachable from CI (listens on
127.0.0.1:4873 behind a firewall allowing only 80/443/SSH), which broke the
architecture-governance workflow - its npm ci step could no longer resolve
@marketplaces/auth.

Packages are now published to git release branches (release/auth,
release/payment in vitanovaPackages) whose root is the package itself, and
installed with git+<repo>#release/auth. No registry, token, tunnel, or CI
secret - anonymous git read is enough.

- package.json: git dependency; .npmrc removed (no scope mapping needed)
- vitanovaPackages release.yml rebuilt to force-push release branches
- ADR-0001 amended with the distribution change and why the registry lost
- BACKEND-HANDOFF: added the multi-tenancy section (hostname -> tenantKey ->
  per-tenant bootstrap config), corrected the install and deploy notes, and
  recorded that no CD pipeline exists
- PACKAGE-EXTRACTION / PACKAGES-USAGE rewritten for the git-branch flow

Verified: npm ci, arch:check:boundaries, ng build, 103/103 tests, all with
no credentials configured.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 02:08:05 +04:00
sdarbinyan
2e4bb4ae00 feat: publish @marketplaces/auth to private registry, drop local package copy
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
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>
2026-08-18 01:32:20 +04:00
sdarbinyan
14c72d1a6a feat: extract auth into @marketplaces/auth package, add backoffice admin provisioning spec
- 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>
2026-08-18 01:05:16 +04:00
sdarbinyan
6d075fc5b9 perf: drop @lucide/angular, hand-roll used icons - initial bundle 13.68MB -> 2.64MB
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
@lucide/angular shipped its entire ~1500-icon set in the initial bundle
despite the app only using 85 named-imported icons - confirmed upstream
tree-shaking failure (sideEffects:false, clean named imports, single
non-splittable fesm file). Replaced icon-registry.ts/icon.component.ts
with hand-rolled inline SVG rendering of just the 85 used icons,
transcribed from lucide's own node data for pixel-identical output.
Zero call-site changes - AppIconName and app-icon's public API unchanged.

Also: karma-coverage wired (npm run test:coverage), baseline captured
in docs/SPRINT-PLAN-NEXT.md (32% statements / 18.5% branches).

Cart-modal -> app-dialog migration was attempted and reverted - real
conflicts (backdrop-close, nested-modal escape priority, iframe sizing),
documented in docs/FUTURE_FEATURES.md for a properly scoped follow-up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 10:55:00 +04:00
sdarbinyan
3cb81a1500 chore(deps): update @angular/cdk 21.1.5 -> 22.0.6
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Ran via ng update @angular/cdk@22 - no code migrations required.

Verified after full upgrade (core/cli/animations/common/compiler/
forms/platform-browser/router/service-worker/cdk all now 22.0.8/
22.0.6): tsc --noEmit clean, ng build --configuration=production
clean (same pre-existing bundle-budget warning, size unchanged),
arch:check:boundaries and arch:check:cycles both pass. Live-verified
in browser: storefront home renders correctly (categories/products/
i18n all working), /backoffice/dashboard (admin shell, lazy-loaded
per the earlier routing fix) renders correctly, no console errors on
either.

Required a Node.js upgrade on the dev machine first (Angular 22 CLI
needs Node >=22.22.3 or >=24.15; machine had v22.16.0) - done by the
user before this update ran.
2026-07-26 19:12:38 +04:00
sdarbinyan
3300494309 chore(deps): update Angular core/cli/animations/common/compiler/forms/platform-browser/router/service-worker 21.1.5 -> 22.0.8
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.
2026-07-26 19:06:43 +04:00
sdarbinyan
7b639cabf8 fix(admin): products canDeactivate guard, unblock npm, drop dead deps
RC-01 Phase 1 mechanical fixes (verified against current repo state,
not blindly reapplied from TODO.md):

- admin/products create/edit/duplicate now protected by an unsaved-
  changes guard (adminProductDirtyGuard), mirroring the existing
  categories pattern. AdminProductsFacade had zero dirty-tracking
  before this - added a dirty signal, set true on updateDraft(),
  cleared on load/create/successful save. Added confirmLeaveUnsaved
  to the adminProducts i18n section (en/ru/hy) - categories already
  had its own copy of this key, products didn't.
- barry-cache bumped ^0.1.0 -> ^0.9.3 (the pinned range no longer
  resolved on the registry - ETARGET - which had been silently
  blocking every npm install/uninstall all cycle).
- Removed primeng/primeicons (npm uninstall, now unblocked) - the
  only consumer (items-carousel) was already deleted in RC PERF-01.
- Removed core/search/services/search-history.service.ts, a dead
  1-line re-export with zero importers (verified: the real
  implementation is features/search/services/search-history.service.ts,
  used by search.facade.ts). Left core/search/models/* alone - those
  ARE live, imported by catalog components.

Verified before touching: HeaderConfig.showProfile toggle is already
removed from the header-section editor template (TODO.md was stale on
this one) - no change needed, will correct the tracking doc separately.

tsc --noEmit clean, npm run build green (bundle unchanged, primeng
was already tree-shaken out, this just removes the dead dependency
declaration itself).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 20:04:51 +04:00
sdarbinyan
f3c8a8cc96 feat(icons): add Lucide icon foundation
Add @lucide/angular dependency and a single shared entry point for
every icon in the app: app-icon (src/app/shared/ui/icon), backed by a
canonical name -> Lucide-icon registry (icon-registry.ts) covering
every concept the RC icon audit needs across storefront, builder, and
backoffice. One name per meaning, one default size/stroke-width, so
every screen renders the same icon the same way.

Package note: lucide-angular (unscoped) is deprecated upstream in
favor of @lucide/angular - installed the maintained package directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 01:49:38 +04:00
sdarbinyan
3bfe820443 feat(project-editor): add field-schema registry + test harness
Milestone 1 of the Configuration Engine sprint.

- Add schema/ registry: FieldSchema model, SECTION_FIELD_SCHEMAS covering
  every editable field per section, and EditorSchemaService (getFields,
  getField, all, getByPath). Single source of truth for labels, defaults,
  and validator references; sections stay hand-authored (metadata-augmented).
- Stand up Karma + Jasmine (ng test) with a headless, sandbox-free Chrome
  launcher; add tsconfig.spec.json, karma.conf.js, angular.json test target,
  and npm "test" script. First spec: editor-schema.service.spec (7 passing).

No behavior change. Gate: arch:check, tsc --noEmit, npm test (7/7), build all green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 01:51:13 +04:00
sdarbinyan
4fb918f5e4 cleaned up 2026-06-21 23:42:39 +04:00
sdarbinyan
824bed199c version 2026-06-20 15:05:09 +04:00
root
3a8bc2f893 change ports in start 2026-03-23 21:31:26 +00:00
root
d29de100c6 add loccal changes 2026-03-23 21:20:11 +00:00
sdarbinyan
369af40f20 bo integration 2026-02-20 10:44:03 +04:00
root
3f285ca15f local build 2026-01-22 11:58:50 +00:00
sdarbinyan
49d19181df updated carousel view 2026-01-18 19:44:46 +04:00
sdarbinyan
bd80896886 very first commit 2026-01-18 18:57:06 +04:00