// ============================================================ // QZ TOKEN FLÖDESTEST // ============================================================ // Testar hela flödet: // 1. Skapa Zoomer-konto // 2. ID-verifiering // 3. Skapa wallet // 4. Skapa mission // 5. Ta uppdrag // 6. Genomför uppdrag (simulerad) // 7. AI-analys // 8. Godkännande // 9. Token reward // 10. Kontrollera saldo // 11. Payout (måndag) const axios = require('axios'); const { Pool } = require('pg'); const API_BASE = process.env.API_BASE || 'http://localhost:8080'; const DB_URL = process.env.DATABASE_URL || 'postgresql://quixzoom:quixzoom_dev@localhost:5434/quixzoom'; const pool = new Pool({ connectionString: DB_URL }); // Test-data const TEST_ZOOMER = { name: 'Test Zoomer', email: 'test@quixzoom.com', phone: '+46701234567' }; const TEST_MISSION = { type: 'verify', base_price_usd: 2.50, complexity_multiplier: 1.0 }; // ============================================================ // TESTFUNKTIONER // ============================================================ async function runFullFlowTest() { console.log('🚀 Startar quiXzoom Token-flödestest\n'); let zoomerId = null; let walletId = null; let missionId = null; let observationId = null; try { // STEG 1: Skapa Zoomer-konto console.log('📱 STEG 1: Skapa Zoomer-konto'); const zoomerResult = await createZoomer(TEST_ZOOMER); zoomerId = zoomerResult.id; console.log(`✅ Zoomer skapad: ${zoomerId}`); // STEG 2: ID-verifiering console.log('\n🆔 STEG 2: ID-verifiering'); await verifyIdentity(zoomerId); console.log('✅ ID verifierad'); // STEG 3: Skapa wallet console.log('\n💰 STEG 3: Skapa wallet'); const walletResult = await createWallet(zoomerId); walletId = walletResult.id; console.log(`✅ Wallet skapad: ${walletId}`); // STEG 4: Skapa mission console.log('\n📋 STEG 4: Skapa mission'); const missionResult = await createMission(TEST_MISSION); missionId = missionResult.id; console.log(`✅ Mission skapad: ${missionId}`); // STEG 5: Ta uppdrag console.log('\n🎯 STEG 5: Ta uppdrag'); await assignMission(missionId, zoomerId); console.log('✅ Uppdrag tilldelat'); // STEG 6: Genomför uppdrag (simulerad) console.log('\n📸 STEG 6: Genomför uppdrag'); const observationResult = await completeMission(missionId, zoomerId); observationId = observationResult.id; console.log(`✅ Uppdrag genomfört: ${observationId}`); // STEG 7: AI-analys console.log('\n🤖 STEG 7: AI-analys'); const analysisResult = await analyzeObservation(observationId); console.log(`✅ AI-analys klar: ${analysisResult.confidence}% confidence`); // STEG 8: Godkännande console.log('\n✅ STEG 8: Godkänn uppdrag'); const approvalResult = await approveMission(missionId, observationId); console.log(`✅ Uppdrag godkänt: ${approvalResult.status}`); // STEG 9: Token reward console.log('\n💎 STEG 9: Token reward'); const rewardResult = await createReward(zoomerId, missionId, observationId); console.log(`✅ Reward skapad: ${rewardResult.transaction.amount_qz_token} QZ TOKEN`); // STEG 10: Kontrollera saldo console.log('\n💳 STEG 10: Kontrollera saldo'); const balanceResult = await checkBalance(zoomerId); console.log(`✅ Saldo: ${balanceResult.balance_qz_token} QZ TOKEN ($${balanceResult.balance_usd})`); // STEG 11: Simulera payout (måndag) console.log('\n💸 STEG 11: Simulera payout'); const payoutResult = await simulatePayout(zoomerId); console.log(`✅ Payout: ${payoutResult.amount_qz_token} QZ TOKEN ($${payoutResult.amount_usd})`); console.log('\n🎉 ALLA STEG KLARA!'); console.log('\n📊 Sammanfattning:'); console.log(` Zoomer: ${zoomerId}`); console.log(` Mission: ${missionId}`); console.log(` Observation: ${observationId}`); console.log(` Reward: ${rewardResult.transaction.amount_qz_token} QZ TOKEN`); console.log(` Payout: ${payoutResult.amount_usd} USD`); } catch (error) { console.error('\n❌ TEST MISSLYCKADES:', error.message); console.error(error.stack); process.exit(1); } finally { await pool.end(); } } // ============================================================ // API-ANROP // ============================================================ async function createZoomer(zoomerData) { // Simulerad — i verkligheten anropas quixzoom-auth-service const result = await pool.query( `INSERT INTO zoomers (name, email, phone, status) VALUES ($1, $2, $3, 'active') RETURNING *`, [zoomerData.name, zoomerData.email, zoomerData.phone] ); return result.rows[0]; } async function verifyIdentity(zoomerId) { // Simulerad ID-verifiering console.log(' Verifierar identitet...'); await new Promise(resolve => setTimeout(resolve, 1000)); await pool.query( `UPDATE zoomers SET status = 'active' WHERE id = $1`, [zoomerId] ); } async function createWallet(zoomerId) { const result = await pool.query( `INSERT INTO zoomer_wallets (zoomer_id, stripe_connect_status) VALUES ($1, 'active') RETURNING *`, [zoomerId] ); // Skapa payout schema await pool.query( `INSERT INTO payout_schedules (zoomer_id, wallet_id, day_of_week, time_of_day) VALUES ($1, $2, 1, '09:00:00')`, [zoomerId, result.rows[0].id] ); return result.rows[0]; } async function createMission(missionData) { // Simulerad — skapa i missions-tabellen const result = await pool.query( `INSERT INTO missions (mission_id, type, status, priority) VALUES ($1, $2, 'pending', 0.5) RETURNING *`, [`mission_${Date.now()}`, missionData.type] ); // Skapa prissättning await pool.query( `INSERT INTO mission_pricing (mission_type, base_price_qz_token, base_price_usd, complexity_multiplier) VALUES ($1, $2, $3, $4)`, [missionData.type, missionData.base_price_usd, missionData.base_price_usd, missionData.complexity_multiplier] ); return result.rows[0]; } async function assignMission(missionId, zoomerId) { await pool.query( `UPDATE missions SET assigned_to = $1, assigned_at = NOW(), status = 'active' WHERE id = $2`, [zoomerId, missionId] ); } async function completeMission(missionId, zoomerId) { // Simulerad observation const result = await pool.query( `INSERT INTO observations (observation_id, source_type, source_id, zoomer_id, status) VALUES ($1, 'quixzoom', $2, $3, 'pending') RETURNING *`, [`obs_${Date.now()}`, `source_${Date.now()}`, zoomerId] ); // Uppdatera mission await pool.query( `UPDATE missions SET status = 'completed', completed_at = NOW(), result = $1 WHERE id = $2`, [JSON.stringify({ observation_id: result.rows[0].id }), missionId] ); return result.rows[0]; } async function analyzeObservation(observationId) { // Simulerad AI-analys console.log(' Kör AI-analys...'); await new Promise(resolve => setTimeout(resolve, 1500)); const confidence = 0.95; await pool.query( `UPDATE observations SET ai_analysis = $1, status = 'validated' WHERE id = $2`, [JSON.stringify({ confidence, objects_detected: 5, quality_score: 0.92 }), observationId] ); return { confidence: confidence * 100 }; } async function approveMission(missionId, observationId) { await pool.query( `UPDATE observations SET status = 'validated', validated_by = 'ai_system', validated_at = NOW() WHERE id = $1`, [observationId] ); return { status: 'approved' }; } async function createReward(zoomerId, missionId, observationId) { // Hämta pris const pricingResult = await pool.query( `SELECT base_price_qz_token FROM mission_pricing LIMIT 1` ); const amount_qz_token = pricingResult.rows[0]?.base_price_qz_token || 2.5; // Anropa API try { const response = await axios.post(`${API_BASE}/api/v1/transactions/mission-reward`, { zoomer_id: zoomerId, mission_id: missionId, observation_id: observationId, amount_qz_token: amount_qz_token, description: `Mission reward for ${missionId}` }); return response.data; } catch (error) { console.log(' API inte tillgängligt, skapar direkt i DB...'); // Fallback: skapa direkt i databas const walletResult = await pool.query( `SELECT id FROM zoomer_wallets WHERE zoomer_id = $1`, [zoomerId] ); const walletId = walletResult.rows[0].id; const txHash = `qz_tx_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; await pool.query( `INSERT INTO token_transactions (tx_hash, tx_type, to_wallet_id, amount_qz_token, amount_usd, exchange_rate, mission_id, observation_id, description, status, confirmed_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, NOW())`, [txHash, 'mission_reward', walletId, amount_qz_token, amount_qz_token, 1.0, missionId, observationId, 'Mission reward', 'confirmed'] ); await pool.query( `UPDATE zoomer_wallets SET balance_qz_token = balance_qz_token + $1 WHERE id = $2`, [amount_qz_token, walletId] ); return { transaction: { tx_hash: txHash, amount_qz_token, amount_usd: amount_qz_token } }; } } async function checkBalance(zoomerId) { const result = await pool.query( `SELECT * FROM zoomer_balance WHERE zoomer_id = $1`, [zoomerId] ); return { balance_qz_token: result.rows[0]?.balance_qz_token || 0, balance_usd: (result.rows[0]?.balance_qz_token || 0) }; } async function simulatePayout(zoomerId) { const balance = await checkBalance(zoomerId); if (balance.balance_qz_token <= 0) { return { amount_qz_token: 0, amount_usd: 0 }; } // Simulerad payout const walletResult = await pool.query( `SELECT id FROM zoomer_wallets WHERE zoomer_id = $1`, [zoomerId] ); const walletId = walletResult.rows[0].id; const txHash = `qz_tx_${Date.now()}_payout`; await pool.query( `INSERT INTO token_transactions (tx_hash, tx_type, from_wallet_id, amount_qz_token, amount_usd, exchange_rate, description, status, confirmed_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW())`, [txHash, 'payout', walletId, balance.balance_qz_token, balance.balance_usd, 1.0, 'Weekly payout', 'confirmed'] ); await pool.query( `UPDATE zoomer_wallets SET balance_qz_token = 0 WHERE id = $1`, [walletId] ); return { amount_qz_token: balance.balance_qz_token, amount_usd: balance.balance_usd }; } // Kör testet runFullFlowTest();