feat(loyalty): restructure program CRUD by interface
Some checks failed
Some checks failed
Move program CRUD from store to merchant/admin interfaces. Store becomes view-only for program config while merchant gets full CRUD and admin gets override capabilities. Merchant portal: - New API endpoints (GET/POST/PATCH/DELETE /program) - New settings page with create/edit/delete form - Overview page now has Create/Edit Program buttons - Settings menu item added to sidebar Admin portal: - New CRUD endpoints (create for merchant, update, delete) - New activate/deactivate program endpoints - Programs list has edit and toggle buttons per row - Merchant detail has create/delete/toggle program actions Store portal: - Removed POST/PATCH /program endpoints (now read-only) - Removed settings page route and template - Terminal, cards, stats, enroll unchanged Tests: 112 passed (58 new) covering merchant API, admin CRUD, store endpoint removal, and program service unit tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -98,3 +98,32 @@ async def merchant_loyalty_overview(
|
||||
"loyalty/merchant/overview.html",
|
||||
context,
|
||||
)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# LOYALTY SETTINGS
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get("/settings", response_class=HTMLResponse, include_in_schema=False)
|
||||
async def merchant_loyalty_settings(
|
||||
request: Request,
|
||||
current_user: UserContext = Depends(get_current_merchant_from_cookie_or_header),
|
||||
merchant: Merchant = Depends(get_merchant_for_current_user_page),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render merchant loyalty settings page.
|
||||
|
||||
Allows merchant to create, configure, and manage their loyalty program.
|
||||
"""
|
||||
context = _get_merchant_context(
|
||||
request,
|
||||
db,
|
||||
current_user,
|
||||
merchant_id=merchant.id,
|
||||
)
|
||||
return templates.TemplateResponse(
|
||||
"loyalty/merchant/settings.html",
|
||||
context,
|
||||
)
|
||||
|
||||
@@ -178,32 +178,6 @@ async def store_loyalty_card_detail(
|
||||
)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# PROGRAM SETTINGS
|
||||
# ============================================================================
|
||||
|
||||
|
||||
@router.get(
|
||||
"/{store_code}/loyalty/settings",
|
||||
response_class=HTMLResponse,
|
||||
include_in_schema=False,
|
||||
)
|
||||
async def store_loyalty_settings(
|
||||
request: Request,
|
||||
store_code: str = Path(..., description="Store code"),
|
||||
current_user: User = Depends(get_current_store_from_cookie_or_header),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Render loyalty program settings page.
|
||||
Allows store to configure points rate, rewards, branding, etc.
|
||||
"""
|
||||
return templates.TemplateResponse(
|
||||
"loyalty/store/settings.html",
|
||||
get_store_context(request, db, current_user, store_code),
|
||||
)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# STATS DASHBOARD
|
||||
# ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user