0eacc322862351bc43ee3f871888401c849f6bea
Pairs with sase.tr#30.
Refund
- admin-sdk: refundPayment({ paymentId, amount?, reason, founderId }) +
RefundResult type; SASE_ADMIN_ENDPOINTS lists the new route.
- POST /api/sase/payments/[paymentId]/refund — auth + spoke-wired,
reason ≥ 5 chars, amount > 0 when provided (full refund if omitted).
Audit on success and failure.
- _refund-button.tsx: per-row [Refund] button in the Billing tab
payments table. Modal has [✓] full vs partial input, reason, and a
destructive submit. Hidden for payments that aren't refundable
(status !== completed/partially_refunded).
- Payment row now exposes an "İşlem" column (only when spoke is wired).
Bonus extension (goodwill)
- BillingActions: new "Bonus +7g/+14g/+30g + özel" buttons surfaced
for active subscriptions. Hits the same /trial/extend wire under the
hood — the spoke generalized that endpoint to active too — but the
panel uses "Bonus süre ekle (goodwill)" copy instead of "Trial uzat".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Süper Panel
Internal admin panel — sp.semih.ai — Tailscale-only access.
Phase 0 skeleton: Next.js 16 + Better Auth (email/password + TOTP) + Prisma + Postgres + Redis. Deployed on Coolify, fronted by Traefik with Let's Encrypt (Cloudflare DNS-01).
See super-panel-prd.md for the full PRD.
Local dev
pnpm install
cp .env.example .env
# fill DATABASE_URL_PANEL, BETTER_AUTH_SECRET (32+ chars)
pnpm --filter @panel/web prisma:generate
pnpm dev
Production deploy
Pushes to main trigger Coolify deploy via webhook.
Deploy status
First production deploy: 2026-05-13. Live at https://sp.semih.ai (Tailscale only).
Description
Languages
TypeScript
99.2%
CSS
0.4%
Shell
0.2%
Dockerfile
0.2%