Sprint 27.
New features/admin/analytics/ module + net-new /:lang/backoffice/analytics
route + Dashboard Quick Action.
- revenue/orders/avg-order-value/sales-over-time/top-products computed by
composing AdminOrdersLocalGateway (Sprint 23's seeded mock orders) - real
aggregation over mock data, not a separate fabricated dataset
- products/categories counts from AdminProductsLocalGateway/
AdminCategoriesLocalGateway
- visitors/funnels/heatmaps render pending-backend badges (no analytics
pipeline exists anywhere in this system) rather than fabricated numbers,
same convention as the Sprint 19 dashboard's pre-Sprint-23 Orders/Revenue
cards
- plain div-bar chart (no charting library), 7/30/90-day range toggle,
CSV export
docs/ADMIN.md + docs/BACKEND.md (new item 16) updated.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sprint 26.
New features/admin/monitoring/ module + net-new /:lang/backoffice/monitoring
route + Dashboard Quick Action.
- Health section reuses AdminDashboardFacade.healthChecks directly (real
data, unchanged since Sprint 19) instead of duplicating the logic
- unified AdminMonitoringEvent feed covering audit/security/login/
failed-login/api/error/warning, category filter + search, 40 seeded
synthetic entries (no logging backend exists anywhere in this system)
- mock queue depth/status cards, mock webhook delivery log
- intentionally kept separate from Sprint 24's per-transaction audit and
Sprint 25's per-user audit - different scopes, no consolidation attempted
Also fixed a real type error: AdminDashboardQuickActionId's union was
missing 'users' and 'monitoring' (added when wiring those Quick Actions),
caught by ng build's template type-checking even though plain tsc --noEmit
passed - a reminder that ng build is the authoritative check here.
docs/ADMIN.md + docs/BACKEND.md (new item 15) updated.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sprint 25.
New features/admin/users/ module, net-new /:lang/backoffice/users route +
Dashboard Quick Action.
- users: name, Telegram username, scope (marketplace vs office admin),
role (inline change), status (active/invited/suspended), last login
- 4 built-in roles (owner/admin/editor/viewer) with flat permission lists
- invitations: email + role + scope form, pending list + revoke (no email
actually sends - local record only)
- passwordless login confirmed already real (AdminAuthService Telegram QR,
docs/BACKEND.md item 1) - linked, not reimplemented
- per-user mock session list (device/IP/last-active, revoke) - flagged as
mock since the real AdminAuthService only ever tracks the current
browser's session
- per-user audit log dialog (role/status changes), same pattern as
Sprint 24's per-transaction audit, intentionally separate from the
system-wide log planned for Sprint 26
docs/ADMIN.md + docs/BACKEND.md (new item 14) updated.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sprint 24.
New features/admin/transactions/ module. AdminTransactionsLocalGateway
derives one synthetic transaction per Sprint 23's seeded mock order rather
than a separate dataset, keeping order numbers/totals consistent across
the two mock feature areas.
- list: search, status filter, type filter (payment/refund/qr_payment),
pagination, CSV export
- retry failed transactions (appends an audit entry)
- fraud flag toggle
- per-transaction audit log (creation/retry/fraud-flag-change), viewed via
dialog - intentionally separate from the system-wide audit/security log
planned for Sprint 26 (Monitoring)
- wired into /:lang/backoffice/transactions, replacing the coming-soon
placeholder
docs/ADMIN.md + docs/BACKEND.md (new item 13) updated.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sprint 23.
New features/admin/orders/ module, same container/facade/service split as
admin/products and admin/categories.
- AdminOrder model + AdminOrdersLocalGateway seeding 24 deterministic
synthetic orders (no real order data source exists anywhere in this
repo - explicitly a placeholder, not a mock of production volume)
- list: search, status filter, pagination, CSV export (client-side Blob
download)
- detail: customer/payment/shipping, itemized total, status timeline,
change-status dropdown, refund request + cancel (window.confirm-gated),
separate customer-facing vs internal notes, print invoice via
window.print() with @media print hiding non-invoice chrome
- wired into /:lang/backoffice/orders(/:id), replacing the coming-soon
placeholder
docs/ADMIN.md + docs/BACKEND.md updated; dashboard's Orders/Revenue cards
(Sprint 19) remain intentionally un-wired to this mock and still render
pending-backend.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sprint 22.
- MediaAsset gains folder (flat) and MediaListParams gains folder/tag
filters; MediaRepository.listFolders() derives the folder list from
existing records
- upload validation: 10MB size cap, mime allow-list (jpeg/png/webp/gif/
svg+xml/pdf), real error messages surfaced through MediaLibraryFacade
instead of a generic swallowed string
- SVG uploads are sanitized (script tags and on*= attributes stripped)
before storage
- raster images (excl. gif) are downscaled to a 2000px max dimension and
re-encoded via canvas before storage - compression, not a crop UI
- tag editing (window.prompt, comma-separated) via
MediaLibraryFacade.updateTags()
- MediaPickerComponent wired into Project Editor branding (logo, compact
logo, favicon) alongside its existing category/product usage - confirmed
no image fields exist on Static Pages or as a dedicated hero field to
wire
docs/ADMIN.md updated with the new Sprint 22 section including the storage
abstraction note (MediaRepository was already the abstraction).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sprint 21.
- archived (soft archive/restore, distinct from visible) with an
include-archived list filter
- barcode field alongside sku
- variants: lightweight name|price|quantity list, same textarea-parse
convention as specifications/attributes
- relatedProductIds: checkbox picker in the editor
- gallery images now added/removed via the shared MediaPickerComponent
instead of a raw URL textarea
- read-only discounted-price preview in the editor
- infinite-scroll toggle on the list (loadMore() appends a page instead
of replacing it; pagination UI swaps for a Load more button)
- category dropdown now sourced from AdminCategoriesGateway (Sprint 20)
instead of AdminProductsLocalGateway's own BackofficeDataService seed
docs/ADMIN.md + docs/BACKEND.md updated with the new field list and the
known trade-off that related-products search is scoped to the currently
loaded page, not the full catalog.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sprint 20. Adds features/admin/categories/ (model, gateway interface +
local gateway, facade, list/editor pages), mirroring the admin/products
container/facade/service split.
- indented hierarchy view + native HTML5 drag-and-drop reorder
- visibility toggle, item counter, empty state, include-deleted filter
- editor: slug uniqueness validation, translations, SEO fields, breadcrumb
preview, image via existing MediaPickerComponent
- soft delete/restore, blocked when a category has children or items
- draft/publish status + localStorage draft recovery (mirrors Project
Editor autosave) + CanDeactivate unsaved-changes guard
- wired into app.routes.ts (replaces the categories coming-soon placeholder)
- docs/ADMIN.md + docs/BACKEND.md updated with the new gap detail
Not yet done: admin/products' category dropdown still reads from its own
AdminProductsGateway.loadCategories() rather than this gateway (Sprint 21).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>