diff --git a/.claude-flow/metrics/system-metrics.json b/.claude-flow/metrics/system-metrics.json deleted file mode 100644 index 40fa797..0000000 --- a/.claude-flow/metrics/system-metrics.json +++ /dev/null @@ -1,1310 +0,0 @@ -[ - { - "timestamp": 1756976770731, - "memoryTotal": 25769803776, - "memoryUsed": 22083682304, - "memoryFree": 3686121472, - "memoryUsagePercent": 85.69596608479819, - "memoryEfficiency": 14.304033915201813, - "cpuCount": 14, - "cpuLoad": 0.13905552455357142, - "platform": "darwin", - "uptime": 244822 - }, - { - "timestamp": 1756978367027, - "memoryTotal": 25769803776, - "memoryUsed": 22116270080, - "memoryFree": 3653533696, - "memoryUsagePercent": 85.82242329915366, - "memoryEfficiency": 14.177576700846345, - "cpuCount": 14, - "cpuLoad": 0.14787946428571427, - "platform": "darwin", - "uptime": 246419 - }, - { - "timestamp": 1756979297344, - "memoryTotal": 25769803776, - "memoryUsed": 22023405568, - "memoryFree": 3746398208, - "memoryUsagePercent": 85.4620615641276, - "memoryEfficiency": 14.537938435872405, - "cpuCount": 14, - "cpuLoad": 0.13162667410714285, - "platform": "darwin", - "uptime": 247349 - }, - { - "timestamp": 1756979797631, - "memoryTotal": 25769803776, - "memoryUsed": 22031400960, - "memoryFree": 3738402816, - "memoryUsagePercent": 85.49308776855469, - "memoryEfficiency": 14.506912231445312, - "cpuCount": 14, - "cpuLoad": 0.11802455357142858, - "platform": "darwin", - "uptime": 247849 - }, - { - "timestamp": 1756980385348, - "memoryTotal": 25769803776, - "memoryUsed": 21984493568, - "memoryFree": 3785310208, - "memoryUsagePercent": 85.31106313069662, - "memoryEfficiency": 14.688936869303376, - "cpuCount": 14, - "cpuLoad": 0.12179129464285714, - "platform": "darwin", - "uptime": 248437 - }, - { - "timestamp": 1756981036792, - "memoryTotal": 25769803776, - "memoryUsed": 21984346112, - "memoryFree": 3785457664, - "memoryUsagePercent": 85.31049092610678, - "memoryEfficiency": 14.68950907389322, - "cpuCount": 14, - "cpuLoad": 0.124755859375, - "platform": "darwin", - "uptime": 249088 - }, - { - "timestamp": 1756981813341, - "memoryTotal": 25769803776, - "memoryUsed": 21988802560, - "memoryFree": 3781001216, - "memoryUsagePercent": 85.3277842203776, - "memoryEfficiency": 14.672215779622405, - "cpuCount": 14, - "cpuLoad": 0.11530412946428571, - "platform": "darwin", - "uptime": 249865 - }, - { - "timestamp": 1756983148070, - "memoryTotal": 25769803776, - "memoryUsed": 22067200000, - "memoryFree": 3702603776, - "memoryUsagePercent": 85.63200632731119, - "memoryEfficiency": 14.367993672688812, - "cpuCount": 14, - "cpuLoad": 0.10501534598214286, - "platform": "darwin", - "uptime": 251200 - }, - { - "timestamp": 1756984078590, - "memoryTotal": 25769803776, - "memoryUsed": 22027255808, - "memoryFree": 3742547968, - "memoryUsagePercent": 85.47700246175131, - "memoryEfficiency": 14.522997538248688, - "cpuCount": 14, - "cpuLoad": 0.11460658482142858, - "platform": "darwin", - "uptime": 252130 - }, - { - "timestamp": 1756985683206, - "memoryTotal": 25769803776, - "memoryUsed": 22015279104, - "memoryFree": 3754524672, - "memoryUsagePercent": 85.43052673339844, - "memoryEfficiency": 14.569473266601562, - "cpuCount": 14, - "cpuLoad": 0.13438197544642858, - "platform": "darwin", - "uptime": 253735 - }, - { - "timestamp": 1756985713214, - "memoryTotal": 25769803776, - "memoryUsed": 22080749568, - "memoryFree": 3689054208, - "memoryUsagePercent": 85.68458557128906, - "memoryEfficiency": 14.315414428710938, - "cpuCount": 14, - "cpuLoad": 0.13148716517857142, - "platform": "darwin", - "uptime": 253765 - }, - { - "timestamp": 1756986643088, - "memoryTotal": 25769803776, - "memoryUsed": 22106800128, - "memoryFree": 3663003648, - "memoryUsagePercent": 85.78567504882812, - "memoryEfficiency": 14.214324951171875, - "cpuCount": 14, - "cpuLoad": 0.14536830357142858, - "platform": "darwin", - "uptime": 254695 - }, - { - "timestamp": 1756987573878, - "memoryTotal": 25769803776, - "memoryUsed": 21998878720, - "memoryFree": 3770925056, - "memoryUsagePercent": 85.36688486735025, - "memoryEfficiency": 14.633115132649749, - "cpuCount": 14, - "cpuLoad": 0.13675362723214285, - "platform": "darwin", - "uptime": 255625 - }, - { - "timestamp": 1756989358041, - "memoryTotal": 25769803776, - "memoryUsed": 22040838144, - "memoryFree": 3728965632, - "memoryUsagePercent": 85.52970886230469, - "memoryEfficiency": 14.470291137695312, - "cpuCount": 14, - "cpuLoad": 0.22188895089285715, - "platform": "darwin", - "uptime": 257410 - }, - { - "timestamp": 1756990287962, - "memoryTotal": 25769803776, - "memoryUsed": 22041051136, - "memoryFree": 3728752640, - "memoryUsagePercent": 85.53053538004556, - "memoryEfficiency": 14.469464619954437, - "cpuCount": 14, - "cpuLoad": 0.19611467633928573, - "platform": "darwin", - "uptime": 258339 - }, - { - "timestamp": 1756991217858, - "memoryTotal": 25769803776, - "memoryUsed": 22146416640, - "memoryFree": 3623387136, - "memoryUsagePercent": 85.93940734863281, - "memoryEfficiency": 14.060592651367188, - "cpuCount": 14, - "cpuLoad": 0.2931431361607143, - "platform": "darwin", - "uptime": 259269 - }, - { - "timestamp": 1756993007497, - "memoryTotal": 25769803776, - "memoryUsed": 22205923328, - "memoryFree": 3563880448, - "memoryUsagePercent": 86.17032368977866, - "memoryEfficiency": 13.829676310221345, - "cpuCount": 14, - "cpuLoad": 0.23416573660714285, - "platform": "darwin", - "uptime": 261059 - }, - { - "timestamp": 1756993937358, - "memoryTotal": 25769803776, - "memoryUsed": 22175989760, - "memoryFree": 3593814016, - "memoryUsagePercent": 86.05416615804037, - "memoryEfficiency": 13.945833841959626, - "cpuCount": 14, - "cpuLoad": 0.2876674107142857, - "platform": "darwin", - "uptime": 261989 - }, - { - "timestamp": 1756994868862, - "memoryTotal": 25769803776, - "memoryUsed": 22129360896, - "memoryFree": 3640442880, - "memoryUsagePercent": 85.87322235107422, - "memoryEfficiency": 14.126777648925781, - "cpuCount": 14, - "cpuLoad": 0.21334402901785715, - "platform": "darwin", - "uptime": 262920 - }, - { - "timestamp": 1756994898867, - "memoryTotal": 25769803776, - "memoryUsed": 22363602944, - "memoryFree": 3406200832, - "memoryUsagePercent": 86.7822011311849, - "memoryEfficiency": 13.217798868815095, - "cpuCount": 14, - "cpuLoad": 0.17414202008928573, - "platform": "darwin", - "uptime": 262950 - }, - { - "timestamp": 1756996674981, - "memoryTotal": 25769803776, - "memoryUsed": 22382346240, - "memoryFree": 3387457536, - "memoryUsagePercent": 86.85493469238281, - "memoryEfficiency": 13.145065307617188, - "cpuCount": 14, - "cpuLoad": 0.2833775111607143, - "platform": "darwin", - "uptime": 264726 - }, - { - "timestamp": 1756997604840, - "memoryTotal": 25769803776, - "memoryUsed": 22346170368, - "memoryFree": 3423633408, - "memoryUsagePercent": 86.71455383300781, - "memoryEfficiency": 13.285446166992188, - "cpuCount": 14, - "cpuLoad": 0.24529157366071427, - "platform": "darwin", - "uptime": 265656 - }, - { - "timestamp": 1756998533975, - "memoryTotal": 25769803776, - "memoryUsed": 22384820224, - "memoryFree": 3384983552, - "memoryUsagePercent": 86.86453501383463, - "memoryEfficiency": 13.135464986165374, - "cpuCount": 14, - "cpuLoad": 0.19928850446428573, - "platform": "darwin", - "uptime": 266585 - }, - { - "timestamp": 1756999432955, - "memoryTotal": 25769803776, - "memoryUsed": 22392537088, - "memoryFree": 3377266688, - "memoryUsagePercent": 86.89448038736978, - "memoryEfficiency": 13.105519612630218, - "cpuCount": 14, - "cpuLoad": 0.172119140625, - "platform": "darwin", - "uptime": 267484 - }, - { - "timestamp": 1757000362679, - "memoryTotal": 25769803776, - "memoryUsed": 22417604608, - "memoryFree": 3352199168, - "memoryUsagePercent": 86.99175516764322, - "memoryEfficiency": 13.00824483235678, - "cpuCount": 14, - "cpuLoad": 0.14739118303571427, - "platform": "darwin", - "uptime": 268414 - }, - { - "timestamp": 1757001292627, - "memoryTotal": 25769803776, - "memoryUsed": 22362128384, - "memoryFree": 3407675392, - "memoryUsagePercent": 86.77647908528647, - "memoryEfficiency": 13.223520914713532, - "cpuCount": 14, - "cpuLoad": 0.19475446428571427, - "platform": "darwin", - "uptime": 269344 - }, - { - "timestamp": 1757002224294, - "memoryTotal": 25769803776, - "memoryUsed": 22397206528, - "memoryFree": 3372597248, - "memoryUsagePercent": 86.9126001993815, - "memoryEfficiency": 13.087399800618499, - "cpuCount": 14, - "cpuLoad": 0.20267159598214285, - "platform": "darwin", - "uptime": 270276 - }, - { - "timestamp": 1757003998867, - "memoryTotal": 25769803776, - "memoryUsed": 22482386944, - "memoryFree": 3287416832, - "memoryUsagePercent": 87.24314371744791, - "memoryEfficiency": 12.756856282552093, - "cpuCount": 14, - "cpuLoad": 0.19932338169642858, - "platform": "darwin", - "uptime": 272050 - }, - { - "timestamp": 1757004928733, - "memoryTotal": 25769803776, - "memoryUsed": 22518530048, - "memoryFree": 3251273728, - "memoryUsagePercent": 87.3833974202474, - "memoryEfficiency": 12.616602579752595, - "cpuCount": 14, - "cpuLoad": 0.17769949776785715, - "platform": "darwin", - "uptime": 272980 - }, - { - "timestamp": 1757006260254, - "memoryTotal": 25769803776, - "memoryUsed": 22553952256, - "memoryFree": 3215851520, - "memoryUsagePercent": 87.52085367838541, - "memoryEfficiency": 12.479146321614593, - "cpuCount": 14, - "cpuLoad": 0.14592633928571427, - "platform": "darwin", - "uptime": 274312 - }, - { - "timestamp": 1757006741173, - "memoryTotal": 25769803776, - "memoryUsed": 22593519616, - "memoryFree": 3176284160, - "memoryUsagePercent": 87.67439524332681, - "memoryEfficiency": 12.325604756673187, - "cpuCount": 14, - "cpuLoad": 0.12845284598214285, - "platform": "darwin", - "uptime": 274793 - }, - { - "timestamp": 1757008570941, - "memoryTotal": 25769803776, - "memoryUsed": 22517923840, - "memoryFree": 3251879936, - "memoryUsagePercent": 87.38104502360025, - "memoryEfficiency": 12.618954976399749, - "cpuCount": 14, - "cpuLoad": 0.17375837053571427, - "platform": "darwin", - "uptime": 276622 - }, - { - "timestamp": 1757008784934, - "memoryTotal": 25769803776, - "memoryUsed": 22463873024, - "memoryFree": 3305930752, - "memoryUsagePercent": 87.17130025227866, - "memoryEfficiency": 12.828699747721345, - "cpuCount": 14, - "cpuLoad": 0.18000139508928573, - "platform": "darwin", - "uptime": 276836 - }, - { - "timestamp": 1757010082885, - "memoryTotal": 25769803776, - "memoryUsed": 22423666688, - "memoryFree": 3346137088, - "memoryUsagePercent": 87.01527913411459, - "memoryEfficiency": 12.984720865885407, - "cpuCount": 14, - "cpuLoad": 0.17156110491071427, - "platform": "darwin", - "uptime": 278134 - }, - { - "timestamp": 1757011317778, - "memoryTotal": 25769803776, - "memoryUsed": 22506799104, - "memoryFree": 3263004672, - "memoryUsagePercent": 87.33787536621094, - "memoryEfficiency": 12.662124633789062, - "cpuCount": 14, - "cpuLoad": 0.19182477678571427, - "platform": "darwin", - "uptime": 279369 - }, - { - "timestamp": 1757012247856, - "memoryTotal": 25769803776, - "memoryUsed": 22472916992, - "memoryFree": 3296886784, - "memoryUsagePercent": 87.2063954671224, - "memoryEfficiency": 12.793604532877595, - "cpuCount": 14, - "cpuLoad": 0.17428152901785715, - "platform": "darwin", - "uptime": 280299 - }, - { - "timestamp": 1757013177725, - "memoryTotal": 25769803776, - "memoryUsed": 22439444480, - "memoryFree": 3330359296, - "memoryUsagePercent": 87.07650502522787, - "memoryEfficiency": 12.923494974772126, - "cpuCount": 14, - "cpuLoad": 0.13152204241071427, - "platform": "darwin", - "uptime": 281229 - }, - { - "timestamp": 1757014979846, - "memoryTotal": 25769803776, - "memoryUsed": 22488563712, - "memoryFree": 3281240064, - "memoryUsagePercent": 87.2671127319336, - "memoryEfficiency": 12.732887268066406, - "cpuCount": 14, - "cpuLoad": 0.16807338169642858, - "platform": "darwin", - "uptime": 283031 - }, - { - "timestamp": 1757015910543, - "memoryTotal": 25769803776, - "memoryUsed": 22500032512, - "memoryFree": 3269771264, - "memoryUsagePercent": 87.31161753336588, - "memoryEfficiency": 12.688382466634124, - "cpuCount": 14, - "cpuLoad": 0.14913504464285715, - "platform": "darwin", - "uptime": 283962 - }, - { - "timestamp": 1757016840412, - "memoryTotal": 25769803776, - "memoryUsed": 22488858624, - "memoryFree": 3280945152, - "memoryUsagePercent": 87.26825714111328, - "memoryEfficiency": 12.731742858886719, - "cpuCount": 14, - "cpuLoad": 0.14114815848214285, - "platform": "darwin", - "uptime": 284892 - }, - { - "timestamp": 1757018644152, - "memoryTotal": 25769803776, - "memoryUsed": 22583656448, - "memoryFree": 3186147328, - "memoryUsagePercent": 87.63612111409506, - "memoryEfficiency": 12.363878885904938, - "cpuCount": 14, - "cpuLoad": 0.14460100446428573, - "platform": "darwin", - "uptime": 286696 - }, - { - "timestamp": 1757019654709, - "memoryTotal": 25769803776, - "memoryUsed": 22517907456, - "memoryFree": 3251896320, - "memoryUsagePercent": 87.3809814453125, - "memoryEfficiency": 12.6190185546875, - "cpuCount": 14, - "cpuLoad": 0.13654436383928573, - "platform": "darwin", - "uptime": 287706 - }, - { - "timestamp": 1757020584574, - "memoryTotal": 25769803776, - "memoryUsed": 22511894528, - "memoryFree": 3257909248, - "memoryUsagePercent": 87.35764821370444, - "memoryEfficiency": 12.642351786295563, - "cpuCount": 14, - "cpuLoad": 0.12245396205357142, - "platform": "darwin", - "uptime": 288636 - }, - { - "timestamp": 1757021581568, - "memoryTotal": 25769803776, - "memoryUsed": 22528606208, - "memoryFree": 3241197568, - "memoryUsagePercent": 87.42249806722006, - "memoryEfficiency": 12.577501932779938, - "cpuCount": 14, - "cpuLoad": 0.10940987723214286, - "platform": "darwin", - "uptime": 289633 - }, - { - "timestamp": 1757022699281, - "memoryTotal": 25769803776, - "memoryUsed": 22516465664, - "memoryFree": 3253338112, - "memoryUsagePercent": 87.37538655598959, - "memoryEfficiency": 12.624613444010407, - "cpuCount": 14, - "cpuLoad": 0.09392438616071429, - "platform": "darwin", - "uptime": 290751 - }, - { - "timestamp": 1757023629190, - "memoryTotal": 25769803776, - "memoryUsed": 22486761472, - "memoryFree": 3283042304, - "memoryUsagePercent": 87.26011912027994, - "memoryEfficiency": 12.739880879720062, - "cpuCount": 14, - "cpuLoad": 0.34134347098214285, - "platform": "darwin", - "uptime": 291681 - }, - { - "timestamp": 1757024559045, - "memoryTotal": 25769803776, - "memoryUsed": 22489694208, - "memoryFree": 3280109568, - "memoryUsagePercent": 87.27149963378906, - "memoryEfficiency": 12.728500366210938, - "cpuCount": 14, - "cpuLoad": 0.24815150669642858, - "platform": "darwin", - "uptime": 292611 - }, - { - "timestamp": 1757025490668, - "memoryTotal": 25769803776, - "memoryUsed": 22523346944, - "memoryFree": 3246456832, - "memoryUsagePercent": 87.40208943684897, - "memoryEfficiency": 12.597910563151032, - "cpuCount": 14, - "cpuLoad": 0.388427734375, - "platform": "darwin", - "uptime": 293542 - }, - { - "timestamp": 1757026427267, - "memoryTotal": 25769803776, - "memoryUsed": 22455500800, - "memoryFree": 3314302976, - "memoryUsagePercent": 87.13881174723306, - "memoryEfficiency": 12.861188252766937, - "cpuCount": 14, - "cpuLoad": 0.31103515625, - "platform": "darwin", - "uptime": 294479 - }, - { - "timestamp": 1757027358042, - "memoryTotal": 25769803776, - "memoryUsed": 22435151872, - "memoryFree": 3334651904, - "memoryUsagePercent": 87.05984751383463, - "memoryEfficiency": 12.940152486165374, - "cpuCount": 14, - "cpuLoad": 0.22031947544642858, - "platform": "darwin", - "uptime": 295410 - }, - { - "timestamp": 1757028288034, - "memoryTotal": 25769803776, - "memoryUsed": 22459318272, - "memoryFree": 3310485504, - "memoryUsagePercent": 87.15362548828125, - "memoryEfficiency": 12.84637451171875, - "cpuCount": 14, - "cpuLoad": 0.17253766741071427, - "platform": "darwin", - "uptime": 296340 - }, - { - "timestamp": 1757029222921, - "memoryTotal": 25769803776, - "memoryUsed": 22519431168, - "memoryFree": 3250372608, - "memoryUsagePercent": 87.38689422607422, - "memoryEfficiency": 12.613105773925781, - "cpuCount": 14, - "cpuLoad": 0.15105329241071427, - "platform": "darwin", - "uptime": 297274 - }, - { - "timestamp": 1757031053562, - "memoryTotal": 25769803776, - "memoryUsed": 22491103232, - "memoryFree": 3278700544, - "memoryUsagePercent": 87.27696736653647, - "memoryEfficiency": 12.723032633463532, - "cpuCount": 14, - "cpuLoad": 0.16228376116071427, - "platform": "darwin", - "uptime": 299105 - }, - { - "timestamp": 1757031984664, - "memoryTotal": 25769803776, - "memoryUsed": 22487859200, - "memoryFree": 3281944576, - "memoryUsagePercent": 87.2643788655599, - "memoryEfficiency": 12.735621134440095, - "cpuCount": 14, - "cpuLoad": 0.9431501116071429, - "platform": "darwin", - "uptime": 300036 - }, - { - "timestamp": 1757032014659, - "memoryTotal": 25769803776, - "memoryUsed": 22499999744, - "memoryFree": 3269804032, - "memoryUsagePercent": 87.31149037679037, - "memoryEfficiency": 12.688509623209626, - "cpuCount": 14, - "cpuLoad": 0.613037109375, - "platform": "darwin", - "uptime": 300066 - }, - { - "timestamp": 1757032944526, - "memoryTotal": 25769803776, - "memoryUsed": 22538846208, - "memoryFree": 3230957568, - "memoryUsagePercent": 87.46223449707031, - "memoryEfficiency": 12.537765502929688, - "cpuCount": 14, - "cpuLoad": 0.4217006138392857, - "platform": "darwin", - "uptime": 300996 - }, - { - "timestamp": 1757033881229, - "memoryTotal": 25769803776, - "memoryUsed": 22501736448, - "memoryFree": 3268067328, - "memoryUsagePercent": 87.31822967529297, - "memoryEfficiency": 12.681770324707031, - "cpuCount": 14, - "cpuLoad": 0.30838448660714285, - "platform": "darwin", - "uptime": 301933 - }, - { - "timestamp": 1757034928890, - "memoryTotal": 25769803776, - "memoryUsed": 22489563136, - "memoryFree": 3280240640, - "memoryUsagePercent": 87.27099100748697, - "memoryEfficiency": 12.72900899251303, - "cpuCount": 14, - "cpuLoad": 0.22017996651785715, - "platform": "darwin", - "uptime": 302980 - }, - { - "timestamp": 1757036115524, - "memoryTotal": 25769803776, - "memoryUsed": 22608723968, - "memoryFree": 3161079808, - "memoryUsagePercent": 87.7333958943685, - "memoryEfficiency": 12.266604105631501, - "cpuCount": 14, - "cpuLoad": 0.28079659598214285, - "platform": "darwin", - "uptime": 304167 - }, - { - "timestamp": 1757037045386, - "memoryTotal": 25769803776, - "memoryUsed": 22560571392, - "memoryFree": 3209232384, - "memoryUsagePercent": 87.54653930664062, - "memoryEfficiency": 12.453460693359375, - "cpuCount": 14, - "cpuLoad": 0.24016462053571427, - "platform": "darwin", - "uptime": 305097 - }, - { - "timestamp": 1757037976652, - "memoryTotal": 25769803776, - "memoryUsed": 22526394368, - "memoryFree": 3243409408, - "memoryUsagePercent": 87.4139149983724, - "memoryEfficiency": 12.586085001627595, - "cpuCount": 14, - "cpuLoad": 0.42515345982142855, - "platform": "darwin", - "uptime": 306028 - }, - { - "timestamp": 1757038906508, - "memoryTotal": 25769803776, - "memoryUsed": 22509404160, - "memoryFree": 3260399616, - "memoryUsagePercent": 87.34798431396484, - "memoryEfficiency": 12.652015686035156, - "cpuCount": 14, - "cpuLoad": 0.31417410714285715, - "platform": "darwin", - "uptime": 306958 - }, - { - "timestamp": 1757040737982, - "memoryTotal": 25769803776, - "memoryUsed": 22573613056, - "memoryFree": 3196190720, - "memoryUsagePercent": 87.59714762369791, - "memoryEfficiency": 12.402852376302093, - "cpuCount": 14, - "cpuLoad": 0.22666713169642858, - "platform": "darwin", - "uptime": 308789 - }, - { - "timestamp": 1757041667845, - "memoryTotal": 25769803776, - "memoryUsed": 22554001408, - "memoryFree": 3215802368, - "memoryUsagePercent": 87.52104441324869, - "memoryEfficiency": 12.478955586751312, - "cpuCount": 14, - "cpuLoad": 0.18558175223214285, - "platform": "darwin", - "uptime": 309719 - }, - { - "timestamp": 1757041697851, - "memoryTotal": 25769803776, - "memoryUsed": 22536634368, - "memoryFree": 3233169408, - "memoryUsagePercent": 87.45365142822266, - "memoryEfficiency": 12.546348571777344, - "cpuCount": 14, - "cpuLoad": 0.223388671875, - "platform": "darwin", - "uptime": 309749 - }, - { - "timestamp": 1757043374157, - "memoryTotal": 25769803776, - "memoryUsed": 22591209472, - "memoryFree": 3178594304, - "memoryUsagePercent": 87.6654307047526, - "memoryEfficiency": 12.334569295247405, - "cpuCount": 14, - "cpuLoad": 0.21575055803571427, - "platform": "darwin", - "uptime": 311426 - }, - { - "timestamp": 1757045203843, - "memoryTotal": 25769803776, - "memoryUsed": 22615801856, - "memoryFree": 3154001920, - "memoryUsagePercent": 87.760861714681, - "memoryEfficiency": 12.239138285319001, - "cpuCount": 14, - "cpuLoad": 0.21861049107142858, - "platform": "darwin", - "uptime": 313255 - }, - { - "timestamp": 1757046849589, - "memoryTotal": 25769803776, - "memoryUsed": 22577872896, - "memoryFree": 3191930880, - "memoryUsagePercent": 87.61367797851562, - "memoryEfficiency": 12.386322021484375, - "cpuCount": 14, - "cpuLoad": 0.17431640625, - "platform": "darwin", - "uptime": 314901 - }, - { - "timestamp": 1757047412359, - "memoryTotal": 25769803776, - "memoryUsed": 22592602112, - "memoryFree": 3177201664, - "memoryUsagePercent": 87.67083485921225, - "memoryEfficiency": 12.329165140787751, - "cpuCount": 14, - "cpuLoad": 0.16566685267857142, - "platform": "darwin", - "uptime": 315464 - }, - { - "timestamp": 1757049172734, - "memoryTotal": 25769803776, - "memoryUsed": 22563028992, - "memoryFree": 3206774784, - "memoryUsagePercent": 87.55607604980469, - "memoryEfficiency": 12.443923950195312, - "cpuCount": 14, - "cpuLoad": 0.16385323660714285, - "platform": "darwin", - "uptime": 317224 - }, - { - "timestamp": 1757050676203, - "memoryTotal": 25769803776, - "memoryUsed": 22601105408, - "memoryFree": 3168698368, - "memoryUsagePercent": 87.7038319905599, - "memoryEfficiency": 12.296168009440095, - "cpuCount": 14, - "cpuLoad": 0.14079938616071427, - "platform": "darwin", - "uptime": 318728 - }, - { - "timestamp": 1757051606061, - "memoryTotal": 25769803776, - "memoryUsed": 22713892864, - "memoryFree": 3055910912, - "memoryUsagePercent": 88.1415049235026, - "memoryEfficiency": 11.858495076497405, - "cpuCount": 14, - "cpuLoad": 0.13776506696428573, - "platform": "darwin", - "uptime": 319658 - }, - { - "timestamp": 1757052537746, - "memoryTotal": 25769803776, - "memoryUsed": 22580903936, - "memoryFree": 3188899840, - "memoryUsagePercent": 87.62543996175131, - "memoryEfficiency": 12.374560038248688, - "cpuCount": 14, - "cpuLoad": 0.11872209821428571, - "platform": "darwin", - "uptime": 320589 - }, - { - "timestamp": 1757054339280, - "memoryTotal": 25769803776, - "memoryUsed": 22595158016, - "memoryFree": 3174645760, - "memoryUsagePercent": 87.68075307210287, - "memoryEfficiency": 12.319246927897126, - "cpuCount": 14, - "cpuLoad": 0.39041573660714285, - "platform": "darwin", - "uptime": 322391 - }, - { - "timestamp": 1757055431658, - "memoryTotal": 25769803776, - "memoryUsed": 22655533056, - "memoryFree": 3114270720, - "memoryUsagePercent": 87.9150390625, - "memoryEfficiency": 12.0849609375, - "cpuCount": 14, - "cpuLoad": 0.32847377232142855, - "platform": "darwin", - "uptime": 323483 - }, - { - "timestamp": 1757055467828, - "memoryTotal": 25769803776, - "memoryUsed": 22662905856, - "memoryFree": 3106897920, - "memoryUsagePercent": 87.94364929199219, - "memoryEfficiency": 12.056350708007812, - "cpuCount": 14, - "cpuLoad": 0.22586495535714285, - "platform": "darwin", - "uptime": 323519 - }, - { - "timestamp": 1757056782262, - "memoryTotal": 25769803776, - "memoryUsed": 22744760320, - "memoryFree": 3025043456, - "memoryUsagePercent": 88.26128641764322, - "memoryEfficiency": 11.73871358235678, - "cpuCount": 14, - "cpuLoad": 0.25851004464285715, - "platform": "darwin", - "uptime": 324834 - }, - { - "timestamp": 1757058004188, - "memoryTotal": 25769803776, - "memoryUsed": 22767648768, - "memoryFree": 3002155008, - "memoryUsagePercent": 88.35010528564453, - "memoryEfficiency": 11.649894714355469, - "cpuCount": 14, - "cpuLoad": 0.40625, - "platform": "darwin", - "uptime": 326056 - }, - { - "timestamp": 1757058940262, - "memoryTotal": 25769803776, - "memoryUsed": 23432790016, - "memoryFree": 2337013760, - "memoryUsagePercent": 90.93119303385416, - "memoryEfficiency": 9.068806966145843, - "cpuCount": 14, - "cpuLoad": 0.5577218191964286, - "platform": "darwin", - "uptime": 326992 - }, - { - "timestamp": 1757059870842, - "memoryTotal": 25769803776, - "memoryUsed": 22779478016, - "memoryFree": 2990325760, - "memoryUsagePercent": 88.39600880940756, - "memoryEfficiency": 11.603991190592438, - "cpuCount": 14, - "cpuLoad": 0.36788504464285715, - "platform": "darwin", - "uptime": 327922 - }, - { - "timestamp": 1757060665141, - "memoryTotal": 25769803776, - "memoryUsed": 22768582656, - "memoryFree": 3001221120, - "memoryUsagePercent": 88.35372924804688, - "memoryEfficiency": 11.646270751953125, - "cpuCount": 14, - "cpuLoad": 0.26845005580357145, - "platform": "darwin", - "uptime": 328717 - }, - { - "timestamp": 1757060771941, - "memoryTotal": 25769803776, - "memoryUsed": 25222758400, - "memoryFree": 547045376, - "memoryUsagePercent": 97.87718454996744, - "memoryEfficiency": 2.1228154500325616, - "cpuCount": 14, - "cpuLoad": 0.31919642857142855, - "platform": "darwin", - "uptime": 328823 - }, - { - "timestamp": 1757060801942, - "memoryTotal": 25769803776, - "memoryUsed": 25176899584, - "memoryFree": 592904192, - "memoryUsagePercent": 97.69922892252603, - "memoryEfficiency": 2.300771077473968, - "cpuCount": 14, - "cpuLoad": 0.24801199776785715, - "platform": "darwin", - "uptime": 328853 - }, - { - "timestamp": 1757060831943, - "memoryTotal": 25769803776, - "memoryUsed": 25676742656, - "memoryFree": 93061120, - "memoryUsagePercent": 99.63887532552084, - "memoryEfficiency": 0.3611246744791572, - "cpuCount": 14, - "cpuLoad": 0.21369280133928573, - "platform": "darwin", - "uptime": 328883 - }, - { - "timestamp": 1757060861943, - "memoryTotal": 25769803776, - "memoryUsed": 24997085184, - "memoryFree": 772718592, - "memoryUsagePercent": 97.00145721435547, - "memoryEfficiency": 2.9985427856445312, - "cpuCount": 14, - "cpuLoad": 0.22384207589285715, - "platform": "darwin", - "uptime": 328913 - }, - { - "timestamp": 1757060891944, - "memoryTotal": 25769803776, - "memoryUsed": 25113264128, - "memoryFree": 656539648, - "memoryUsagePercent": 97.45229085286459, - "memoryEfficiency": 2.547709147135407, - "cpuCount": 14, - "cpuLoad": 0.43104771205357145, - "platform": "darwin", - "uptime": 328943 - }, - { - "timestamp": 1757060921945, - "memoryTotal": 25769803776, - "memoryUsed": 25421070336, - "memoryFree": 348733440, - "memoryUsagePercent": 98.64673614501953, - "memoryEfficiency": 1.3532638549804688, - "cpuCount": 14, - "cpuLoad": 0.32052176339285715, - "platform": "darwin", - "uptime": 328973 - }, - { - "timestamp": 1757060951945, - "memoryTotal": 25769803776, - "memoryUsed": 25011208192, - "memoryFree": 758595584, - "memoryUsagePercent": 97.05626169840494, - "memoryEfficiency": 2.9437383015950616, - "cpuCount": 14, - "cpuLoad": 0.24100167410714285, - "platform": "darwin", - "uptime": 329003 - }, - { - "timestamp": 1757061720052, - "memoryTotal": 25769803776, - "memoryUsed": 23711154176, - "memoryFree": 2058649600, - "memoryUsagePercent": 92.01138814290366, - "memoryEfficiency": 7.988611857096345, - "cpuCount": 14, - "cpuLoad": 0.21930803571428573, - "platform": "darwin", - "uptime": 329772 - }, - { - "timestamp": 1757061750044, - "memoryTotal": 25769803776, - "memoryUsed": 24752013312, - "memoryFree": 1017790464, - "memoryUsagePercent": 96.05045318603516, - "memoryEfficiency": 3.9495468139648438, - "cpuCount": 14, - "cpuLoad": 0.2721470424107143, - "platform": "darwin", - "uptime": 329802 - }, - { - "timestamp": 1757061780043, - "memoryTotal": 25769803776, - "memoryUsed": 23812554752, - "memoryFree": 1957249024, - "memoryUsagePercent": 92.40487416585287, - "memoryEfficiency": 7.595125834147126, - "cpuCount": 14, - "cpuLoad": 0.19789341517857142, - "platform": "darwin", - "uptime": 329832 - }, - { - "timestamp": 1757061810043, - "memoryTotal": 25769803776, - "memoryUsed": 23802118144, - "memoryFree": 1967685632, - "memoryUsagePercent": 92.36437479654947, - "memoryEfficiency": 7.63562520345053, - "cpuCount": 14, - "cpuLoad": 0.15530831473214285, - "platform": "darwin", - "uptime": 329862 - }, - { - "timestamp": 1757061840043, - "memoryTotal": 25769803776, - "memoryUsed": 23803248640, - "memoryFree": 1966555136, - "memoryUsagePercent": 92.36876169840494, - "memoryEfficiency": 7.631238301595062, - "cpuCount": 14, - "cpuLoad": 0.11931501116071429, - "platform": "darwin", - "uptime": 329892 - }, - { - "timestamp": 1757061870043, - "memoryTotal": 25769803776, - "memoryUsed": 24106696704, - "memoryFree": 1663107072, - "memoryUsagePercent": 93.54629516601562, - "memoryEfficiency": 6.453704833984375, - "cpuCount": 14, - "cpuLoad": 0.11031668526785714, - "platform": "darwin", - "uptime": 329922 - }, - { - "timestamp": 1757061900043, - "memoryTotal": 25769803776, - "memoryUsed": 24049745920, - "memoryFree": 1720057856, - "memoryUsagePercent": 93.32529703776041, - "memoryEfficiency": 6.674702962239593, - "cpuCount": 14, - "cpuLoad": 0.08918108258928571, - "platform": "darwin", - "uptime": 329952 - }, - { - "timestamp": 1757061930043, - "memoryTotal": 25769803776, - "memoryUsed": 24014929920, - "memoryFree": 1754873856, - "memoryUsagePercent": 93.19019317626953, - "memoryEfficiency": 6.809806823730469, - "cpuCount": 14, - "cpuLoad": 0.07254464285714286, - "platform": "darwin", - "uptime": 329982 - }, - { - "timestamp": 1757061960043, - "memoryTotal": 25769803776, - "memoryUsed": 25666912256, - "memoryFree": 102891520, - "memoryUsagePercent": 99.60072835286459, - "memoryEfficiency": 0.3992716471354072, - "cpuCount": 14, - "cpuLoad": 0.118896484375, - "platform": "darwin", - "uptime": 330012 - }, - { - "timestamp": 1757061990047, - "memoryTotal": 25769803776, - "memoryUsed": 21877653504, - "memoryFree": 3892150272, - "memoryUsagePercent": 84.89646911621094, - "memoryEfficiency": 15.103530883789062, - "cpuCount": 14, - "cpuLoad": 0.16737583705357142, - "platform": "darwin", - "uptime": 330042 - }, - { - "timestamp": 1757062020047, - "memoryTotal": 25769803776, - "memoryUsed": 22036316160, - "memoryFree": 3733487616, - "memoryUsagePercent": 85.51216125488281, - "memoryEfficiency": 14.487838745117188, - "cpuCount": 14, - "cpuLoad": 0.138916015625, - "platform": "darwin", - "uptime": 330072 - }, - { - "timestamp": 1757062050048, - "memoryTotal": 25769803776, - "memoryUsed": 21972238336, - "memoryFree": 3797565440, - "memoryUsagePercent": 85.26350657145181, - "memoryEfficiency": 14.736493428548187, - "cpuCount": 14, - "cpuLoad": 0.12813895089285715, - "platform": "darwin", - "uptime": 330102 - }, - { - "timestamp": 1757062080049, - "memoryTotal": 25769803776, - "memoryUsed": 21954543616, - "memoryFree": 3815260160, - "memoryUsagePercent": 85.19484202067056, - "memoryEfficiency": 14.805157979329437, - "cpuCount": 14, - "cpuLoad": 0.13605608258928573, - "platform": "darwin", - "uptime": 330132 - }, - { - "timestamp": 1757062110050, - "memoryTotal": 25769803776, - "memoryUsed": 21945073664, - "memoryFree": 3824730112, - "memoryUsagePercent": 85.15809377034506, - "memoryEfficiency": 14.841906229654938, - "cpuCount": 14, - "cpuLoad": 0.12098911830357142, - "platform": "darwin", - "uptime": 330162 - }, - { - "timestamp": 1757062140050, - "memoryTotal": 25769803776, - "memoryUsed": 21946417152, - "memoryFree": 3823386624, - "memoryUsagePercent": 85.1633071899414, - "memoryEfficiency": 14.836692810058594, - "cpuCount": 14, - "cpuLoad": 0.10546875, - "platform": "darwin", - "uptime": 330192 - }, - { - "timestamp": 1757062170051, - "memoryTotal": 25769803776, - "memoryUsed": 21990064128, - "memoryFree": 3779739648, - "memoryUsagePercent": 85.33267974853516, - "memoryEfficiency": 14.667320251464844, - "cpuCount": 14, - "cpuLoad": 0.10902622767857142, - "platform": "darwin", - "uptime": 330222 - }, - { - "timestamp": 1757062200052, - "memoryTotal": 25769803776, - "memoryUsed": 21993455616, - "memoryFree": 3776348160, - "memoryUsagePercent": 85.34584045410156, - "memoryEfficiency": 14.654159545898438, - "cpuCount": 14, - "cpuLoad": 0.10431780133928571, - "platform": "darwin", - "uptime": 330252 - }, - { - "timestamp": 1757062230053, - "memoryTotal": 25769803776, - "memoryUsed": 21974728704, - "memoryFree": 3795075072, - "memoryUsagePercent": 85.2731704711914, - "memoryEfficiency": 14.726829528808594, - "cpuCount": 14, - "cpuLoad": 0.17152622767857142, - "platform": "darwin", - "uptime": 330282 - }, - { - "timestamp": 1757062260054, - "memoryTotal": 25769803776, - "memoryUsed": 21933719552, - "memoryFree": 3836084224, - "memoryUsagePercent": 85.11403401692709, - "memoryEfficiency": 14.885965983072907, - "cpuCount": 14, - "cpuLoad": 0.13605608258928573, - "platform": "darwin", - "uptime": 330312 - }, - { - "timestamp": 1757062290055, - "memoryTotal": 25769803776, - "memoryUsed": 21903392768, - "memoryFree": 3866411008, - "memoryUsagePercent": 84.99635060628256, - "memoryEfficiency": 15.003649393717438, - "cpuCount": 14, - "cpuLoad": 0.09573800223214286, - "platform": "darwin", - "uptime": 330342 - }, - { - "timestamp": 1757062320055, - "memoryTotal": 25769803776, - "memoryUsed": 21123710976, - "memoryFree": 4646092800, - "memoryUsagePercent": 81.97078704833984, - "memoryEfficiency": 18.029212951660156, - "cpuCount": 14, - "cpuLoad": 0.08761160714285714, - "platform": "darwin", - "uptime": 330372 - } -] \ No newline at end of file diff --git a/.drone.yml b/.drone.yml deleted file mode 100644 index c01c09f..0000000 --- a/.drone.yml +++ /dev/null @@ -1,114 +0,0 @@ -kind: pipeline -type: docker -name: default - -steps: - # Build Backend Docker Image - - name: build-backend - image: plugins/docker - settings: - repo: registry.local.nothaft.cloud/picpeak-backend - tags: - - latest - - ${DRONE_COMMIT_SHA:0:8} - - ${DRONE_BRANCH}-latest - dockerfile: backend/Dockerfile - context: backend/ - registry: registry.local.nothaft.cloud - build_args: - - VERSION=${DRONE_TAG:-dev} - - # Build Frontend Docker Image - - name: build-frontend - image: plugins/docker - settings: - repo: registry.local.nothaft.cloud/picpeak-frontend - tags: - - latest - - ${DRONE_COMMIT_SHA:0:8} - - ${DRONE_BRANCH}-latest - dockerfile: frontend/Dockerfile - context: frontend/ - registry: registry.local.nothaft.cloud - build_args: - - VERSION=${DRONE_TAG:-dev} - - VITE_API_URL=${VITE_API_URL:-/api} - -trigger: - branch: - - main - - develop - event: - - push - - pull_request - ---- -kind: pipeline -type: docker -name: release - -steps: - # Build Backend Release - - name: build-backend-release - image: plugins/docker - settings: - repo: registry.local.nothaft.cloud/picpeak-backend - tags: - - ${DRONE_TAG} - - latest - dockerfile: backend/Dockerfile - context: backend/ - registry: registry.local.nothaft.cloud - - # Build Frontend Release - - name: build-frontend-release - image: plugins/docker - settings: - repo: registry.local.nothaft.cloud/picpeak-frontend - tags: - - ${DRONE_TAG} - - latest - dockerfile: frontend/Dockerfile - context: frontend/ - registry: registry.local.nothaft.cloud - - # -------- NEW: Publish Docker images to GitHub Container Registry -------- - - name: push-backend-ghcr - image: plugins/docker - settings: - repo: ghcr.io/the-luap/picpeak-backend - tags: - - ${DRONE_TAG} - - latest - dockerfile: backend/Dockerfile - context: backend/ - registry: ghcr.io - username: - from_secret: GITHUB_USERNAME - password: - from_secret: GITHUB_TOKEN - build_args: - - VERSION=${DRONE_TAG} - - - name: push-frontend-ghcr - image: plugins/docker - settings: - repo: ghcr.io/the-luap/picpeak-frontend - tags: - - ${DRONE_TAG} - - latest - dockerfile: frontend/Dockerfile - context: frontend/ - registry: ghcr.io - username: - from_secret: GITHUB_USERNAME - password: - from_secret: GITHUB_TOKEN - build_args: - - VERSION=${DRONE_TAG} - - VITE_API_URL=${VITE_API_URL:-/api} - - -trigger: - event: - - tag \ No newline at end of file diff --git a/.gitea/workflows/mirror-to-github.yml b/.gitea/workflows/mirror-to-github.yml deleted file mode 100644 index 129dcce..0000000 --- a/.gitea/workflows/mirror-to-github.yml +++ /dev/null @@ -1,132 +0,0 @@ -name: Mirror to GitHub - -on: - workflow_dispatch: # Allow manual triggering only - -jobs: - mirror: - runs-on: ubuntu-latest - # Note: For GitHub fine-grained tokens, ensure the token has: - # - Repository access to the-luap/picpeak - # - Repository permissions: Contents (Read and Write), Metadata (Read) - # For classic tokens: repo scope is sufficient - steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 # Full history for proper mirroring - - - name: Setup Git - run: | - git config --global user.name "the-luap" - git config --global user.email "paul-nothaft@hotmail.de" - - - name: Remove sensitive files and directories - run: | - echo "Current files before cleanup:" - ls -la | head -10 || true - echo "..." - - # Remove sensitive files/directories if they exist - echo "Removing sensitive files..." - rm -rf .gitea/ || true - rm -rf scripts/install-gitea-runner.sh || true - rm -rf .drone* || true - rm -rf photo-sharing-prd.md || true - rm -rf CLAUDE.md || true - rm -rf storage/ || true - rm -rf events/ || true - rm -rf .playwright-mcp/ - rm -rf .swarm || true - rm -rf .claude-flow || true - - - echo "Sensitive files removal completed" - - # Add and commit the cleanup if there are changes - git add -A - if ! git diff --cached --quiet; then - git commit -m "chore: remove sensitive files for GitHub mirror" - echo "✅ Committed cleanup of sensitive files" - else - echo "✅ No sensitive files to remove" - fi - - echo "Final file structure (top level):" - ls -la | head -10 || true - - - name: Check GitHub token - env: - GITHUBTOKEN: ${{ secrets.GITHUBTOKEN }} - run: | - if [ -z "$GITHUBTOKEN" ]; then - echo "ERROR: GITHUBTOKEN secret is not set!" - echo "Please add a GitHub Personal Access Token as a secret named GITHUBTOKEN" - echo "" - echo "For fine-grained tokens:" - echo " - Go to GitHub Settings > Developer settings > Personal access tokens > Fine-grained tokens" - echo " - Create token with repository access to the-luap/picpeak" - echo " - Grant permissions: Contents (Read and Write), Metadata (Read)" - echo "" - echo "For classic tokens:" - echo " - Go to GitHub Settings > Developer settings > Personal access tokens > Tokens (classic)" - echo " - Create token with 'repo' scope" - exit 1 - else - echo "✅ GitHub token is available (length: ${#GITHUBTOKEN})" - # Try to detect token type (fine-grained tokens are typically longer) - if [ ${#GITHUBTOKEN} -gt 80 ]; then - echo "📌 Token appears to be a fine-grained personal access token" - else - echo "📌 Token appears to be a classic personal access token" - fi - fi - - - name: Push to GitHub - env: - GITHUBTOKEN: ${{ secrets.GITHUBTOKEN }} - GIT_TRACE: 1 # Enable Git trace for debugging if needed - run: | - # Remove existing github remote if it exists - git remote remove github || true - - # Configure Git to use the token for authentication - # This method works for both classic and fine-grained tokens - git config --global url."https://the-luap:${GITHUBTOKEN}@github.com/".insteadOf "https://github.com/" - - # Add GitHub remote (clean URL without credentials) - git remote add github https://github.com/the-luap/picpeak.git - - # Verify remote was added - echo "GitHub remote configuration:" - git remote -v - - # Push to GitHub main branch with error handling - echo "Pushing to GitHub..." - if git push github main --force 2>&1; then - echo "✅ Push to GitHub completed successfully!" - else - echo "❌ Push to GitHub failed!" - echo "" - echo "Common issues and solutions:" - echo "1. Token permissions: Ensure your token has 'Contents: write' permission" - echo "2. Token expiration: Check if your token has expired" - echo "3. Repository access: Verify the token has access to the-luap/picpeak repository" - echo "" - echo "For fine-grained tokens, required permissions:" - echo " - Repository access: the-luap/picpeak" - echo " - Repository permissions: Contents (Read and Write), Metadata (Read)" - echo "" - echo "For classic tokens, required scope: 'repo'" - exit 1 - fi - - # Clean up the git config after push - git config --global --unset url."https://the-luap:${GITHUBTOKEN}@github.com/".insteadOf - - - name: Workflow completed - run: | - echo "✅ Mirror to GitHub workflow completed successfully!" - echo "📊 Repository mirrored to: https://github.com/the-luap/picpeak" - echo "🔒 Sensitive files have been removed from the mirror" - diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml deleted file mode 100644 index c207bdc..0000000 --- a/.gitea/workflows/test.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Test and Lint - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main ] - -jobs: - backend-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: '18' - - - name: Install backend dependencies - working-directory: ./backend - run: npm ci - - - name: Run backend linting - working-directory: ./backend - run: npm run lint || true # Continue on lint errors for now - - - name: Run backend tests - working-directory: ./backend - run: npm test || true # Continue on test failures for now - - frontend-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: '18' - - - name: Install frontend dependencies - working-directory: ./frontend - run: npm ci --legacy-peer-deps - - - name: Run frontend linting - working-directory: ./frontend - run: npm run lint || true # Continue on lint errors for now - - - name: Build frontend - working-directory: ./frontend - run: npm run build \ No newline at end of file diff --git a/.gitea/workflows/version-and-release.yml b/.gitea/workflows/version-and-release.yml deleted file mode 100644 index 54448e8..0000000 --- a/.gitea/workflows/version-and-release.yml +++ /dev/null @@ -1,269 +0,0 @@ -name: Version and Release - -on: - workflow_dispatch: - -jobs: - version-bump: - runs-on: ubuntu-latest - outputs: - new_version: ${{ steps.version.outputs.new_version }} - version_changed: ${{ steps.version.outputs.version_changed }} - component_changed: ${{ steps.version.outputs.component_changed }} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - token: ${{ secrets.GITEA_TOKEN || github.token }} - - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: '18' - - - name: Configure Git - run: | - git config --global user.name 'Gitea Actions Bot' - git config --global user.email 'actions@gitea.local' - - - name: Detect changes and bump version - id: version - run: | - set -e # Exit on error - - echo "=== Debug Info ===" - echo "GitHub event before: ${{ github.event.before }}" - echo "GitHub SHA: ${{ github.sha }}" - echo "Current directory: $(pwd)" - echo "Git log (last 5): $(git log --oneline -5)" - - # Get the commit range for changed files - if [ "${{ github.event.before }}" != "0000000000000000000000000000000000000000" ] && [ "${{ github.event.before }}" != "" ]; then - COMMIT_RANGE="${{ github.event.before }}..${{ github.sha }}" - echo "Using commit range: $COMMIT_RANGE" - CHANGED_FILES=$(git diff --name-only $COMMIT_RANGE || echo "") - else - # First commit or no previous commit, check against HEAD~1 if it exists - if git rev-parse HEAD~1 >/dev/null 2>&1; then - COMMIT_RANGE="HEAD~1..HEAD" - echo "Using commit range: $COMMIT_RANGE" - CHANGED_FILES=$(git diff --name-only $COMMIT_RANGE || echo "") - else - echo "First commit detected, checking all files" - CHANGED_FILES=$(git ls-files) - fi - fi - - echo "Changed files:" - echo "$CHANGED_FILES" - - # Check what changed (using echo to pipe to grep to avoid grep exit codes) - BACKEND_CHANGED=$(echo "$CHANGED_FILES" | grep -c '^backend/' || echo "0") - FRONTEND_CHANGED=$(echo "$CHANGED_FILES" | grep -c '^frontend/' || echo "0") - ROOT_CHANGED=$(echo "$CHANGED_FILES" | grep -c -E '^(package\.json|docker-compose|Dockerfile|scripts/)' || echo "0") - - echo "Backend files changed: $BACKEND_CHANGED" - echo "Frontend files changed: $FRONTEND_CHANGED" - echo "Root files changed: $ROOT_CHANGED" - - # Get current versions - BACKEND_VERSION=$(node -p "require('./backend/package.json').version" 2>/dev/null || echo "1.1.0") - FRONTEND_VERSION=$(node -p "require('./frontend/package.json').version" 2>/dev/null || echo "1.1.0") - - echo "Current backend version: $BACKEND_VERSION" - echo "Current frontend version: $FRONTEND_VERSION" - - # Determine what to update based on changes - BACKEND_UPDATE=false - FRONTEND_UPDATE=false - COMPONENT_CHANGED="none" - - if [ "$ROOT_CHANGED" -gt 0 ]; then - # Root changes affect both components - BACKEND_UPDATE=true - FRONTEND_UPDATE=true - COMPONENT_CHANGED="both" - SOURCE_VERSION=$BACKEND_VERSION - echo "Root changes detected - updating both components" - elif [ "$BACKEND_CHANGED" -gt 0 ] && [ "$FRONTEND_CHANGED" -gt 0 ]; then - # Both components changed - BACKEND_UPDATE=true - FRONTEND_UPDATE=true - COMPONENT_CHANGED="both" - # Use the higher version as source - if [ "$(printf '%s\n' "$BACKEND_VERSION" "$FRONTEND_VERSION" | sort -V | tail -n1)" = "$BACKEND_VERSION" ]; then - SOURCE_VERSION=$BACKEND_VERSION - else - SOURCE_VERSION=$FRONTEND_VERSION - fi - echo "Both backend and frontend changed - updating both" - elif [ "$BACKEND_CHANGED" -gt 0 ]; then - # Only backend changed - BACKEND_UPDATE=true - COMPONENT_CHANGED="backend" - SOURCE_VERSION=$BACKEND_VERSION - echo "Only backend changed - updating backend" - elif [ "$FRONTEND_CHANGED" -gt 0 ]; then - # Only frontend changed - FRONTEND_UPDATE=true - COMPONENT_CHANGED="frontend" - SOURCE_VERSION=$FRONTEND_VERSION - echo "Only frontend changed - updating frontend" - else - echo "No relevant changes detected" - echo "version_changed=false" >> $GITHUB_OUTPUT - echo "component_changed=none" >> $GITHUB_OUTPUT - echo "new_version=" >> $GITHUB_OUTPUT - exit 0 - fi - - echo "Component changed: $COMPONENT_CHANGED" - echo "Source version: $SOURCE_VERSION" - echo "Backend update: $BACKEND_UPDATE" - echo "Frontend update: $FRONTEND_UPDATE" - - # Calculate new version - IFS='.' read -r -a version_parts <<< "$SOURCE_VERSION" - MAJOR="${version_parts[0]}" - MINOR="${version_parts[1]}" - PATCH="${version_parts[2]}" - - # Increment patch version and ensure tag uniqueness - git fetch --tags --quiet || true - NEW_PATCH=$((PATCH + 1)) - NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH" - - while git rev-parse "v${NEW_VERSION}" >/dev/null 2>&1; do - echo "Tag v${NEW_VERSION} already exists, bumping patch version again" - NEW_PATCH=$((NEW_PATCH + 1)) - NEW_VERSION="$MAJOR.$MINOR.$NEW_PATCH" - done - - echo "New version: $NEW_VERSION" - echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "component_changed=$COMPONENT_CHANGED" >> $GITHUB_OUTPUT - - # Update versions in package.json files - if [ "$BACKEND_UPDATE" = true ]; then - echo "Updating backend version to $NEW_VERSION" - cd backend && npm version $NEW_VERSION --no-git-tag-version - cd .. - fi - - if [ "$FRONTEND_UPDATE" = true ]; then - echo "Updating frontend version to $NEW_VERSION" - cd frontend && npm version $NEW_VERSION --no-git-tag-version - cd .. - fi - - # Check if there are changes to commit - if [[ -n $(git status --porcelain) ]]; then - echo "version_changed=true" >> $GITHUB_OUTPUT - else - echo "version_changed=false" >> $GITHUB_OUTPUT - fi - - - name: Commit version bump - if: steps.version.outputs.version_changed == 'true' - run: | - set -e # Exit on any error - - # First, ensure we have the latest changes - echo "Fetching latest changes..." - git fetch origin main - - # Check if we're behind and need to update - LOCAL=$(git rev-parse HEAD) - REMOTE=$(git rev-parse origin/main) - - if [ "$LOCAL" != "$REMOTE" ]; then - echo "Local is behind remote, pulling changes..." - git pull origin main --no-rebase - fi - - COMPONENT="${{ steps.version.outputs.component_changed }}" - - if [ "$COMPONENT" = "both" ]; then - git add backend/package.json backend/package-lock.json frontend/package.json frontend/package-lock.json - git commit -m "chore: bump version to ${{ steps.version.outputs.new_version }} (backend + frontend)" - elif [ "$COMPONENT" = "backend" ]; then - git add backend/package.json backend/package-lock.json - git commit -m "chore: bump backend version to ${{ steps.version.outputs.new_version }}" - elif [ "$COMPONENT" = "frontend" ]; then - git add frontend/package.json frontend/package-lock.json - git commit -m "chore: bump frontend version to ${{ steps.version.outputs.new_version }}" - fi - - # Pull latest changes before pushing to avoid conflicts - echo "Pulling latest changes from origin/main..." - if ! git pull --rebase origin main; then - echo "Rebase failed, attempting to resolve..." - # If rebase fails, abort and try a regular merge - git rebase --abort || true - git pull origin main --no-rebase - fi - - # Push the changes with retry logic - echo "Pushing version bump..." - PUSH_SUCCESS=false - - for i in 1 2 3; do - echo "Push attempt $i of 3..." - - # Try to push - if git push origin main 2>&1; then - echo "Successfully pushed version bump on attempt $i" - PUSH_SUCCESS=true - break - else - echo "Push failed on attempt $i" - - if [ $i -lt 3 ]; then - echo "Waiting 5 seconds before retry..." - sleep 5 - - echo "Pulling latest changes..." - git fetch origin main - - # Try rebase first, fall back to merge - if ! git rebase origin/main; then - echo "Rebase failed, trying merge..." - git rebase --abort 2>/dev/null || true - git pull origin main --no-rebase - fi - fi - fi - done - - if [ "$PUSH_SUCCESS" = "false" ]; then - echo "ERROR: Failed to push after 3 attempts" - exit 1 - fi - - - name: Create Git tag - if: steps.version.outputs.version_changed == 'true' - run: | - COMPONENT="${{ steps.version.outputs.component_changed }}" - - if [ "$COMPONENT" = "both" ]; then - TAG_MESSAGE="Release v${{ steps.version.outputs.new_version }} (backend + frontend)" - elif [ "$COMPONENT" = "backend" ]; then - TAG_MESSAGE="Release v${{ steps.version.outputs.new_version }} (backend)" - elif [ "$COMPONENT" = "frontend" ]; then - TAG_MESSAGE="Release v${{ steps.version.outputs.new_version }} (frontend)" - fi - - git tag -a "v${{ steps.version.outputs.new_version }}" -m "$TAG_MESSAGE" - git push origin "v${{ steps.version.outputs.new_version }}" - - trigger-drone: - needs: version-bump - if: needs.version-bump.outputs.version_changed == 'true' - runs-on: ubuntu-latest - steps: - - name: Trigger Drone Build - run: | - echo "Version bumped to ${{ needs.version-bump.outputs.new_version }}" - echo "Component(s) changed: ${{ needs.version-bump.outputs.component_changed }}" - echo "Drone will automatically trigger on the new tag" - # Drone CI will automatically trigger on the tag push event diff --git a/.swarm/memory.db b/.swarm/memory.db deleted file mode 100644 index 4b95fc9..0000000 Binary files a/.swarm/memory.db and /dev/null differ diff --git a/.swarm/memory.db-shm b/.swarm/memory.db-shm deleted file mode 100644 index 363c5e8..0000000 Binary files a/.swarm/memory.db-shm and /dev/null differ diff --git a/.swarm/memory.db-wal b/.swarm/memory.db-wal deleted file mode 100644 index 9f768e9..0000000 Binary files a/.swarm/memory.db-wal and /dev/null differ diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 471e64e..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,386 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Product Overview - -A secure photo sharing platform designed for weddings and events, enabling photographers to share time-limited, password-protected galleries. The platform features automatic expiration, archiving, and a scrappbook.de-inspired modern, minimalist UI. - -## Architecture Overview - -- **Backend**: Node.js/Express API with SQLite/PostgreSQL, file-based photo storage -- **Frontend**: React SPA with scrappbook.de-style design (requires implementation) -- **Storage**: File-based with active/archived separation -- **Services**: Background workers for email, archiving, file watching, and expiration monitoring -- **Analytics**: Umami integration for engagement tracking - -## Essential Commands - -### Backend Development -```bash -cd backend -npm install # Install dependencies -npm run migrate # Initialize database schema -npm run dev # Start with hot-reload (port 3001) -npm test # Run Jest tests -npm run lint # ESLint checks -``` - -### Running a Single Test -```bash -cd backend -npm test -- path/to/test.test.js -npm test -- --testNamePattern="test name" -``` - -### Production Deployment -See [DEPLOYMENT_GUIDE.md](./DEPLOYMENT_GUIDE.md) for comprehensive deployment instructions including: -- Docker Compose deployment -- PM2 deployment -- Manual installation -- Non-nginx deployment options -- SSL/HTTPS setup -- Troubleshooting guide - -**⚠️ CRITICAL PRODUCTION NOTICE:** -- Production runs on a SEPARATE SERVER - never assume local changes affect production -- ALWAYS request production server details before any troubleshooting -- NO trial-and-error approaches in production - data loss is unacceptable -- Every change must be thoroughly analyzed and tested locally first - -## Key Product Requirements (from PRD) - -### Core Features -1. **File-Based System**: Drop photos in folders → automatic gallery creation -2. **Automatic Expiration**: Default 30 days, with 7-day warning emails -3. **Password Protection**: Secure access with customizable passwords -4. **Automatic Archiving**: ZIP compression and storage after expiration -5. **Email Notifications**: Creation, warning, and expiration notifications -6. **Analytics**: Umami tracking for views, downloads, and engagement - -### Folder Structure -``` -/events/ - ├── active/ - │ ├── wedding-smith-jones-2024-06-15/ - │ │ ├── collages/ - │ │ └── individual/ - │ └── birthday-emma-2024-07-20/ - └── archived/ - └── wedding-smith-jones-2024-06-15.zip -``` - -## Frontend Implementation Requirements - -### Design Style (scrappbook.de-inspired) -- **Color Palette**: Primary green (#5C8762), neutral backgrounds -- **Typography**: Clean, modern sans-serif (Noto Sans or similar) -- **Layout**: Minimalist, modular sections with grid-based photo displays -- **Aesthetic**: Professional yet approachable, photographer-focused - -### Key Frontend Components to Build -1. **Landing Page**: Password entry with event preview -2. **Gallery View**: - - Responsive photo grid with lazy loading - - Toggle between collages/individual photos - - Prominent expiration banner - - Download urgency indicators -3. **Photo Lightbox**: Full-screen viewing with zoom -4. **Mobile-First**: Responsive design with touch gestures -5. **Personalization**: Dynamic theming per event type - -### User Experience Priorities -- Clear expiration warnings (sticky banner) -- One-click "Download All" for urgent galleries -- Smooth image loading with skeleton screens -- Intuitive navigation between photo categories -- Professional presentation matching photographer branding - -## Key Architecture Patterns - -### Authentication Flow -- JWT-based with separate tokens for admin and gallery access -- Gallery tokens include event-specific claims -- Auth middleware: `backend/src/middleware/auth.js` - - `adminAuth` - Admin panel protection - - `photoAuth` - Protected photo access - - `verifyGalleryAccess` - Gallery-specific validation - -### Database Schema (Knex/SQLite) -Main tables: -- `events` - Gallery metadata with expiration, custom messages, themes -- `photos` - Photo records linked to events -- `access_logs` - IP-based usage tracking -- `email_queue` - Async email processing -- `admin_users` - Admin authentication - -### Service Architecture -Background services run as separate processes: -- **emailService**: Processes email queue with retry logic -- **archiveService**: Creates ZIP archives of expired events -- **expirationChecker**: Cron job for expiration warnings -- **fileWatcher**: Monitors for new photo uploads -- **backupService**: Scheduled backups with checksum-based change detection - -### API Structure -- `/api/admin/*` - Admin panel endpoints (requires adminAuth) -- `/api/gallery/*` - Public gallery endpoints -- `/api/auth/*` - Authentication endpoints -- Rate limiting: 100 req/15min (general), 5 req/15min (auth) - -## Critical Implementation Notes - -1. **Security**: All gallery access requires valid JWT with event-specific claims -2. **Expiration**: Events auto-expire based on `expires_at`, with 7-day email warnings -3. **Email Queue**: Async processing with retry logic, check `email_queue` table -4. **File Processing**: Sharp library for thumbnail generation (300x300) -5. **Frontend Status**: Only skeleton exists - requires full implementation based on PRD -6. **Umami Analytics**: Track password entries, downloads, views, expiration warnings - -## Troubleshooting Guidelines - -### Before ANY Production Troubleshooting: -1. **ALWAYS request specific details**: - - Production server URL/IP - - Current error messages/logs - - Recent changes or deployments - - Affected users/galleries - - Time of issue occurrence - -2. **Thorough Analysis Required**: - - Use detailed thinking/analysis for EVERY troubleshooting task - - Review all related code before suggesting changes - - Consider all potential side effects - - Never make assumptions about production environment - -3. **Safe Troubleshooting Steps**: - - First, reproduce issue in local/dev environment - - Analyze logs without modifying production - - Create detailed action plan before any changes - - Always have rollback strategy ready - - Document every step taken - -### Common Issues & Safe Approaches: -- **Email not sending**: Check email_queue table, SMTP settings, service status -- **Photos not loading**: Verify file permissions, storage paths, nginx config -- **Gallery access issues**: Check JWT tokens, expiration dates, access_logs -- **Performance problems**: Analyze with monitoring tools first, never experiment - -### Data Safety Rules: -- NEVER delete or modify production data without explicit backup confirmation -- ALWAYS verify backups exist before any data operations -- NO direct database modifications without transaction safety -- Log all actions for audit trail - -## Environment Variables - -### Backend (.env) -- `JWT_SECRET` - Token signing -- `ADMIN_URL`, `FRONTEND_URL` - CORS origins -- `SMTP_*` - Email configuration -- `DB_*` - PostgreSQL credentials (production) -- `UMAMI_URL` - Umami instance URL (for server-side tracking) -- `UMAMI_WEBSITE_ID` - Website ID from Umami - -### Frontend (.env) -- `VITE_API_URL` - Backend API URL -- `VITE_UMAMI_URL` - Umami analytics URL -- `VITE_UMAMI_WEBSITE_ID` - Website ID from Umami -- `VITE_UMAMI_SHARE_URL` - (Optional) Public share URL for embedded dashboard - -## Testing Approach -- Jest with Supertest for API testing -- Test files in `__tests__` directories -- Database migrations run before tests -- Mock email sending in tests - -## Umami Analytics Integration - -The frontend includes comprehensive Umami analytics integration for tracking user behavior and gallery performance. - -### Tracked Events: -- **Gallery Events**: - - `gallery_password_entry` - Password attempts (success/failure) - - `gallery_photo_view` - Individual photo views - - `gallery_photo_download` - Single photo downloads - - `gallery_bulk_download` - Bulk/all photo downloads - - `gallery_expired` - Expired gallery access attempts -- **Admin Events**: - - `admin_login` - Admin authentication - - `admin_event_created` - New event creation - - `admin_event_archived` - Event archiving - - `admin_event_deleted` - Event deletion - - `admin_settings_updated` - Settings changes -- **User Behavior**: - - Search queries (with debouncing) - - Expiration warning views - - Page views with automatic tracking - -### Setup: -1. Install Umami (self-hosted or cloud) -2. Create a website in Umami dashboard -3. Set environment variables: - ``` - VITE_UMAMI_URL=https://your-umami-instance.com - VITE_UMAMI_WEBSITE_ID=your-website-id - VITE_UMAMI_SHARE_URL=https://your-umami-instance.com/share/... - ``` - -### Analytics Dashboard: -- Admin panel includes analytics page at `/admin/analytics` -- Summary view with key metrics -- Option to embed full Umami dashboard -- Real-time event tracking - -## Accessibility & Performance Features - -### Accessibility (WCAG 2.1 AA Compliance) -- **Error Boundaries**: Graceful error handling with recovery options -- **Skip Links**: Skip to main content for keyboard navigation -- **ARIA Labels**: Proper labeling for screen readers -- **Focus Management**: Focus trap in modals, visible focus indicators -- **Keyboard Navigation**: Full keyboard support in gallery lightbox (arrows, escape, +/-, d for download) -- **Loading States**: Skeleton screens instead of spinners for better UX -- **Offline Support**: Visual indicator when offline -- **Form Validation**: Accessible error messages with aria-describedby - -### Performance Optimizations -- **Lazy Loading**: Images load on scroll with Intersection Observer -- **Skeleton Screens**: Instant visual feedback during loading -- **Error Recovery**: Component-level error boundaries prevent full page crashes -- **Optimistic Updates**: Immediate UI updates with background sync -- **Debounced Search**: Prevents excessive API calls -- **Analytics**: Non-blocking Umami integration - -### Component Library Enhancements -- `` - Catches and displays errors gracefully -- `` - Full-page error recovery -- `` - Flexible skeleton loader with variants -- `` - Network status monitoring -- `` - Accessibility navigation -- `useFocusTrap` - Modal focus management hook -- `useOnlineStatus` - Network status hook - -## Theme System & Branding - -### Theme Features -- **Dynamic Theming**: CSS variables for runtime theme switching -- **Preset Themes**: Default, Wedding, Birthday, Corporate, Minimal -- **Customization Options**: - - Primary/Accent/Background/Text colors - - Font family selection - - Border radius (none, sm, md, lg) - - Custom logo upload - - Custom CSS injection -- **Event-Specific Themes**: Override global theme per gallery -- **Live Preview**: Real-time theme changes in admin panel - -### Theme Context API -```typescript -const { theme, setTheme, setThemeByName } = useTheme(); -``` - -### Branding Settings -- Company name, tagline, and support email -- Custom footer text -- Optional watermarking on downloads -- Logo upload for gallery header - -### CSS Variables -```css ---color-primary: #5C8762; ---color-primary-light: #7aa583; ---color-primary-dark: #4a6f4f; ---color-accent: #22c55e; ---color-background: #fafafa; ---color-text: #171717; ---font-family: 'Inter', sans-serif; ---border-radius: 0.5rem; -``` - -## Backup Service - -### Overview -The backup service provides automated, scheduled backups of all photo data with checksum-based change detection to minimize transfer overhead. - -### Features -- **Multiple Destinations**: Local directory, remote server (rsync), S3-compatible storage -- **Change Detection**: SHA256 checksums track file changes, only modified files are backed up -- **Scheduled Execution**: Configurable cron-based scheduling (default: 2 AM daily) -- **Email Notifications**: Alerts on backup failure, optional success notifications -- **Retention Management**: Automatic cleanup of old backup runs based on retention policy -- **Progress Tracking**: Database storage of backup history, file states, and statistics - -### Configuration -Backup settings are stored in `app_settings` table with `backup_` prefix: -- `backup_enabled`: Enable/disable the service -- `backup_schedule`: Cron expression (e.g., '0 2 * * *') -- `backup_destination_type`: 'local', 'rsync', or 's3' -- `backup_retention_days`: How long to keep backup history -- `backup_include_archived`: Whether to backup archived events -- `backup_exclude_patterns`: File patterns to exclude - -### API Endpoints -- `GET /api/admin/backup/config` - Get current configuration -- `PUT /api/admin/backup/config` - Update configuration -- `GET /api/admin/backup/status` - Get backup status and history -- `POST /api/admin/backup/run` - Trigger manual backup -- `POST /api/admin/backup/test-connection` - Test destination connectivity - -### Testing -Run backup service test: `npm run test-backup` - -### Database Tables -- `backup_runs`: Tracks each backup execution with statistics -- `backup_file_states`: Stores file checksums for change detection - -## Thumbnail Generation - -### Square Thumbnail Implementation (Issue #12 Fix) -The system now generates **square 300x300px thumbnails** to prevent blurry/stretched images in the gallery grid: - -- **Problem**: Previously generated 300px width with proportional height (e.g., 300x200 for 3:2 photos), but CSS forced square display causing distortion -- **Solution**: Thumbnails now use `cover` fit mode to crop to exact 300x300px dimensions with center positioning -- **Configuration**: Settings stored in `app_settings` table with keys: `thumbnail_width`, `thumbnail_height`, `thumbnail_fit`, `thumbnail_quality`, `thumbnail_format` -- **Migration**: Run `040_add_thumbnail_settings.js` to add default square thumbnail settings -- **Regeneration Script**: Use `scripts/regenerate-square-thumbnails.js` to update existing thumbnails - -### Thumbnail Settings API -- `GET /api/admin/thumbnails/settings` - Get current thumbnail configuration -- `PUT /api/admin/thumbnails/settings` - Update thumbnail settings (requires regeneration) -- `POST /api/admin/thumbnails/regenerate` - Regenerate all thumbnails with new settings -- `GET /api/admin/thumbnails/regenerate/status` - Check regeneration progress - -## Success Metrics (from PRD) -- Time to generate gallery: <2 minutes -- Guest satisfaction: >90% -- System uptime: 99.9% -- Email delivery rate: >98% -- Successful archiving: 100% - -## Documentation & Development Practices - -### Documentation Guidelines: -- **NEVER create new documentation files for simple tasks** -- **ALWAYS update existing documentation (like this CLAUDE.md)** -- Only create new .md files when explicitly requested -- Avoid creating temporary scripts for one-off tasks - -### Development Best Practices: -- Test all changes thoroughly in local environment first -- Use version control for all changes -- Keep commits atomic and well-described -- Review impact on all integrated services -- Consider backward compatibility -- Update tests when changing functionality - -### Production Deployment Checklist: -- [ ] All tests passing locally -- [ ] Linting and type checks pass -- [ ] Database migrations tested with rollback plan -- [ ] Environment variables documented -- [ ] Backup strategy confirmed -- [ ] Monitoring alerts configured -- [ ] Rollback procedure documented -- [ ] Stakeholders notified of maintenance window -- always use docker deployment for testing \ No newline at end of file diff --git a/photo-sharing-prd.md b/photo-sharing-prd.md deleted file mode 100644 index 81c1a35..0000000 --- a/photo-sharing-prd.md +++ /dev/null @@ -1,372 +0,0 @@ -# Product Requirements Document: Event Photo Sharing Platform - -## 1. Executive Summary - -### 1.1 Product Overview -A secure, customizable photo sharing platform designed primarily for wedding photo booths but adaptable for any event type. The platform enables event organizers to easily share photos with guests through password-protected, time-limited links while maintaining a simple file-based backend system with automatic archiving. - -### 1.2 Key Value Propositions -- **Simple Backend Management**: Drop photos in folders, generate links instantly -- **Secure Sharing**: Password-protected access with expiration dates -- **Automated Lifecycle**: Automatic archiving and storage optimization -- **Proactive Communication**: Email notifications for key events -- **Personalized Experience**: Custom branding for each event -- **Analytics Integration**: Track engagement through Umami -- **Versatile Use Cases**: Optimized for weddings but suitable for any event - -## 2. Product Goals & Objectives - -### 2.1 Primary Goals -- Provide a seamless, time-limited photo sharing experience for event guests -- Minimize technical complexity for administrators -- Ensure photo privacy through password protection and link expiration -- Automate storage management through intelligent archiving -- Enable detailed analytics on photo access and engagement -- Keep stakeholders informed through automated notifications - -### 2.2 Success Metrics -- Time to generate new event gallery (<2 minutes) -- Guest satisfaction score (>90%) -- Photo view/download rates -- System uptime (99.9%) -- Successful automatic archiving rate (100%) -- Email delivery rate (>98%) - -## 3. User Personas - -### 3.1 Administrator (Event Organizer/Photographer) -- **Background**: Professional photographer or event organizer -- **Technical Skills**: Basic to intermediate -- **Needs**: Quick photo upload, easy link generation, access analytics, automated cleanup -- **Pain Points**: Complex upload processes, managing multiple events, storage management - -### 3.2 End User (Event Guest) -- **Background**: Wedding guest or event attendee -- **Technical Skills**: Varies widely -- **Needs**: Easy photo viewing, downloading, sharing within timeframe -- **Pain Points**: Complicated interfaces, slow loading, expired links - -### 3.3 Event Host (Bride/Groom/Celebrant) -- **Background**: Person celebrating the event -- **Technical Skills**: Basic -- **Needs**: Notification of gallery availability, awareness of expiration -- **Pain Points**: Missing the opportunity to save photos, not knowing when gallery is ready - -## 4. Functional Requirements - -### 4.1 Backend Administration - -#### 4.1.1 File Management System -- **Photo Upload**: Direct file system access via designated folders -- **Folder Structure**: - ``` - /events/ - ├── active/ - │ ├── wedding-smith-jones-2024-06-15/ - │ │ ├── collages/ - │ │ │ ├── collage_001.jpg - │ │ │ └── collage_002.jpg - │ │ └── individual/ - │ │ ├── photo_001.jpg - │ │ └── photo_002.jpg - │ └── birthday-emma-2024-07-20/ - │ └── photos/ - └── archived/ - └── wedding-smith-jones-2024-06-15.zip - ``` -- **Supported Formats**: JPEG, PNG, WebP -- **Auto-detection**: System monitors folders for new photos -- **Automatic Archiving**: Upon expiration, compress folder to ZIP and move to archive - -#### 4.1.2 Link Generation -- **Unique URL Generation**: Automatic creation of shareable links -- **Password Setting**: Admin sets password during link creation -- **Expiration Date**: Mandatory expiration date selection (default: 30 days) -- **Event Metadata**: - - Event type (wedding, birthday, corporate, etc.) - - Names (couple names for weddings, celebrant for others) - - Event date - - Host email address (for notifications) - - Admin notification email - - Custom welcome message - - Color theme selection - - Link validity period - -#### 4.1.3 Email Notification System -- **Trigger Events**: - - Link creation: Notify host with access details - - Link expiration warning: 7 days before expiration - - Link expiration: Notify both host and admin - - Archive completion: Confirm to admin -- **Email Templates**: Customizable, branded email templates -- **Configuration**: SMTP settings, from address, reply-to address - -#### 4.1.4 Admin Dashboard -- **Event Management**: List all events, active/inactive/archived status -- **Expiration Overview**: Timeline view of upcoming expirations -- **Analytics Overview**: Quick stats per event -- **Link Management**: Copy links, reset passwords, extend expiration, deactivate events -- **Bulk Operations**: Archive old events, batch photo operations -- **Email Configuration**: Template management, SMTP settings -- **Archive Management**: View and download archived ZIPs - -### 4.2 Frontend Guest Experience - -#### 4.2.1 Landing Page -- **Password Entry**: Clean, intuitive password input -- **Event Preview**: Show event name, date, and expiration notice -- **Expiration Warning**: Prominent display if <7 days remaining -- **Expired State**: Clear message with contact information if expired -- **Responsive Design**: Mobile-first approach - -#### 4.2.2 Gallery View -- **Expiration Banner**: Sticky banner showing days remaining -- **Grid Layout**: Responsive photo grid with lazy loading -- **View Toggle**: Switch between collages and individual photos -- **Sorting Options**: By date, name, or custom order -- **Search**: Basic filename or date search -- **Download Urgency**: Prominent "Download All" for soon-to-expire galleries - -#### 4.2.3 Photo Interactions -- **Lightbox View**: Full-screen photo viewing with navigation -- **Zoom**: Pinch-to-zoom on mobile, mouse wheel on desktop -- **Download Options**: - - Single photo download - - Bulk download (selected photos) - - Download all (ZIP file) -- **Sharing**: Direct link to specific photos (respects expiration) - -#### 4.2.4 Personalization -- **Dynamic Theming**: Based on event type and admin preferences -- **Custom Headers**: Event names, dates, and messages -- **Branded Elements**: Optional logo upload -- **Expiration Messaging**: Customizable expiration notices - -### 4.3 Analytics Integration - -#### 4.3.1 Umami Analytics -- **Page Views**: Track gallery visits -- **User Actions**: Photo views, downloads, time spent -- **Device/Browser Stats**: Understand user base -- **Geographic Data**: Guest locations -- **Custom Events**: - - Password entries (successful/failed) - - Photo downloads - - Share button clicks - - Expiration warning views - - Last-minute download spikes - -### 4.4 Archiving System - -#### 4.4.1 Automatic Archiving Process -- **Trigger**: Activated upon link expiration -- **Process**: - 1. Create ZIP file with folder structure preserved - 2. Verify ZIP integrity - 3. Move ZIP to archive location - 4. Delete original files - 5. Update database with archive location - 6. Send confirmation emails - -#### 4.4.2 Archive Management -- **Storage Optimization**: Compression settings for long-term storage -- **Retrieval System**: Admin can restore archives if needed -- **Retention Policy**: Configurable long-term retention rules - -## 5. Technical Requirements - -### 5.1 Architecture - -#### 5.1.1 Infrastructure -- **Backend Access**: Dedicated FQDN (e.g., admin.photos.domain.com) -- **Frontend Access**: Public FQDN (e.g., photos.domain.com) -- **File Storage**: Local file system or network-attached storage -- **Archive Storage**: Separate location for long-term ZIP storage -- **Database**: Lightweight database for metadata (SQLite or PostgreSQL) -- **Email Service**: SMTP integration or email service provider - -#### 5.1.2 Security -- **HTTPS**: Required for both frontend and backend -- **Password Hashing**: Bcrypt or similar for stored passwords -- **Rate Limiting**: Prevent brute force attacks -- **Access Logs**: Track all access attempts -- **Expiration Enforcement**: Server-side validation of link validity - -### 5.2 Performance Requirements -- **Page Load Time**: <3 seconds on 4G connection -- **Image Optimization**: Automatic thumbnail generation -- **Caching**: CDN integration for static assets -- **Concurrent Users**: Support 100+ simultaneous users per event -- **Archive Generation**: Complete within 10 minutes for 1000 photos - -### 5.3 Technology Stack (Recommended) -- **Backend**: Node.js with Express or Python with FastAPI -- **Frontend**: React or Vue.js for dynamic interactions -- **Image Processing**: Sharp (Node.js) or Pillow (Python) -- **File Monitoring**: Chokidar or Watchdog -- **Analytics**: Umami self-hosted or cloud -- **Email Service**: Nodemailer or SendGrid -- **Job Queue**: Bull (Node.js) or Celery (Python) for archiving tasks -- **Scheduler**: Node-cron or APScheduler for expiration checks - -## 6. User Interface Requirements - -### 6.1 Design Principles -- **Modern Aesthetic**: Clean, minimalist design -- **Wedding-Optimized**: Elegant typography, romantic color options -- **Urgency Communication**: Clear expiration indicators -- **Accessibility**: WCAG 2.1 AA compliant -- **Responsive**: Mobile, tablet, and desktop optimized - -### 6.2 UI Components -- **Photo Grid**: Masonry or uniform grid layout -- **Navigation**: Sticky header with view toggles -- **Expiration Timer**: Countdown display for urgent galleries -- **Loading States**: Skeleton screens for better UX -- **Error Handling**: Friendly error messages -- **Email Status**: Indicators for sent notifications - -### 6.3 Branding Options -- **Color Schemes**: Pre-defined themes plus custom colors -- **Font Selection**: Google Fonts integration -- **Layout Templates**: Multiple gallery layout options -- **Email Templates**: Matching email designs - -## 7. Non-Functional Requirements - -### 7.1 Scalability -- Horizontal scaling capability -- Support for 10,000+ photos per event -- Efficient handling of high-resolution images -- Queue system for archiving operations - -### 7.2 Reliability -- 99.9% uptime SLA -- Automated backups (including archives) -- Graceful error handling -- Failed job retry mechanisms - -### 7.3 Maintainability -- Clear code documentation -- Modular architecture -- Automated testing suite -- Monitoring for failed archiving jobs - -### 7.4 Compliance -- GDPR compliance for EU users -- Copyright considerations -- Privacy policy and terms of service -- Data retention policies - -## 8. Email Templates - -### 8.1 Link Creation Email (to Host) -- Subject: "Your [Event Name] Photos Are Ready!" -- Content: Access details, password, expiration date -- Call-to-action: View gallery button - -### 8.2 Expiration Warning Email -- Subject: "Your [Event Name] Photos Expire in 7 Days" -- Content: Urgency message, download instructions -- Call-to-action: Download all photos button - -### 8.3 Expiration Notification Email -- To Host: "Your [Event Name] Photo Gallery Has Expired" -- To Admin: "[Event Name] Gallery Archived Successfully" -- Content: Confirmation of archiving, contact for retrieval - -## 9. Future Enhancements - -### 9.1 Phase 2 Features -- **Flexible Expiration**: Extend expiration for individual users -- **Partial Downloads**: Resume interrupted downloads -- **AI-Powered Features**: Face recognition for automatic grouping -- **Social Integration**: Direct sharing to social media -- **Guest Uploads**: Allow guests to add their photos -- **Video Support**: Basic video playback - -### 9.2 Phase 3 Features -- **Mobile Apps**: Native iOS/Android applications -- **Print Integration**: Direct ordering of prints -- **Event Packages**: Bundled services with photographers -- **Multi-language Support**: Internationalization -- **Cloud Archive**: Optional cloud storage for archives - -## 10. Success Criteria - -### 10.1 Launch Criteria -- Successfully handle 10 concurrent events -- Process 1,000 photos in <5 minutes -- 100% successful archiving rate -- Achieve 95% positive user feedback in beta -- Email delivery rate >98% - -### 10.2 Post-Launch Metrics -- Monthly active events: 100+ -- Average photos per event: 200+ -- Guest engagement rate: 70%+ -- Download rate: 50%+ of guests -- On-time archiving: 99%+ - -## 11. Risks & Mitigation - -### 11.1 Technical Risks -- **Storage Limitations**: Implement automated archiving and cloud storage -- **Performance Issues**: Progressive loading and CDN usage -- **Security Breaches**: Regular security audits -- **Archive Failures**: Redundant archiving with verification -- **Email Delivery**: Multiple SMTP providers, delivery monitoring - -### 11.2 Business Risks -- **Low Adoption**: Marketing partnerships with photographers -- **Feature Creep**: Strict MVP scope adherence -- **Support Burden**: Comprehensive documentation and FAQs -- **Expired Link Complaints**: Clear communication, grace period - -## 12. Timeline & Milestones - -### 12.1 Development Phases -- **Phase 1 (MVP)**: 10-12 weeks - - Core functionality - - Basic UI - - Expiration system - - Email notifications - - Archiving system - - Umami integration -- **Phase 2 (Enhancement)**: 4-6 weeks - - Advanced features - - Performance optimization -- **Phase 3 (Polish)**: 2-4 weeks - - UI refinements - - Beta testing - -### 12.2 Key Milestones -- Week 2: Technical architecture finalized -- Week 4: Backend functionality complete -- Week 6: Frontend gallery functional -- Week 7: Email system integrated -- Week 8: Archiving system complete -- Week 9: Analytics integrated -- Week 12: Beta launch - -## 13. Appendices - -### 13.1 Technical Specifications -- Detailed API documentation -- Database schema (including expiration tracking) -- File naming conventions -- Archive format specifications - -### 13.2 Design Mockups -- UI wireframes -- Email template designs -- Expiration state displays -- Style guide -- Component library - -### 13.3 Testing Plan -- Unit test coverage -- Integration testing -- Archiving system testing -- Email delivery testing -- User acceptance criteria \ No newline at end of file diff --git a/scripts/install-gitea-runner.sh b/scripts/install-gitea-runner.sh deleted file mode 100755 index 9c6b1d8..0000000 --- a/scripts/install-gitea-runner.sh +++ /dev/null @@ -1,176 +0,0 @@ -#!/bin/bash - -# Gitea Act Runner Installation Script -set -e - -echo "===================================" -echo "Gitea Act Runner Installation" -echo "===================================" - -# Configuration -GITEA_URL="https://gitea.nothaft.cloud" -RUNNER_NAME="picpeak-runner-$(hostname)" -RUNNER_VERSION="0.2.10" # Latest stable version - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' - -echo -e "${YELLOW}This script will help you install and register a Gitea Act Runner${NC}" -echo "" - -# Step 1: Get registration token -echo -e "${GREEN}Step 1: Get Registration Token${NC}" -echo "1. Go to: $GITEA_URL/admin/runners" -echo "2. Click 'Create new Runner'" -echo "3. Copy the registration token" -echo "" -read -p "Enter your registration token: " REGISTRATION_TOKEN - -if [ -z "$REGISTRATION_TOKEN" ]; then - echo -e "${RED}Error: Registration token is required${NC}" - exit 1 -fi - -# Step 2: Choose installation method -echo "" -echo -e "${GREEN}Step 2: Choose Installation Method${NC}" -echo "1. Docker (Recommended)" -echo "2. Binary installation" -read -p "Choose method (1 or 2): " METHOD - -if [ "$METHOD" == "1" ]; then - # Docker installation - echo "" - echo -e "${GREEN}Installing with Docker...${NC}" - - # Check if Docker is installed - if ! command -v docker &> /dev/null; then - echo -e "${RED}Error: Docker is not installed${NC}" - echo "Please install Docker first: https://docs.docker.com/get-docker/" - exit 1 - fi - - # Create docker-compose file for runner - cat > docker-compose.runner.yml << EOF -version: '3.8' - -services: - gitea-runner: - image: gitea/act_runner:latest - container_name: gitea-runner - restart: unless-stopped - environment: - - GITEA_INSTANCE_URL=$GITEA_URL - - GITEA_RUNNER_REGISTRATION_TOKEN=$REGISTRATION_TOKEN - - GITEA_RUNNER_NAME=$RUNNER_NAME - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - ./runner-data:/data - networks: - - picpeak - -networks: - picpeak: - external: true -EOF - - echo "Starting Gitea Runner with Docker..." - docker-compose -f docker-compose.runner.yml up -d - - echo "" - echo -e "${GREEN}✓ Runner installed and started with Docker${NC}" - echo "Check logs with: docker logs gitea-runner" - -elif [ "$METHOD" == "2" ]; then - # Binary installation - echo "" - echo -e "${GREEN}Installing binary...${NC}" - - # Detect OS and architecture - OS=$(uname -s | tr '[:upper:]' '[:lower:]') - ARCH=$(uname -m) - - case "$ARCH" in - x86_64) - ARCH="amd64" - ;; - aarch64|arm64) - ARCH="arm64" - ;; - *) - echo -e "${RED}Unsupported architecture: $ARCH${NC}" - exit 1 - ;; - esac - - # Download act_runner - DOWNLOAD_URL="https://gitea.com/gitea/act_runner/releases/download/v${RUNNER_VERSION}/act_runner-${RUNNER_VERSION}-${OS}-${ARCH}" - - echo "Downloading from: $DOWNLOAD_URL" - curl -L -o act_runner "$DOWNLOAD_URL" - chmod +x act_runner - - # Create config directory - mkdir -p ~/.config/act_runner - - # Register the runner - echo "" - echo -e "${GREEN}Registering runner...${NC}" - ./act_runner register \ - --no-interactive \ - --instance "$GITEA_URL" \ - --token "$REGISTRATION_TOKEN" \ - --name "$RUNNER_NAME" \ - --labels "ubuntu-latest:docker://node:16-bullseye,ubuntu-22.04:docker://node:16-bullseye,ubuntu-20.04:docker://node:16-bullseye" - - # Create systemd service - if [ "$OS" == "linux" ]; then - echo "" - echo -e "${GREEN}Creating systemd service...${NC}" - - sudo tee /etc/systemd/system/gitea-runner.service > /dev/null << EOF -[Unit] -Description=Gitea Act Runner -After=network.target - -[Service] -Type=simple -User=$USER -WorkingDirectory=$PWD -ExecStart=$PWD/act_runner daemon -Restart=always -RestartSec=5 -Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - -[Install] -WantedBy=multi-user.target -EOF - - sudo systemctl daemon-reload - sudo systemctl enable gitea-runner - sudo systemctl start gitea-runner - - echo -e "${GREEN}✓ Runner installed as systemd service${NC}" - echo "Check status with: sudo systemctl status gitea-runner" - echo "Check logs with: sudo journalctl -u gitea-runner -f" - else - echo "" - echo -e "${GREEN}✓ Runner installed${NC}" - echo "Start runner with: ./act_runner daemon" - fi -fi - -echo "" -echo -e "${GREEN}===================================" -echo "Installation Complete!" -echo "===================================${NC}" -echo "" -echo "Next steps:" -echo "1. Go to: $GITEA_URL/paul/picpeak/settings/actions/runners" -echo "2. Verify your runner appears in the list" -echo "3. Push a commit to trigger the test workflow" -echo "" -echo "If the runner doesn't appear, check the logs for errors." \ No newline at end of file diff --git a/storage/events/active/.gitkeep b/storage/events/active/.gitkeep deleted file mode 100755 index e69de29..0000000 diff --git a/storage/events/archived/.gitkeep b/storage/events/archived/.gitkeep deleted file mode 100755 index e69de29..0000000 diff --git a/storage/thumbnails/.gitkeep b/storage/thumbnails/.gitkeep deleted file mode 100755 index e69de29..0000000 diff --git a/storage/uploads/favicons/favicon-1751900441264.png b/storage/uploads/favicons/favicon-1751900441264.png deleted file mode 100755 index 1541735..0000000 Binary files a/storage/uploads/favicons/favicon-1751900441264.png and /dev/null differ diff --git a/storage/uploads/favicons/favicon-1751900464374.png b/storage/uploads/favicons/favicon-1751900464374.png deleted file mode 100755 index 1541735..0000000 Binary files a/storage/uploads/favicons/favicon-1751900464374.png and /dev/null differ diff --git a/storage/uploads/favicons/favicon-1751900673622.png b/storage/uploads/favicons/favicon-1751900673622.png deleted file mode 100755 index 1541735..0000000 Binary files a/storage/uploads/favicons/favicon-1751900673622.png and /dev/null differ diff --git a/storage/uploads/favicons/favicon-1751901117619.png b/storage/uploads/favicons/favicon-1751901117619.png deleted file mode 100755 index 1541735..0000000 Binary files a/storage/uploads/favicons/favicon-1751901117619.png and /dev/null differ diff --git a/storage/uploads/favicons/favicon-1752428072068.png b/storage/uploads/favicons/favicon-1752428072068.png deleted file mode 100755 index ac40b82..0000000 Binary files a/storage/uploads/favicons/favicon-1752428072068.png and /dev/null differ diff --git a/storage/uploads/logos/logo-1751899826077.png b/storage/uploads/logos/logo-1751899826077.png deleted file mode 100755 index c412564..0000000 Binary files a/storage/uploads/logos/logo-1751899826077.png and /dev/null differ diff --git a/storage/uploads/logos/logo-1751900093292.png b/storage/uploads/logos/logo-1751900093292.png deleted file mode 100755 index c412564..0000000 Binary files a/storage/uploads/logos/logo-1751900093292.png and /dev/null differ diff --git a/storage/uploads/logos/logo-1751900103851.png b/storage/uploads/logos/logo-1751900103851.png deleted file mode 100755 index c412564..0000000 Binary files a/storage/uploads/logos/logo-1751900103851.png and /dev/null differ diff --git a/storage/uploads/logos/logo-1751900150420.png b/storage/uploads/logos/logo-1751900150420.png deleted file mode 100755 index 1541735..0000000 Binary files a/storage/uploads/logos/logo-1751900150420.png and /dev/null differ diff --git a/storage/uploads/logos/logo-1751900199827.png b/storage/uploads/logos/logo-1751900199827.png deleted file mode 100755 index 1541735..0000000 Binary files a/storage/uploads/logos/logo-1751900199827.png and /dev/null differ diff --git a/storage/uploads/logos/logo-1751967884477.png b/storage/uploads/logos/logo-1751967884477.png deleted file mode 100755 index 687b482..0000000 Binary files a/storage/uploads/logos/logo-1751967884477.png and /dev/null differ diff --git a/storage/uploads/logos/logo-1752236747132.png b/storage/uploads/logos/logo-1752236747132.png deleted file mode 100755 index ed816b3..0000000 Binary files a/storage/uploads/logos/logo-1752236747132.png and /dev/null differ