Commit Graph

38 Commits

Author SHA1 Message Date
mguschin
403d8bce4d fix: show user nav (not admin nav) when impersonating a user
When viewed_user is set, the sidebar should render the full user
navigation (connections, catalog, sync, profile) instead of the
admin-only panel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 17:54:28 +03:00
mguschin
0c71497522 feat: add delete button to admin users list page
Allow admin (not just system) to delete users directly from the list
without navigating to the detail page. Also enables role management
link and create-user role selector for admin role.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 17:48:29 +03:00
mguschin
1d268a6b58 feat: add Отчество field to admin user detail page
- Add middle_name input to the edit form (3-column name grid)
- Save middle_name in the edit handler
- Show role selector for admin role (previously system-only)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 17:21:51 +03:00
mguschin
e0594f67a8 feat: add favicon (SVG shopping-bag logo + ICO fallback)
Orange #FF5500 rounded-square with shopping-bag icon matching the
sidebar logo. Includes SVG (modern), ICO (16+32px, legacy), and
apple-touch-icon PNG.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:50:08 +03:00
mguschin
eb4165e48b feat: apply new Мои Товары design system across all templates
Replace Pico CSS with custom design: dark sidebar layout, Golos Text +
JetBrains Mono fonts, orange accent (#FF5500), new component classes
(cards, tables, buttons, tags, toggles, alerts, tabs, login split-panel).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 12:43:08 +03:00
mguschin
75513e647d revert: restore horizontal scroll table layout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:11:54 +03:00
mguschin
db0a3bb4d6 fix: table compresses to page width with fixed layout and ellipsis overflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:09:32 +03:00
mguschin
fca3ca115e fix: show create user errors inside dialog, pre-fill form on error
Used novalidate + server-side validation so errors appear in the dialog
rather than as browser-native popups. Form fields retain submitted values.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 21:01:46 +03:00
mguschin
52825f70de feat: admin can create users from /admin/users page
Adds a dialog form on the users list. Validates email uniqueness,
password length. Creates user as active with confirmed email.
System role can assign admin role; admin role can only create users.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:58:00 +03:00
mguschin
8549e98f8d feat: hide user nav links for admin, redirect admin to /admin/users on login
Connections/Catalog/VK/Sync nav links only shown for regular users or when
admin is viewing as a user. Admin/system users land on /admin/users after login.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:48:02 +03:00
mguschin
5e7be16755 feat: remove register, add evo webhooks, admin view-as user
- Remove /register route and nav links (users created via Evotor webhook)
- Fix evotor_webhooks.py: use phone=None instead of phone="" to avoid unique constraint
- Add admin "view as user" feature: POST /admin/users/{id}/view-as sets viewed_user_id
  in session; POST /admin/view-as/stop clears it
- catalog, vk_catalog, sync, connections GET routes use get_viewed_user() so admins
  see another user's data while browsing
- Orange banner shown at top when admin is viewing as another user

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-13 20:44:25 +03:00
mguschin
75b3872170 feat: per-task on/off switches on /sync page for staged rollout
Adds evo_mirror_enabled and vk_mirror_enabled flags to SyncConfig.
Each of the three background tasks (Зеркало Эвотор / Зеркало ВК /
Синхронизация) can now be enabled independently from the /sync page.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 23:32:02 +03:00
mguschin
02abddc587 refactor: derive VK description postfix from measure_name, drop global postfix setting
Each product's description is now built as "Name (цена за M.)" using its
own measure_name. The global description_postfix setting is removed —
it couldn't handle per-product units.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 23:08:45 +03:00
mguschin
e169a91146 feat: /sync settings page with price multiplier and description postfix
Adds price_multiplier and description_postfix to SyncConfig. The sync
page at /sync lets users configure them. vk_sync reads these per-user
settings and applies the multiplier to price and appends the postfix
as "(postfix)" to the VK product description.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 23:04:23 +03:00
mguschin
9960d760a0 feat: API request/response logging with admin log viewer
- Add api_logs table (migration 0007) and ApiLog model
- Add web/lib/api_logger.py — httpx wrapper that records every outbound call
- Wire api_logger into vk_sync, vk_catalog, and connections test endpoints
- Add /admin/logs page with filters (service, method, status, time range, URL search) and expandable request/response detail
- Add "Логи" nav link for admin users

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 22:00:14 +03:00
mguschin
7b4f52b005 feat: VK OAuth flow, catalog sync improvements, and expanded test suite
- Add VK OAuth implicit flow: /vk-auth redirect, /vk-callback JS page,
  /vk-callback/save endpoint with state validation
- Add VK_CLIENT_ID/VK_CLIENT_SECRET to config
- Add refresh_token/token_expires_at columns to vk_connections (migration 0006)
- Fix vk_catalog task: handle price/thumb_photo as string or dict (VK API v5.199)
- Fix connections/vk/test: use groups.getById instead of market.getAlbums
  (works with both user and group tokens)
- Add orphan deletion to mirror_to_vk: VK products not in Evotor are removed
- Handle ungrouped Evotor products: push to "Без категории" VK album
- Respect SyncConfig.is_enabled in mirror_to_vk
- Add product count column to catalog groups page
- Add group name column to catalog products page
- Expand test suite: 73 new tests covering connections routes, catalog routes,
  vk_sync task logic, and catalog task helpers (138 total, all passing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 15:09:47 +03:00
mguschin
796cf49ff9 feat: Evotor + VK catalog sync, connections, and store/group filters
- Evotor catalog: background Celery task syncing stores/groups/products
  from Evotor API; UI pages with per-store and per-group sync toggles
- VK connection: manual token + group ID entry with inline test button
- Evotor connection: inline test button (calls /stores)
- VK catalog: background task syncing VK Market albums and products;
  separate catalog UI at /vk-catalog/albums
- SyncFilter extended to support entity_type=group with parent_entity_id
- Migration 0004: vk_cached_albums + vk_cached_products tables
- Beat schedule updated to run both refresh_catalog and refresh_vk_catalog
- README updated with new schema, routes, tasks, and config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 18:09:11 +03:00
mguschin
5ead89e0cf feat: Evotor user lifecycle, RBAC, admin panel
- Receive Evotor webhooks: POST /user/create, /user/verify, /user/token
- Create users in pending status; match to existing users by email/phone
- Send invite link via Celery notification task; user sets password at /invite
- Abstract EmailProvider/SMSProvider with ConsoleEmailProvider default
- Role-based access control: role enum on users + roles/permissions tables
- Admin panel: /admin/users (list, filter, search, paginate), user detail card
  with activate/suspend/reset-password/send-invite/edit/delete actions
- Admin roles management: /admin/roles with per-role permission assignment
- Extend user profile card: role, status, Evotor ID, email confirmation badge
- Auth routes: register, login, logout, confirm-email, forgot/reset password
- Alembic migrations 0002 (full schema + new fields) and 0003 (RBAC + seeds)
- Port Pico CSS + Bootstrap Icons UI from Node.js commit (854c912)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 12:01:36 +03:00
mguschin
854c912a88 Migrate web app from Python/FastAPI to Node.js/TypeScript
Replace the entire Python/FastAPI backend with a Node.js/TypeScript stack:
- Framework: Hono + @hono/node-server
- Templates: Nunjucks (.njk) replacing Jinja2 (.html)
- ORM: Drizzle ORM with mysql2 (same MariaDB schema, no migrations needed)
- Sessions: hono-sessions with CookieStore
- CSS: Pico CSS v2 replacing Bootstrap 5 (Bootstrap Icons CDN kept)
- Dev: tsx watch; Prod: tsc + node dist/index.js

Original Python app preserved in web-python/ as backup.
Updated Dockerfile.web and docker-compose.yml for Node.js deployment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 19:33:32 +03:00
mguschin
fd7d0022ea Add VK OAuth implicit flow and fix sync issues
- Replace manual community token entry with OAuth button that redirects
  to VK authorization and auto-saves token via /vk/callback
- Fix groups.get API call (was groups.getById) to correctly retrieve
  admin group id and name from user token response
- Fix price comparison: VK price.amount is in roubles, not kopecks
- Keep manual token input as fallback when VK_CLIENT_ID is not set

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 17:21:16 +03:00
mguschin
1bf82adbfc Add sync engine and wire it into the web app
- Add sync_engine.py: background asyncio loop syncing Evotor products to VK market
- Wire sync_loop into lifespan alongside health_check_loop
- Add SYNC_INTERVAL_SECONDS and VK_DEFAULT_PHOTO_PATH settings to config
- Mount default product image in docker-compose
- Add synced_at column to CachedProduct model + migration
- Show synced_at status in catalog products template
- Fix VK groups API response parsing (handle list vs dict)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 17:05:37 +03:00
mguschin
aaeaa4f658 Fix product page dropdown clipped by table-responsive overflow
Set overflow: visible on table-responsive and use data-bs-strategy="fixed"
so the filter dropdown renders outside the scroll container.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 15:57:43 +03:00
mguschin
debb2efb3d Replace VK OAuth with manual community token entry
Resolves #4 — VK OAuth flow caused "Security Error" because market sync
requires a community access token, not a personal user token. Replaced
OAuth with manual token input (same pattern as Evotor). Added
step-by-step instructions. Updated health checker to validate community
tokens via groups.getById instead of users.get.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 15:32:13 +03:00
mguschin
4d4d5b0118 Add Jivosite live chat widget support
Resolves #3 — widget is loaded on every page via base.html when
JIVOSITE_WIDGET_ID env var is set. Centralized Jinja2Templates instance
in web/templates_env.py with jivosite_widget_id as a global.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 14:11:25 +03:00
mguschin
00b74b8aa9 Simplify Evotor connect to manual token entry only
Resolves #2 — removes semi-automatic OAuth flow (Переподключить button,
/evotor/connect and /evotor/link routes) and makes manual token entry
the sole connect option. Adds step-by-step instructions with a direct
link to the app on Evotor marketplace (opens in new tab).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 13:01:12 +03:00
mguschin
0926757b7a Fix dropdown clipping using fixed positioning strategy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 18:17:25 +03:00
mguschin
13c32e9181 Fix dropdown clipping in product table using data-bs-boundary
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 18:16:33 +03:00
mguschin
6b9eb562ba Fix dropdown clipping in product table by allowing overflow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 18:13:07 +03:00
mguschin
40e7abd012 Fix typo and redirect connections/add to evotor page
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 17:39:31 +03:00
mguschin
3d7a456299 Add manual token entry for Evotor connection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 17:35:17 +03:00
mguschin
e376c86fbe Switch Evotor integration to webhook-based token delivery flow
Replace OAuth 2.0 authorization code flow with Evotor's proprietary
webhook token delivery: POST /evotor/callback receives token server-to-server,
GET /evotor/link links it to the logged-in user's account.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 17:18:25 +03:00
mguschin
784bb27958 chore: replace EvoSync with ЭВОСИНК throughout UI
Update all page titles and branding in FastAPI app and templates to use Russian transliteration of product name.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-06 18:40:11 +03:00
mguschin
9aeef73b10 feat: release v1.8.0 — connections dashboard, VK OAuth, sync config, catalog browser
- Connections dashboard with add/remove flow and background health checks
- VK OAuth connection with profile info and health monitoring
- Sync configuration page with master toggle and filter summary
- Catalog browser with store/group/product tables, filter management, CSV export
- Alembic migrations for all new tables
- run/read_config.py for shell sync script DB integration
- CHANGELOG.md updated for v1.8.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 16:08:19 +03:00
mguschin
cfc7229daf feat: add VK OAuth connection with health checks
- Add VkConnection model with is_online/last_checked_at fields
- Add /vk OAuth flow (connect/callback/disconnect/page)
- Add VK entry to connections dashboard
- Extend background health checker to check VK tokens via users.get
- Add Alembic migration for vk_connections table
- Add VK_CLIENT_ID/SECRET/SCOPES/API_VERSION config settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 15:29:42 +03:00
mguschin
379f781e1e feat: add connections dashboard with background health checks
- Add /connections page showing all integrations with online/offline status
- Add background health checker that polls Evotor API every 10 minutes
- Add is_online and last_checked_at fields to evotor_connections table
- Replace Evotor navbar link with unified Connections link
- Redirect connect/disconnect flows to /connections
- Add Alembic migration for new columns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 15:26:49 +03:00
mguschin
865798967a feat: add Evotor OAuth connection feature with formatted phone input
- Add EvotorConnection model to store user's Evotor access tokens
- Implement OAuth 2.0 flow: /evotor (view), /evotor/connect, /evotor/callback, /evotor/disconnect
- Add Evotor connection page with connected/disconnected states
- Implement phone input masking (+7 (XXX) XXX-XX-XX) using Inputmask
- Add Russian validation messages for form fields
- Update phone validator to match masked format
- Add httpx dependency for async OAuth token exchange
- Add Evotor settings to config: CLIENT_ID, CLIENT_SECRET, SCOPES

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 21:33:41 +03:00
mguschin
bd0ff8f449 Integrate Bootstrap 5 and Bootstrap Icons into UI
- Add Bootstrap 5.3.3 + Icons via CDN to base.html
- Replace 315-line hand-written CSS with 35-line brand overrides
- Update all 13 templates with Bootstrap utility classes:
  - Responsive navbar with mobile hamburger menu
  - Consistent card-based layout for forms and profile
  - Proper button alignment with d-flex and d-grid utilities
  - List groups for data display (profile info)
  - Professional alerts and icons
- No backend changes, no build toolchain needed
- Responsive design works on mobile/tablet/desktop

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-05 21:05:30 +03:00
mguschin
951c12a208 Add user registration and auth web app
FastAPI + Jinja2 + MariaDB web application with registration,
login, profile, password reset, and email confirmation flows.
All UI in Russian. Styled with Evotor brand colors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:01:58 +03:00