70725193eb
Addresses findings from consolidated Phase 1 code review: - Add composite unique indexes + composite FKs so subscription_prompts and packages cannot reference mismatched (tenant_id, package_id, prompt_id) tuples, enforcing ACL lineage at the schema level. - Add status CHECK constraints on all KOL tables as defense-in-depth. - ListActiveSubscribersForPackage: drop meaningless tenant_id IS NOT NULL, add end_at expiry filter so fan-out skips expired subscribers. - ApproveKolSubscription: add status='pending' guard to prevent double-approval. - ListSubscriptionPromptsByTenant: join subscription/prompt/package/profile lifecycle so hidden/archived content no longer leaks; surface kol_display_name for UI. - ListPublishedKolPackages: exclude expired subscribers from marketplace count. - KolDashboardTrend: rewrite as CTE with day-series, returning both daily usage and new subscription counts. - Remove cosmetic tenant_id IS NOT NULL from dashboard overview queries (the column is NOT NULL by schema). - check_tenant_scope.sh: require tenant_id = sqlc.(n?)arg filter, reject tenant_id IS NOT NULL as a fake scope, maintain explicit exemption list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.4 KiB
Bash
Executable File
52 lines
1.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# CI guard: reject tenant-scoped SQL query files missing tenant_id = sqlc.(n?)arg filters.
|
|
# Files that are legitimately cross-tenant must be explicitly exempted.
|
|
# Usage: scripts/check_tenant_scope.sh
|
|
|
|
set -euo pipefail
|
|
|
|
QUERY_DIR="internal/tenant/repository/queries"
|
|
EXIT_CODE=0
|
|
|
|
# Files that are cross-tenant by design. Each must justify itself in a header comment.
|
|
EXEMPT=(
|
|
"audit.sql"
|
|
"kol_marketplace.sql"
|
|
"kol_usage.sql"
|
|
)
|
|
|
|
is_exempt() {
|
|
local name="$1"
|
|
for e in "${EXEMPT[@]}"; do
|
|
if [[ "$name" == "$e" ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
for f in "$QUERY_DIR"/*.sql; do
|
|
basename=$(basename "$f")
|
|
if is_exempt "$basename"; then
|
|
continue
|
|
fi
|
|
|
|
# Must contain at least one tenant_id = sqlc.arg(...) or sqlc.narg(...) filter.
|
|
if ! grep -Eq 'tenant_id[[:space:]]*=[[:space:]]*sqlc\.(n?arg)\(' "$f"; then
|
|
echo "ERROR: $f must filter on tenant_id = sqlc.(n?arg)(...)"
|
|
EXIT_CODE=1
|
|
fi
|
|
|
|
# Reject cosmetic "tenant_id IS NOT NULL" that bypasses actor scoping.
|
|
if grep -Eq 'tenant_id[[:space:]]+IS[[:space:]]+NOT[[:space:]]+NULL' "$f"; then
|
|
echo "ERROR: $f uses 'tenant_id IS NOT NULL' — this does not scope the actor"
|
|
EXIT_CODE=1
|
|
fi
|
|
done
|
|
|
|
if [ "$EXIT_CODE" -eq 0 ]; then
|
|
echo "All non-exempt query files contain tenant_id = sqlc.arg filters."
|
|
fi
|
|
|
|
exit $EXIT_CODE
|