Added init endpoint.
This commit is contained in:
@ -1,8 +1,13 @@
|
||||
from fastapi import FastAPI
|
||||
from fastapi import FastAPI, Depends
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from contextlib import asynccontextmanager
|
||||
from app.database import init_db
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, func
|
||||
from decimal import Decimal
|
||||
from app.database import init_db, get_db
|
||||
from app.routers import auth, users, wallet, bets, websocket, admin, sport_events, spread_bets, gamification, matches
|
||||
from app.models import User, Wallet
|
||||
from app.utils.security import get_password_hash
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
@ -50,3 +55,64 @@ async def root():
|
||||
@app.get("/health")
|
||||
async def health():
|
||||
return {"status": "healthy"}
|
||||
|
||||
|
||||
@app.get("/init")
|
||||
async def init_admin(db: AsyncSession = Depends(get_db)):
|
||||
"""
|
||||
Initialize the application with a default admin user.
|
||||
Only works if no admin users exist in the database.
|
||||
Creates: admin@test.com / password123
|
||||
"""
|
||||
# Check if any admin users exist
|
||||
result = await db.execute(
|
||||
select(func.count(User.id)).where(User.is_admin == True)
|
||||
)
|
||||
admin_count = result.scalar()
|
||||
|
||||
if admin_count > 0:
|
||||
return {
|
||||
"success": False,
|
||||
"message": "Admin user(s) already exist. Initialization skipped.",
|
||||
"admin_count": admin_count
|
||||
}
|
||||
|
||||
# Check if user with this email already exists
|
||||
existing = await db.execute(
|
||||
select(User).where(User.email == "admin@test.com")
|
||||
)
|
||||
if existing.scalar_one_or_none():
|
||||
return {
|
||||
"success": False,
|
||||
"message": "User with email admin@test.com already exists but is not an admin."
|
||||
}
|
||||
|
||||
# Create admin user
|
||||
admin_user = User(
|
||||
email="admin@test.com",
|
||||
username="admin",
|
||||
password_hash=get_password_hash("password123"),
|
||||
display_name="Administrator",
|
||||
is_admin=True,
|
||||
)
|
||||
db.add(admin_user)
|
||||
await db.flush()
|
||||
|
||||
# Create wallet for admin
|
||||
wallet = Wallet(
|
||||
user_id=admin_user.id,
|
||||
balance=Decimal("10000.00"),
|
||||
escrow=Decimal("0.00"),
|
||||
)
|
||||
db.add(wallet)
|
||||
|
||||
await db.commit()
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message": "Admin user created successfully",
|
||||
"credentials": {
|
||||
"email": "admin@test.com",
|
||||
"password": "password123"
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,17 +44,25 @@ export const AdminDataTools = () => {
|
||||
const seedMutation = useMutation({
|
||||
mutationFn: adminApi.seedDatabase,
|
||||
onSuccess: (data) => {
|
||||
console.log('Seed success:', data)
|
||||
toast.success(data.message)
|
||||
if (data.test_admin) {
|
||||
toast.success(`Test admin created: ${data.test_admin.username} / ${data.test_admin.password}`, {
|
||||
duration: 10000,
|
||||
})
|
||||
}
|
||||
// Show what was created
|
||||
const counts = data.created_counts
|
||||
toast.success(`Created: ${counts.users} users, ${counts.events} events, ${counts.bets} bets`, {
|
||||
duration: 5000,
|
||||
})
|
||||
queryClient.invalidateQueries()
|
||||
refetchPreview()
|
||||
},
|
||||
onError: (error: any) => {
|
||||
toast.error(error.response?.data?.detail || 'Seed failed')
|
||||
console.error('Seed error:', error)
|
||||
const message = error.response?.data?.detail || error.message || 'Seed failed'
|
||||
toast.error(message)
|
||||
},
|
||||
})
|
||||
|
||||
@ -216,7 +224,7 @@ export const AdminDataTools = () => {
|
||||
<input
|
||||
type="number"
|
||||
value={seedConfig.num_users}
|
||||
onChange={(e) => setSeedConfig({ ...seedConfig, num_users: parseInt(e.target.value) || 0 })}
|
||||
onChange={(e) => setSeedConfig({ ...seedConfig, num_users: Math.max(1, parseInt(e.target.value) || 1) })}
|
||||
min={1}
|
||||
max={100}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg"
|
||||
@ -228,7 +236,7 @@ export const AdminDataTools = () => {
|
||||
<input
|
||||
type="number"
|
||||
value={seedConfig.num_events}
|
||||
onChange={(e) => setSeedConfig({ ...seedConfig, num_events: parseInt(e.target.value) || 0 })}
|
||||
onChange={(e) => setSeedConfig({ ...seedConfig, num_events: Math.max(0, parseInt(e.target.value) || 0) })}
|
||||
min={0}
|
||||
max={50}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg"
|
||||
@ -240,7 +248,7 @@ export const AdminDataTools = () => {
|
||||
<input
|
||||
type="number"
|
||||
value={seedConfig.num_bets_per_event}
|
||||
onChange={(e) => setSeedConfig({ ...seedConfig, num_bets_per_event: parseInt(e.target.value) || 0 })}
|
||||
onChange={(e) => setSeedConfig({ ...seedConfig, num_bets_per_event: Math.max(0, parseInt(e.target.value) || 0) })}
|
||||
min={0}
|
||||
max={20}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg"
|
||||
@ -252,7 +260,7 @@ export const AdminDataTools = () => {
|
||||
<input
|
||||
type="number"
|
||||
value={seedConfig.starting_balance}
|
||||
onChange={(e) => setSeedConfig({ ...seedConfig, starting_balance: parseInt(e.target.value) || 0 })}
|
||||
onChange={(e) => setSeedConfig({ ...seedConfig, starting_balance: parseInt(e.target.value) || 100 })}
|
||||
min={100}
|
||||
max={10000}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg"
|
||||
|
||||
Reference in New Issue
Block a user