refactor: rename extension identity to spirekeeper

Fork of satmachineadmin's v2-bitspire line into its own repo. Renames
both identifiers so this extension is fully independent of the original
satmachineadmin install (which remains in service):

  - extension id   satmachineadmin -> spirekeeper
    (router prefix, static path/static_url_for, module symbols, task
     names, templates dir, config/manifest paths)
  - database name  satoshimachine  -> spirekeeper
    (Database(ext_spirekeeper), all schema-qualified table refs)

Also resets versioning to 0.1.0, sets the display name + manifest to
spirekeeper/aiolabs, and fixes the placeholder pyproject description.
Historical aiolabs/satmachineadmin#N issue references in comments are
left pointing at the original repo where those issues live.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-06-13 22:30:05 +02:00
commit a059e3f596
22 changed files with 242 additions and 242 deletions

View file

@ -94,7 +94,7 @@ from .models import (
UpsertCassetteConfigData,
)
satmachineadmin_api_router = APIRouter()
spirekeeper_api_router = APIRouter()
async def _assert_wallet_owned_by(wallet_id: str, user_id: str) -> None:
@ -254,7 +254,7 @@ async def _assert_super_config_cap_safe(
# =============================================================================
@satmachineadmin_api_router.post("/api/v1/dca/machines", response_model=Machine)
@spirekeeper_api_router.post("/api/v1/dca/machines", response_model=Machine)
async def api_create_machine(
data: CreateMachineData, user: User = Depends(check_user_exists)
) -> Machine:
@ -274,14 +274,14 @@ async def api_create_machine(
return machine
@satmachineadmin_api_router.get("/api/v1/dca/machines", response_model=list[Machine])
@spirekeeper_api_router.get("/api/v1/dca/machines", response_model=list[Machine])
async def api_list_machines(
user: User = Depends(check_user_exists),
) -> list[Machine]:
return await get_machines_for_operator(user.id)
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/machines/{machine_id}", response_model=Machine
)
async def api_get_machine(
@ -293,7 +293,7 @@ async def api_get_machine(
return machine
@satmachineadmin_api_router.put(
@spirekeeper_api_router.put(
"/api/v1/dca/machines/{machine_id}", response_model=Machine
)
async def api_update_machine(
@ -341,7 +341,7 @@ async def api_update_machine(
return updated
@satmachineadmin_api_router.delete(
@spirekeeper_api_router.delete(
"/api/v1/dca/machines/{machine_id}", status_code=HTTPStatus.NO_CONTENT
)
async def api_delete_machine(
@ -379,7 +379,7 @@ async def _client_owned_by(client_id: str, user_id: str) -> DcaClient:
return client
@satmachineadmin_api_router.post("/api/v1/dca/clients", response_model=DcaClient)
@spirekeeper_api_router.post("/api/v1/dca/clients", response_model=DcaClient)
async def api_create_client(
data: CreateDcaClientData, user: User = Depends(check_user_exists)
) -> DcaClient:
@ -388,7 +388,7 @@ async def api_create_client(
return await create_dca_client(data)
@satmachineadmin_api_router.get("/api/v1/dca/clients", response_model=list[DcaClient])
@spirekeeper_api_router.get("/api/v1/dca/clients", response_model=list[DcaClient])
async def api_list_clients(
machine_id: str | None = None,
user: User = Depends(check_user_exists),
@ -402,7 +402,7 @@ async def api_list_clients(
return await get_dca_clients_for_machine(machine_id)
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/clients/{client_id}", response_model=DcaClient
)
async def api_get_client(
@ -411,7 +411,7 @@ async def api_get_client(
return await _client_owned_by(client_id, user.id)
@satmachineadmin_api_router.put(
@spirekeeper_api_router.put(
"/api/v1/dca/clients/{client_id}", response_model=DcaClient
)
async def api_update_client(
@ -426,7 +426,7 @@ async def api_update_client(
return updated
@satmachineadmin_api_router.delete(
@spirekeeper_api_router.delete(
"/api/v1/dca/clients/{client_id}", status_code=HTTPStatus.NO_CONTENT
)
async def api_delete_client(
@ -436,7 +436,7 @@ async def api_delete_client(
await delete_dca_client(client_id)
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/clients/{client_id}/balance",
response_model=ClientBalanceSummary,
)
@ -450,7 +450,7 @@ async def api_get_client_balance(
return summary
@satmachineadmin_api_router.post(
@spirekeeper_api_router.post(
"/api/v1/dca/clients/{client_id}/settle", response_model=DcaPayment
)
async def api_settle_client_balance(
@ -498,7 +498,7 @@ async def _deposit_owned_by(deposit_id: str, user_id: str) -> DcaDeposit:
return deposit
@satmachineadmin_api_router.post("/api/v1/dca/deposits", response_model=DcaDeposit)
@spirekeeper_api_router.post("/api/v1/dca/deposits", response_model=DcaDeposit)
async def api_create_deposit(
data: CreateDepositData, user: User = Depends(check_user_exists)
) -> DcaDeposit:
@ -531,7 +531,7 @@ async def api_create_deposit(
return await create_deposit(user.id, data, currency=machine.fiat_code)
@satmachineadmin_api_router.get("/api/v1/dca/deposits", response_model=list[DcaDeposit])
@spirekeeper_api_router.get("/api/v1/dca/deposits", response_model=list[DcaDeposit])
async def api_list_deposits(
client_id: str | None = None,
user: User = Depends(check_user_exists),
@ -544,7 +544,7 @@ async def api_list_deposits(
return await get_deposits_for_operator(user.id)
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/deposits/{deposit_id}", response_model=DcaDeposit
)
async def api_get_deposit(
@ -553,7 +553,7 @@ async def api_get_deposit(
return await _deposit_owned_by(deposit_id, user.id)
@satmachineadmin_api_router.put(
@spirekeeper_api_router.put(
"/api/v1/dca/deposits/{deposit_id}", response_model=DcaDeposit
)
async def api_update_deposit(
@ -573,7 +573,7 @@ async def api_update_deposit(
return updated
@satmachineadmin_api_router.put(
@spirekeeper_api_router.put(
"/api/v1/dca/deposits/{deposit_id}/status", response_model=DcaDeposit
)
async def api_update_deposit_status(
@ -588,7 +588,7 @@ async def api_update_deposit_status(
return updated
@satmachineadmin_api_router.delete(
@spirekeeper_api_router.delete(
"/api/v1/dca/deposits/{deposit_id}", status_code=HTTPStatus.NO_CONTENT
)
async def api_delete_deposit(
@ -608,7 +608,7 @@ async def api_delete_deposit(
# =============================================================================
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/settlements", response_model=list[DcaSettlement]
)
async def api_list_settlements(
@ -617,7 +617,7 @@ async def api_list_settlements(
return await get_settlements_for_operator(user.id)
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/machines/{machine_id}/settlements",
response_model=list[DcaSettlement],
)
@ -637,7 +637,7 @@ async def api_list_settlements_for_machine(
# order).
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/settlements/stuck", response_model=StuckSettlementsResponse
)
async def api_list_stuck_settlements(
@ -668,7 +668,7 @@ async def api_list_stuck_settlements(
)
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/settlements/{settlement_id}", response_model=DcaSettlement
)
async def api_get_settlement(
@ -683,7 +683,7 @@ async def api_get_settlement(
return settlement
@satmachineadmin_api_router.post(
@spirekeeper_api_router.post(
"/api/v1/dca/settlements/{settlement_id}/partial-dispense",
response_model=DcaSettlement,
)
@ -718,7 +718,7 @@ async def api_partial_dispense(
raise HTTPException(HTTPStatus.BAD_REQUEST, str(exc)) from exc
@satmachineadmin_api_router.post(
@spirekeeper_api_router.post(
"/api/v1/dca/settlements/{settlement_id}/force-reset",
response_model=DcaSettlement,
)
@ -768,7 +768,7 @@ async def api_force_reset_settlement(
return updated
@satmachineadmin_api_router.post(
@spirekeeper_api_router.post(
"/api/v1/dca/settlements/{settlement_id}/retry",
response_model=DcaSettlement,
)
@ -821,7 +821,7 @@ async def api_retry_settlement(
return after if after is not None else updated
@satmachineadmin_api_router.post(
@spirekeeper_api_router.post(
"/api/v1/dca/settlements/{settlement_id}/notes",
response_model=DcaSettlement,
)
@ -854,7 +854,7 @@ async def api_append_settlement_note(
# =============================================================================
@satmachineadmin_api_router.get("/api/v1/dca/payments", response_model=list[DcaPayment])
@spirekeeper_api_router.get("/api/v1/dca/payments", response_model=list[DcaPayment])
async def api_list_payments(
leg_type: str | None = None,
user: User = Depends(check_user_exists),
@ -869,7 +869,7 @@ async def api_list_payments(
# =============================================================================
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/commission-splits", response_model=list[CommissionSplit]
)
async def api_get_commission_splits(
@ -889,7 +889,7 @@ async def api_get_commission_splits(
return await get_commission_splits(user.id, None)
@satmachineadmin_api_router.put(
@spirekeeper_api_router.put(
"/api/v1/dca/commission-splits", response_model=list[CommissionSplit]
)
async def api_replace_commission_splits(
@ -905,7 +905,7 @@ async def api_replace_commission_splits(
return await replace_commission_splits(user.id, data.machine_id, data.legs)
@satmachineadmin_api_router.delete(
@spirekeeper_api_router.delete(
"/api/v1/dca/commission-splits",
status_code=HTTPStatus.NO_CONTENT,
)
@ -927,7 +927,7 @@ async def api_delete_commission_splits(
# =============================================================================
@satmachineadmin_api_router.get("/api/v1/dca/super-config", response_model=SuperConfig)
@spirekeeper_api_router.get("/api/v1/dca/super-config", response_model=SuperConfig)
async def api_get_super_config(
_user: User = Depends(check_user_exists),
) -> SuperConfig:
@ -940,7 +940,7 @@ async def api_get_super_config(
return config
@satmachineadmin_api_router.put("/api/v1/dca/super-config", response_model=SuperConfig)
@spirekeeper_api_router.put("/api/v1/dca/super-config", response_model=SuperConfig)
async def api_update_super_config(
data: UpdateSuperConfigData,
_user: User = Depends(check_super_user),
@ -988,7 +988,7 @@ async def api_update_super_config(
# fields per row are denomination and count.
@satmachineadmin_api_router.get(
@spirekeeper_api_router.get(
"/api/v1/dca/machines/{machine_id}/cassettes",
response_model=list[CassetteConfig],
)
@ -1003,7 +1003,7 @@ async def api_list_machine_cassettes(
return await list_cassette_configs_for_machine(machine_id)
@satmachineadmin_api_router.post(
@spirekeeper_api_router.post(
"/api/v1/dca/machines/{machine_id}/cassettes/publish",
response_model=list[CassetteConfig],
)
@ -1049,7 +1049,7 @@ async def api_publish_machine_cassettes(
"No cassette_configs rows exist for this machine yet — "
"waiting for the ATM's bootstrap state event. Power on the "
"ATM and confirm it has reached the configured relay; "
"satmachineadmin will auto-populate cassette_configs on "
"spirekeeper will auto-populate cassette_configs on "
"receipt."
),
)
@ -1068,7 +1068,7 @@ async def api_publish_machine_cassettes(
)
# Apply each per-row edit so the operator-believed state on
# satmachineadmin reflects the published payload, even if the ATM
# spirekeeper reflects the published payload, even if the ATM
# ack lands later (v2). updated_by audit-stamps the operator user id.
for pos, row in payload.positions.items():
updated = await update_cassette_config(