feat: order total-formula panel, dashboard metrics, revision-API core (F53/F55/F56)
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Checked F49-F56 against current source before writing anything; three
resolved to "already done, nothing to build":
F49 (ed25519 admin auth flip) - lives entirely in the external
@marketplaces/auth package plus a live backend; nothing in this repo.
F50 (HttpOnly session cookie) - HttpOnly can only be set via a
Set-Cookie response header. No frontend code can ever set one via
document.cookie. 100% backend, always was.
F51 (route permission guards) - already deliberately paused by prior
work with a stated reason ("could lock an admin out without warning"
across 27 routes, no live backend to verify against). Respected that
judgment rather than overriding it blind.
F54 (wire mock requestRefund) - already resolved by the Block 3 gateway
swap; the facade calls gateway.requestRefund(), which now hits the
real endpoint. No mock left to wire.
Built:
- AdminOrder gains optional per-line pricing fields (unitPriceMinor,
lineTotalMinor, priceSnapshotId, discountMinor) plus fxQuoteId and
routing, per PHASE-1-MONEY-FX-PAYMENTS-CONTRACT.md §5.3/§6.5. All
optional - most orders today have none of it, and absence must render
as "not available", never a fabricated 0.
- OrderTotalFormulaComponent: pure presentational panel reconstructing
total = sum(unitPrice*qty) - discounts + delivery, wired into order
detail. Refuses to show a partial breakdown - every line must carry
unitPriceMinor or the panel says so plainly instead of half-computing.
- AdminDashboardMetrics gains 8 optional fields per
PHASE-9-TENANT-REGISTRY-DOMAINS-CONTRACT.md §7's target list (GMV, paid
orders, conversion, payment failure rate, moderation queue, low stock,
unmatched events, integration health). Status is 'unknown' when a field
is absent, not 'healthy' - a successful fetch with no field present is
not the same as a confirmed-healthy metric, same pattern the existing
'images-without-alt' check already used.
- Marketplace revision gateway core (F52/F55's shared dependency):
models/marketplace-revision.model.ts, interface, api+local gateways,
token. Additive only - the 724-line project-editor facade's actual
localStorage-to-API rewire is NOT done here; that is a separate,
larger, stateful change (autosave/undo/redo all currently synchronous)
that deserves its own verified pass, not a rushed retrofit.
One real contract ambiguity surfaced and resolved with a stated
assumption, not silently: §5 describes 4 pipeline stages
(draft/validated/preview/published) but only 3 write endpoints
(validate/publish/rollback). Modeled validate() as moving straight to
'preview' - the state publish() actually requires - treating 'validated'
as a value the caller may never observe. Documented in the model's own
comment for backend to confirm.
Local gateway enforces the pipeline order rather than being a permissive
stub: can't publish a draft, can't re-validate a previewed revision,
rollback only from published, rollback creates a new revision rather
than mutating the old one.
Verified: 152/152 unit tests (13 new), arch:check clean, production
build succeeds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -995,6 +995,14 @@ export const en: Translations = {
|
||||
draftDiscard: 'Discard draft',
|
||||
healthProductsCount: 'Products',
|
||||
healthCategoriesCount: 'Categories',
|
||||
healthGmv: 'GMV',
|
||||
healthPaidOrders: 'Paid orders',
|
||||
healthConversionRate: 'Conversion rate',
|
||||
healthPaymentFailureRate: 'Payment failure rate',
|
||||
healthModerationQueue: 'Moderation queue',
|
||||
healthLowStock: 'Low stock',
|
||||
healthUnmatchedEvents: 'Unmatched events',
|
||||
healthIntegrationHealth: 'Integration health',
|
||||
healthDraftExists: 'Draft',
|
||||
healthImagesWithoutAlt: 'Images missing alt text',
|
||||
healthStaticPagesUnpublished: 'Unpublished static pages',
|
||||
|
||||
@@ -995,6 +995,14 @@ export const hy: Translations = {
|
||||
draftDiscard: 'Չեղարկել սևագիրը',
|
||||
healthProductsCount: 'Ապրանքներ',
|
||||
healthCategoriesCount: 'Կատեգորիաներ',
|
||||
healthGmv: 'GMV',
|
||||
healthPaidOrders: 'Վճարված պատվերներ',
|
||||
healthConversionRate: 'Փոխարկման տոկոս',
|
||||
healthPaymentFailureRate: 'Անհաջող վճարումների տոկոս',
|
||||
healthModerationQueue: 'Մոդերացիայի հերթ',
|
||||
healthLowStock: 'Ցածր պահուստ',
|
||||
healthUnmatchedEvents: 'Չհամապատասխանեցված իրադարձություններ',
|
||||
healthIntegrationHealth: 'Ինտեգրումների վիճակ',
|
||||
healthDraftExists: 'Սևագիր',
|
||||
healthImagesWithoutAlt: 'Alt տեքստ չունեցող պատկերներ',
|
||||
healthStaticPagesUnpublished: 'Չհրապարակված ստատիկ էջեր',
|
||||
|
||||
@@ -995,6 +995,14 @@ export const ru: Translations = {
|
||||
draftDiscard: 'Отменить черновик',
|
||||
healthProductsCount: 'Товары',
|
||||
healthCategoriesCount: 'Категории',
|
||||
healthGmv: 'GMV',
|
||||
healthPaidOrders: 'Оплаченные заказы',
|
||||
healthConversionRate: 'Конверсия',
|
||||
healthPaymentFailureRate: 'Доля неудачных платежей',
|
||||
healthModerationQueue: 'Очередь модерации',
|
||||
healthLowStock: 'Низкий остаток',
|
||||
healthUnmatchedEvents: 'Несопоставленные события',
|
||||
healthIntegrationHealth: 'Состояние интеграций',
|
||||
healthDraftExists: 'Черновик',
|
||||
healthImagesWithoutAlt: 'Изображения без alt-текста',
|
||||
healthStaticPagesUnpublished: 'Неопубликованные статические страницы',
|
||||
|
||||
@@ -994,6 +994,14 @@ export interface Translations {
|
||||
draftDiscard: string;
|
||||
healthProductsCount: string;
|
||||
healthCategoriesCount: string;
|
||||
healthGmv: string;
|
||||
healthPaidOrders: string;
|
||||
healthConversionRate: string;
|
||||
healthPaymentFailureRate: string;
|
||||
healthModerationQueue: string;
|
||||
healthLowStock: string;
|
||||
healthUnmatchedEvents: string;
|
||||
healthIntegrationHealth: string;
|
||||
healthDraftExists: string;
|
||||
healthImagesWithoutAlt: string;
|
||||
healthStaticPagesUnpublished: string;
|
||||
|
||||
Reference in New Issue
Block a user