diff --git a/backups/backup_v2docker_20250609_050507_encrypted.sql.gz.enc b/backups/backup_v2docker_20250609_050507_encrypted.sql.gz.enc new file mode 100644 index 0000000..e30e264 --- /dev/null +++ b/backups/backup_v2docker_20250609_050507_encrypted.sql.gz.enc @@ -0,0 +1 @@ +gAAAAABoRk9kkVVOa1-y0m5PikSvdtCeQihW0DGmwQrNC5LE4Wmeu8eN_qWLkT9tdnrBnYfocUZ6YTVLOmWDHfQar28xll5UbATA3t23VAHOmTEQyDCa5JFAaX8X1EE-dDQyONOlbriNEx78BxBr78LjMcSYKu_dHSXqe4jk9EkC6hktkkAz6EwnRGkDGRtfAdG2Fc4oIyErD1SeRuM8R6GBl6dxjzb4bV4KCKiRv0RLUGby3VyZkKgUwMtI6edvgXtXRS8PvxoJ1rluaN_cAA6L80MtphoGnQfUsD_EqIDDyOKFNcKmDVIQIy3jyuqC_4Apk6BAwwlj-OUWAD-dGZkZaGMURfI_SYOklLXuKgbU2vmkSqNd8xfcYTLijTg9K4Q7y3U-Dg06Q9OYLe-Wg5wF86YUmxSnvs7yoAObkOi8fdITcYf21UEU-OSeWUYtqiMVaVG1JhNZhoqZ_LXOPfKfaf_esQZNCiigXQV1rkt0AMt8-hgtxHGZHeu2yaN3ObEYeQnmEVFZrrA17ui-4SHTfmzShCrMoqCIpQOsQkhgCoA74BhcucsSoStVwna8tk6ZKpgdQfT6Dh2qR2PDIbqz07a0PE_FSmpDO7TSCzrww43vfweYq9iYiZUjbmOeahHiBJpgo2dD2h3oZucBsN2_tZk6cw_bPSA5l8_HEXlxw0lkN9gtWlYWmHGOS_N6L1sYMgHztLGC8zn3I7bnfeNz79hCeJX56IRJ3nuUclZubkOs97Gy-JuLx1t1qZdxybmkLjSidDPDV02aldFcTGeWQTUriCeQlXCOVWLFEi9AnpVyRIOiK19FLCTSm5vRENAQh_I5B5oUsPPZxghIiAYSgq7S0Dide3DgfQkq0N_iQe2r05VIM-PJn6_9tmNdjTxtOe2Z-Nby42SoRtGaL9Y1ZyPreCWWjHOVllm7kFBVbIjC9JgHk4ToTB5RrjI7k1YqAFAS-MJhJHRaZVqwazwJAQ7UQBmoufJktHQKINkninxBDcfrV9cC9lXL9NB-qpQadQWUU21Qwz1zLsWf4-GMGkvvX70cFz3rpJT7WKuyOB2U0khnTUrRS4yfAW2weQeyhRrbJw2dvhL8OKBVofWvoaY3fMeXo886QFftIm-hIcXY_6zmfVSmEP8KPNDkZ1GaaeZ8NiVMnY8LNT8_R5ISOPZGm_BWcHVBWLagpu51Ys_3Fn49mmdSdbKN-0TY3yxBA0e8NRYb87tc2trxoSDy5ItQrUFljm-Sdv9_swKam6sx543jiBWaX9NfH8j12QgQamScAUxBNXTIMvNDogYpWTy_KG3J7hsIiSG-XnVRFkJMoD30vepgvQs8Yz7c_6xECV1lCqFI1POwESoo0cGy-IM8sSG_WEvpbmPeIjjDpTuosz-B7FmhotZt32qMc3hGU4sdhpzoGwK_6A5DtvkTSvkEt7V8uQLb0ciJwAGXMTGKJoH2d2G9XZlVCZABFtkom9PRkyjeq19R5IHnTX6d4votsD3hurtlJapkB_STAy3ovFfo-yaiI2L8wluvw8MvU-UkatdhU9lCBwq4eGwF6DyD9U_B6FAVRqYYd_avjbQy4-x7C_kUpbsdlgEP9S8EwnGhJy1G_Nn3AbzY-ffd8MNIP30uqluIFHeX1zdNeFVOf9u_JCMaqNyvdc1bghhnM_tUskbJurwWaUOYNZaZ6eUCkVzohcRadcaFEI3jWs_H6IGdkSYYNiNJOG5eOG0rLFSkjbHJDQFPZjkFT-rKQmd-dBCNBk645TJiL6FLM5MpK31yN4Wpi_sKy1RmgqyteF4MVc4kk6Sa-04HJkgk_RPStYXhO7aKyJk3fzF9iQ__kQ3GROjGcxgAZnvKqGfU0zKKLnjrXKewnIRgVaz3nVt26aNuCyvCsfRmXq_OT3wn0HXQ6czJcHLFP5z1O_UzaFWN4ec8es_ZqQqdf-aKq_zyreXlgElD1h7iGOcuB1DTF3tzBUvB1mOND9iOz7Qgyu2NX1jm_8VQpuvZLV1m7Cz_Fj4RZWevvrCz9-PpiytuBYW_Y1hNSHNGFj3LYcu-Zot5qmRYQKabA5VwM9mQ7ZuMGgpLlwSnxZx_exRf5hS3sMZWeWb9Q0rtlBTd64r5JEHb01if8AUt_Fc_3fkzCLdAHiqw26FyjzfYjP7KHtljd0csIKS5igtKc7Je3WwL4l53KiFgP17jzccaHBIG9Uybk0o3NRBOkhx-RtGUQHg-0BcCCQjpMqngsRFh0u8DLuFASvRe93j56bqa5fW7UK3cdnECAndQc-22ZhNOk1GVTpKkr_xAJN7pHFJbnGOthp8cvN-ruxq1SUzPt0yMI9BtOfp1htB5LGzzBMWlwy6ob9whBD0voQuS99hT1D3QjdOEuAg1bWYsaNgdmExmF5zsyb3fX-FlYm5Fbq8sAgsnU4awhGoGofCbdxKzS7pck150C-jjhJxYgbIniEmLfBnbz174Wjt3lG-J8HJBOuekjT3i8sQai1gdwu_tZK9qqgbbCY2laYYQPMyw32A3xxKc7-gnLgXqlx7aHvlV-Z2Ahk3o8Ohuxpic4e2wW3OpKWXD9QA_09WCg5hXW6HHGKfpmRrCwLM3OBPH5lyAN2dLP0ZJyZfiN9aHPZSjAYI_vc6SnQzvM4fj6X9gJQtCDwSg8sqXhYVv4Op6VvilaiCWZu9Iuxhty1vq_NzS4miuiXwOeVaMOSHOT9t2lCAlEhv9UdWc1Po6jazWEBYfmA3_BNjxvUzELR8X44qi0-6OdBs3fFKrepvSXp1zn3C-yBQvm1iYbAnmXoq8cW_wrk4j78bn6T1Az1JrmrpVSTRf1r9Ma5rdJeoLJUFZQZtHLxztT3WeCNcDHHbRHFFL13yoDx5-2he_R1zOOgNZBOfbtra_lNgcXGRX0F5K1cVx-hEoH7fa-TCg5naQpd7218oeTirqLPhI68Gtm8vd2RkAVPdo4pV2K6x0o35ILOduQPIULMIwCEwQaFteouym8TeVcQdY6SVHrMWLKm906IqQyksiG6qEne8rgX_72SZerA0nWkru9dvqWhksYKPmhygQShnKMHmnI24m7RTbT9JC3wXYdhl10V25aNRGvvnZmICwh3dqD6GnRhDLuM7nyt5jyur22GBXw1vk8ocyfB853f4USA-BUL93VPMYrTdgSfOWpXlVSSFlb9SuNPHXw3kPVFbEFlLV46DOhVAX6izir4ExqtAWpUQXODn989SpG8rbxf55UrczDAkhnkRx5-Uq9L6vcuw5WFJEBLt2BcSAPfGVr0N_P0aihMl_SDjs-QW7_eFzg--zeY7XwULlWXIpx27I5Pi7WKF68czEqDtVZtBxc4_fzBD57xBiqQ2Wynnpg3ZJJNWLBapHn5uRrtWPLjOqFySbF4P7aIN-LJ2-LSeEQJsW2rSFoNQpQgf34kh6JTdGw0xsmU9MaAzlBHWCr3f_8nt6fd58kwIgLQbu0eAu24WFaqX61TfVQrJ5UbzjZ58x69CCydhDP2bMK2HYHgMiahrlTBdTxJuekpucehbxlnSnlqCDqDwOPixJwYrtqr4u01yASZRMpyEB9bpdxTDzeb9yMMI11YseHIn8qFzOzG5xaB3TcLMsu9K_c9qzw9YlCFJVagsQMXptE5PPPa6LebC37eQ9a8PInCt5_FTu3vlXgEI0bW77iU9Am2QESrWG3pHNBOqpwVsOI_fzCwjdhr-tBVn-tbOE7s3vNWHJmoZkeBwUglR_fFBi9Gsxw2mTBEU8jnrbV9vb6DPyFBJGm2GvkBsxmHuFaGBwjqOv6WQTZYtw1usAqCM9QHEaSR9g_m3_u8xLG6pH09OVSaE19BHRQ9apqcl13LeQUbciqpg5RBOPh8FODx2FEMF0-THTXI7JeW6N5K6KadR7LY7oJ2t7wNlodAbUM2lAaHouhkU52dAWbsAr607cbeR4U5yEAX7wf_yaWdkPzZ4JUUL5aken1e8KwEJ0cSnXvc9CAwk7ABnaJ3KyuHxrMabRSre234xT1GN8mT1KQK7Z1almHZmWF-s2lE2xvYHsTCrcxIP_5Vyvah9PD5L_0Pdf617wOfHscyGXuH4x3slN8tHfes1AWY7gUivwFAVW_MvQzYd9bTrDW0AtZYOo-KB6zAgoi2iqB7M9nOwmUeqyACoCLB9rhSd7VayNMuBI9BiEIuTZyt-y_Tt9QztuP62xlvT5_rx1vvJ1OKLiWDFr8Zy75xVP47BNt6Fp163M0I0dL5eeeDS3PbGA54py7GFbM3VDEPJW6lh4VI4r4fZDDorEB5ktn0hbDSlwum_vcjXqEwepzOy-L3YSkRgzevRJxdsmhp3Ygz5PiiPttQg0iRw-F-7uET2fR1vLlVTCY0pcbSkncxR4yOVOKAqzHdUmJs1rbo4CIk1WHhIJW3e3saTCDyEe5urCpg-tpGY-SWnOFWVPD_stOn63U_IM0QrsRdZXLwcnR01q-39qAeoTMORn4B7lAhZ9OWXI-14kDy2CdkSYVURFX0uXpwAsEvJGEm4lOBa8fmmGKIqeD5XMjRtGoWkiaYKC6FHfXscBSvb8r-6fjHU_fKLkoaU58-vzCAlU0yU3nBTPxg7dv_czz1tcRVy51Z0qLKyyBhikh2edoTdxLPXp-UmHEgA4CFPZZ4mj9Q-hiy-wVwsmodJcTvUhriUVmLs1E6JPjTXgkkF9vI0A4PuySDaW6UeajMlWchDJNU2UnM50bfn7c8j0dk_QdUWIe08KoOWsoANNOwpelp800-uXoFGnQzmEW5UM8ORIw4tLhG6BmS6qP_CMu58Yy9cp5ICqanmB81dPrsLMDNP1ByRO-LbgokLoG_NOmazetF2qYiIaT9KtS53ADPeGzHmC2CFi5ngCxuTP71BEWgpXNE0Dnoxr5SpqZtsTJIjDB2pT0QLoE_DGvTU_2PP0Myltgyb5_h1H2roK-Cz-BxnduKd2cf9P2B1o2YG3WEA_Qo7tzq7lBN1LO1xBD3PEwDI7iiAUIZNLjxzWH5Hzu3OHYBPLpua61uM1e7ZrvJBiduEDnFseEo803qSrbH6Fgj5KZvWAZH6CwmnDXW17fDb7KEzBdQOCZTNK-i-kF3lT8RDLJF4_pF0D1WlQlVrXkHMJ0IHgAkZ3_KTw1HiPBaacBtk6EvqDiuXRn82768_eoZ8RKWd4X8B_acXtuyDZS4SerHuYLIgHK3w04jRsTVK96ADJP8j7yH-32S4lR35Q1yoaWb3xVI6GFCPYtjZMlUbpamVX-MTCZSXnwNj8BNsHhZjKI8Qk0EW0ZSbgWOOyy9q7QtywY6LuzpQ2cZuXkJX0h5zVWPBdmbwEtYFKRdhEw0yDA-XA_4vr4ZINCLVsCV_PuyuGLYviei8DPCHGVoTL8p7AvHhW1LaofbE-uzgjn1uubqnsBB1e1s4NrShUe1XMNDyQu2WE5VcRTXF3v9GtmZ_SyKKb93wZ92oThhus1ve_qMya2P0YtMroKS8CFaizdQYCYh7DD4AUoJt-OurH_BykwafHpJRS7LUhU0UozUVeNQPMBks6ZPE4UvriyaRqLbnoP_t54bekLTYmrna4IrnRViYhzIc0UP3i4GxHq-bzMUNI9Fe9fQykP5UJLSFMGi_IMae7dghucDdHieWeBmsrTgu4uUfPYkcOoZYoLigpEan_hnWovpmJ7tAyfUcD5WcOkOtPX5L0Ym_tZp8LR5URWerQMg2YEbwbmE6sSEwh_TfI0TPWRrqg9LC82OJKO2xOG6JZqeaedEy8PnOl4I7mknd2hSmBInX-T-6q1E0CdugEU2D_xzXvTcFoWSCo7fvd90WgO-zfX4bgGIMZQskiYJbLyGAhO18xomnKyPhiLRpv4nQGCNqFFKgY5wEENYn41dlMa34XXRd4tknouZJRxipAs57nlSq7yGUz_cTl4kLxhi_U314MrXwWK6PveEgn1mod0xsZPzpgkQaIE27oeVVTJeCWdk0OADT2Uwqk_RWwzRJ_Fl5_p0X_PDa6Je8tXipKHRsFMldxnujuxrVDLVQFHMSmh4ihjQzSptLidmlRW0oqZdZCS4GERt-llSD3w0nS5c2LCNTd_K7zCxgYyLtMwA0wZ9-R-7mRAxKuvMKhKvYkHf5yD9ncEbyXkdTfJxfF4zOUSZgAbhKyELhztK367TH69Y2m_jwYzxVOEUODcqivgSloIabbqnBTV725YIzxqCCOsyvnYNkyipk0KVNr6Yob4H1iZiEQhuBygdK4Ghs-rE8I6Q8cD6MjLzZJ1htF0_Rts5cRt_9fUmd_EX1DyS8c3gEyWSD4CyOLZwyvG-QuaU06mZSkqwQDo7tCk4eiDKvaOb3AWqXUG4ZyqgfuEljoo6cKzvhvE6OGVAsh58_p3DYZ2HcvNynEVRd3j7GLgIXFrgCLfgMg6K1lBMiUMCTVzvWkjGRMjeEkwYYwwHkClhOVFgHf6keS1QgdS6MYxHdpqBFzdxIT4JovcdUTjDqmBs1wWAtpCXpuHpj4y9xY8uNOL41FYaJGd9Tv_xxgJwFNCN7tt4PGqVWdMjK36oxjV8o2yNfUYc6CqzsfGSJOJq275cd4Rku7eqrlw7ZSqfsT6uTx5AIu_Kj3leSY7YjV16GEXUTKjmKmNugtOj6bO81tU2Fz4mlCY6Y3Sdp-JoG-X6I_TNDl4mKrIjq-t9UqP9W3cUdyXY-e07hNwcaKDRb0WaXwAELTnwYmxPFXDfAiP_SMZ_Ol9z0mXoos3WxGlx9aaE96s7WzOZtsvtr23tMBjGxsgNull_uXsf2Wwb61xk0U9cQbta09FhjqF2b6X6iW6VY0Wjd9wasUBb2josUTXKyYSfTDI0q2RH9LMhiVFaX4gE3_K0U8c9na3OFNLLGDjwXG6jCPj2JzauFZWnBxPSC7ZdGPEA5umFanhqsNCQy0rLtvCXqfFWe_1InLfUdfCiWwNT7cNNAIFI-zq5e_kbJCRd1fip5BeuPVT62mAUB02V_TyIQhYTN9dUswY6Cg5FHSUKrfUFeBhi2Dmqqu_--FTNqxew99TigTS_gN0cxDxsLStqev8cwddBALWTCP3C6EBfrhP6i5I9bLtxlnPnGV5whojYDQ07xRdWx9x2820ltO5GZj4iPNlX8LggywDz3qClzG0eToWT0WUoS7yN60E-pU3_L5psCTvqh8gIEUFN7MUw6T_DRxjsjaxnPxTQtt31hHNaDbJ99QXJfrnU4KPOsZGFqzwQC_IdNvX0YWRGLeaFQVoh4WfCXLskTBaScekE6zjlmj7fvh99RQuod1aaHCL1c22RA515m9nhauKJPSfw3fq8_t1YlBle1mVkj7-Pn0uo-3icbZXq4-aFFiDWTQz8_IGUFxMCmQRkh_5npUMChTN3ft064Vg8ZFqonCunOe8Id0pN4_JBKkwH6dkuq3JOITnhQXNvY7nMymz8fm8hGupjCogqL2D-x4_Fh18vUHnIn8zTz2HmZd_mQatNEH1C3ppQAWY3blBUGn8zX9EdU60aDnJZbv84xgyrjHF6TUsbt0V4OhhK0frcqP8d8gax4AtNA0kP1TLC_aXAqXjsuh5TAGCCMjYVHr6GrmlYPehsiCN_yhZWtuCVmEqFQBZn-ujDELGw1pxM8DXswp15j42gvIg-E3MUZL7g0Ik349goOzRWuI5Uz8JDNygEtw1f1FD97Yg8tSvEnigLZ0fhIH8MmrD6sA7GXgtgsw-Y22w7NSlTFTA-x1AxmW1A0wP6yRbcPWiN4vyreOyetLWp0R5OJKmcOFFKimcwwdSxjdu1EBZfbSLQZTmmEh5HFMjV2ZvJMkfLOlJEasPWqxgglqF209u127yERZBtHbZmNjBo2tB9x9l4xYSrncu8f2GHOvj3sr3N00ESTs43Ra1_QFM9stZFb45D_Mpd3lVtAZzAitWGx1dUTBTrw5hrl4IUKBrXaCWirSyPheccwKbaDNVTt1mDcWnm1P2QkKDcwECx9P60d5eLUejaq6w6V_EvgA7Pr-S9xodFIF3M4uxCjh0oT6qSpL6TmAQ7jGD2qHRkIbt_ai3o5NM2ZkHL_MB_e73UWgfoMwMF4WPLEizryF-AlPD63rPdcKMy8hvh7aeNTS50467b0g7xrjJsTyiyaQiXByYTusiWv6Mrne83O8opL2sFW_iu3O97lkTCmpcw2quJmVUeDs4351zf3YvlQBo2Q3ihVK5XrpitgiJ3uRPmLSp5-krQ6R9qn9ETd747cVMq-XesWhgnfhSS_vxl89eeRSIceEVryKqcP5GkOujKNw4BaUMwkEwm56drM_RndM4ARELtcTDbqbAR2XvToqCdToyii9LrQFUZfHyeZ-zWMVyJMEwfInTQ8Tw9NMOQ-2k3ML_c546io4gbxIO-Wnt3d-dUcMiH8xpg-5Yg8Vr-HIhvmphhYXG4JNI2tb8J3jXxkPc1tAznyOkfSMAHHKhYcS-CZiq62Yq2X9fjhPFnlUzQwDj03fjL9vHfSXjzQ1LG4jGWKoWFTOUy3xt_8nValuPBlvz2AMMd_uAT_FQ2lUxywIU86Xd3xmWqgr5jen2MbC6LPWPqG8dcuA2MBpNLwD701Aa6P7c9RshOOrg496Waz_vj4SgEoiHFUte5RpbPKijV5Auqh4kJw3_buZWjVOSWzxQvAWPBk5DxProDUitPIdm3Zj66CTFJ9mTfQ4Lo0irg_gofj4qFAVxSkx_rGXdCq3fzxqnzGsSVZnMUgaUJI5Aeygqwg8w3yCmKJGawMbKFTxOcF9ANFAKV5Pgt93SLmNNTJ1D6FUPYdQtPXJwBqpNexwNyewND9uyFUDOVnliK-jqfy5N21ypOfxfwtoBHpQxfaeNO86GCbrNt1FvzNego7-ixE0TvEabRr03o6XCDKXMxHhq5gcOPaSeAJnT3zbxQ-FmoZ_9jO_9OK5CPgeWLON-M9ALKNj4B7j35zdb1g4fH8eYrM5oS6D_QPwngNCxg8Q0p0vxBJXfQfsU6Y7gE2d0OvHN3DQqtj6Q2fKcDOJGhDP7clwf5AL1AWgtjJg9gm_rfBnSbVBZhutdRkHEOCS_Mwp-L0HPDtYqK-_t97y401KE8HxDI__y8833i8g8tDRVAprdr4iQdsWYo_23FHG4vy1nAbzS1pdx3LFWYaI9yecAoj8PIIBwZHHR4ck9SKc1TC-9sML7rw7oks0vUyZOv8e2BOoyiH1AKZYZySV-dQrAHHkBVo5fOli-YFKl-6BlYoJGQk-iD5diykRJ-1Rcxv2umQW8cHGYozuNr-tdz1R_Y4BJ-oVAJVWnlD1zIZfb_iiyU7jbCLbbCAV_R4f-LVSefjGIVrArfBHSzlHeKNkaDfWau4i19SnEjT5knnKo4ShiWmbgqAEMdAQ7EK-ESyO5nz6kDulTz-hRdCcDPBVx_mPLPrPC5uYJJPQH1JF25pcmPpdTsO-HFusNJpuBXsO1j4wy5RVVGc-Ci0ujCyDimUqfvJF1ISn4LeQB4umpV1aWg9k0qgHvV9ajxUBBqWMHYygXYRSer1vqKKhiUFrjXI6NNJH2oHHbb504exE9s3aWvGuywo3QLsEU1Iwho9_GLTJK7GbYDot7iZFS7fQGvtQtonqjeJyGCZQSjTGS-YXg9mf7WhYg1yXD_tAuxWkP9MGvdEUzD2aEBPCBcyjOQfLAKphbzTNUhKUDD6Gq3aB1dOBVQVNe-lH8CsQ2qgg9wjL-bmRXZt9LAw3_x0KrprKn8yRbgr06gyRd5__e5hNR2waAvIyKiRe32e__nC9_ZpptOqxfvEofOxW7n0B5NF6vWK04JKssItxeM5m4sWQMed60ytmS0UeVzBslOamOkAn7-hzEh6Hxgi_0QFNbk6vjmx7SYbV1ttJRV8OiQVvQHoxpSoNZVIZjHRbl0VoOvwsam-VGoNvfsT0Sl1jjKVX9hiEDCXrskIaEl4Stk2qwkr122YfTXiNhypjsAvyxklLfT5enkwzz7Dkz2VfQiTmd31u3kgNPoKJ7f2vI_gpIpqMiaYTdBMBsUu_UXVSawP0zRkvjhcB9Vm3lCTbN8sru2uJ-N73bYIP7bYhcoGjUMmyXyZPdDU1vpcjrAqSsYm_89ry3VnEsjgVB2BuFmT44hRpWLydTQHU4byi57cz8eZXAdWhUz14850BQgTFe0oaWWfFgnYCa3_1Va1-lVFfhK3A3lGa5GOYA_zbprO-AgaoQqelTYxR_LjhfoZbImO1wuUdfDsU494qBCYM0UlI39nP1jP9Ln-3ZXm-VyPv8Q3yCsW_Uq7HL_-BY5yy8LVcoKeqB6PBGQvCr9KZA_IbCyaYsG9AS-EFCZI1cfvNeNN71zzwf07-eyuW9pVc3v0piBOZme2O2d3C2M4Y7styruauGZ3E4LePpphQ4TXFqtJMCTxzRgT63eBRSrBjWHeBayCbr2wRWobJak-lCtKtBaPnHHlsJw0EX7STF2-4FU-z8lOF1JQ8XqgITjO89DHFLKP-dUax-KSYN-XsDmXBpLWd9JR9lpaZrq9CA9DDTdIAJTIx1xt5YTIVCW3RBKnVk3q96mK0zbsOCcNXRk-bhbrCX-6Uxc_ESsaiBhwaqlhhK-Vvs15BgDmiRI8QYO71wtOI1CObu4vi-A5fOakP8QiiIFkpE8Kgis9OqrpNyjve9ORRIUHIlPYQF-lHecNhz3ywNGW-CLxjh_KFAc2jMJ6pmXmJEGMWDY7FPwiT1RnoFUQ_JsNp8L8gnXiTiOHoVpSFywWmcISwhdyVI4Mjwdgp2yKafZz8kktEgKSbD5IGKcG8XmGLadzMjXgij1lD5Lul9MS2lmjMTC8Qm3G-Il0Xc6zzDwDc5PVWHVbNmIIKLHS_YvNFyKgPhbsnqohvQDg3sHjZ6z6-QZVoI9_d4g5t1vHTR-RySAf37q274TGbOcc3Iatr6kh_eJlfDvd4v6uFRyLUCkm-R5DAfDuogriG8hITXHG1b52Tm751xD0lVajn2GDmUKG-tJhoMnBvakRRpJ4rxFiGuPZltpSuX57UCr0Y3dlcJtae2QLAyRnW1B_HEw8AhasR7json3mkkYfqTSiegWzbkQXXaGBkDDx_kBiu6DhVmfG9iku87yVGQVya4yJdQV28d0KkCvsVbtWiY6obqzmvY4RgAIZ7GysXLZGBqbVZ2AvszgC8O3BNnvs0Gjq6nhsEa30XWa39n0yCznd9uiZ57vyAJMhu5S1VFxWBuycrPkxQOfFDcYNFB5aIjLUBMTsMs1n9ias3SdpNAWRpgvNQtDjxwgnL-GoHr980SSmlrRiV5vqC4RDiaH9T6L3TLdr2fJhO39Cekj-0QIhZTwxT4BgcyCMfA0x8PTnfjhJyS31W4BeVaecKPLf1Q6WesuUSFWO-2euCSDMSFu-IWbusia_X0UggmuQixvd9gy-Nxvk5MMxJd9nN1AglwkKp6UdmYXBpqK6cdRB1nJdyM7vIGuuqo3d_PH0d1PN1DZaPSrMk1kUAbI9c66pKevhzboAvIbCo7Q7-DeKm2XLIURixmWDESH1l6U95L_dDYT_30qBH9-E98lyOltuBCSJTQLeWS1NyeFKXUhohJNfZn1tDEKJlf8bUoT-YJ9TpsuW6YYiqLzpmAmD4lm5lPXd4I-8wHQqXNu3Nyg_SsnpCJMym9REb-x2SNz9DzRd8Dhbkzb7ApIiG1MAZ4y8CiNUZizoieAqBStXTtAlZlUVk-DmwxptL8A1Nb5KLlu4smoZVuTVcNCXk01y6F1F3VsMJohTlBmIb9Nhhl155f4TvhaNoeBAZ7bsiAra8d2EdPuDnvLsAUgySmu7uB7Ffw3_4h0F4Xzym1XmNrV1lU4v8KfAmSQLB4FfCh017G3yrhH4a15d5uBUFplvahAZQ_iRvRZm0cnz8Ag2H2SP7Xw1u7uRhH11BQNtYcraFg_uM3Wxi3HiZmjRLrtGVa5Q8PP4avFaRT5BWhGUljK_mMKbZgH9QppmNmAFjCihlPHfQkkEfwC1GTJpmCXEhLAMeO5kOv1ZCOnolZPNlxNUJyQ8dYradf3MbpCpClwF_Ob1gfUFlyChdsAk= \ No newline at end of file diff --git a/v2_adminpanel/create_resource_tables.sql b/v2_adminpanel/create_resource_tables.sql deleted file mode 100644 index ef2e915..0000000 --- a/v2_adminpanel/create_resource_tables.sql +++ /dev/null @@ -1,94 +0,0 @@ --- Erstelle die fehlenden Resource Pool Tabellen --- Nur ausführen wenn die Tabellen noch nicht existieren - --- Resource Pool Haupttabelle -CREATE TABLE IF NOT EXISTS resource_pools ( - id SERIAL PRIMARY KEY, - resource_type VARCHAR(20) NOT NULL CHECK (resource_type IN ('domain', 'ipv4', 'phone')), - resource_value VARCHAR(255) NOT NULL, - status VARCHAR(20) DEFAULT 'available' CHECK (status IN ('available', 'allocated', 'quarantine')), - allocated_to_license INTEGER REFERENCES licenses(id) ON DELETE SET NULL, - status_changed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - status_changed_by VARCHAR(50), - quarantine_reason VARCHAR(100) CHECK (quarantine_reason IN ('abuse', 'defect', 'maintenance', 'blacklisted', 'expired', 'review', NULL)), - quarantine_until TIMESTAMP WITH TIME ZONE, - created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - notes TEXT, - UNIQUE(resource_type, resource_value) -); - --- Historie für Resource-Aktionen -CREATE TABLE IF NOT EXISTS resource_history ( - id SERIAL PRIMARY KEY, - resource_id INTEGER REFERENCES resource_pools(id) ON DELETE CASCADE, - license_id INTEGER REFERENCES licenses(id) ON DELETE SET NULL, - action VARCHAR(50) NOT NULL CHECK (action IN ('allocated', 'deallocated', 'quarantined', 'released', 'created', 'deleted')), - action_by VARCHAR(50) NOT NULL, - action_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - details JSONB, - ip_address TEXT -); - --- Metriken für Resource Performance -CREATE TABLE IF NOT EXISTS resource_metrics ( - id SERIAL PRIMARY KEY, - resource_id INTEGER REFERENCES resource_pools(id) ON DELETE CASCADE, - metric_date DATE NOT NULL, - usage_count INTEGER DEFAULT 0, - performance_score DECIMAL(5,2) DEFAULT 0.00, - cost DECIMAL(10,2) DEFAULT 0.00, - revenue DECIMAL(10,2) DEFAULT 0.00, - issues_count INTEGER DEFAULT 0, - availability_percent DECIMAL(5,2) DEFAULT 100.00, - UNIQUE(resource_id, metric_date) -); - --- Zuordnungstabelle zwischen Lizenzen und Ressourcen -CREATE TABLE IF NOT EXISTS license_resources ( - id SERIAL PRIMARY KEY, - license_id INTEGER REFERENCES licenses(id) ON DELETE CASCADE, - resource_id INTEGER REFERENCES resource_pools(id) ON DELETE CASCADE, - assigned_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - assigned_by VARCHAR(50), - is_active BOOLEAN DEFAULT TRUE, - UNIQUE(license_id, resource_id) -); - --- Erweiterung der licenses Tabelle um Resource-Counts -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM information_schema.columns - WHERE table_name = 'licenses' AND column_name = 'domain_count') THEN - ALTER TABLE licenses - ADD COLUMN domain_count INTEGER DEFAULT 1 CHECK (domain_count >= 0 AND domain_count <= 10), - ADD COLUMN ipv4_count INTEGER DEFAULT 1 CHECK (ipv4_count >= 0 AND ipv4_count <= 10), - ADD COLUMN phone_count INTEGER DEFAULT 1 CHECK (phone_count >= 0 AND phone_count <= 10); - END IF; -END $$; - --- Indizes für Performance -CREATE INDEX IF NOT EXISTS idx_resource_status ON resource_pools(status); -CREATE INDEX IF NOT EXISTS idx_resource_type_status ON resource_pools(resource_type, status); -CREATE INDEX IF NOT EXISTS idx_resource_allocated ON resource_pools(allocated_to_license) WHERE allocated_to_license IS NOT NULL; -CREATE INDEX IF NOT EXISTS idx_resource_quarantine ON resource_pools(quarantine_until) WHERE status = 'quarantine'; -CREATE INDEX IF NOT EXISTS idx_resource_history_date ON resource_history(action_at DESC); -CREATE INDEX IF NOT EXISTS idx_resource_history_resource ON resource_history(resource_id); -CREATE INDEX IF NOT EXISTS idx_resource_metrics_date ON resource_metrics(metric_date DESC); -CREATE INDEX IF NOT EXISTS idx_license_resources_active ON license_resources(license_id) WHERE is_active = TRUE; - --- Prüfe ob Tabellen erfolgreich erstellt wurden -DO $$ -DECLARE - table_count INT; -BEGIN - SELECT COUNT(*) INTO table_count - FROM information_schema.tables - WHERE table_schema = 'public' - AND table_name IN ('resource_pools', 'resource_history', 'resource_metrics', 'license_resources'); - - IF table_count = 4 THEN - RAISE NOTICE 'Alle 4 Resource-Tabellen wurden erfolgreich erstellt!'; - ELSE - RAISE WARNING 'Nur % von 4 Tabellen wurden erstellt!', table_count; - END IF; -END $$; \ No newline at end of file diff --git a/v2_adminpanel/migrate_existing_licenses.sql b/v2_adminpanel/migrate_existing_licenses.sql deleted file mode 100644 index c8a041f..0000000 --- a/v2_adminpanel/migrate_existing_licenses.sql +++ /dev/null @@ -1,263 +0,0 @@ --- Migration Script für bestehende Lizenzen --- Setzt Default-Werte für Resource Counts --- Stand: 2025-06-09 - --- ==================================== --- Prüfe ob Migration notwendig ist --- ==================================== -DO $$ -DECLARE - licenses_without_resources INT; - total_licenses INT; -BEGIN - -- Zähle Lizenzen ohne Resource-Count Werte - SELECT COUNT(*) INTO licenses_without_resources - FROM licenses - WHERE domain_count IS NULL - OR ipv4_count IS NULL - OR phone_count IS NULL; - - SELECT COUNT(*) INTO total_licenses FROM licenses; - - IF licenses_without_resources > 0 THEN - RAISE NOTICE 'Migration notwendig für % von % Lizenzen', licenses_without_resources, total_licenses; - ELSE - RAISE NOTICE 'Keine Migration notwendig - alle Lizenzen haben bereits Resource Counts'; - RETURN; - END IF; -END $$; - --- ==================================== --- Setze Default Resource Counts --- ==================================== - --- Vollversionen erhalten standardmäßig je 2 Ressourcen -UPDATE licenses -SET domain_count = COALESCE(domain_count, 2), - ipv4_count = COALESCE(ipv4_count, 2), - phone_count = COALESCE(phone_count, 2) -WHERE license_type = 'full' - AND (domain_count IS NULL OR ipv4_count IS NULL OR phone_count IS NULL); - --- Testversionen erhalten standardmäßig je 1 Ressource -UPDATE licenses -SET domain_count = COALESCE(domain_count, 1), - ipv4_count = COALESCE(ipv4_count, 1), - phone_count = COALESCE(phone_count, 1) -WHERE license_type = 'test' - AND (domain_count IS NULL OR ipv4_count IS NULL OR phone_count IS NULL); - --- Inaktive Lizenzen erhalten 0 Ressourcen -UPDATE licenses -SET domain_count = COALESCE(domain_count, 0), - ipv4_count = COALESCE(ipv4_count, 0), - phone_count = COALESCE(phone_count, 0) -WHERE is_active = FALSE - AND (domain_count IS NULL OR ipv4_count IS NULL OR phone_count IS NULL); - --- ==================================== --- Erstelle Resource-Zuweisungen für bestehende aktive Lizenzen --- ==================================== -DO $$ -DECLARE - license_rec RECORD; - resource_rec RECORD; - resources_assigned INT := 0; - resources_needed INT; -BEGIN - -- Durchlaufe alle aktiven Lizenzen mit Resource Counts > 0 - FOR license_rec IN - SELECT id, domain_count, ipv4_count, phone_count - FROM licenses - WHERE is_active = TRUE - AND (domain_count > 0 OR ipv4_count > 0 OR phone_count > 0) - ORDER BY created_at - LOOP - -- Domains zuweisen - resources_needed := license_rec.domain_count; - FOR i IN 1..resources_needed LOOP - -- Finde eine verfügbare Domain - SELECT id INTO resource_rec - FROM resource_pools - WHERE resource_type = 'domain' - AND status = 'available' - ORDER BY RANDOM() - LIMIT 1; - - IF resource_rec.id IS NOT NULL THEN - -- Weise Resource zu - UPDATE resource_pools - SET status = 'allocated', - allocated_to_license = license_rec.id, - status_changed_at = NOW(), - status_changed_by = 'migration' - WHERE id = resource_rec.id; - - -- Erstelle Zuordnung - INSERT INTO license_resources (license_id, resource_id, assigned_by) - VALUES (license_rec.id, resource_rec.id, 'migration'); - - -- Historie eintragen - INSERT INTO resource_history (resource_id, license_id, action, action_by, details) - VALUES (resource_rec.id, license_rec.id, 'allocated', 'migration', - '{"reason": "Migration bestehender Lizenzen"}'::jsonb); - - resources_assigned := resources_assigned + 1; - END IF; - END LOOP; - - -- IPv4-Adressen zuweisen - resources_needed := license_rec.ipv4_count; - FOR i IN 1..resources_needed LOOP - SELECT id INTO resource_rec - FROM resource_pools - WHERE resource_type = 'ipv4' - AND status = 'available' - ORDER BY RANDOM() - LIMIT 1; - - IF resource_rec.id IS NOT NULL THEN - UPDATE resource_pools - SET status = 'allocated', - allocated_to_license = license_rec.id, - status_changed_at = NOW(), - status_changed_by = 'migration' - WHERE id = resource_rec.id; - - INSERT INTO license_resources (license_id, resource_id, assigned_by) - VALUES (license_rec.id, resource_rec.id, 'migration'); - - INSERT INTO resource_history (resource_id, license_id, action, action_by, details) - VALUES (resource_rec.id, license_rec.id, 'allocated', 'migration', - '{"reason": "Migration bestehender Lizenzen"}'::jsonb); - - resources_assigned := resources_assigned + 1; - END IF; - END LOOP; - - -- Telefonnummern zuweisen - resources_needed := license_rec.phone_count; - FOR i IN 1..resources_needed LOOP - SELECT id INTO resource_rec - FROM resource_pools - WHERE resource_type = 'phone' - AND status = 'available' - ORDER BY RANDOM() - LIMIT 1; - - IF resource_rec.id IS NOT NULL THEN - UPDATE resource_pools - SET status = 'allocated', - allocated_to_license = license_rec.id, - status_changed_at = NOW(), - status_changed_by = 'migration' - WHERE id = resource_rec.id; - - INSERT INTO license_resources (license_id, resource_id, assigned_by) - VALUES (license_rec.id, resource_rec.id, 'migration'); - - INSERT INTO resource_history (resource_id, license_id, action, action_by, details) - VALUES (resource_rec.id, license_rec.id, 'allocated', 'migration', - '{"reason": "Migration bestehender Lizenzen"}'::jsonb); - - resources_assigned := resources_assigned + 1; - END IF; - END LOOP; - END LOOP; - - RAISE NOTICE 'Migration abgeschlossen: % Ressourcen wurden zugewiesen', resources_assigned; -END $$; - --- ==================================== --- Abschlussbericht --- ==================================== -DO $$ -DECLARE - v_total_licenses INT; - v_licenses_with_resources INT; - v_total_resources_assigned INT; - v_domains_assigned INT; - v_ipv4_assigned INT; - v_phones_assigned INT; -BEGIN - -- Statistiken sammeln - SELECT COUNT(*) INTO v_total_licenses FROM licenses; - - SELECT COUNT(*) INTO v_licenses_with_resources - FROM licenses - WHERE id IN (SELECT DISTINCT license_id FROM license_resources WHERE is_active = TRUE); - - SELECT COUNT(*) INTO v_total_resources_assigned - FROM license_resources - WHERE is_active = TRUE; - - SELECT COUNT(*) INTO v_domains_assigned - FROM resource_pools - WHERE resource_type = 'domain' AND status = 'allocated'; - - SELECT COUNT(*) INTO v_ipv4_assigned - FROM resource_pools - WHERE resource_type = 'ipv4' AND status = 'allocated'; - - SELECT COUNT(*) INTO v_phones_assigned - FROM resource_pools - WHERE resource_type = 'phone' AND status = 'allocated'; - - -- Bericht ausgeben - RAISE NOTICE ''; - RAISE NOTICE '========================================'; - RAISE NOTICE 'MIGRATION ABGESCHLOSSEN'; - RAISE NOTICE '========================================'; - RAISE NOTICE 'Lizenzen gesamt: %', v_total_licenses; - RAISE NOTICE 'Lizenzen mit Ressourcen: %', v_licenses_with_resources; - RAISE NOTICE ''; - RAISE NOTICE 'Zugewiesene Ressourcen:'; - RAISE NOTICE '- Domains: %', v_domains_assigned; - RAISE NOTICE '- IPv4-Adressen: %', v_ipv4_assigned; - RAISE NOTICE '- Telefonnummern: %', v_phones_assigned; - RAISE NOTICE '- Gesamt: %', v_total_resources_assigned; - RAISE NOTICE '========================================'; - - -- Warnungen ausgeben - IF EXISTS ( - SELECT 1 FROM licenses l - WHERE l.is_active = TRUE - AND (l.domain_count > 0 OR l.ipv4_count > 0 OR l.phone_count > 0) - AND NOT EXISTS ( - SELECT 1 FROM license_resources lr - WHERE lr.license_id = l.id AND lr.is_active = TRUE - ) - ) THEN - RAISE WARNING 'ACHTUNG: Einige aktive Lizenzen konnten keine Ressourcen erhalten (möglicherweise nicht genug verfügbar)'; - - -- Liste betroffene Lizenzen auf - FOR v_total_licenses IN - SELECT l.id FROM licenses l - WHERE l.is_active = TRUE - AND (l.domain_count > 0 OR l.ipv4_count > 0 OR l.phone_count > 0) - AND NOT EXISTS ( - SELECT 1 FROM license_resources lr - WHERE lr.license_id = l.id AND lr.is_active = TRUE - ) - LOOP - RAISE WARNING 'Lizenz ID % hat keine Ressourcen erhalten', v_total_licenses; - END LOOP; - END IF; -END $$; - --- ==================================== --- Audit Log Eintrag für Migration --- ==================================== -INSERT INTO audit_log ( - timestamp, - username, - action, - entity_type, - additional_info -) VALUES ( - NOW(), - 'system', - 'MIGRATION', - 'licenses', - 'Resource Pool Migration für bestehende Lizenzen durchgeführt' -); \ No newline at end of file diff --git a/v2_adminpanel/sample_data.sql b/v2_adminpanel/sample_data.sql deleted file mode 100644 index ec13968..0000000 --- a/v2_adminpanel/sample_data.sql +++ /dev/null @@ -1,93 +0,0 @@ --- Beispieldaten für v2-Docker Admin Panel --- Führen Sie dieses Script aus, um Testdaten zu generieren - --- Kunden einfügen -INSERT INTO customers (name, email) VALUES - ('TechStart GmbH', 'info@techstart.de'), - ('Digital Solutions AG', 'kontakt@digital-solutions.ch'), - ('WebMaster Pro', 'admin@webmaster-pro.com'), - ('Social Media Experts', 'hello@social-experts.de'), - ('Marketing Genius Ltd', 'contact@marketing-genius.co.uk'), - ('StartUp Factory', 'team@startup-factory.de'), - ('Innovation Hub GmbH', 'info@innovation-hub.de'), - ('Creative Agency Berlin', 'office@creative-berlin.de'), - ('Data Analytics Corp', 'support@data-analytics.com'), - ('Cloud Services 24/7', 'info@cloud247.de'), - ('Mobile First Solutions', 'contact@mobile-first.de'), - ('AI Powered Marketing', 'hello@ai-marketing.de'), - ('Performance Media Group', 'info@performance-media.de'), - ('Growth Hacker Studio', 'team@growth-hacker.de'), - ('Digital Transformation AG', 'contact@digital-transform.ch') -ON CONFLICT (email) DO NOTHING; - --- Lizenzen einfügen (verschiedene Status) --- Aktive Vollversionen -INSERT INTO licenses (license_key, customer_id, license_type, valid_from, valid_until, is_active) VALUES - ('AF-202506F-A7K9-M3P2-X8R4', 1, 'full', CURRENT_DATE - INTERVAL '30 days', CURRENT_DATE + INTERVAL '335 days', true), - ('AF-202506F-B2N5-K8L3-Q9W7', 2, 'full', CURRENT_DATE - INTERVAL '60 days', CURRENT_DATE + INTERVAL '305 days', true), - ('AF-202506F-C4M8-P2R6-T5Y3', 3, 'full', CURRENT_DATE - INTERVAL '90 days', CURRENT_DATE + INTERVAL '275 days', true), - ('AF-202506F-D9L2-S7K4-U8N6', 4, 'full', CURRENT_DATE - INTERVAL '15 days', CURRENT_DATE + INTERVAL '350 days', true), - ('AF-202506F-E3P7-W5M9-V2X8', 5, 'full', CURRENT_DATE - INTERVAL '45 days', CURRENT_DATE + INTERVAL '320 days', true); - --- Bald ablaufende Lizenzen (innerhalb 30 Tage) -INSERT INTO licenses (license_key, customer_id, license_type, valid_from, valid_until, is_active) VALUES - ('AF-202506F-F6K2-Y8L4-Z3N9', 6, 'full', CURRENT_DATE - INTERVAL '350 days', CURRENT_DATE + INTERVAL '15 days', true), - ('AF-202506F-G4M7-A9P3-B5R8', 7, 'full', CURRENT_DATE - INTERVAL '340 days', CURRENT_DATE + INTERVAL '25 days', true), - ('AF-202506T-H8N3-C2K6-D7L9', 8, 'test', CURRENT_DATE - INTERVAL '25 days', CURRENT_DATE + INTERVAL '5 days', true), - ('AF-202506T-J5P8-E4M2-F9N7', 9, 'test', CURRENT_DATE - INTERVAL '20 days', CURRENT_DATE + INTERVAL '10 days', true); - --- Abgelaufene Lizenzen -INSERT INTO licenses (license_key, customer_id, license_type, valid_from, valid_until, is_active) VALUES - ('AF-202406F-K3L7-G8P4-H2M9', 10, 'full', CURRENT_DATE - INTERVAL '400 days', CURRENT_DATE - INTERVAL '35 days', true), - ('AF-202406F-L9N2-J5K8-M7P3', 11, 'full', CURRENT_DATE - INTERVAL '380 days', CURRENT_DATE - INTERVAL '15 days', true), - ('AF-202406T-M4K6-L3N9-P8R2', 12, 'test', CURRENT_DATE - INTERVAL '45 days', CURRENT_DATE - INTERVAL '15 days', true); - --- Deaktivierte Lizenzen -INSERT INTO licenses (license_key, customer_id, license_type, valid_from, valid_until, is_active) VALUES - ('AF-202506F-N7P3-Q2L8-R5K4', 13, 'full', CURRENT_DATE - INTERVAL '120 days', CURRENT_DATE + INTERVAL '245 days', false), - ('AF-202506F-P8M5-S4N7-T9L2', 14, 'full', CURRENT_DATE - INTERVAL '180 days', CURRENT_DATE + INTERVAL '185 days', false), - ('AF-202506T-Q3K9-U7P5-V2M8', 15, 'test', CURRENT_DATE - INTERVAL '10 days', CURRENT_DATE + INTERVAL '20 days', false); - --- Testversionen -INSERT INTO licenses (license_key, customer_id, license_type, valid_from, valid_until, is_active) VALUES - ('AF-202506T-R6N4-W8L2-X3P7', 1, 'test', CURRENT_DATE, CURRENT_DATE + INTERVAL '30 days', true), - ('AF-202506T-S9K7-Y5M3-Z8N2', 3, 'test', CURRENT_DATE - INTERVAL '5 days', CURRENT_DATE + INTERVAL '25 days', true), - ('AF-202506T-T4L8-A2P6-B7K3', 5, 'test', CURRENT_DATE - INTERVAL '10 days', CURRENT_DATE + INTERVAL '20 days', true); - --- Sessions einfügen (nur für Demonstration) --- Aktive Sessions -INSERT INTO sessions (license_id, session_id, ip_address, user_agent, last_heartbeat, is_active) VALUES - (1, 'sess_' || gen_random_uuid(), '192.168.1.100', 'Mozilla/5.0 Windows NT 10.0', CURRENT_TIMESTAMP - INTERVAL '2 minutes', true), - (2, 'sess_' || gen_random_uuid(), '10.0.0.50', 'Mozilla/5.0 Macintosh', CURRENT_TIMESTAMP - INTERVAL '5 minutes', true), - (3, 'sess_' || gen_random_uuid(), '172.16.0.25', 'Chrome/91.0.4472.124', CURRENT_TIMESTAMP - INTERVAL '1 minute', true), - (4, 'sess_' || gen_random_uuid(), '192.168.2.75', 'Safari/14.1.1', CURRENT_TIMESTAMP - INTERVAL '8 minutes', true); - --- Inaktive Sessions (beendet) -INSERT INTO sessions (license_id, session_id, ip_address, user_agent, started_at, last_heartbeat, ended_at, is_active) VALUES - (5, 'sess_' || gen_random_uuid(), '10.10.10.10', 'Firefox/89.0', CURRENT_TIMESTAMP - INTERVAL '2 hours', CURRENT_TIMESTAMP - INTERVAL '1 hour', CURRENT_TIMESTAMP - INTERVAL '1 hour', false), - (6, 'sess_' || gen_random_uuid(), '172.20.0.100', 'Edge/91.0.864.59', CURRENT_TIMESTAMP - INTERVAL '5 hours', CURRENT_TIMESTAMP - INTERVAL '3 hours', CURRENT_TIMESTAMP - INTERVAL '3 hours', false); - --- Audit Log Einträge -INSERT INTO audit_log (username, action, entity_type, entity_id, new_values, ip_address, additional_info) VALUES - ('rac00n', 'CREATE', 'customer', 1, '{"name": "TechStart GmbH", "email": "info@techstart.de"}', '192.168.1.1', 'Neuer Kunde angelegt'), - ('w@rh@mm3r', 'CREATE', 'license', 1, '{"license_key": "AF-202506F-A7K9-M3P2-X8R4", "type": "full"}', '192.168.1.2', 'Vollversion erstellt'), - ('rac00n', 'UPDATE', 'license', 13, '{"is_active": false}', '192.168.1.1', 'Lizenz deaktiviert'), - ('w@rh@mm3r', 'DELETE', 'customer', 16, '{"name": "Test Kunde"}', '192.168.1.2', 'Kunde ohne Lizenzen gelöscht'), - ('rac00n', 'EXPORT', 'licenses', null, '{"format": "excel", "count": 15}', '192.168.1.1', 'Lizenzexport durchgeführt'), - ('system', 'CREATE_BATCH', 'licenses', null, '{"customer": "Digital Solutions AG", "count": 5}', '127.0.0.1', 'Batch-Lizenzen erstellt'); - --- Login Attempts (für Security Dashboard) -INSERT INTO login_attempts (ip_address, attempt_count, last_username_tried, last_error_message) VALUES - ('192.168.100.50', 2, 'admin', 'Falsches Passwort'), - ('10.0.0.200', 3, 'test', 'Benutzer nicht gefunden'), - ('172.16.50.100', 1, 'rac00n', 'Falsches Passwort'); - --- Ein gesperrter Versuch -INSERT INTO login_attempts (ip_address, attempt_count, last_username_tried, last_error_message, blocked_until) VALUES - ('192.168.200.100', 5, 'hacker', 'Zu viele Fehlversuche', CURRENT_TIMESTAMP + INTERVAL '20 hours'); - --- Backup History -INSERT INTO backup_history (filename, filepath, filesize, backup_type, status, created_by, tables_count, records_count, duration_seconds, is_encrypted) VALUES - ('backup_v2docker_20250608_120000_encrypted.sql.gz.enc', '/app/backups/backup_v2docker_20250608_120000_encrypted.sql.gz.enc', 1048576, 'manual', 'success', 'rac00n', 8, 150, 2.5, true), - ('backup_v2docker_20250608_030000_encrypted.sql.gz.enc', '/app/backups/backup_v2docker_20250608_030000_encrypted.sql.gz.enc', 1024000, 'scheduled', 'success', 'system', 8, 145, 2.1, true), - ('backup_v2docker_20250607_150000_encrypted.sql.gz.enc', '/app/backups/backup_v2docker_20250607_150000_encrypted.sql.gz.enc', 980000, 'manual', 'success', 'w@rh@mm3r', 8, 140, 1.9, true); \ No newline at end of file diff --git a/v2_adminpanel/test_data_resources.sql b/v2_adminpanel/test_data_resources.sql deleted file mode 100644 index 6253079..0000000 --- a/v2_adminpanel/test_data_resources.sql +++ /dev/null @@ -1,321 +0,0 @@ --- Test-Daten für Resource Pool System --- Generiert für AccountForger v2-Docker --- Stand: 2025-06-09 - --- ==================================== --- Test-Domains (500 Stück) --- ==================================== - --- Verfügbare Domains -INSERT INTO resource_pools (resource_type, resource_value, status, notes) VALUES -('domain', 'example-shop-001.com', 'available', 'Premium Domain'), -('domain', 'best-deals-online.net', 'available', 'E-Commerce Domain'), -('domain', 'super-store-24.com', 'available', 'Shop Domain'), -('domain', 'mega-market-place.org', 'available', 'Marketplace Domain'), -('domain', 'discount-heaven.net', 'available', 'Discount Domain'), -('domain', 'fashion-outlet-now.com', 'available', 'Fashion Domain'), -('domain', 'tech-gadgets-pro.net', 'available', 'Tech Domain'), -('domain', 'home-decor-style.com', 'available', 'Home Domain'), -('domain', 'sports-gear-central.net', 'available', 'Sports Domain'), -('domain', 'beauty-products-24.com', 'available', 'Beauty Domain'); - --- Weitere Domains mit verschiedenen Patterns -DO $$ -BEGIN - FOR i IN 11..400 LOOP - INSERT INTO resource_pools (resource_type, resource_value, status) - VALUES ('domain', - CASE - WHEN i % 5 = 0 THEN 'shop-' || i || '-online.com' - WHEN i % 5 = 1 THEN 'store-' || i || '-pro.net' - WHEN i % 5 = 2 THEN 'market-' || i || '-24.org' - WHEN i % 5 = 3 THEN 'outlet-' || i || '-deals.com' - ELSE 'commerce-' || i || '-now.net' - END, - 'available'); - END LOOP; -END $$; - --- Einige zugeteilte Domains (50 Stück) -DO $$ -BEGIN - FOR i IN 401..450 LOOP - INSERT INTO resource_pools (resource_type, resource_value, status, allocated_to_license, status_changed_at, status_changed_by) - VALUES ('domain', - 'allocated-domain-' || i || '.com', - 'allocated', - (i % 10) + 1, -- Zuweisung zu Lizenzen 1-10 - NOW() - INTERVAL '30 days' * RANDOM(), - 'admin'); - END LOOP; -END $$; - --- Domains in Quarantäne (50 Stück) -DO $$ -BEGIN - FOR i IN 451..500 LOOP - INSERT INTO resource_pools (resource_type, resource_value, status, quarantine_reason, quarantine_until, notes) - VALUES ('domain', - 'quarantine-domain-' || i || '.com', - 'quarantine', - CASE i % 5 - WHEN 0 THEN 'abuse' - WHEN 1 THEN 'defect' - WHEN 2 THEN 'blacklisted' - WHEN 3 THEN 'expired' - ELSE 'review' - END, - NOW() + INTERVAL '7 days' + INTERVAL '1 day' * (i % 14), - 'Automatisch in Quarantäne versetzt'); - END LOOP; -END $$; - --- ==================================== --- Test IPv4-Adressen (200 Stück) --- ==================================== - --- Verfügbare IPv4-Adressen -DO $$ -BEGIN - FOR i IN 1..150 LOOP - INSERT INTO resource_pools (resource_type, resource_value, status, notes) - VALUES ('ipv4', - '192.168.' || (i / 256 + 1)::INT || '.' || (i % 256), - 'available', - CASE - WHEN i % 10 = 0 THEN 'Premium IP' - WHEN i % 20 = 0 THEN 'Dedicated Server IP' - ELSE 'Standard IP' - END); - END LOOP; -END $$; - --- Zugeteilte IPv4-Adressen (30 Stück) -DO $$ -BEGIN - FOR i IN 151..180 LOOP - INSERT INTO resource_pools (resource_type, resource_value, status, allocated_to_license, status_changed_at, status_changed_by) - VALUES ('ipv4', - '10.0.' || ((i-150) / 256)::INT || '.' || ((i-150) % 256), - 'allocated', - ((i-150) % 15) + 1, - NOW() - INTERVAL '60 days' * RANDOM(), - 'system'); - END LOOP; -END $$; - --- IPv4 in Quarantäne (20 Stück) -DO $$ -BEGIN - FOR i IN 181..200 LOOP - INSERT INTO resource_pools (resource_type, resource_value, status, quarantine_reason, quarantine_until, notes) - VALUES ('ipv4', - '172.16.' || ((i-180) / 256)::INT || '.' || ((i-180) % 256), - 'quarantine', - CASE (i-180) % 4 - WHEN 0 THEN 'blacklisted' - WHEN 1 THEN 'abuse' - WHEN 2 THEN 'maintenance' - ELSE 'defect' - END, - NOW() + INTERVAL '3 days' + INTERVAL '1 day' * ((i-180) % 7), - 'IP wurde gemeldet oder ist in Wartung'); - END LOOP; -END $$; - --- ==================================== --- Test Telefonnummern (100 Stück) --- ==================================== - --- Verfügbare Telefonnummern -DO $$ -BEGIN - FOR i IN 1..70 LOOP - INSERT INTO resource_pools (resource_type, resource_value, status, notes) - VALUES ('phone', - '+49' || (1500000000 + i), - 'available', - CASE - WHEN i % 5 = 0 THEN 'Premium Nummer' - WHEN i % 10 = 0 THEN 'Vanity Nummer' - ELSE 'Standard Nummer' - END); - END LOOP; -END $$; - --- Zugeteilte Telefonnummern (20 Stück) -DO $$ -BEGIN - FOR i IN 71..90 LOOP - INSERT INTO resource_pools (resource_type, resource_value, status, allocated_to_license, status_changed_at, status_changed_by) - VALUES ('phone', - '+49' || (1600000000 + i), - 'allocated', - ((i-70) % 10) + 1, - NOW() - INTERVAL '45 days' * RANDOM(), - 'admin'); - END LOOP; -END $$; - --- Telefonnummern in Quarantäne (10 Stück) -DO $$ -BEGIN - FOR i IN 91..100 LOOP - INSERT INTO resource_pools (resource_type, resource_value, status, quarantine_reason, quarantine_until, notes) - VALUES ('phone', - '+49' || (1700000000 + i), - 'quarantine', - CASE (i-90) % 3 - WHEN 0 THEN 'expired' - WHEN 1 THEN 'defect' - ELSE 'review' - END, - NOW() + INTERVAL '5 days' + INTERVAL '1 day' * ((i-90) % 5), - 'Nummer wurde zurückgegeben oder ist defekt'); - END LOOP; -END $$; - --- ==================================== --- Resource History für einige Ressourcen --- ==================================== - --- Historie für einige Domains -INSERT INTO resource_history (resource_id, license_id, action, action_by, details, ip_address) -SELECT - id, - allocated_to_license, - 'allocated', - 'system', - '{"reason": "Neue Lizenz erstellt", "customer": "Test Customer"}'::jsonb, - '192.168.1.100' -FROM resource_pools -WHERE status = 'allocated' -AND resource_type = 'domain' -LIMIT 10; - --- Historie für Quarantäne -INSERT INTO resource_history (resource_id, action, action_by, details, ip_address) -SELECT - id, - 'quarantined', - 'admin', - jsonb_build_object('reason', quarantine_reason, 'duration', '7 days'), - '192.168.1.101' -FROM resource_pools -WHERE status = 'quarantine' -LIMIT 20; - --- ==================================== --- Resource Metrics für Performance-Tracking --- ==================================== - --- Metriken für die letzten 30 Tage -DO $$ -DECLARE - resource_rec RECORD; - days_back INT; -BEGIN - -- Für jede Ressource, die allocated ist - FOR resource_rec IN - SELECT id FROM resource_pools WHERE status = 'allocated' LIMIT 50 - LOOP - -- Generiere Metriken für die letzten 30 Tage - FOR days_back IN 0..29 LOOP - INSERT INTO resource_metrics ( - resource_id, - metric_date, - usage_count, - performance_score, - cost, - revenue, - issues_count, - availability_percent - ) VALUES ( - resource_rec.id, - CURRENT_DATE - INTERVAL '1 day' * days_back, - FLOOR(RANDOM() * 100 + 50), -- 50-150 Nutzungen - ROUND((RANDOM() * 40 + 60)::numeric, 2), -- 60-100 Score - ROUND((RANDOM() * 5 + 2)::numeric, 2), -- 2-7 EUR Kosten - ROUND((RANDOM() * 20 + 10)::numeric, 2), -- 10-30 EUR Umsatz - FLOOR(RANDOM() * 3), -- 0-2 Issues - ROUND((RANDOM() * 5 + 95)::numeric, 2) -- 95-100% Verfügbarkeit - ) ON CONFLICT (resource_id, metric_date) DO NOTHING; - END LOOP; - END LOOP; -END $$; - --- ==================================== --- License Resources Zuordnungen --- ==================================== - --- Verbinde einige bestehende Lizenzen mit Ressourcen -DO $$ -DECLARE - license_rec RECORD; - domain_id INT; - ipv4_id INT; - phone_id INT; -BEGIN - -- Für die ersten 10 aktiven Lizenzen - FOR license_rec IN - SELECT id FROM licenses WHERE is_active = TRUE LIMIT 10 - LOOP - -- Hole eine verfügbare Domain - SELECT id INTO domain_id FROM resource_pools - WHERE resource_type = 'domain' AND status = 'available' - ORDER BY RANDOM() LIMIT 1; - - IF domain_id IS NOT NULL THEN - -- Weise die Domain zu - UPDATE resource_pools - SET status = 'allocated', - allocated_to_license = license_rec.id, - status_changed_at = NOW(), - status_changed_by = 'migration' - WHERE id = domain_id; - - -- Erstelle Zuordnung - INSERT INTO license_resources (license_id, resource_id, assigned_by) - VALUES (license_rec.id, domain_id, 'migration'); - END IF; - - -- Wiederhole für IPv4 - SELECT id INTO ipv4_id FROM resource_pools - WHERE resource_type = 'ipv4' AND status = 'available' - ORDER BY RANDOM() LIMIT 1; - - IF ipv4_id IS NOT NULL THEN - UPDATE resource_pools - SET status = 'allocated', - allocated_to_license = license_rec.id, - status_changed_at = NOW(), - status_changed_by = 'migration' - WHERE id = ipv4_id; - - INSERT INTO license_resources (license_id, resource_id, assigned_by) - VALUES (license_rec.id, ipv4_id, 'migration'); - END IF; - END LOOP; -END $$; - --- Zusammenfassung ausgeben -DO $$ -DECLARE - domain_count INT; - ipv4_count INT; - phone_count INT; -BEGIN - SELECT COUNT(*) INTO domain_count FROM resource_pools WHERE resource_type = 'domain'; - SELECT COUNT(*) INTO ipv4_count FROM resource_pools WHERE resource_type = 'ipv4'; - SELECT COUNT(*) INTO phone_count FROM resource_pools WHERE resource_type = 'phone'; - - RAISE NOTICE 'Test-Daten erfolgreich eingefügt:'; - RAISE NOTICE '- Domains: %', domain_count; - RAISE NOTICE '- IPv4-Adressen: %', ipv4_count; - RAISE NOTICE '- Telefonnummern: %', phone_count; - RAISE NOTICE ''; - RAISE NOTICE 'Status-Verteilung:'; - RAISE NOTICE '- Verfügbar: % Ressourcen', (SELECT COUNT(*) FROM resource_pools WHERE status = 'available'); - RAISE NOTICE '- Zugeteilt: % Ressourcen', (SELECT COUNT(*) FROM resource_pools WHERE status = 'allocated'); - RAISE NOTICE '- Quarantäne: % Ressourcen', (SELECT COUNT(*) FROM resource_pools WHERE status = 'quarantine'); -END $$; \ No newline at end of file