Commit Graph

6 Commits

Author SHA1 Message Date
sdarbinyan
17adc9e9fd feat(admin): users and permissions
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>
2026-07-15 11:05:21 +04:00
sdarbinyan
7d65913245 feat(admin): transaction management
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>
2026-07-15 10:57:29 +04:00
sdarbinyan
2d8d6b6dc4 feat(admin): order management
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>
2026-07-15 10:50:59 +04:00
sdarbinyan
30afb5d778 feat(media): reusable media management
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>
2026-07-15 10:42:23 +04:00
sdarbinyan
60c63a0d2a feat(admin): complete product management
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>
2026-07-15 10:31:00 +04:00
sdarbinyan
6a8c4a549a feat(admin): complete category management
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>
2026-07-15 09:34:13 +04:00