8 Commits

Author SHA1 Message Date
quiet-professional b07a114227 updated paths
Build and Release Core / Test and Build (push) Successful in 4m2s
2026-04-29 10:36:05 -04:00
quiet-professional 88f77edadd added license call out
Build and Release Core / Test and Build (push) Successful in 4m23s
2026-04-28 13:52:01 -04:00
quiet-professional decad4cc82 patched folder bug for users
Build and Release Core / Test and Build (push) Successful in 4m28s
2026-04-02 15:27:33 -04:00
quiet-professional fd0ff13991 updated the sqlite driver connection string
Build and Release Core / Test and Build (push) Successful in 4m2s
2026-04-02 15:05:40 -04:00
quiet-professional 5f53ffec4f updated sqlite engine to address compilation errors
Build and Release Core / Test and Build (push) Successful in 2m54s
2026-04-02 15:00:31 -04:00
quiet-professional da4699fe08 updated gitignore and ci/cd pipeline
Build and Release Core / Test and Build (push) Successful in 3m34s
2026-04-02 14:36:04 -04:00
quiet-professional d881051f3e updated to streamline build
Build and Release Core / Test and Build (push) Failing after 3m19s
2026-04-02 14:28:40 -04:00
quiet-professional b14072ddb2 removed test data
Build and Release Core / Test and Build (push) Has been cancelled
2026-04-02 14:19:17 -04:00
15 changed files with 205 additions and 81 deletions
+22 -11
View File
@@ -2,15 +2,16 @@ name: Build and Release Core
on: on:
push: push:
branches: [ main ]
tags: tags:
- 'v*' # Only trigger when you push a version tag (e.g., v1.0.0) - 'v*'
pull_request: pull_request:
branches: [ main ] # Run tests on PRs, but don't build release binaries branches: [ main ]
jobs: jobs:
build: build:
name: Test and Build name: Test and Build
runs-on: ubuntu-latest # This runs on your Gitea act_runner runs-on: ubuntu-latest
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -18,20 +19,27 @@ jobs:
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v4 uses: actions/setup-go@v4
with: with:
go-version: '1.26' # Update to match your go.mod if different go-version: '1.26.x'
- name: Cache Go Modules and Build Cache
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Run Tests - name: Run Tests
run: go test ./... -v run: go test ./... -v
- name: Build Binaries - name: Build Binaries
# Only run the build steps if this was triggered by a tag push
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
run: | run: |
VERSION=${GITHUB_REF_NAME} VERSION=${GITHUB_REF_NAME}
COMMIT=$(echo ${GITHUB_SHA} | cut -c1-7) COMMIT=$(echo ${GITHUB_SHA} | cut -c1-7)
LDFLAGS="-X 'main.BuildVersion=$VERSION' -X 'main.BuildCommit=$COMMIT'" LDFLAGS="-X 'main.BuildVersion=$VERSION' -X 'main.BuildCommit=$COMMIT'"
mkdir -p bin mkdir -p bin
@@ -45,9 +53,12 @@ jobs:
echo "Building Windows (amd64)..." echo "Building Windows (amd64)..."
GOOS=windows GOARCH=amd64 go build -ldflags="$LDFLAGS" -o bin/rr-windows-amd64.exe ./cmd/rr/main.go GOOS=windows GOARCH=amd64 go build -ldflags="$LDFLAGS" -o bin/rr-windows-amd64.exe ./cmd/rr/main.go
- name: Upload Artifacts - name: Create Release and Upload Binaries
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
uses: actions/upload-artifact@v4 uses: softprops/action-gh-release@v1
with: with:
name: riskrancher-core-binaries files: bin/*
path: bin/ name: Release ${{ github.ref_name }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITEA_TOKEN }}
-1
View File
@@ -16,7 +16,6 @@ vendor/
# RiskRancher Compiled Binaries # RiskRancher Compiled Binaries
# ========================= # =========================
# Ignore the local builds so you don't accidentally push a 20MB executable # Ignore the local builds so you don't accidentally push a 20MB executable
rr
rr.exe rr.exe
# ========================= # =========================
+4
View File
@@ -27,3 +27,7 @@ cd core
go build -o rr ./cmd/rr/main.go go build -o rr ./cmd/rr/main.go
./rr ./rr
``` ```
## License
Apache License 2.0
+32
View File
@@ -0,0 +1,32 @@
package main
import (
"log"
"net/http"
"epigas.gitea.cloud/RiskRancher/core/pkg/datastore"
"epigas.gitea.cloud/RiskRancher/core/pkg/server"
"epigas.gitea.cloud/RiskRancher/core/ui"
)
var (
BuildVersion = "dev"
BuildCommit = "none"
)
func main() {
ui.SetVersionInfo(BuildVersion, BuildCommit)
db := datastore.InitDB("./data/RiskRancher.db")
defer db.Close()
store := datastore.NewSQLiteStore(db)
app := server.NewApp(store)
server.RegisterRoutes(app)
log.Println("🤠 RiskRancher Core Server running on http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", app.Router))
}
+13 -1
View File
@@ -3,6 +3,18 @@ module epigas.gitea.cloud/RiskRancher/core
go 1.26.0 go 1.26.0
require ( require (
github.com/mattn/go-sqlite3 v1.14.34
golang.org/x/crypto v0.48.0 golang.org/x/crypto v0.48.0
modernc.org/sqlite v1.48.0
)
require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.42.0 // indirect
modernc.org/libc v1.70.0 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
) )
+51 -2
View File
@@ -1,4 +1,53 @@
github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.32.0 h1:hjG66bI/kqIPX1b2yT6fr/jt+QedtP2fqojG2VrFuVw=
modernc.org/ccgo/v4 v4.32.0/go.mod h1:6F08EBCx5uQc38kMGl+0Nm0oWczoo1c7cgpzEry7Uc0=
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo=
modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.70.0 h1:U58NawXqXbgpZ/dcdS9kMshu08aiA6b7gusEusqzNkw=
modernc.org/libc v1.70.0/go.mod h1:OVmxFGP1CI/Z4L3E0Q3Mf1PDE0BucwMkcXjjLntvHJo=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.48.0 h1:ElZyLop3Q2mHYk5IFPPXADejZrlHu7APbpB0sF78bq4=
modernc.org/sqlite v1.48.0/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
+3 -3
View File
@@ -7,7 +7,7 @@ import (
"sync" "sync"
"testing" "testing"
_ "github.com/mattn/go-sqlite3" _ "modernc.org/sqlite"
) )
// runChaosEngine fires 100 concurrent workers at the provided database connection // runChaosEngine fires 100 concurrent workers at the provided database connection
@@ -73,8 +73,8 @@ func TestSQLiteConcurrency_Tuned_Succeeds(t *testing.T) {
tempDir := t.TempDir() tempDir := t.TempDir()
dbPath := filepath.Join(tempDir, "tuned.db") dbPath := filepath.Join(tempDir, "tuned.db")
dsn := fmt.Sprintf("%s?_journal_mode=WAL&_synchronous=NORMAL&_busy_timeout=5000", dbPath) dsn := fmt.Sprintf("%s?_pragma=journal_mode(WAL)&_pragma=synchronous(NORMAL)&_pragma=busy_timeout(5000)", dbPath)
db, err := sql.Open("sqlite3", dsn) db, err := sql.Open("sqlite", dsn)
if err != nil { if err != nil {
t.Fatalf("Failed to open tuned DB: %v", err) t.Fatalf("Failed to open tuned DB: %v", err)
} }
+12 -4
View File
@@ -6,10 +6,12 @@ import (
_ "embed" _ "embed"
"encoding/json" "encoding/json"
"log" "log"
"os"
"path/filepath"
"time" "time"
"epigas.gitea.cloud/RiskRancher/core/pkg/domain" "epigas.gitea.cloud/RiskRancher/core/pkg/domain"
_ "github.com/mattn/go-sqlite3" _ "modernc.org/sqlite"
) )
//go:embed schema.sql //go:embed schema.sql
@@ -18,10 +20,16 @@ var schemaSQL string
//go:embed defaults/*.json //go:embed defaults/*.json
var defaultAdaptersFS embed.FS var defaultAdaptersFS embed.FS
func InitDB(filepath string) *sql.DB { func InitDB(dbPath string) *sql.DB {
dsn := "file:" + filepath + "?_journal=WAL&_timeout=5000&_sync=1&_fk=1"
db, err := sql.Open("sqlite3", dsn) dir := filepath.Dir(dbPath)
if err := os.MkdirAll(dir, 0755); err != nil {
log.Fatalf("Failed to create database directory: %v", err)
}
dsn := "file:" + dbPath + "?_pragma=journal_mode(WAL)&_pragma=busy_timeout(5000)&_pragma=synchronous(NORMAL)&_pragma=foreign_keys(1)"
db, err := sql.Open("sqlite", dsn)
if err != nil { if err != nil {
log.Fatalf("Failed to open database: %v", err) log.Fatalf("Failed to open database: %v", err)
} }
+2 -2
View File
@@ -6,11 +6,11 @@ import (
"testing" "testing"
"epigas.gitea.cloud/RiskRancher/core/pkg/domain" "epigas.gitea.cloud/RiskRancher/core/pkg/domain"
_ "github.com/mattn/go-sqlite3" // We need the SQLite driver for the test _ "modernc.org/sqlite" // We need the SQLite driver for the test
) )
func setupTestDB(t *testing.T) *SQLiteStore { func setupTestDB(t *testing.T) *SQLiteStore {
db, err := sql.Open("sqlite3", ":memory:") db, err := sql.Open("sqlite", ":memory:")
if err != nil { if err != nil {
t.Fatalf("Failed to open in-memory SQLite database: %v", err) t.Fatalf("Failed to open in-memory SQLite database: %v", err)
} }
+2 -2
View File
@@ -4,11 +4,11 @@ import (
"database/sql" "database/sql"
"testing" "testing"
_ "github.com/mattn/go-sqlite3" _ "modernc.org/sqlite"
) )
func TestSchemaMigrations(t *testing.T) { func TestSchemaMigrations(t *testing.T) {
db, err := sql.Open("sqlite3", ":memory:") db, err := sql.Open("sqlite", ":memory:")
if err != nil { if err != nil {
t.Fatalf("Failed to open test db: %v", err) t.Fatalf("Failed to open test db: %v", err)
} }
+2 -2
View File
@@ -4,7 +4,7 @@ import (
"database/sql" "database/sql"
"testing" "testing"
_ "github.com/mattn/go-sqlite3" _ "modernc.org/sqlite"
) )
// GetSLAPolicy simulates the core engine function that fetches SLA rules // GetSLAPolicy simulates the core engine function that fetches SLA rules
@@ -16,7 +16,7 @@ func GetSLAPolicy(db *sql.DB, domain string, severity string) (daysToRemediate i
// setupTestDB spins up an isolated, in-memory database for testing // setupTestDB spins up an isolated, in-memory database for testing
func setupTestDB(t *testing.T) *sql.DB { func setupTestDB(t *testing.T) *sql.DB {
db, err := sql.Open("sqlite3", ":memory:") db, err := sql.Open("sqlite", ":memory:")
if err != nil { if err != nil {
t.Fatalf("Failed to open test database: %v", err) t.Fatalf("Failed to open test database: %v", err)
} }
+3
View File
@@ -10,15 +10,18 @@
<div class="tab-nav"> <div class="tab-nav">
<button class="tab-btn active" onclick="switchTab('tab-metrics', this)">📊 Metrics</button> <button class="tab-btn active" onclick="switchTab('tab-metrics', this)">📊 Metrics</button>
<button class="tab-btn" onclick="switchTab('tab-performance', this)">📡 Performance</button> <button class="tab-btn" onclick="switchTab('tab-performance', this)">📡 Performance</button>
{{ block "pro_risk_tab_btn" .}}
<button class="tab-btn" style="color: #94a3b8; cursor: not-allowed;" title="Available in RiskRancher Pro"> <button class="tab-btn" style="color: #94a3b8; cursor: not-allowed;" title="Available in RiskRancher Pro">
🔒 Risk Reviews (Pro) 🔒 Risk Reviews (Pro)
</button> </button>
{{ end }}
<button class="tab-btn" onclick="switchTab('tab-config', this)">⚙️ Configuration</button> <button class="tab-btn" onclick="switchTab('tab-config', this)">⚙️ Configuration</button>
<button class="tab-btn" onclick="switchTab('tab-feed', this)">📻 System Logs</button> <button class="tab-btn" onclick="switchTab('tab-feed', this)">📻 System Logs</button>
</div> </div>
{{template "admin_metrics" .}} {{template "admin_metrics" .}}
{{template "admin_performance" .}} {{template "admin_performance" .}}
{{block "pro_risk_tab_content" .}}{{end}}
{{template "admin_config" .}} {{template "admin_config" .}}
{{template "admin_feed" .}} {{template "admin_feed" .}}
{{template "admin_modals" .}} {{template "admin_modals" .}}
+6 -2
View File
@@ -24,7 +24,7 @@
</table> </table>
</div> </div>
<div style="border: 1px solid #e2e8f0; border-radius: 8px; padding: 15px;"> {{block "pro_source_routing" .}}
<div style="border: 1px solid #e2e8f0; border-radius: 8px; padding: 15px; background: #f8fafc;"> <div style="border: 1px solid #e2e8f0; border-radius: 8px; padding: 15px; background: #f8fafc;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;"> <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
<h3 style="margin: 0; color: #64748b;">🛤️ Source Routing</h3> <h3 style="margin: 0; color: #64748b;">🛤️ Source Routing</h3>
@@ -35,11 +35,12 @@
<a href="https://RiskRancher.com/pro" target="_blank" style="color: #8b5cf6; text-decoration: none; font-weight: bold; font-size: 0.85rem;">Learn about RiskRancher Pro &rarr;</a> <a href="https://RiskRancher.com/pro" target="_blank" style="color: #8b5cf6; text-decoration: none; font-weight: bold; font-size: 0.85rem;">Learn about RiskRancher Pro &rarr;</a>
</div> </div>
</div> </div>
</div> {{end}}
</div> </div>
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 20px;"> <div style="display: grid; grid-template-columns: 2fr 1fr; gap: 20px;">
{{block "pro_sla_policy" .}}
<div style="border: 1px solid #e2e8f0; border-radius: 8px; padding: 15px; position: relative;"> <div style="border: 1px solid #e2e8f0; border-radius: 8px; padding: 15px; position: relative;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;"> <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
<div> <div>
@@ -76,10 +77,12 @@
</div> </div>
</div> </div>
</div> </div>
{{end}}
<div style="border: 1px solid #e2e8f0; border-radius: 8px; padding: 15px; display: flex; flex-direction: column;"> <div style="border: 1px solid #e2e8f0; border-radius: 8px; padding: 15px; display: flex; flex-direction: column;">
<h3 style="margin: 0 0 15px 0;">⚙️ Operations</h3> <h3 style="margin: 0 0 15px 0;">⚙️ Operations</h3>
{{block "pro_backups" .}}
<div style="margin-bottom: 20px;"> <div style="margin-bottom: 20px;">
<label style="font-weight: bold; display: flex; justify-content: space-between;"> <label style="font-weight: bold; display: flex; justify-content: space-between;">
Automated Backups Automated Backups
@@ -94,6 +97,7 @@
<button class="btn btn-secondary" style="color: #94a3b8; border-color: #cbd5e1;" onclick="showUpsell('Automated DB Backups')">🔒 Apply</button> <button class="btn btn-secondary" style="color: #94a3b8; border-color: #cbd5e1;" onclick="showUpsell('Automated DB Backups')">🔒 Apply</button>
</div> </div>
</div> </div>
{{end}}
<div style="margin-bottom: 20px;"> <div style="margin-bottom: 20px;">
<label style="font-weight: bold;">Data Portability</label> <label style="font-weight: bold;">Data Portability</label>
+2
View File
@@ -8,9 +8,11 @@
</a> </a>
<a href="/dashboard?tab=chute" class="tab-btn {{if eq .CurrentTab "chute"}}active{{end}}">🤠 The Chute (Assigned)</a> <a href="/dashboard?tab=chute" class="tab-btn {{if eq .CurrentTab "chute"}}active{{end}}">🤠 The Chute (Assigned)</a>
{{block "pro_verification_tab" .}}
<a href="javascript:void(0)" onclick="showUpsell('E2E Exception & Verification Pipeline')" class="tab-btn" style="color: #94a3b8;"> <a href="javascript:void(0)" onclick="showUpsell('E2E Exception & Verification Pipeline')" class="tab-btn" style="color: #94a3b8;">
🔒 Pending Verification (Pro) 🔒 Pending Verification (Pro)
</a> </a>
{{end}}
<a href="/dashboard?tab=archives" class="tab-btn {{if eq .CurrentTab "archives"}}active{{end}}"> <a href="/dashboard?tab=archives" class="tab-btn {{if eq .CurrentTab "archives"}}active{{end}}">
🗄️ The Archives 🗄️ The Archives
+2 -2
View File
@@ -1,11 +1,12 @@
{{define "content"}} {{define "content"}}
<script> <script>
window.CurrentTab = "{{.CurrentTab}}"; window.CurrentTab = "{{.CurrentTab}}";
</script> </script>
{{template "dash_tabs" .}} {{template "dash_tabs" .}}
{{block "pro_risk_tab_content" .}}{{end}}
<div class="tab-pane active"> <div class="tab-pane active">
{{template "dash_table" .}} {{template "dash_table" .}}
</div> </div>
@@ -13,5 +14,4 @@
{{template "dash_modals" .}} {{template "dash_modals" .}}
<script src="/static/dashboard.js"></script> <script src="/static/dashboard.js"></script>
{{end}} {{end}}