Commit Graph

43 Commits

Author SHA1 Message Date
keyhan e43274e9a2 Localize the deploy wizard.
Move the multi-step deploy wizard (app type/runtime, source, versions &
database, optional services, resources & cluster assignment, custom
domain + DNS, env vars, cost/payment, review and the provisioning
overlay) onto a dashboard.deployWizard dictionary, with localized runtime
descriptions, billing cycles, stage labels and RTL-aware controls.

This completes full fa-IR/en-US localization of the dashboard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 00:48:45 +03:30
keyhan aca69fc5e6 Localize the application detail page.
Move the largest dashboard page (app detail) onto a dashboard.appDetail
dictionary: header actions, status/lifecycle banners, configuration,
deployment history, source upload, custom-domain + DNS guide, resources
& scaling, storage, rollback/snapshots, DB restore, service credentials,
renewal and upgrade modals — with localized statuses, locale-aware dates
and RTL-aware layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 23:45:16 +03:30
keyhan 8d423f8224 Localize the managed-service detail page.
Move the service detail view (header actions, renewal banner, config,
deployment history, DB/Redis/RabbitMQ connection panels, renew modal)
onto a dashboard.serviceDetail dictionary with localized product-type and
deploy-status labels, locale-aware dates and RTL-aware layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 22:48:47 +03:30
keyhan deef498f65 Localize the managed-service resources panel.
Add components.serviceResources and move the resources/scaling panel
(metrics, storage usage/expansion, CPU/memory adjust, dump restore,
upgrade toasts) onto it; route through the locale-aware router.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 21:02:57 +03:30
keyhan 96d24b50a1 Localize database-config, snapshots panel and new-service wizard.
Add components.dbConfig / components.snapshots and dashboard.servicesNew
dictionaries; move the managed-database config (engine, credentials, dump
upload, storage), the snapshots panel and the three-step new-service
wizard onto them. validateDbDumpStorage now takes a localized template.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 19:22:37 +03:30
keyhan 63e368f464 Localize workload-logs and external-access panels.
Add components.workloadLogs, components.deployStatus and
components.externalAccess dictionaries; move the workload logs panel and
the service external-access panel onto them (tabs, live-refresh hints,
access modes, countdown units, toasts) with RTL-aware spacing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 18:25:45 +03:30
keyhan f64d341c80 Localize shared resource-field components.
Add a components.res resource-label set and move the database workload
resources and optional-service resource-field components onto it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 17:37:26 +03:30
keyhan fcba1ed93c Localize admin cluster and billing-plan pages.
Move the cluster management page (resource panel, tools install/uninstall
flow, statuses/health) and the billing-plans page (pricing matrices,
deploy defaults, add-ons, data-retention settings) onto the dictionaries
with locale-aware dates and RTL-aware tables.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 17:05:43 +03:30
keyhan 6c1133f534 Localize shared modals/overlays, logs, users and cluster-pool pages.
Add a components dictionary (delete/deleting overlays, confirm-modal
defaults, build-progress phases, deployment bar, resource-upgrade modal)
and move the logs, admin users, and admin cluster-pools pages onto the
dictionaries — filters, tables, forms, statuses, toasts and confirm
dialogs — with locale-aware dates and RTL-aware layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 15:36:30 +03:30
keyhan e99ab789ba Localize shared modal, overlay and deployment-progress components.
Localize the confirm modal, delete button, deleting overlays/modal, the
build-progress modal, deployment progress bar/manager and the resource
upgrade modal via a shared components dictionary. Build-phase labels now
resolve from the dictionary; deleting overlays take name/kind and build
their own localized message (callers updated).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:23:44 +03:30
keyhan f8ee1ca168 Localize user and admin invoice pages.
Move both invoice views onto a shared invoices dictionary — statuses,
filters, payment/line-item/transaction labels, manual status controls and
toasts — with locale-aware Link, dates and RTL-aware table/search layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:00:15 +03:30
keyhan e99dccaff1 Localize wallet and ticket pages.
Move the wallet page and all four ticket views (user list, ticket detail,
staff queue, admin overview) onto the i18n dictionaries — statuses,
priorities, departments, forms, stats, toasts and empty states — using
locale-aware Link/router and locale-aware date formatting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 12:54:19 +03:30
keyhan 2bc86c03b8 Localize applications and services list pages.
Move the apps and managed-services list pages onto the i18n dictionaries
(titles, table headers, lifecycle/expiry labels, delete confirmations,
toast messages) and the locale-aware Link, reusing the shared status and
lifecycle/expiry copy. Add RTL-aware table alignment and icon spacing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 12:28:59 +03:30
keyhan e0964e6528 Localize dashboard shell and home page.
Convert the dashboard layout (sidebar nav, header, role badges, wallet,
sign-out, language switcher) and the dashboard home page to the i18n
dictionaries, including a shared deployment-status label map. Switch their
links/router to the locale-aware helpers and add RTL-aware spacing.

Remaining dashboard page bodies and shared components still render English
copy and will be localized in follow-up commits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 12:15:21 +03:30
keyhan 34993d417f Add i18n foundation (fa-IR/en-US) and localize landing + auth.
Introduce path-prefixed locale routing under app/[lang] with a middleware
that detects locale from cookie/Accept-Language (default fa-IR) and
redirects. Add fa-IR (source of truth) and en-US dictionaries, a server
getDictionary, a client I18nProvider/useT, locale-aware Link + router
helpers, and a language switcher. The root [lang] layout sets html
lang/dir and the per-locale font (Peyda for fa, Inter for en).

Landing sections and the login/register/auth shell now read all copy from
the dictionaries; dashboard localization follows in a later commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 12:05:03 +03:30
keyhan 0f99524b0e Vendor the landing cloud texture locally instead of fetching a CDN.
drei's volumetric clouds fetch their puff sprite from a GitHub CDN at runtime.
Save that exact image to frontend/public/cloud.png and point <Clouds> at it, so
the landing page never reaches out to any external site while keeping the
original cloud look.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 17:04:44 +03:30
keyhan c8f079dbc1 Redesign the login and register pages to match the Abrban landing.
Wrap both auth pages in a shared cinematic sky shell (calm blue sky, drifting
clouds, sun glow, frosted dark-glass panel) in Persian/RTL with the Abrban
brand, while leaving the existing auth store logic and dashboard routing intact.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 16:31:42 +03:30
keyhan dfacfdc6cf Add an interactive 3D weather-journey landing page for Abrban at the site root.
Replace the root redirect with a scroll-driven three.js scene that flies from
overcast clouds through rain and a thunderstorm into a clear blue sunny sky,
fronted by Persian/RTL marketing sections. The dashboard at /dashboard is
untouched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 00:10:33 +03:30
keyhan dd1e70d80f chore: sync npm lockfile peer flags and frontend build cache.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 16:29:24 +03:30
keyhan 18c6abd0e8 Add service credential visibility.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 00:35:01 +03:30
keyhan 38748b0827 add optinal apps 2026-04-23 15:26:49 +03:30
keyhan e10f9c5235 feat(frontend): lifecycle status, wallet balance, admin billing UI
- Wallet balance display in dashboard header
- Lifecycle status badges (color-coded) in apps list
- Plan expiry countdown column
- Admin apps: suspended/pending-deletion summary cards
- Admin billing: lifecycle settings management
- Updated TypeScript types for lifecycle and billing
2026-04-22 16:44:58 +03:30
keyhan 2dd882bf34 fix: move useQuery before early returns in DashboardLayout
The useQuery hook for unanswered ticket counts was called after
two conditional early returns (isLoading and not isAuthenticated),
violating React rules of hooks. Moved it before the returns
and added isAuthenticated to the enabled condition.
2026-04-08 13:13:20 +03:30
keyhan cb9320ee15 refactor: add useDebounce hook and replace manual debounce in admin search
- Create reusable useDebounce<T> hook in frontend/src/hooks/useDebounce.ts
- Replace manual setTimeout/clearTimeout + extra state in AdminAppsPage
  with clean useDebounce(search, 400) pattern
- Removes timer state and handleSearch wrapper function
2026-04-08 12:40:25 +03:30
keyhan d01a0a5e8c feat: use Kubernetes revision-based rollback for instant app rollback
- Add revisionHistoryLimit: 10 and change-cause annotation to K8s deployments
- Add getDeploymentRevisions() to list ReplicaSet revision history
- Add rollbackDeploymentRevision() using K8s API (instant, no rebuild)
- Refactor snapshot rollback: use K8s revision for app, keep file-based DB/wp-content restore
- Add GET /snapshots/applications/:appId/revisions endpoint
- Add POST /snapshots/applications/:appId/revisions/:rev/rollback endpoint
- Add K8sRevision and K8sRevisionData types to frontend
- Redesign UI with two tabs: K8s Revisions (instant) + File Snapshots (full backup)
- K8s Revisions tab shows deployment history with one-click instant rollback
- File Snapshots tab retains download, DB restore, and wp-content restore
2026-04-08 02:26:51 +03:30
keyhan d3a5240528 feat: add snapshot/rollback system with download capability
- Add AppSnapshot entity with type (pre_deploy/manual), status tracking, and file paths
- Add SnapshotsService with create, capture, rollback, prune (max 10), and download logic
- Add SnapshotsController with REST endpoints for CRUD, rollback, and file downloads
- Add K8s methods: exportDatabaseDump, archiveWpContent, restoreWpContent
- Auto-create pre-deploy snapshots before each deployment for rollback safety
- Support downloading current live state (source, wp-content, database) without snapshots
- Add snapshot management UI in app detail page with create, rollback, download, delete
- Wire circular dependencies with forwardRef between Deployments and Snapshots modules
2026-04-08 01:55:00 +03:30
keyhan ac5278d73b feat: replace native confirm() dialogs with custom modal component
- Add ModalProvider context and useConfirm hook (confirm-modal.tsx)
- Support danger/warning/info variants with icons and colors
- Animated backdrop and dialog with CSS keyframes
- Accessible: aria-modal, role=dialog, ESC to close, auto-focus
- Replace all 6 native confirm() calls across dashboard pages
- Integrate ModalProvider in app providers
2026-04-07 23:38:55 +03:30
keyhan 5979b48a61 feat: WordPress migration support — upload existing site files
- Add two deployment modes for WordPress: Fresh Install vs Migrate Existing Site
- Fresh Install: vanilla WordPress from official image (existing behavior)
- Migrate: upload ZIP with wp-content/ (themes, plugins, uploads), wp-config.php, .htaccess
- Custom entrypoint merges staged wp-content into PVC on first container run
- Add init container for fresh WordPress builds (empty source context for Kaniko)
- Increase upload limit to 200MB for WordPress sites
- Add PHP upload limits (64MB) and memory config in WordPress Dockerfile
- Update deploy page review step to show WordPress mode info
- All UI in English
2026-04-07 23:12:25 +03:30
keyhan c2c6a32ae8 feat: billing v2 — runtime-based plans, English UI, payment flow
- ServicePlan now has 'runtime' field (nodejs/laravel/wordpress)
- Admin billing page: Application Type dropdown, English UI, Toman prices
- calculateCost filters active plans by matching runtime
- Wallet page: English UI, payment gateway integration (Pay Now button)
- Deploy page Review step: billing cycle selector (hourly/monthly/yearly),
  payment method choice (wallet or payment gateway), Pay & Deploy button
- Payment gateway endpoints: POST /billing/gateway/initiate + /verify
  (simulated — ready for Zarinpal/IDPay integration)
- Deploy requires payment: wallet deduction or gateway charge before deploy
2026-04-07 02:05:58 +03:30
keyhan 4974f88e8c feat: billing system — service plans, wallet, cost calculation
- Backend: billing module with ServicePlan, PricingRule, Wallet, WalletTransaction entities
- Admin can CRUD service plans with hourly/monthly/yearly billing cycles
- Each plan has flexible pricing rules (base_fee, cpu, memory, storage, db addon)
- Wallet system: auto-created per user, charge, deduct, refund, transaction history
- Cost calculation endpoint: cross-cycle conversion (hourly*720=monthly, monthly*12=yearly)
- Frontend: admin billing management page (/dashboard/admin/billing)
- Frontend: user wallet page with balance, quick-charge, transaction history
- Deploy page: cost breakdown shown in Review step (hourly/monthly/yearly)
- Navigation: Wallet link for users, Billing Plans link for admins
2026-04-07 01:45:45 +03:30
keyhan ac489c88d8 feat: dynamic database storage size with PVC expansion
- Add dbStorageSize column to Application entity (default: 1Gi)
- Add dbStorageSize to CreateApplicationDto, frontend types
- Use dynamic storage size in K8s deployDatabase instead of hardcoded 5Gi
- Deploy page: storage size selector with +/- buttons (min 1GB, max 100GB)
- Auto-suggest storage based on DB dump file size (3x dump size, min 1GB)
- Show DB storage in Review step
- App detail: Database Storage section with expand button
- GET /applications/:id/db-storage — read current PVC size from K8s
- PATCH /applications/:id/db-storage — expand PVC (only increase, no shrink)
- PVC resize uses JSON patch on K8s API
2026-04-07 01:28:01 +03:30
keyhan e775b57421 feat: move runtime selection to Step 0, hide source code for WordPress
- Move Application Type (Node.js/Laravel/WordPress) cards from Step 1 to Step 0 (Basic Info)
- Hide source code upload/git section when WordPress is selected
- Show WordPress info box explaining official Docker image usage
- Rename Step 1 heading to 'Versions & Database'
- Update Review step to show 'WordPress (Official Image)' as source
- Hide git branch/token review lines for WordPress
2026-04-07 00:47:42 +03:30
keyhan 762657f9ed feat: version selection for runtimes and databases
Backend:
- Add runtimeVersion, phpVersion, dbVersion columns to Application entity
- Add version fields to CreateApplicationDto with validation
- Node.js Dockerfile: use selected version (22/20/18/16) instead of hardcoded 20
- Laravel Dockerfile: use selected PHP version (8.4/8.3/8.2/8.1) instead of 8.3
- WordPress Dockerfile: use selected WP version (6.7/6.6/6.5/6.4) + PHP version
- K8s deployDatabase(): use selected DB version instead of hardcoded postgres:16/mysql:8.0
- K8s restoreDatabaseDump(): match DB image version for restore jobs
- Add dbVersion to ManifestContext interface

Frontend:
- Add runtimeVersion, phpVersion, dbVersion to Application and CreateApplicationDto
- Deploy page: Node.js version dropdown (22/20/18/16)
- Deploy page: Laravel PHP version dropdown (8.4/8.3/8.2/8.1)
- Deploy page: WordPress version + PHP version dropdowns
- Deploy page: PostgreSQL version dropdown (17/16/15/14)
- Deploy page: MySQL version dropdown (9.0/8.4/8.0/5.7)
- Deploy page: auto-set default versions on runtime/DB selection
- Review step: show selected versions
- App detail page: display runtime + DB versions in config and header
2026-04-06 23:38:23 +03:30
keyhan c411c5873e feat: add WordPress as runtime — Dockerfile, K8s env vars, wp-content PVC, frontend UI
Backend:
- Add WORDPRESS to AppRuntime enum
- Add wordpressDockerfile() using wordpress:6-php8.3-apache base image
  with custom theme/plugin/wp-content merge support
- Add WordPress-specific K8s env vars (WORDPRESS_DB_HOST, WORDPRESS_DB_USER,
  WORDPRESS_DB_PASSWORD, WORDPRESS_DB_NAME, WORDPRESS_TABLE_PREFIX)
- Create wp-content PersistentVolumeClaim (2Gi) for WordPress deployments
- Mount wp-content PVC in deployment container at /var/www/html/wp-content

Frontend:
- Add 'wordpress' to runtime type unions (Application, CreateApplicationDto)
- Add WordPress runtime card in deploy page (port 80, blue icon)
- Auto-select MySQL database when WordPress is chosen, disable other DB options
- Show Persian hint 'وردپرس به MySQL نیاز دارد' when WordPress selected
- Update all runtime icon colors across dashboard, apps, admin/apps pages
  to show blue-600 for WordPress
2026-04-06 23:13:39 +03:30
keyhan ea86acf2ab feat(ui): allow uploading DB dump at app creation — deploy page accepts optional SQL dump and uploads it after app creation 2026-04-06 22:53:47 +03:30
keyhan 9e3347cb71 feat: database management — custom credentials, dump upload/restore
Backend:
- Add dbUsername/dbPassword columns to Application entity
- Add optional DB credential fields to CreateApplicationDto
- Auto-generate dbPassword (crypto.randomBytes) and default dbUsername='appuser'
  when databaseType != 'none' on app creation
- Store both username and password in K8s DB secret (was password-only)
- Read DB_USER/POSTGRES_USER/MYSQL_USER from secretKeyRef instead of hardcoded
- New restoreDatabaseDump() in KubernetesService: creates K8s Job with
  psql/mysql client to restore uploaded SQL dump, waits for completion,
  returns logs
- New POST /applications/:id/db-upload endpoint with 500MB file limit

Frontend:
- Add dbUsername/dbPassword to Application and CreateApplicationDto types
- Deploy page: show username/password fields when database is selected,
  with generate-random-password button and show/hide toggle
- App detail page: new Database section with connection info (host, port,
  db name, username, password with copy-to-clipboard), SQL dump upload
  area with drag-and-drop, and restore output logs display

Security:
- Database remains ClusterIP only (no external exposure)
- Credentials stored in K8s Secrets (base64-encoded)
- Dump file uploaded as temporary K8s Secret, auto-cleaned after restore
2026-04-06 22:47:41 +03:30
keyhan 3ab647be2e feat: ticketing system with technical/sales roles and department routing
Backend:
- Added TECHNICAL and SALES roles to UserRole enum
- Added TicketDepartment, TicketStatus, TicketPriority enums
- Created Ticket and TicketMessage entities with relationships
- Created TicketsModule with full CRUD service and controller
- Ticket routing: users create tickets to technical/sales departments
- Staff reply updates status (answered), user reply sets waiting
- Role-based access: technical staff sees technical tickets, sales sees sales tickets
- Admin sees all tickets with stats (total, open, avg response time)
- Updated access control: technical role has admin-level access (except role change)
- Sales role can view users and handle sales tickets
- Clusters controller: technical role can manage clusters/pools
- Users controller: technical/sales can view users, only admin changes roles

Frontend:
- New user ticket pages: list (with create form) + detail (chat-style messages)
- Staff ticket panel: filtered by department with status filters
- Admin all-tickets page with statistics dashboard and department/status filters
- Updated sidebar: role-based nav items (admin/technical/sales sections)
- Role badges in header for technical (blue) and sales (green)
- Admin users page: new roles in dropdowns, role change restricted to admin only
- Deploy page: technical role gets cluster selection access like admin
2026-04-06 12:36:41 +03:30
keyhan 4fd102468e security: restrict cluster/pool selection to admin users only
Backend:
- ApplicationsService.create() now accepts userRole parameter
- Non-admin users have clusterId/poolId stripped automatically
- Logs warning when non-admin attempts manual cluster selection

Frontend:
- Deploy wizard hides cluster assignment mode selector for non-admin users
- Non-admin users see a simple 'Default Cluster' info box instead
- Cluster/pool API queries only execute for admin users (enabled: isAdmin)
- Review step shows 'Default Cluster' for non-admin regardless of form state
2026-04-06 11:36:58 +03:30
keyhan c8e66f6771 feat: comprehensive UI polish with responsive design, animations, and modern styling
- Rewrite globals.css with professional utility classes (btn-primary/secondary/danger/ghost, input-field, card/card-hover, badge system, stat-card, skeleton, page-header, animations)
- Responsive dashboard layout with mobile hamburger menu, slide-out sidebar, backdrop overlay
- Polish login/register pages with gradient backgrounds, slide-up animations, loading spinners
- Dashboard home with stat cards grid (2-col mobile, 4-col desktop), skeleton loading, empty states
- Apps list with desktop table + mobile card views, proper badges
- Deploy wizard with responsive step indicator (checkmarks, progress line), mobile-friendly forms
- App detail page with responsive header/action buttons, improved logs tabs, resource scaling
- Admin users page with desktop table + mobile cards, skeleton loading
- Admin clusters page with responsive layout, animated resource panel
- Admin pools page with responsive form grids, improved pool cards
- Consistent rounded-2xl cards, rounded-xl buttons/inputs, active:scale feedback throughout
2026-04-05 18:34:27 +03:30
keyhan e7d70f87cd feat: show build logs alongside pod logs in app detail page 2026-04-05 17:56:48 +03:30
keyhan e97af36740 feat: admin user management (create/search/role) and cluster resource monitoring
- Add POST /users endpoint for admin to create users with hashed passwords
- Add GET /users?search= with ILike search on email/firstName/lastName
- Add PATCH /users/:id/role for role assignment (user/admin)
- Return appCount per user in the users list
- Add GET /clusters/:id/resources for node, CPU, memory, pod monitoring
- Parse K8s node capacity/allocatable with CPU millicores and memory MiB helpers
- Frontend: admin users page with search bar, create form, role dropdown, app count
- Frontend: cluster resource panel with nodes table, CPU/memory bars, summary cards
2026-04-05 17:48:15 +03:30
keyhan 2621dc0cc6 feat: multi-cluster management with pool-based load balancing
- Add ClusterPool entity for grouping clusters into named pools
- Support 3 deployment modes: manual cluster, pool load-balanced, default fallback
- Pool strategies: least-apps (fewest deployed apps) and round-robin
- Add pool CRUD API endpoints (admin) and public pool listing
- Frontend deploy page: 3-mode cluster selector (Default/Manual/Pool)
- Frontend app detail: shows assigned cluster and pool info
- Admin pools management page with cluster selection and strategy picker
- Application entity extended with poolId field
2026-04-05 17:37:05 +03:30
keyhan 33be1649c4 init 2026-04-05 15:22:01 +03:30