Commit Graph

32 Commits

Author SHA1 Message Date
keyhan 97e4c865b6 Require paid access before redeploy.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:37:13 +03:30
keyhan e4fe8f63cb Hide stop action for failed apps.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:31:21 +03:30
keyhan 68d1ccb196 Track cancelled deployments separately.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:15:43 +03:30
keyhan 8b197e69bc Add invoice payment management.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 21:34:47 +03:30
keyhan a7293973d5 Add staff password reset, raise code upload limit, and guard restore sizing.
Admins and technical staff can reset passwords via PATCH /users/:id/password with scoped permissions for technical users; deploy/source uploads allow up to 10GiB and block deploy when allocated storage is smaller than uploaded archive or DB dump, with an inline error modal.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-16 01:03:07 +03:30
keyhan 5239e8aa94 Add prepaid resource credits with prorated deploy billing.
When users delete an app before plan expiry, remaining resources become credits for a new deploy. The deploy calculator shows covered vs additional charges, prices optional services correctly, and prorates extras to days left on the credit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 17:37:44 +03:30
keyhan 35dd771f63 Add unified logs platform with Helm-managed central Elasticsearch.
Deploy cloudhost-logging on cluster registration, ship app and optional service logs to ES with owner isolation, and fix Kibana 8.12 auth via kibana_system.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 15:56:33 +03:30
keyhan 2303985d0c Add time-limited external access for optional services and database.
Users can open temporary NodePort access with auto-revoke via Bull jobs and a dashboard UI to manage active grants.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 13:58:08 +03:30
keyhan c7981074d4 fix(ui): keep resource scaling form values while user is editing
Skip syncing form state from the 5s resources poll when the form is
dirty, and reset dirty only after apply or workload tab change.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 01:11:10 +03:30
keyhan b24d1505b6 feat: per-workload resources, storage GiB metrics, optional service disks
- Expose DB/Redis/RabbitMQ usage plus sidecars in getResourceUsage
- Storage API: GiB fields, Redis/Rabbit PVC usage, fix du/exec container names
- PATCH /resources accepts workload; persist entity fields only for app
- App detail: workload cards, disk bars, DB expand, scale target select

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 16:28:01 +03:30
keyhan 0c0a6cd5be fix: reliable source upload, build cancel, WordPress port 80 default
- Replace port-forward/netcat PVC upload with kubectl cp for integrity
- Add build cancellation API and session cleanup; deploy catches cancel
- Default port 80 for WordPress, PHP, and Laravel on create
- Build progress modal with cancel; Helm/K8s adjustments for deployments
- Update build and kubernetes specs

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 16:03:45 +03:30
keyhan 583c4c4c90 feat(deploy): add DNS verification with modal before proceeding to next step
Add standalone DNS check endpoint and verify DNS on Next click in the
deploy wizard (step 2). Show error modal with CNAME instructions when
DNS is not configured instead of disabling the Next button. Also make
the custom domain clickable in the app detail header.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 01:20:57 +03:30
keyhan 30ccfa4ee2 fix: update cost estimate on domain toggle, switch to English, fix toggle overflow
- Cost calculation now reads custom domain price from PlatformSetting
  as fallback when no CUSTOM_DOMAIN_ADDON pricing rule exists
- Convert all custom domain UI text from Persian to English
- Fix toggle switch overflow by adding shrink-0, min-w-0, and proper
  absolute positioning

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 00:49:20 +03:30
keyhan 435cf92817 feat: add custom domain support with SSL, DNS verification, and billing
Users can assign a custom domain to their app with automatic SSL via
cert-manager. Includes DNS verification flow (CNAME check), Persian
instructions, admin-configurable pricing via PlatformSetting, and
integration into the deploy wizard cost calculation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 00:36:29 +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 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 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 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 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 3c3e0e48fa refactor: migrate from react-hot-toast to react-toastify and replace all emoji icons with Lucide React
- Replaced react-hot-toast with react-toastify (ToastContainer in providers.tsx)
- Removed @heroicons/react dependency
- Added lucide-react for consistent SVG icon system
- Migrated all 18 frontend pages from emoji icons to Lucide components
- Updated sidebar navigation, login/register, dashboard, apps, deploy,
  tickets, admin users/clusters/pools pages
- All emoji indicators (status, runtime, actions) now use proper SVG icons
- Build passes with zero TypeScript errors
2026-04-06 17:20:56 +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 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 1b1ccfc18f feat: support private git repositories with token auth
- Entity: added gitToken and gitBranch columns to Application
- DTO: added gitToken and gitBranch fields to Create/Update DTOs
- Build pipeline: git-clone init container now injects token into
  HTTPS URL for private repo authentication (GitHub PAT, GitLab token, etc.)
- Build pipeline: supports cloning specific branch (default: main)
- Frontend deploy page: added Access Token (password field) and Branch
  inputs when Git Repository source is selected
- Frontend deploy page: Review step shows branch and token status
- Frontend app detail: shows branch badge and 🔑 Private indicator
  when git credentials are configured
- Works with: GitHub, GitLab, Bitbucket, any HTTPS-based git host
2026-04-05 16:48:35 +03:30
keyhan a7ef4649e5 feat: add app preview via NodePort
- Backend: getPreviewInfo() in KubernetesService auto-patches ClusterIP
  service to NodePort for direct external access
- Backend: GET /applications/:id/preview endpoint returns access URL
  with nodePort, host IP (extracted from kubeconfig), and ingress URL
- Frontend: '🌐 Preview' button on app detail page (visible when running)
  opens the deployed app in a new browser tab via NodePort URL
- Tested: service patched to NodePort 30107 successfully
2026-04-05 16:33:48 +03:30
keyhan 51e56c6996 feat: add resource monitoring and live scaling
- Backend: getResourceUsage() method in KubernetesService fetches real-time
  CPU/Memory metrics from K8s metrics-server API per pod
- Backend: updateResources() method patches live K8s deployments with new
  CPU/Memory requests+limits and replica count
- Backend: GET /applications/:id/resources endpoint for monitoring
- Backend: PATCH /applications/:id/resources endpoint for scaling
- Backend: ScaleResourcesDto with validation for resource fields
- Frontend: Resource monitoring card with per-pod CPU/Memory progress bars
  (color-coded: green < 50%, yellow < 80%, red > 80%)
- Frontend: Pod status table showing phase, readiness, restarts
- Frontend: Scaling controls for CPU request/limit, memory request/limit,
  and replicas with +/- buttons
- Frontend: Auto-refresh metrics every 5 seconds when monitoring is open
- Frontend: parseCpuToMillicores/parseMemoryToMi helpers for metric parsing
2026-04-05 16:03:01 +03:30
keyhan 0438192f8e feat: add redeploy endpoint — rebuild from latest git/zip source and deploy new version
- Backend: added redeployApplication() to DeploymentsService that creates
  a new deployment record and re-runs the full build+deploy pipeline
- Backend: added POST /deployments/applications/:appId/redeploy endpoint
- Frontend: added Redeploy button on app detail page, visible after first
  deploy when no build is in progress
- For git-based apps: pulls latest code from repo on each redeploy
- For zip-based apps: rebuilds from last uploaded source code
2026-04-05 15:47:56 +03:30
keyhan 33be1649c4 init 2026-04-05 15:22:01 +03:30