chore: Apply dashboard audit remediations, sync engine counts, update APIs

This commit is contained in:
DmitrL-dev 2026-03-27 16:54:18 +10:00
parent 53c87c972d
commit 5ddfa74771
14 changed files with 354 additions and 153 deletions

View file

@ -65,12 +65,24 @@ func currentPeriod() (time.Time, time.Time) {
}
// RecordScan atomically increments the scan counter and checks quota.
// Returns remaining scans. Returns error if quota exceeded.
// Uses the free tier default limit (1000). For plan-aware quotas, use RecordScanWithLimit.
func (t *UsageTracker) RecordScan(userID, ip string) (int, error) {
return t.RecordScanWithLimit(userID, ip, 1000)
}
// RecordScanWithLimit atomically increments the scan counter and checks against planLimit.
// planLimit: -1=unlimited, 0=no scans allowed, >0=monthly cap.
// Returns remaining scans. Returns error if quota exceeded.
func (t *UsageTracker) RecordScanWithLimit(userID, ip string, planLimit int) (int, error) {
if t.db == nil {
return 999, nil // no DB = no limits
}
// Plan explicitly forbids scanning
if planLimit == 0 {
return 0, fmt.Errorf("scanning not available on current plan")
}
t.mu.Lock()
defer t.mu.Unlock()
@ -84,6 +96,12 @@ func (t *UsageTracker) RecordScan(userID, ip string) (int, error) {
lookupVal = userID
}
// Resolve effective limit for DB storage (unlimited = 0 sentinel in DB)
dbLimit := planLimit
if planLimit < 0 {
dbLimit = 0 // 0 in DB = unlimited
}
// Try to get existing quota record for current period
var scansUsed, scansLimit int
var quotaID string
@ -94,10 +112,14 @@ func (t *UsageTracker) RecordScan(userID, ip string) (int, error) {
err := t.db.QueryRow(query, lookupVal, periodStart).Scan(&quotaID, &scansUsed, &scansLimit)
if err == sql.ErrNoRows {
// Create new quota record
// Create new quota record with plan-based limit
quotaID = generateID("usg")
plan := "free"
limit := 1000
if planLimit > 1000 {
plan = "paid"
} else if planLimit < 0 {
plan = "unlimited"
}
var insertQuery string
if userID != "" {
insertQuery = `INSERT INTO usage_quotas (id, user_id, plan, scans_used, scans_limit, period_start, period_end)
@ -106,12 +128,15 @@ func (t *UsageTracker) RecordScan(userID, ip string) (int, error) {
insertQuery = `INSERT INTO usage_quotas (id, ip_addr, plan, scans_used, scans_limit, period_start, period_end)
VALUES ($1, $2, $3, 1, $4, $5, $6)`
}
_, err = t.db.Exec(insertQuery, quotaID, lookupVal, plan, limit, periodStart, periodEnd)
_, err = t.db.Exec(insertQuery, quotaID, lookupVal, plan, dbLimit, periodStart, periodEnd)
if err != nil {
slog.Error("usage: create quota", "error", err)
return 999, nil // fail open — don't block on DB errors
}
return limit - 1, nil
if planLimit < 0 {
return -1, nil // unlimited
}
return planLimit - 1, nil
}
if err != nil {
@ -119,7 +144,13 @@ func (t *UsageTracker) RecordScan(userID, ip string) (int, error) {
return 999, nil // fail open
}
// Unlimited plan (scans_limit = 0)
// Update stored limit if plan changed (e.g. upgrade mid-month)
if scansLimit != dbLimit {
t.db.Exec(`UPDATE usage_quotas SET scans_limit = $1 WHERE id = $2`, dbLimit, quotaID)
scansLimit = dbLimit
}
// Unlimited plan (scans_limit = 0 in DB)
if scansLimit == 0 {
t.db.Exec(`UPDATE usage_quotas SET scans_used = scans_used + 1 WHERE id = $1`, quotaID)
return -1, nil // unlimited
@ -127,7 +158,7 @@ func (t *UsageTracker) RecordScan(userID, ip string) (int, error) {
// Check quota
if scansUsed >= scansLimit {
return 0, fmt.Errorf("quota exceeded: %d/%d scans used this month", scansUsed, scansLimit)
return 0, fmt.Errorf("quota exceeded: %d/%d scans used this month — upgrade at syntrex.pro/pricing", scansUsed, scansLimit)
}
// Increment