Retires Support/donation/tiers page in favor of simple configurable link
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2,7 +2,7 @@ from fastapi import APIRouter
|
||||
|
||||
from app.config import settings
|
||||
from app.database import get_session
|
||||
from app.models import DonationTier, Event, StationConfig, Show, ShowSchedule
|
||||
from app.models import Event, StationConfig, Show, ShowSchedule
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -20,7 +20,6 @@ async def reset_database():
|
||||
await session.execute(ShowSchedule.__table__.delete())
|
||||
await session.execute(Show.__table__.delete())
|
||||
await session.execute(Event.__table__.delete())
|
||||
await session.execute(DonationTier.__table__.delete())
|
||||
await session.execute(StationConfig.__table__.delete())
|
||||
await session.commit()
|
||||
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.auth import get_current_admin_user
|
||||
from app.database import get_session
|
||||
from app.models import DonationTier
|
||||
from app.schemas import TierCreate, TierUpdate, TierResponse
|
||||
from app.user_models import User
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/", response_model=list[TierResponse])
|
||||
async def list_tiers(session: AsyncSession = Depends(get_session)):
|
||||
result = await session.execute(
|
||||
select(DonationTier).order_by(DonationTier.display_order)
|
||||
)
|
||||
return list(result.scalars().all())
|
||||
|
||||
|
||||
@router.get("/{tier_id}", response_model=TierResponse)
|
||||
async def get_tier(tier_id: int, session: AsyncSession = Depends(get_session)):
|
||||
result = await session.execute(select(DonationTier).where(DonationTier.id == tier_id))
|
||||
tier = result.scalar_one_or_none()
|
||||
if not tier:
|
||||
return {"error": "Tier not found"}
|
||||
return tier
|
||||
|
||||
|
||||
@router.post("/", response_model=TierResponse, status_code=201)
|
||||
async def create_tier(
|
||||
payload: TierCreate,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
_: User = Depends(get_current_admin_user),
|
||||
):
|
||||
tier = DonationTier(**payload.model_dump())
|
||||
session.add(tier)
|
||||
await session.commit()
|
||||
await session.refresh(tier)
|
||||
return tier
|
||||
|
||||
|
||||
@router.put("/{tier_id}", response_model=TierResponse)
|
||||
async def update_tier(
|
||||
tier_id: int,
|
||||
payload: TierUpdate,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
_: User = Depends(get_current_admin_user),
|
||||
):
|
||||
result = await session.execute(select(DonationTier).where(DonationTier.id == tier_id))
|
||||
tier = result.scalar_one_or_none()
|
||||
if not tier:
|
||||
return {"error": "Tier not found"}
|
||||
for key, value in payload.model_dump(exclude_unset=True).items():
|
||||
setattr(tier, key, value)
|
||||
await session.commit()
|
||||
await session.refresh(tier)
|
||||
return tier
|
||||
|
||||
|
||||
@router.delete("/{tier_id}", status_code=204)
|
||||
async def delete_tier(
|
||||
tier_id: int,
|
||||
session: AsyncSession = Depends(get_session),
|
||||
_: User = Depends(get_current_admin_user),
|
||||
):
|
||||
result = await session.execute(select(DonationTier).where(DonationTier.id == tier_id))
|
||||
tier = result.scalar_one_or_none()
|
||||
if not tier:
|
||||
return {"error": "Tier not found"}
|
||||
await session.delete(tier)
|
||||
await session.commit()
|
||||
+1
-2
@@ -8,7 +8,7 @@ from app.config import settings
|
||||
from app.database import async_session, engine
|
||||
from app.models import Base, Show, StationConfig, HistoryEntry, TeamMember, CommunityHighlight
|
||||
from app.user_models import User
|
||||
from app.api import events, tiers, auth, station_config, history, team, community, shows, storage
|
||||
from app.api import events, auth, station_config, history, team, community, shows, storage
|
||||
|
||||
|
||||
async def _ensure_station_config(session):
|
||||
@@ -87,7 +87,6 @@ app.add_middleware(
|
||||
# Register routers
|
||||
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
|
||||
app.include_router(events.router, prefix="/api/events", tags=["events"])
|
||||
app.include_router(tiers.router, prefix="/api/tiers", tags=["tiers"])
|
||||
app.include_router(station_config.router, prefix="/api/station-config", tags=["station-config"])
|
||||
app.include_router(history.router, prefix="/api/history", tags=["history"])
|
||||
app.include_router(team.router, prefix="/api/team", tags=["team"])
|
||||
|
||||
+3
-13
@@ -7,10 +7,8 @@ from sqlalchemy import (
|
||||
LargeBinary,
|
||||
String,
|
||||
Text,
|
||||
Numeric,
|
||||
Boolean,
|
||||
Date,
|
||||
JSON,
|
||||
ForeignKey,
|
||||
UniqueConstraint,
|
||||
)
|
||||
@@ -63,17 +61,6 @@ class Event(Base):
|
||||
active = Column(Boolean, default=True)
|
||||
|
||||
|
||||
class DonationTier(Base):
|
||||
__tablename__ = "donation_tiers"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
name = Column(String(50), unique=True, nullable=False)
|
||||
amount = Column(Numeric(10, 2), nullable=False)
|
||||
icon = Column(String(10), nullable=False)
|
||||
benefits = Column(JSON, nullable=False)
|
||||
display_order = Column(Integer, nullable=False)
|
||||
|
||||
|
||||
class StationConfig(Base):
|
||||
__tablename__ = "station_config"
|
||||
|
||||
@@ -104,6 +91,9 @@ class StationConfig(Base):
|
||||
email = Column(String(100), nullable=False, default="hello@kmountainflower.org")
|
||||
website = Column(String(200), nullable=False, default="kmountainflower.org")
|
||||
|
||||
# Donation
|
||||
donation_url = Column(String(500), nullable=False, default="")
|
||||
|
||||
|
||||
class HistoryEntry(Base):
|
||||
__tablename__ = "history_entries"
|
||||
|
||||
+2
-29
@@ -51,35 +51,6 @@ class EventResponse(BaseModel):
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
# ── DonationTier ─────────────────────────────────────────
|
||||
|
||||
class TierCreate(BaseModel):
|
||||
name: str
|
||||
amount: float
|
||||
icon: str
|
||||
benefits: list[str]
|
||||
display_order: int
|
||||
|
||||
|
||||
class TierUpdate(BaseModel):
|
||||
name: Optional[str] = None
|
||||
amount: Optional[float] = None
|
||||
icon: Optional[str] = None
|
||||
benefits: Optional[list[str]] = None
|
||||
display_order: Optional[int] = None
|
||||
|
||||
|
||||
class TierResponse(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
amount: float
|
||||
icon: str
|
||||
benefits: list[str]
|
||||
display_order: int
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
# ── StationConfig ─────────────────────────────────────────
|
||||
|
||||
class StationConfigResponse(BaseModel):
|
||||
@@ -101,6 +72,7 @@ class StationConfigResponse(BaseModel):
|
||||
phone: str
|
||||
email: str
|
||||
website: str
|
||||
donation_url: str
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
@@ -122,6 +94,7 @@ class StationConfigUpdate(BaseModel):
|
||||
phone: Optional[str] = None
|
||||
email: Optional[str] = None
|
||||
website: Optional[str] = None
|
||||
donation_url: Optional[str] = None
|
||||
|
||||
|
||||
# ── HistoryEntry ──────────────────────────────────────────
|
||||
|
||||
+2
-51
@@ -14,7 +14,7 @@ from datetime import date
|
||||
from sqlalchemy import select
|
||||
|
||||
from app.database import async_session
|
||||
from app.models import Show, ShowSchedule, Event, DonationTier, StationConfig
|
||||
from app.models import Show, ShowSchedule, Event, StationConfig
|
||||
from app.models import HistoryEntry, TeamMember, CommunityHighlight
|
||||
|
||||
# ── Seed data ──────────────────────────────────────────────
|
||||
@@ -193,37 +193,6 @@ EVENTS: list[dict] = [
|
||||
},
|
||||
]
|
||||
|
||||
TIERS: list[dict] = [
|
||||
{
|
||||
"name": "Seed",
|
||||
"amount": 5.00,
|
||||
"icon": "🌱",
|
||||
"benefits": ["Digital thank-you card", "Name listed on our website", "Quarterly newsletter"],
|
||||
"display_order": 1,
|
||||
},
|
||||
{
|
||||
"name": "Stream",
|
||||
"amount": 15.00,
|
||||
"icon": "🎵",
|
||||
"benefits": ["All Seed benefits", "KMountain Flower pin", "Priority show-request line", "Annual station update call"],
|
||||
"display_order": 2,
|
||||
},
|
||||
{
|
||||
"name": "Ridge",
|
||||
"amount": 30.00,
|
||||
"icon": "🏔️",
|
||||
"benefits": ["All Stream benefits", "Official member patch", "Exclusive show invitations", "Annual station tour"],
|
||||
"display_order": 3,
|
||||
},
|
||||
{
|
||||
"name": "Summit",
|
||||
"amount": 60.00,
|
||||
"icon": "⭐",
|
||||
"benefits": ["All Ridge benefits", "Featured on the Summit Wall", "Name on-air during anniversary special", "Lifetime patron recognition"],
|
||||
"display_order": 4,
|
||||
},
|
||||
]
|
||||
|
||||
STATION_CONFIG: dict = {
|
||||
"key": "default",
|
||||
"callsign": "KMTN",
|
||||
@@ -242,6 +211,7 @@ STATION_CONFIG: dict = {
|
||||
"phone": "(970) 555-0198",
|
||||
"email": "hello@kmountainflower.org",
|
||||
"website": "kmountainflower.org",
|
||||
"donation_url": "",
|
||||
}
|
||||
|
||||
HISTORY_ENTRIES: list[dict] = [
|
||||
@@ -348,19 +318,6 @@ async def _upsert_event(session, data: dict) -> None:
|
||||
session.add(Event(**data, active=True))
|
||||
|
||||
|
||||
async def _upsert_tier(session, data: dict) -> None:
|
||||
"""Get-or-create a donation tier matched on name."""
|
||||
existing = await session.execute(
|
||||
select(DonationTier).where(DonationTier.name == data["name"])
|
||||
)
|
||||
tier = existing.scalar_one_or_none()
|
||||
if tier:
|
||||
for key, value in data.items():
|
||||
setattr(tier, key, value)
|
||||
else:
|
||||
session.add(DonationTier(**data))
|
||||
|
||||
|
||||
async def _upsert_station_config(session, data: dict) -> None:
|
||||
"""Get-or-create the singleton station config (key='default')."""
|
||||
existing = await session.execute(
|
||||
@@ -452,11 +409,6 @@ async def seed() -> None:
|
||||
await session.commit()
|
||||
print(f" ✓ Seeded {len(EVENTS)} events")
|
||||
|
||||
for data in TIERS:
|
||||
await _upsert_tier(session, data)
|
||||
await session.commit()
|
||||
print(f" ✓ Seeded {len(TIERS)} donation tiers")
|
||||
|
||||
await _upsert_station_config(session, STATION_CONFIG)
|
||||
await session.commit()
|
||||
print(" ✓ Seeded station config")
|
||||
@@ -491,7 +443,6 @@ async def truncate_all() -> None:
|
||||
await session.execute(ShowSchedule.__table__.delete())
|
||||
await session.execute(Show.__table__.delete())
|
||||
await session.execute(Event.__table__.delete())
|
||||
await session.execute(DonationTier.__table__.delete())
|
||||
await session.execute(StationConfig.__table__.delete())
|
||||
await session.execute(HistoryEntry.__table__.delete())
|
||||
await session.execute(TeamMember.__table__.delete())
|
||||
|
||||
Reference in New Issue
Block a user