Harden platform security, reliability, and CI after full audit.
Close deployment IDOR and gate stub payment endpoints, add production secret validation, health probes, Redis-backed build progress, GitHub Actions CI, expanded tests, billing/k8s refactors, and ops runbooks. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useParams } from 'next/navigation';
|
||||
import api from '@/lib/api';
|
||||
import { queryKeys } from '@/lib/query-keys';
|
||||
import { notify } from '@/lib/notify';
|
||||
import type { Application, Deployment, ResourceUsage, ClusterPublic, ClusterPoolPublic, AppSnapshot, K8sRevisionData, K8sRevision, OptionalServiceCredentials, Invoice } from '@/types';
|
||||
import { useState, useRef, useCallback, useEffect } from 'react';
|
||||
@@ -250,7 +251,7 @@ export default function AppDetailPage() {
|
||||
|
||||
// ─── Billing & Renewal ──────────────────────────────
|
||||
const { data: walletData } = useQuery<{ balance: number }>({
|
||||
queryKey: ['wallet'],
|
||||
queryKey: queryKeys.walletBalance,
|
||||
queryFn: () => api.get('/billing/wallet').then((r) => r.data),
|
||||
});
|
||||
|
||||
@@ -271,7 +272,7 @@ export default function AppDetailPage() {
|
||||
onSuccess: (res) => {
|
||||
notify.success(res.data.message || 'Application renewed successfully!');
|
||||
queryClient.invalidateQueries({ queryKey: ['application', appId] });
|
||||
queryClient.invalidateQueries({ queryKey: ['wallet'] });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.walletBalance });
|
||||
setShowRenewalModal(false);
|
||||
setRenewCoupon('');
|
||||
},
|
||||
@@ -646,7 +647,7 @@ export default function AppDetailPage() {
|
||||
queryClient.invalidateQueries({ queryKey: ['resources', appId] });
|
||||
queryClient.invalidateQueries({ queryKey: ['storage-usage', appId] });
|
||||
queryClient.invalidateQueries({ queryKey: ['db-storage', appId] });
|
||||
queryClient.invalidateQueries({ queryKey: ['wallet'] });
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.walletBalance });
|
||||
setShowUpgradeConfirm(false);
|
||||
setUpgradeCostData(null);
|
||||
setPendingUpgradePayload(null);
|
||||
@@ -2134,22 +2135,22 @@ export default function AppDetailPage() {
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-[11px]">
|
||||
<thead>
|
||||
<tr className="text-left text-gray-500 border-b border-gray-200">
|
||||
<th className="pb-1 font-medium">{ad.name}</th>
|
||||
<th className="pb-1 font-medium">{ad.status}</th>
|
||||
<th className="pb-1 font-medium">{ad.ready}</th>
|
||||
<th className="pb-1 font-medium">R</th>
|
||||
<tr className="text-start text-gray-500 border-b border-gray-200">
|
||||
<th className="pb-1 font-medium text-start">{ad.name}</th>
|
||||
<th className="pb-1 font-medium text-start">{ad.status}</th>
|
||||
<th className="pb-1 font-medium text-start">{ad.ready}</th>
|
||||
<th className="pb-1 font-medium text-start">{ad.restarts}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-100">
|
||||
{w.pods.map((pod) => (
|
||||
<tr key={pod.name} className="text-gray-700">
|
||||
<td className="py-1 font-mono truncate max-w-[140px]" title={pod.name}>{pod.name}</td>
|
||||
<td className="py-1">
|
||||
<td className="py-1 text-start font-mono truncate max-w-[140px]" dir="ltr" title={pod.name}>{pod.name}</td>
|
||||
<td className="py-1 text-start">
|
||||
<span className={`px-1.5 py-0.5 rounded text-[10px] font-medium ${pod.status === 'Running' ? 'bg-green-100 text-green-700' : pod.status === 'Pending' ? 'bg-yellow-100 text-yellow-700' : 'bg-red-100 text-red-700'}`}>{pod.status}</span>
|
||||
</td>
|
||||
<td className="py-1">{pod.ready ? <CheckCircle className="w-3.5 h-3.5 text-green-500" /> : <Clock className="w-3.5 h-3.5 text-yellow-500" />}</td>
|
||||
<td className="py-1">{pod.restarts}</td>
|
||||
<td className="py-1 text-start">{pod.ready ? <CheckCircle className="w-3.5 h-3.5 text-green-500" /> : <Clock className="w-3.5 h-3.5 text-yellow-500" />}</td>
|
||||
<td className="py-1 text-start">{pod.restarts}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
Reference in New Issue
Block a user