mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-10-28 15:51:26 +00:00
Projects become publicly browsable after admin approval; management and secret-adjacent reads (logs, variables, exec, connection URLs) require owner/member/admin auth, and platform controls sit behind RequireAdmin. - Backend: OptionalAuth middleware, read/authed/admin route groups, projects.is_approved + service_templates.owner_id migration, visibility-aware sqlc queries, admin overview/users/approval endpoints, EnsureAdminAccount bootstrap (ADMIN_* env), 30 seeded templates with owner CRUD, managed-database connection URLs gated owner+admin, fix DB.Stats() infinite recursion. - Frontend: expandable persisted sidebar + clickable user menu, public landing page with searchable docs browser (GitHub sync, bundled snapshot + localStorage fallback), DocsBrowser shared with /docs, template create/edit/JSON-upload for owned templates, database create dialog, admin console (stats, approvals, project edit/delete, user admin toggles), HA/Security/Usage polish with dead CSS tokens mapped to real theme vars, anonymous-safe gating on every mutation control. - Tests: safe window.localStorage access fixes happy-dom crashes in PlatformShell and canvas storage. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
60 lines
1.3 KiB
Go
60 lines
1.3 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
_ "github.com/lib/pq"
|
|
)
|
|
|
|
type DB struct {
|
|
*sql.DB
|
|
}
|
|
|
|
type DBConfig struct {
|
|
MaxOpenConns int
|
|
MaxIdleConns int
|
|
ConnMaxLifetime time.Duration
|
|
ConnMaxIdleTime time.Duration
|
|
}
|
|
|
|
func NewConnection(databaseURL string) (*DB, error) {
|
|
return NewConnectionWithConfig(databaseURL, DBConfig{
|
|
MaxOpenConns: 25,
|
|
MaxIdleConns: 25,
|
|
ConnMaxLifetime: 5 * time.Minute,
|
|
ConnMaxIdleTime: 5 * time.Minute,
|
|
})
|
|
}
|
|
|
|
func NewConnectionWithConfig(databaseURL string, config DBConfig) (*DB, error) {
|
|
db, err := sql.Open("postgres", databaseURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to open database: %w", err)
|
|
}
|
|
|
|
// Configure connection pool
|
|
db.SetMaxOpenConns(config.MaxOpenConns)
|
|
db.SetMaxIdleConns(config.MaxIdleConns)
|
|
db.SetConnMaxLifetime(config.ConnMaxLifetime)
|
|
db.SetConnMaxIdleTime(config.ConnMaxIdleTime)
|
|
|
|
// Test the connection
|
|
if err := db.PingContext(context.Background()); err != nil {
|
|
return nil, fmt.Errorf("unable to ping database: %w", err)
|
|
}
|
|
|
|
return &DB{DB: db}, nil
|
|
}
|
|
|
|
func (db *DB) Health(ctx context.Context) error {
|
|
return db.PingContext(ctx)
|
|
}
|
|
|
|
// Stats returns connection pool statistics for monitoring
|
|
func (db *DB) Stats() sql.DBStats {
|
|
return db.DB.Stats()
|
|
}
|