NW
3deddbc1b1
fix: make migrations idempotent, pass checkColumnExists to all migrations
2026-06-25 22:52:59 +01:00
NW
a8bf50df24
feat: add i18n localization system (en/es/de) with admin panel
...
- Add i18n module with tForUser/tForLang/t functions and {{param}} interpolation
- Add 3 locale files: en.json, es.json, de.json (201 keys each)
- Add language selection on /start and /language command with flag emojis
- Localize all bot user-facing strings (handlers, keyboards, errors)
- Localize messageRouter keyboard matching via locale keys
- Add DB migrations 008 (language column) and 009 (language_set column)
- Add localization admin tab at /locales for editing translations
- Add userService.getUserLanguage/setUserLanguage methods
- Cache user object on msg.__user to avoid triple DB fetch
- Idempotent migrations with checkColumnExists guards
- Error boundary on i18n locale file loading
- Admin locales route uses AVAILABLE_LANGUAGES import
2026-06-25 21:22:32 +01:00
NW
a6d81cfe83
feat: commission tracking based on wallet balances with payment history
...
- Commission = 5% of total wallet balances (not sales)
- Track commission payments in commission_payments table (migration 007)
- Show 'Due Now' = current commission - last payment amount
- Record payment form with amount and optional note
- Payment history table with date, balances, commission, paid, delta
- Delta shows difference between consecutive payments (new users = more owed)
- Seed phrase unlock reminder shows the commission due amount
- Stat warning highlight when commission is due
2026-06-23 13:01:15 +01:00
NW
c7bf3f132c
feat: unified Catalog page with Location→Category→Subcategory→Product tree
...
- New /catalog page with tree view: Location (🌍 ) → Category (📂 ) → Subcategory (📁 ) → Product
- Add/delete locations, categories, subcategories, products from one page
- JS-powered subcategory dropdown filtered by category
- Sticky sidebar with Add Location/Category/Product forms
- Responsive grid layout (tree + forms side by side, stacks on mobile)
- Navigation simplified: Catalog replaces separate Locations/Categories/Products
- Old routes still accessible for backward compatibility
- Subcategories table migration (006_subcategories.js)
- subcategory_id column added to products table
- Seed data includes subcategories (VPN, Accounts, Hardware, etc.)
2026-06-22 21:12:05 +01:00
NW
49945d9d81
security(csv-export): harden mnemonic export with super admin, audit, watermark ( #48 )
...
- Add SUPER_ADMIN_IDS config (fallback to ADMIN_IDS if not set)
- Add isSuperAdmin() to middleware/auth.js
- Create auditService.js for structured audit logging (DB + pino)
- Create migration 005_audit_log.js
- Add confirmation dialog before CSV export (confirm_export_ callback)
- Check isSuperAdmin before export — block non-super admins
- Audit log every export: admin ID, wallet type, wallet count
- Add exported_by watermark column to CSV with admin telegram ID
- Notify all other super admins when export occurs
- Add SUPER_ADMIN_IDS to .env.example
8 files changed, 154 insertions, 39 deletions
2026-06-22 10:07:58 +01:00
NW
a04e60d751
feat(state): replace in-memory Map with SQLite-backed stateService ( #59 )
...
- Create src/services/stateService.js with get/set/delete/has API
- Create migration 004_user_states.js (chat_id PK, state_data JSON, updated_at)
- TTL of 24 hours — expired states auto-deleted
- Cleanup job runs every hour (setInterval)
- Replace src/context/userStates.js Map with async stateService proxy
- Add await to all 45 userStates.get/set/delete/has calls across 13 files
- Add initStates() call in index.js startup sequence
- All state survives bot restarts now
18 files changed, 172 insertions, 46 deletions
2026-06-22 10:02:57 +01:00
NW
ce1b6003cb
feat(logging): replace 207 console.log/error/warn with pino structured logger ( #58 )
...
- Add pino + pino-pretty dependencies
- Create src/utils/logger.js with env-based LOG_LEVEL
- Replace all 207 console.log/error/warn calls across 46 source files
- Remove [DEBUG], [ERROR] string prefixes (levels convey this)
- Add pino redact for sensitive fields (mnemonic, privateKey, token, etc.)
- Structured logging with context objects instead of string interpolation
- NODE_ENV=production disables pino-pretty transport
49 files changed, 5601 insertions, 6056 deletions
2026-06-22 01:42:47 +01:00
NW
4b8144ac40
refactor(arch): split database.js into migrations + connection module ( #57 )
...
- database.js: 292→42 lines (connection + async helpers only)
- 001_initial_schema.js: 7 CREATE TABLE statements in transaction
- 002_add_columns.js: 5 ALTER TABLE checks with checkColumnExists
- 003_add_indexes.js: 6 CREATE INDEX statements
- runner.js: versioned migration runner with _meta table
- index.js: calls runMigrations() + cleanUpInvalidForeignKeys()
- ALLOWED_TABLES whitelist preserved in runner.js
- Schema version tracked in _meta table for idempotent runs
2026-06-17 22:28:11 +01:00