mitai-jinkendo/backend/routers/tiers_mgmt.py

118 lines
3.5 KiB
Python
Raw Normal View History

"""
Tier Management Endpoints for Mitai Jinkendo
Admin-only CRUD for subscription tiers.
"""
from fastapi import APIRouter, HTTPException, Depends
from db import get_db, get_cursor, r2d
from auth import require_admin
router = APIRouter(prefix="/api/tiers", tags=["tiers"])
@router.get("")
def list_tiers(session: dict = Depends(require_admin)):
"""Admin: List all tiers."""
with get_db() as conn:
cur = get_cursor(conn)
cur.execute("""
SELECT * FROM tiers
ORDER BY sort_order
""")
return [r2d(r) for r in cur.fetchall()]
@router.post("")
def create_tier(data: dict, session: dict = Depends(require_admin)):
"""
Admin: Create new tier.
Required fields:
- id: Tier ID (e.g., 'enterprise')
- name: Display name
- price_monthly_cents, price_yearly_cents: Prices (NULL for free tiers)
"""
tier_id = data.get('id', '').strip()
name = data.get('name', '').strip()
description = data.get('description', '')
price_monthly_cents = data.get('price_monthly_cents')
price_yearly_cents = data.get('price_yearly_cents')
sort_order = data.get('sort_order', 99)
if not tier_id or not name:
raise HTTPException(400, "ID und Name fehlen")
with get_db() as conn:
cur = get_cursor(conn)
# Check if ID already exists
cur.execute("SELECT id FROM tiers WHERE id = %s", (tier_id,))
if cur.fetchone():
raise HTTPException(400, f"Tier '{tier_id}' existiert bereits")
# Create tier
cur.execute("""
INSERT INTO tiers (
id, name, description, price_monthly_cents, price_yearly_cents, sort_order
)
VALUES (%s, %s, %s, %s, %s, %s)
""", (tier_id, name, description, price_monthly_cents, price_yearly_cents, sort_order))
conn.commit()
return {"ok": True, "id": tier_id}
@router.put("/{tier_id}")
def update_tier(tier_id: str, data: dict, session: dict = Depends(require_admin)):
"""Admin: Update tier."""
with get_db() as conn:
cur = get_cursor(conn)
updates = []
values = []
if 'name' in data:
updates.append('name = %s')
values.append(data['name'])
if 'description' in data:
updates.append('description = %s')
values.append(data['description'])
if 'price_monthly_cents' in data:
updates.append('price_monthly_cents = %s')
values.append(data['price_monthly_cents'])
if 'price_yearly_cents' in data:
updates.append('price_yearly_cents = %s')
values.append(data['price_yearly_cents'])
if 'active' in data:
updates.append('active = %s')
values.append(data['active'])
if 'sort_order' in data:
updates.append('sort_order = %s')
values.append(data['sort_order'])
if not updates:
return {"ok": True}
updates.append('updated = CURRENT_TIMESTAMP')
values.append(tier_id)
cur.execute(
f"UPDATE tiers SET {', '.join(updates)} WHERE id = %s",
values
)
conn.commit()
return {"ok": True}
@router.delete("/{tier_id}")
def delete_tier(tier_id: str, session: dict = Depends(require_admin)):
"""Admin: Delete tier (soft-delete: set active=false)."""
with get_db() as conn:
cur = get_cursor(conn)
cur.execute("UPDATE tiers SET active = false WHERE id = %s", (tier_id,))
conn.commit()
return {"ok": True}