···1332 return bundleNum, nil
1333}
13341335+func (p *PostgresDB) GetPLCHistory(ctx context.Context, limit int, fromBundle int) ([]*PLCHistoryPoint, error) {
1336+ query := `
1337+ WITH daily_stats AS (
1338+ SELECT
1339+ DATE(start_time) as date,
1340+ MAX(bundle_number) as last_bundle,
1341+ COUNT(*) as bundle_count,
1342+ SUM(uncompressed_size) as total_uncompressed,
1343+ SUM(compressed_size) as total_compressed,
1344+ MAX(cumulative_uncompressed_size) as cumulative_uncompressed,
1345+ MAX(cumulative_compressed_size) as cumulative_compressed
1346+ FROM plc_bundles
1347+ WHERE bundle_number >= $1
1348+ GROUP BY DATE(start_time)
1349+ )
1350+ SELECT
1351+ date::text,
1352+ last_bundle,
1353+ SUM(bundle_count * 10000) OVER (ORDER BY date) as cumulative_operations,
1354+ total_uncompressed,
1355+ total_compressed,
1356+ cumulative_uncompressed,
1357+ cumulative_compressed
1358+ FROM daily_stats
1359+ ORDER BY date ASC
1360+ `
1361+1362+ if limit > 0 {
1363+ query += fmt.Sprintf(" LIMIT %d", limit)
1364+ }
1365+1366+ rows, err := p.db.QueryContext(ctx, query, fromBundle)
1367+ if err != nil {
1368+ return nil, err
1369+ }
1370+ defer rows.Close()
1371+1372+ var history []*PLCHistoryPoint
1373+ for rows.Next() {
1374+ var point PLCHistoryPoint
1375+ var cumulativeOps int64
1376+1377+ err := rows.Scan(
1378+ &point.Date,
1379+ &point.BundleNumber,
1380+ &cumulativeOps,
1381+ &point.UncompressedSize,
1382+ &point.CompressedSize,
1383+ &point.CumulativeUncompressed,
1384+ &point.CumulativeCompressed,
1385+ )
1386+ if err != nil {
1387+ return nil, err
1388+ }
1389+1390+ point.OperationCount = int(cumulativeOps)
1391+1392+ history = append(history, &point)
1393+ }
1394+1395+ return history, rows.Err()
1396+}
1397+1398// ===== MEMPOOL OPERATIONS =====
13991400func (p *PostgresDB) AddToMempool(ctx context.Context, ops []MempoolOperation) error {
+10
internal/storage/types.go
···139 return 10000
140}
1410000000000142// MempoolOperation represents an operation waiting to be bundled
143type MempoolOperation struct {
144 ID int64
···139 return 10000
140}
141142+type PLCHistoryPoint struct {
143+ Date string `json:"date"`
144+ BundleNumber int `json:"last_bundle_number"`
145+ OperationCount int `json:"operations"`
146+ UncompressedSize int64 `json:"size_uncompressed"`
147+ CompressedSize int64 `json:"size_compressed"`
148+ CumulativeUncompressed int64 `json:"cumulative_uncompressed"`
149+ CumulativeCompressed int64 `json:"cumulative_compressed"`
150+}
151+152// MempoolOperation represents an operation waiting to be bundled
153type MempoolOperation struct {
154 ID int64