feat: event proposal and approval workflow #9

Closed
padreug wants to merge 38 commits from feat/event-approval-workflow into main
Showing only changes of commit 4d91426e82 - Show all commits

refactor: consolidate create and propose endpoints into single POST /events
Some checks failed
lint.yml / refactor: consolidate create and propose endpoints into single POST /events (pull_request) Failing after 0s

Remove separate /events/propose endpoint. POST /events now uses
invoice key (any user) and determines approval status based on:
- LNbits admin → auto-approved
- auto_approve setting → auto-approved
- Otherwise → proposed (requires admin approval)

Separate PUT /events/{id} for updates (admin key, event owner).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Padreug 2026-04-27 18:24:10 +02:00

View file

@ -105,13 +105,45 @@ async def api_events_all(
@events_api_router.post("/api/v1/events")
@events_api_router.put("/api/v1/events/{event_id}")
async def api_event_create(
data: CreateEvent,
wallet: WalletTypeInfo = Depends(require_admin_key),
event_id: str | None = None,
wallet: WalletTypeInfo = Depends(require_invoice_key),
):
if event_id:
"""
Create a new event. Any authenticated user can create events.
Admin-created events are auto-approved. Non-admin events require
approval unless auto_approve is enabled in extension settings.
"""
if not data.wallet:
data.wallet = wallet.wallet.id
from lnbits.settings import settings
ext_settings = await get_settings()
user_id = wallet.wallet.user
is_admin = (
user_id == settings.super_user
or user_id in settings.lnbits_admin_users
)
if not is_admin and not ext_settings.auto_approve:
data.status = "proposed"
event = await create_event(data)
# Publish to Nostr if approved
if event.status == "approved":
await _publish_or_delete_nostr_event(event)
return event.dict()
@events_api_router.put("/api/v1/events/{event_id}")
async def api_event_update(
event_id: str,
data: CreateEvent,
wallet: WalletTypeInfo = Depends(require_admin_key),
):
"""Update an existing event. Requires admin key (event owner)."""
event = await get_event(event_id)
if not event:
raise HTTPException(
@ -129,25 +161,6 @@ async def api_event_create(
# Republish to Nostr if event is approved (kind 31922 is replaceable)
if event.status == "approved" and event.nostr_event_id:
await _publish_or_delete_nostr_event(event)
else:
if not data.wallet:
data.wallet = wallet.wallet.id
# Check if approval is required for non-admin users
from lnbits.settings import settings
ext_settings = await get_settings()
user_id = wallet.wallet.user
is_admin = (
user_id == settings.super_user
or user_id in settings.lnbits_admin_users
)
if not is_admin and not ext_settings.auto_approve:
data.status = "proposed"
event = await create_event(data)
# Publish to Nostr if auto-approved (admin-created)
if event.status == "approved":
await _publish_or_delete_nostr_event(event)
return event.dict()
@ -201,28 +214,6 @@ async def api_form_delete(
#########Event Approval##########
@events_api_router.post("/api/v1/events/propose")
async def api_event_propose(
data: CreateEvent,
wallet: WalletTypeInfo = Depends(require_invoice_key),
):
"""
Propose a new event for admin approval.
Requires invoice key (any authenticated user, not admin-only).
Auto-approved if the admin has enabled auto_approve in settings.
"""
ext_settings = await get_settings()
data.status = "approved" if ext_settings.auto_approve else "proposed"
data.wallet = wallet.wallet.id
event = await create_event(data)
# Publish to Nostr if auto-approved
if event.status == "approved":
await _publish_or_delete_nostr_event(event)
return event.dict()
@events_api_router.get("/api/v1/events/pending")
async def api_events_pending(
admin: Account = Depends(check_admin),