feat: integrate Grafana dashboards into BOC DashboardPage

- Add Infrastructure Health section with CPU/Memory/Disk panels
- Add Service Status section with PM2/Docker panels
- Create GrafanaPanel component for iframe embedding
- Build passes successfully
This commit is contained in:
Bernt
2026-07-29 19:03:06 +00:00
parent af874040ca
commit e5623d2f84
77 changed files with 11338 additions and 779 deletions
+44
View File
@@ -140,3 +140,47 @@ func accountsToMaps(accounts []Account) []map[string]interface{} {
}
return result
}
// Transaction represents a ledger transaction
type Transaction struct {
ID string `json:"id"`
Date string `json:"date"`
Description string `json:"description"`
Amount float64 `json:"amount"`
Type string `json:"type"`
AccountCode string `json:"account_code,omitempty"`
AccountName string `json:"account_name,omitempty"`
}
// GetTransactions returns all journal entries as transactions
func (c *RealClient) GetTransactions(ctx context.Context) ([]Transaction, error) {
rows, err := c.db.QueryContext(ctx, `
SELECT je.id, je.entry_date, je.description,
COALESCE(jl.debit, 0) - COALESCE(jl.credit, 0) as amount,
CASE
WHEN COALESCE(jl.debit, 0) > 0 THEN 'debit'
ELSE 'credit'
END as type,
a.code, a.name
FROM journal_entries je
JOIN journal_lines jl ON je.id = jl.journal_entry_id
JOIN accounts a ON jl.account_id = a.id
ORDER BY je.entry_date DESC
LIMIT 100
`)
if err != nil {
return nil, fmt.Errorf("query transactions: %w", err)
}
defer rows.Close()
var transactions []Transaction
for rows.Next() {
var t Transaction
if err := rows.Scan(&t.ID, &t.Date, &t.Description, &t.Amount, &t.Type, &t.AccountCode, &t.AccountName); err != nil {
return nil, fmt.Errorf("scan transaction: %w", err)
}
transactions = append(transactions, t)
}
return transactions, rows.Err()
}