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
+134
View File
@@ -0,0 +1,134 @@
package repository
import (
"context"
"database/sql"
"time"
)
// Contract represents a legal contract
type Contract struct {
ID string `json:"id"`
Title string `json:"title"`
Type string `json:"type"`
CustomerID string `json:"customer_id"`
Value float64 `json:"value"`
Currency string `json:"currency"`
StartDate time.Time `json:"start_date"`
EndDate time.Time `json:"end_date"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// ContractTemplate represents a reusable contract template
type ContractTemplate struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Content string `json:"content"`
Language string `json:"language"`
}
// LegalRepository handles all legal-related database operations
type LegalRepository struct {
db *sql.DB
}
func NewLegalRepository(db *sql.DB) *LegalRepository {
return &LegalRepository{db: db}
}
// ListContracts returns all contracts
func (r *LegalRepository) ListContracts(ctx context.Context) ([]Contract, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT id, title, type, customer_id, value, currency, start_date, end_date, status, created_at, updated_at
FROM boc_contracts
ORDER BY created_at DESC
`)
if err != nil {
return nil, err
}
defer rows.Close()
var contracts []Contract
for rows.Next() {
var c Contract
if err := rows.Scan(&c.ID, &c.Title, &c.Type, &c.CustomerID, &c.Value, &c.Currency, &c.StartDate, &c.EndDate, &c.Status, &c.CreatedAt, &c.UpdatedAt); err != nil {
continue
}
contracts = append(contracts, c)
}
return contracts, rows.Err()
}
// GetContract returns a single contract by ID
func (r *LegalRepository) GetContract(ctx context.Context, id string) (*Contract, error) {
var c Contract
err := r.db.QueryRowContext(ctx, `
SELECT id, title, type, customer_id, value, currency, start_date, end_date, status, created_at, updated_at
FROM boc_contracts
WHERE id = $1
`, id).Scan(&c.ID, &c.Title, &c.Type, &c.CustomerID, &c.Value, &c.Currency, &c.StartDate, &c.EndDate, &c.Status, &c.CreatedAt, &c.UpdatedAt)
if err != nil {
return nil, err
}
return &c, nil
}
// CreateContract creates a new contract
func (r *LegalRepository) CreateContract(ctx context.Context, c *Contract) error {
return r.db.QueryRowContext(ctx, `
INSERT INTO boc_contracts (title, type, customer_id, value, currency, start_date, end_date, status)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING id, created_at, updated_at
`, c.Title, c.Type, c.CustomerID, c.Value, c.Currency, c.StartDate, c.EndDate, c.Status).Scan(&c.ID, &c.CreatedAt, &c.UpdatedAt)
}
// UpdateContract updates an existing contract
func (r *LegalRepository) UpdateContract(ctx context.Context, id string, c *Contract) error {
_, err := r.db.ExecContext(ctx, `
UPDATE boc_contracts
SET title = $1, type = $2, customer_id = $3, value = $4, currency = $5, start_date = $6, end_date = $7, status = $8, updated_at = NOW()
WHERE id = $9
`, c.Title, c.Type, c.CustomerID, c.Value, c.Currency, c.StartDate, c.EndDate, c.Status, id)
return err
}
// ListTemplates returns all contract templates
func (r *LegalRepository) ListTemplates(ctx context.Context) ([]ContractTemplate, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT id, name, type, content, language
FROM boc_contract_templates
ORDER BY name
`)
if err != nil {
return nil, err
}
defer rows.Close()
var templates []ContractTemplate
for rows.Next() {
var t ContractTemplate
if err := rows.Scan(&t.ID, &t.Name, &t.Type, &t.Content, &t.Language); err != nil {
continue
}
templates = append(templates, t)
}
return templates, rows.Err()
}
// GetTemplate returns a single template by type
func (r *LegalRepository) GetTemplate(ctx context.Context, contractType string) (*ContractTemplate, error) {
var t ContractTemplate
err := r.db.QueryRowContext(ctx, `
SELECT id, name, type, content, language
FROM boc_contract_templates
WHERE type = $1
LIMIT 1
`, contractType).Scan(&t.ID, &t.Name, &t.Type, &t.Content, &t.Language)
if err != nil {
return nil, err
}
return &t, nil
}