commit 5f37e4087df1078fa7f46e96ad0188703ce530ef
Author: Samuel Tariku <56712590+SamuelTariku@users.noreply.github.com>
Date: Mon Apr 6 13:57:08 2026 +0300
initial commit
diff --git a/FortuneBetAPI.ps1 b/FortuneBetAPI.ps1
new file mode 100644
index 0000000..456639f
--- /dev/null
+++ b/FortuneBetAPI.ps1
@@ -0,0 +1,94 @@
+
+# FortuneBetAPI.ps1
+
+# Global state
+$Global:FortuneBetToken = $null
+$Global:FortuneBetRefreshToken = $null
+$Global:ApiBase = "http://127.0.0.1:8080/api/v1"
+$Global:TenantSlug = "fortunebets" # adjust if different
+
+function Invoke-FortuneBetRequest {
+ param(
+ [string]$Method,
+ [string]$Path,
+ [object]$Body = $null,
+ [switch]$Tenant
+ )
+
+ $url = if ($Tenant) {
+ "$Global:ApiBase/tenant/$Global:TenantSlug/$Path"
+ } else {
+ "$Global:ApiBase/$Path"
+ }
+
+ $headers = @{
+ "Content-Type" = "application/json"
+ }
+
+ if ($Global:FortuneBetToken) {
+ $headers["Authorization"] = "Bearer $($Global:FortuneBetToken)"
+ }
+
+ $bodyJson = if ($Body) { ($Body | ConvertTo-Json -Depth 5 -Compress) } else { $null }
+
+ try {
+ $response = Invoke-RestMethod -Method $Method -Uri $url -Headers $headers -Body $bodyJson
+ return $response
+ }
+ catch {
+ Write-Error "Request failed: $($_.Exception.Message)"
+ if ($_.ErrorDetails) { Write-Host $_.ErrorDetails }
+ }
+}
+
+function Login-FortuneBetCustomer {
+ param(
+ [string]$Email,
+ [string]$Password
+ )
+
+ $payload = @{
+ email = $Email
+ password = $Password
+ }
+
+ $resp = Invoke-FortuneBetRequest -Method "POST" -Path "auth/customer-login" -Tenant -Body $payload
+ if ($resp -and $resp.access_token) {
+ $Global:FortuneBetToken = $resp.access_token
+ $Global:FortuneBetRefreshToken = $resp.refresh_token
+ Write-Host "β
Logged in. Token stored."
+ } else {
+ Write-Error "β Login failed. Response: $($resp | ConvertTo-Json -Depth 5)"
+ }
+}
+
+function Refresh-FortuneBetToken {
+ if (-not $Global:FortuneBetRefreshToken) {
+ Write-Error "No refresh token stored."
+ return
+ }
+
+ $payload = @{
+ refresh_token = $Global:FortuneBetRefreshToken
+ }
+
+ $resp = Invoke-FortuneBetRequest -Method "POST" -Path "auth/refresh" -Body $payload
+ if ($resp -and $resp.access_token) {
+ $Global:FortuneBetToken = $resp.access_token
+ Write-Host "π Token refreshed."
+ } else {
+ Write-Error "β Refresh failed."
+ }
+}
+
+# Example convenience wrapper
+function Get-FortuneBetProfile {
+ $resp = Invoke-FortuneBetRequest -Method "GET" -Path "user/customer-profile" -Tenant
+ return $resp
+}
+
+# Example usage:
+# . .\FortuneBetAPI.ps1 # dot-source to load functions
+# Login-FortuneBetCustomer -Email "test@example.com" -Password "1234"
+# Get-FortuneBetProfile
+# Refresh-FortuneBetToken
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..47408f5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,156 @@
+# Fortune Tester
+
+
+
+This is a tiny powershell script that i use to test the backend quickly.
+It probably would be better have unit and integration tests on the backend directly
+but alas, there is never any time to do something like this.
+
+You will need for fzf (use scoop / choco) and PSFzf
+
+## βοΈ Requirements
+
+Youβll need:
+
+* **PowerShell** (obviously)
+* **fzf** (for interactive selection)
+
+ * Install via `scoop install fzf` or `choco install fzf`
+* **PSFzf** (PowerShell integration for fzf)
+
+---
+
+## π Getting Started
+
+Load the CLI helpers:
+
+```powershell
+. ./fortune.ps1
+```
+
+Then launch the interactive test menu:
+
+```powershell
+. ./fortune_tests.ps1
+```
+
+This will open an `fzf` selector listing all available test functions.
+
+---
+
+## π§ How It Works
+
+* Every function inside `fortune_tests.ps1` is automatically registered
+* The `Main` function scans and feeds them into `fzf`
+* You select a function β provide params β it runs
+
+---
+
+## π Authentication Helpers
+
+These functions log you in and store tokens globally for reuse:
+
+* `LoginClient`
+* `LoginAdmin`
+* `LoginSuper`
+
+They automatically populate:
+
+* `$Global:FortuneBetToken`
+* `$Global:FortuneBetRefreshToken`
+
+So you donβt have to manually copy tokens
+
+---
+
+## π‘ Core Command
+
+Everything ultimately goes through:
+
+```powershell
+fortune call [-Tenant] [-Body @{...}]
+```
+
+### Example
+
+```powershell
+fortune call GET "leagues" -Tenant
+```
+
+---
+
+## π§ͺ Adding New Tests
+
+Add a new function inside `fortune_tests.ps1`:
+
+```powershell
+function MyNewTest {
+ fortune call GET "some-endpoint" -Tenant
+}
+```
+
+Thatβs it. It will automatically appear in the selector.
+
+---
+
+## π§© Available Test Categories
+
+### Payments
+
+* CryptoPay (deposit, withdrawal)
+* Chapa (deposit, banks, withdrawal)
+* ArifPay (checkout)
+
+### Direct Deposits
+
+* Create / Approve / Reject
+* Bank cycling
+* Account management
+
+### Betting
+
+* Event β Odds β Selection pipeline (`EventOddPipe`)
+* Bet placement (`CreateBet`)
+
+### Virtual Games
+
+* Providers
+* Game listing
+* Demo launch
+
+### Admin / Super Admin
+
+* Bank management
+* Direct deposit bank setup
+
+---
+
+## π Token Refresh
+
+```powershell
+fortune refresh
+```
+
+Uses the stored refresh token to get a new access token.
+
+---
+
+## π§± Environment Variables
+
+Defined in `fortune.ps1`:
+
+```powershell
+$Global:ApiBase = "http://127.0.0.1:8080/api/v1"
+$Global:TenantSlug = "fortunebets"
+```
+
+Change these if youβre pointing to a different environment.
+
+---
+
+## π‘ Why This Exists
+
+Because postman takes alot of RAM
+
+---
+
diff --git a/arifpay_requests.ps1 b/arifpay_requests.ps1
new file mode 100644
index 0000000..e87d634
--- /dev/null
+++ b/arifpay_requests.ps1
@@ -0,0 +1,27 @@
+
+function TestArifPayDeposit {
+ $request = @{
+ amount=200
+ customerEmail="samueltarikufantaye@gmail.com"
+ customerPhone="0946685511"
+ }
+ fortune call POST "arifpay/checkout" -Body $request
+}
+
+# function TestARIFCheckout {
+# $request = @{
+# cancelUrl="https://example1.com"
+# phone="251922655097"
+# email="Ex@gmail.net"
+# nonce="251assaddsasad93554asdasd8208sawas"
+# errorUrl="http://error.com"
+# notifyUrl="https://664db983ede9a2b5565497ee.mockapi.io/user"
+# successUrl="http://example.com"
+# paymentMethods=
+# expireDate=
+# items=
+# beneficiaries=
+# lang=
+#
+# }
+# }
diff --git a/calls.ps1 b/calls.ps1
new file mode 100644
index 0000000..1b9f867
--- /dev/null
+++ b/calls.ps1
@@ -0,0 +1,4 @@
+curl -X GET "http://127.0.0.1:8080/api/v1/tenant/fortunebets/user/customer-profile" \
+ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmb3J0dW5lLWJldCIsImF1ZCI6WyJhcGkuZm9ydHVuZWJldHMubmV0Il0sImV4cCI6MTc1NjQyMzQ4MywibmJmIjoxNzU2NDIyODgzLCJpYXQiOjE3NTY0MjI4ODMsIlVzZXJJZCI6MSwiUm9sZSI6ImN1c3RvbWVyIiwiQ29tcGFueUlEIjp7IlZhbHVlIjoxLCJWYWxpZCI6dHJ1ZX19.Fn8m0M8FR8Gt5I6LMPvImwI1fuUOgnj3Jexz7kBt6Vg" \
+ -H "Content-Type: application/json" \
+ -v
diff --git a/chapa_requests.ps1 b/chapa_requests.ps1
new file mode 100644
index 0000000..a77fe1b
--- /dev/null
+++ b/chapa_requests.ps1
@@ -0,0 +1,23 @@
+
+
+function TestChapaDeposit {
+ $request = @{
+ amount=200
+ }
+ fortune call POST "chapa/payments/deposit" -Body $request
+}
+
+function TestChapaBanks {
+ fortune call GET "chapa/banks"
+}
+
+function TestChapaWithdraw {
+ $request = @{
+ account_name="Samuel Tariku"
+ account_number="0946685511"
+ amount="200"
+ reference="1"
+ bank_code=128 #CBEBirr
+ }
+ fortune call POST "chapa/payments/withdraw" -Body $request
+}
diff --git a/demo.mp4 b/demo.mp4
new file mode 100644
index 0000000..f62ae03
Binary files /dev/null and b/demo.mp4 differ
diff --git a/fortune.ps1 b/fortune.ps1
new file mode 100644
index 0000000..3bb2d59
--- /dev/null
+++ b/fortune.ps1
@@ -0,0 +1,174 @@
+
+# fortune.ps1
+# Simple CLI wrapper for FortuneBet backend
+
+$Global:FortuneBetToken = $null
+$Global:FortuneBetRefreshToken = $null
+$Global:ApiBase = "http://127.0.0.1:8080/api/v1"
+$Global:TenantSlug = "fortunebets"
+
+function Invoke-FortuneAPI {
+ param(
+ [string]$Method,
+ [string]$Path,
+ [object]$Body = $null,
+ [switch]$Tenant
+ )
+
+ $url = if ($Tenant) {
+ "$Global:ApiBase/tenant/$Global:TenantSlug/$Path"
+ } else {
+ "$Global:ApiBase/$Path"
+ }
+
+ $headers = @{ "Content-Type" = "application/json" }
+ if ($Global:FortuneBetToken) {
+ $headers["Authorization"] = "Bearer $($Global:FortuneBetToken)"
+ }
+
+ $bodyJson = if ($Body) {
+ ($Body | ConvertTo-Json -Depth 5 -Compress)
+ } else {
+ $null
+ }
+ Write-Host "β‘οΈ $Method $url"
+ Write-Host "Headers:" ($headers | ConvertTo-Json -Compress)
+ try {
+ if ($Method -eq "GET" -or $Method -eq "HEAD") {
+ Invoke-RestMethod -Method $Method -Uri $url -Headers $headers -Verbose
+ } elseif ($BodyJson) {
+ Invoke-RestMethod -Method $Method -Uri $url -Headers $headers -Body $bodyJson -Verbose
+ } else {
+ Invoke-RestMethod -Method $Method -Uri $url -Headers $headers -Verbose
+ }
+ } catch {
+ Write-Error "Request failed: $($_.Exception.Message)"
+ if ($_.ErrorDetails) {
+ Write-Host $_.ErrorDetails
+ }
+ }
+}
+
+function fortune {
+ param(
+ [Parameter(Position = 0)]
+ [string]$Command,
+
+ [Parameter(Position = 1)]
+ [string]$Method,
+
+ [Parameter(Position = 2)]
+ [string]$Path,
+
+ [Parameter(Position = 3)]
+ [object]$Body,
+
+ [switch]$Tenant,
+
+ [string]$Email,
+ [string]$Password
+ )
+
+ switch ($Command) {
+ "login" {
+ if (-not $Email -or -not $Password) {
+ Write-Error "Usage: fortune login -Email -Password "
+ return
+ }
+
+ $payload = @{
+ email = $Email
+ password = $Password
+ }
+
+ $resp = Invoke-FortuneAPI -Method "POST" -Path "auth/customer-login" -Tenant -Body $payload
+ echo $resp.data
+ if ($resp -and $resp.data.access_token) {
+ $Global:FortuneBetToken = $resp.data.access_token
+ $Global:FortuneBetRefreshToken = $resp.data.refresh_token
+ Write-Host "β
Logged in."
+ } else {
+ Write-Error "β Login failed."
+ }
+ }
+ "login-super" {
+ if (-not $Email -or -not $Password) {
+ Write-Error "Usage: fortune login-super -Email -Password "
+ return
+ }
+
+ $payload = @{
+ email = $Email
+ password = $Password
+ }
+
+ $resp = Invoke-FortuneAPI -Method "POST" -Path "auth/super-login" -Body $payload
+ echo $resp.data
+ if ($resp -and $resp.data.access_token) {
+ $Global:FortuneBetToken = $resp.data.access_token
+ $Global:FortuneBetRefreshToken = $resp.data.refresh_token
+ Write-Host "β
Logged in."
+ } else {
+ Write-Error "β Login failed."
+ }
+ }
+ "login-admin" {
+ if (-not $Email -or -not $Password) {
+ Write-Error "Usage: fortune login-admin -Email -Password "
+ return
+ }
+
+ $payload = @{
+ email = $Email
+ password = $Password
+ }
+
+ $resp = Invoke-FortuneAPI -Method "POST" -Path "auth/admin-login" -Tenant -Body $payload
+ echo $resp.data
+ if ($resp -and $resp.data.access_token) {
+ $Global:FortuneBetToken = $resp.data.access_token
+ $Global:FortuneBetRefreshToken = $resp.data.refresh_token
+ Write-Host "β
Logged in."
+ } else {
+ Write-Error "β Login failed."
+ }
+ }
+ "refresh" {
+ if (-not $Global:FortuneBetRefreshToken) {
+ Write-Error "No refresh token stored."
+ return
+ }
+
+ $payload = @{
+ refresh_token = $Global:FortuneBetRefreshToken
+ access_token = $Global:FortuneBetToken
+ }
+ $resp = Invoke-FortuneAPI -Method "POST" -Path "auth/refresh" -Body $payload
+ if ($resp -and $resp.data.access_token) {
+ $Global:FortuneBetToken = $resp.data.access_token
+ Write-Host "π Token refreshed."
+ } else {
+ Write-Error "β Refresh failed."
+ }
+ }
+ "call" {
+ if (-not $Method -or -not $Path) {
+ Write-Error "Usage: fortune call [-Tenant] [-Body @{...}]"
+ return
+ }
+
+ $resp = Invoke-FortuneAPI -Method $Method -Path $Path -Tenant:$Tenant -Body $Body
+ if ($resp) {
+ $resp | ConvertTo-Json -Depth 10
+ }
+ }
+ default {
+ Write-Host "Fortune CLI"
+ Write-Host ""
+ Write-Host "Commands:"
+ Write-Host " fortune login -Email -Password "
+ Write-Host " fortune refresh"
+ Write-Host " fortune call [-Tenant] [-Body @{...}]"
+ }
+ }
+}
diff --git a/fortune_tests.ps1 b/fortune_tests.ps1
new file mode 100644
index 0000000..f93c99c
--- /dev/null
+++ b/fortune_tests.ps1
@@ -0,0 +1,382 @@
+# CryptoPay Tests
+function TestCryptoPayDeposit {
+ $request = @{
+ amount=200
+ currency="ETB"
+ crypto_currency="USDT"
+ }
+ fortune call POST "cryptopay/deposit" -Body $request -Tenant
+}
+function TestCryptoPayWithdraw {
+ param(
+ [string]$address
+ )
+ $request = @{
+ address=$address
+ amount=200
+ currency="ETB"
+ crypto_currency="USDT"
+ }
+ fortune call POST "cryptopay/withdrawal" -Body $request -Tenant
+}
+# Chapa Tests
+function TestChapaDeposit {
+ $request = @{
+ amount=200
+ }
+ fortune call POST "chapa/payments/deposit" -Body $request
+}
+
+function TestChapaBanks {
+ fortune call GET "chapa/banks"
+}
+
+function TestChapaWithdraw {
+ $request = @{
+ account_name="Samuel Tariku"
+ account_number="0946685511"
+ amount="200"
+ reference="1"
+ bank_code=128 #CBEBirr
+ }
+ fortune call POST "chapa/payments/withdraw" -Body $request
+}
+
+# Arifpay Tests
+function TestArifPayDeposit {
+ $request = @{
+ amount=200
+ customerEmail="samueltarikufantaye@gmail.com"
+ customerPhone="0946685511"
+ }
+ fortune call POST "arifpay/checkout" -Body $request
+}
+
+# function TestARIFCheckout {
+# $request = @{
+# cancelUrl="https://example1.com"
+# phone="251922655097"
+# email="Ex@gmail.net"
+# nonce="251assaddsasad93554asdasd8208sawas"
+# errorUrl="http://error.com"
+# notifyUrl="https://664db983ede9a2b5565497ee.mockapi.io/user"
+# successUrl="http://example.com"
+# paymentMethods=
+# expireDate=
+# items=
+# beneficiaries=
+# lang=
+#
+# }
+# }
+
+#
+# Testing Direct Deposit
+#
+function CreateDirectDeposit {
+ $deposit = @{
+ bank_name="cbe"
+ sender_account_number="123456789"
+ sender_account_holder="Samuel Tariku"
+ receiver_account_number="123456789"
+ receiver_account_holder="Fortune Admin"
+ amount=1000.0
+ reference_number="123456"
+ }
+ fortune call POST "direct-deposits" -Tenant -Body $deposit
+}
+function GetAllDirectDeposits {
+ fortune call GET "direct-deposits?status=PENDING" | less
+}
+
+function ApproveDirectDeposit {
+ param(
+ [Int64]$id
+ )
+ fortune call POST "direct-deposits/$id/approve" | less
+}
+
+
+function RejectDirectDeposit {
+ param(
+ [Int64]$id
+ )
+
+ $reject = @{
+ reason="Incorrect account number"
+ }
+ fortune call POST "direct-deposits/$id/reject" -Body $reject | less
+}
+
+#
+# Testing Super Admin Bank
+#
+
+function CreateBank {
+ $bank = @{
+ swift="CBETTA"
+ name="Commerical Bank Of Ethiopia"
+ acct_length=10
+ country_code="et"
+ }
+ fortune call POST "bank" -Body $bank
+}
+
+function GetAllBanks {
+ fortune call GET "bank" | less
+}
+function GetBankByID {
+ param(
+ [Int64]$id
+ )
+ fortune call GET "banks/$id" | less
+}
+function DeleteBank {
+ param(
+ [Int64]$id
+ )
+ fortune call DELETE "banks/$id" | less
+}
+#
+#Testing Direct Deposit Bank
+#
+
+function CreateDDBank {
+ param(
+ [Int64]$id
+ )
+ $bank = @{
+ company_id=1
+ bank_id=$id
+ interval=1
+ is_cycle=$true
+ }
+ fortune call POST "direct-deposit-bank" -Body $bank
+}
+
+function GetAllDDBanks {
+ fortune call GET "direct-deposit-bank" | less
+}
+function GetDDBankByID {
+ param(
+ [Int64]$id
+ )
+ fortune call GET "direct-deposit-bank/$id" | less
+}
+function ManuallyCycleBank {
+ param(
+ [Int64]$id
+ )
+ fortune call POST "direct-deposit-bank/$id/cycle" | less
+}
+function DeleteDDBank {
+ param(
+ [Int64]$id
+ )
+ fortune call DELETE "direct-deposit-bank/$id" | less
+}
+
+# Testing Direct Deposit Account
+#
+function CreateDDAccount {
+ param(
+ [Int64]$id
+ )
+ $account = @{
+ dd_bank_id=$id
+ account_number="1234567"
+ account_holder="Fortune Admin"
+ }
+ fortune call POST "direct-deposit-account" -Body $account
+}
+function GetDDAccountForBank {
+ param(
+ [Int64]$id
+ )
+ fortune call GET "direct-deposit-bank/$id/accounts" | less
+}
+
+
+function GetVirtualGameProviders {
+ fortune call GET "virtual-game/orchestrator/providers"
+}
+function GetVirtualGameList {
+ fortune call GET "virtual-game/orchestrator/games?providerID=veliplay"
+}
+
+function StartVeliGameDemo {
+ param(
+ [Int64]$gameID,
+ [string]$providerID
+ )
+
+ $gameData = @{
+ providerId=$providerID
+ gameId=$gameID
+ language="en"
+ deviceType= "DESKTOP"
+ brandId="fortune_bets"
+ }
+
+ fortune call POST "veli/start-demo-game" -Body $gameData
+}
+
+
+function GetLeagues {
+ fortune call GET "leagues" -Tenant
+}
+
+function GetEvents {
+ fortune call GET "upcoming-events" -Tenant
+}
+function GetOdds {
+ param(
+ [Int64]$eventID
+ )
+ fortune call GET "odds/upcoming/${eventID}" -Tenant
+}
+
+function GetOdds {
+ param(
+ [Int64]$eventID
+ )
+ fortune call GET "odds/upcoming/${eventID}" -Tenant
+}
+
+function Select-Event {
+ param ($Events)
+
+ $selection = $Events |
+ ForEach-Object {
+ "$($_.id),$($_.match_name),$($_.league_name),$($_.start_time)"
+ } |
+ fzf --delimiter=',' --with-nth=2,3,4
+
+ if ($selection) {
+ $selectedId = ($selection -split ",")[0]
+ return $Events | Where-Object { $_.id -eq [int]$selectedId }
+ }
+}
+# @{id=29169722; event_id=1732385; market_type=winning_margin; market_name=Winning Margin; market_category=others; market_id=56; number_of_outcomes=10; raw_odds=System.Object[]; fetched_at=12/9/2025 04:15:38; expires_at=12/9/2025 05:15:38; is_active=True}
+function Select-Odd {
+ param ($Odds)
+ $selection = $Odds | ForEach-Object {
+ "$($_.id),$($_.market_name)"
+ } | fzf --delimiter=',' --with-nth=2
+
+ if ($selection) {
+ $selectedId = ($selection -split ",")[0]
+ return $Odds | Where-Object { $_.id -eq [int]$selectedId }
+ }
+}
+
+#@{id=4967715; name=1; odds=1.500} @{id=4967716; name=Draw; odds=4.000} @{id=4967717; name=2; odds=5.500}
+#@{id=4967741; odds=1.925; header=1; handicap=-1.0} @{id=4967746; odds=1.875; header=2; handicap=+1.0}
+function Select-RawOdd {
+ param ($Odds)
+ $selection = $Odds | ForEach-Object {
+ "$($_.id),$($_.name),$($_.header),$($_.handicap),"
+ } | fzf --delimiter=',' --with-nth=2,3,4
+
+ if ($selection) {
+ $selectedId = ($selection -split ",")[0]
+ return $Odds | Where-Object { $_.id -eq [int]$selectedId }
+ }
+}
+
+function EventOddPipe {
+ $events = GetEvents | ConvertFrom-Json
+ $selectedEvent = Select-Event $events.data
+ Write-Host $selectedEvent.id
+ $odds = GetOdds $selectedEvent.id | ConvertFrom-Json
+ $selectedOdd = Select-Odd $odds.data
+ #Write-Host $selectedOdd.raw_odds
+ $selectedRawOdd = Select-RawOdd $selectedOdd.raw_odds
+ Write-Host $selectedRawOdd
+
+ return @{
+ selectedEvent=$selectedEvent
+ selectedOdd=$selectedOdd
+ selectedRawOdd=$selectedRawOdd
+ }
+}
+# Create Bet
+function CreateBet {
+
+ $eventOdd = EventOddPipe
+
+ Write-Host $eventOdd
+
+ $req = @{
+ outcomes = @(
+ @{
+ event_id=[int64]$eventOdd.selectedEvent.id
+ odd_id=[int64]$eventOdd.selectedRawOdd.id
+ market_id=[int64]$eventOdd.selectedOdd.market_id
+ }
+ )
+ amount=30.0
+ }
+ fortune call POST "sport/bet" -Tenant -Body $req
+}
+# Login Tests
+function LoginClient{
+ fortune login -Email john.doe@example.com -Password password@123
+}
+function LoginAdmin{
+ fortune login-admin -Email test.admin@gmail.com -Password NLd3m6taW71H
+}
+function LoginSuper{
+ fortune login-super -Email cybersamt@gmail.com -Password H6xW6pe1w8ys
+}
+
+# Register Tasks
+function Register {
+ param(
+ [string]$otp
+ )
+ $req = @{
+ first_name="Samuel"
+ last_name="Tariku"
+ phone_number="+251900000002"
+ password="password@123"
+ otp=$otp
+ referral_code=""
+ }
+ fortune call POST "user/register" -Tenant $req
+}
+
+function SendRegisterOTP {
+ $req = @{
+ phone_number="+251900000002"
+ }
+ fortune call POST "user/sendRegisterCode" -Tenant $req
+}
+
+function Main {
+ $scriptPath = $PSCommandPath
+
+ $functions = Get-ChildItem Function: |
+ Where-Object {
+ $_.ScriptBlock.File -eq $scriptPath -and
+ $_.Name -ne "Main"
+ } |
+ Select-Object -ExpandProperty Name |
+ Sort-Object
+
+ $fn = $functions | fzf --prompt="Select action > "
+ if (-not $fn) {
+ return
+ }
+
+ $command = Get-Command $fn
+ $params = @{}
+
+ foreach ($p in $command.Parameters.Values) {
+ $params[$p.Name] = Read-Host "Enter $($p.Name)"
+ }
+
+ & $fn @params
+}
+
+Main
diff --git a/report_request_calls.ps1 b/report_request_calls.ps1
new file mode 100644
index 0000000..aa9133f
--- /dev/null
+++ b/report_request_calls.ps1
@@ -0,0 +1,19 @@
+function GetAllReportRequests {
+ fortune call GET "reports/requests" | less
+}
+function DownloadReport {
+ param(
+ [Int64]$id
+ )
+ fortune call GET "reports/download/$id" | less
+}
+function GenerateEventIntervalReport {
+ $report = @{
+ type="event_interval"
+ metadata=@{
+ interval="day"
+ }
+ }
+ fortune call POST "reports/requests" -Body $report
+}
+