@daniellins/power-claude 0.16.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @daniellins/power-claude might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.md +121 -0
- package/bin/cli.js +124 -0
- package/installer/__tests__/doctor-ready-oracles.test.cjs +140 -0
- package/installer/__tests__/merge-settings.test.cjs +330 -0
- package/installer/adopt.js +161 -0
- package/installer/copy.js +203 -0
- package/installer/doctor.js +266 -0
- package/installer/install.js +155 -0
- package/installer/manifest.js +102 -0
- package/installer/motor-scripts.js +50 -0
- package/installer/motor-scripts.json +39 -0
- package/installer/uninstall.js +99 -0
- package/installer/update.js +376 -0
- package/installer/util.js +113 -0
- package/installer/wizard.js +64 -0
- package/package.json +26 -0
- package/scripts/__fixtures__/anti-path-demo/agents/ap-writer.md +13 -0
- package/scripts/__fixtures__/anti-path-demo/templates/write-tmpl.md +7 -0
- package/scripts/__fixtures__/anti-path-demo/workflows/wf-ap.smoke.json +10 -0
- package/scripts/__fixtures__/anti-path-demo/workflows/wf-ap.yaml +25 -0
- package/scripts/__fixtures__/assess-tier/retrofit-leve/pod/agents/content-chief.md +1 -0
- package/scripts/__fixtures__/assess-tier/retrofit-leve/pod/workflows/wf-criacao-redteam.yaml +3 -0
- package/scripts/__fixtures__/assess-tier/retrofit-leve/pod-spec.json +13 -0
- package/scripts/__fixtures__/fidelity/fake-green-average-in-band.yaml +21 -0
- package/scripts/__fixtures__/fidelity/fake-green-average.yaml +18 -0
- package/scripts/__fixtures__/fidelity/fake-green-denominator.yaml +19 -0
- package/scripts/__fixtures__/fidelity/fake-green-missing-evidence.yaml +18 -0
- package/scripts/__fixtures__/fidelity/fake-green-threshold.yaml +18 -0
- package/scripts/__fixtures__/fidelity/fake-green-weight.yaml +18 -0
- package/scripts/__fixtures__/fidelity/golden.yaml +31 -0
- package/scripts/__fixtures__/fidelity/trindade-incoherent.yaml +15 -0
- package/scripts/__fixtures__/forge-canonical/pod-spec-example.json +37 -0
- package/scripts/__fixtures__/migrate-squad/authored/agents/offer-engineer.md +17 -0
- package/scripts/__fixtures__/migrate-squad/authored/knowledge/no-source.md +7 -0
- package/scripts/__fixtures__/migrate-squad/authored/knowledge/value-stack-method.md +8 -0
- package/scripts/__fixtures__/migrate-squad/authored/specs/wf-sample.smoke.json +24 -0
- package/scripts/__fixtures__/migrate-squad/authored/specs/wf-sample.spec.json +45 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/HEADLINE.md +3 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/README.md +4 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/agents/hormozi-offer.md +14 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/dead-redundant.md +4 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/method-guide.md +6 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/checklists/veto-screen.md +4 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/config/config.yaml +2 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/data/case-library.md +3 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/scripts/validate-mvn.py +16 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/sops/sop-sample.md +3 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/squad-io.yaml +14 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/tasks/gather-context.md +7 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/templates/output-tmpl.md +5 -0
- package/scripts/__fixtures__/migrate-squad/legacy-squad/workflows/wf-sample.yaml +24 -0
- package/scripts/__fixtures__/pipeline/pipelines/pipeline-checkpoint.yaml +21 -0
- package/scripts/__fixtures__/pipeline/pipelines/pipeline-demo.yaml +22 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/agents/maker.md +13 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/memory/learnings.consolidated.md +8 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/memory/learnings.jsonl +83 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/templates/make-tmpl.md +8 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-a/workflows/wf-a.yaml +16 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/agents/user.md +13 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/memory/learnings.consolidated.md +8 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/memory/learnings.jsonl +14 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/templates/use-tmpl.md +6 -0
- package/scripts/__fixtures__/pipeline/pods/pipe-b/workflows/wf-b.yaml +16 -0
- package/scripts/__fixtures__/pod-run/agents/forge-chief.md +13 -0
- package/scripts/__fixtures__/pod-run/agents/pod-critic.md +13 -0
- package/scripts/__fixtures__/pod-run/templates/build-tmpl.md +8 -0
- package/scripts/__fixtures__/pod-run/templates/gate-tmpl.md +6 -0
- package/scripts/__fixtures__/pod-run/workflows/wf-min.yaml +43 -0
- package/scripts/__fixtures__/pod-run/workflows/wf-skip-modes.yaml +50 -0
- package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-all-skippable.yaml +30 -0
- package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-criteria-escalar-de-bloco.yaml +40 -0
- package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-skip-mode-desconhecido.yaml +30 -0
- package/scripts/__fixtures__/pod-workflow/invalid-checkpoint-unknown-key.yaml +29 -0
- package/scripts/__fixtures__/pod-workflow/invalid-cycle.yaml +26 -0
- package/scripts/__fixtures__/pod-workflow/invalid-fix-loop-backedge.yaml +29 -0
- package/scripts/__fixtures__/pod-workflow/invalid-fix-loop-forward.yaml +29 -0
- package/scripts/__fixtures__/pod-workflow/invalid-handoff-open.yaml +27 -0
- package/scripts/__fixtures__/pod-workflow/invalid-knowledge-shape.yaml +18 -0
- package/scripts/__fixtures__/pod-workflow/invalid-missing-agent.yaml +15 -0
- package/scripts/__fixtures__/pod-workflow/invalid-missing-outputs.yaml +15 -0
- package/scripts/__fixtures__/pod-workflow/invalid-missing-template.yaml +15 -0
- package/scripts/__fixtures__/pod-workflow/invalid-missing-veto.yaml +13 -0
- package/scripts/__fixtures__/pod-workflow/invalid-template-not-on-disk.yaml +16 -0
- package/scripts/__fixtures__/pod-workflow/invalid-veto-prose.yaml +17 -0
- package/scripts/__fixtures__/pod-workflow/knowledge/a.md +4 -0
- package/scripts/__fixtures__/pod-workflow/knowledge/b.md +4 -0
- package/scripts/__fixtures__/pod-workflow/knowledge/c.md +4 -0
- package/scripts/__fixtures__/pod-workflow/templates/step-tmpl.md +7 -0
- package/scripts/__fixtures__/pod-workflow/valid-checkpoint-skip-modes.yaml +29 -0
- package/scripts/__fixtures__/pod-workflow/valid-fix-loop.yaml +30 -0
- package/scripts/__fixtures__/pod-workflow/valid-knowledge.yaml +30 -0
- package/scripts/__fixtures__/pod-workflow/valid-veto-always-true.yaml +20 -0
- package/scripts/__fixtures__/pod-workflow/valid.yaml +27 -0
- package/scripts/__fixtures__/smoke-canary/agents/canary-reporter.md +13 -0
- package/scripts/__fixtures__/smoke-canary/agents/canary-researcher.md +13 -0
- package/scripts/__fixtures__/smoke-canary/agents/canary-synth.md +13 -0
- package/scripts/__fixtures__/smoke-canary/memory/learnings.consolidated.md +10 -0
- package/scripts/__fixtures__/smoke-canary/memory/learnings.jsonl +448 -0
- package/scripts/__fixtures__/smoke-canary/templates/report-tmpl.md +9 -0
- package/scripts/__fixtures__/smoke-canary/templates/research-tmpl.md +7 -0
- package/scripts/__fixtures__/smoke-canary/templates/synth-tmpl.md +9 -0
- package/scripts/__fixtures__/smoke-canary/workflows/wf-canary.smoke.json +11 -0
- package/scripts/__fixtures__/smoke-canary/workflows/wf-canary.yaml +53 -0
- package/scripts/__fixtures__/source-audit/fake-green-bronze-unsignaled.yaml +10 -0
- package/scripts/__fixtures__/source-audit/fake-green-counts.yaml +9 -0
- package/scripts/__fixtures__/source-audit/fake-green-missing-evidence.yaml +9 -0
- package/scripts/__fixtures__/source-audit/fake-green-unclassified.yaml +10 -0
- package/scripts/__fixtures__/source-audit/fake-green-verdict.yaml +10 -0
- package/scripts/__fixtures__/source-audit/golden-blocked.yaml +10 -0
- package/scripts/__fixtures__/source-audit/golden.yaml +11 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-count.md +13 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-field.md +13 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-fileref.md +13 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-json.md +13 -0
- package/scripts/__fixtures__/sweep-forms/agents/forms-section.md +13 -0
- package/scripts/__fixtures__/sweep-forms/specs/wf-forms.spec.json +5 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_count.md +5 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_field.md +3 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_fileref.md +3 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_json.md +0 -0
- package/scripts/__fixtures__/sweep-forms/templates/t_section.md +3 -0
- package/scripts/__fixtures__/sweep-forms/workflows/wf-forms.smoke.json +13 -0
- package/scripts/__fixtures__/sweep-forms/workflows/wf-forms.yaml +67 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-1-noop-state-json.fixture.md +18 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-2-crash-buildworkflowyaml.fixture.md +26 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-3-nasce-verde-skip-modes.fixture.md +29 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-4-guarda-sem-irmao.fixture.md +17 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-5a-diff-stat-sem-guarda.fixture.md +17 -0
- package/scripts/__fixtures__/validate-story-acs-corpus/corpus-5b-test-f-sobre-diretorio.fixture.md +20 -0
- package/scripts/__fixtures__/veto-checks/copy-clean.md +4 -0
- package/scripts/__fixtures__/veto-checks/copy-dashes.md +4 -0
- package/scripts/__fixtures__/veto-checks/n8n-bad.md +18 -0
- package/scripts/__fixtures__/veto-checks/n8n-ok.md +22 -0
- package/scripts/__fixtures__/veto-checks/page-bad.html +7 -0
- package/scripts/__fixtures__/veto-checks/phash/copy.png +0 -0
- package/scripts/__fixtures__/veto-checks/phash/distinct.png +0 -0
- package/scripts/__fixtures__/veto-checks/phash/distinct2.png +0 -0
- package/scripts/__fixtures__/veto-checks/phash/make-fixtures.cjs +203 -0
- package/scripts/__fixtures__/veto-checks/phash/ref.png +0 -0
- package/scripts/__fixtures__/veto-checks/slide-ok.html +15 -0
- package/scripts/__fixtures__/veto-checks/slide-overflow.html +14 -0
- package/scripts/__fixtures__/veto-checks/sweep-pod/agents/vc-checker.md +13 -0
- package/scripts/__fixtures__/veto-checks/sweep-pod/templates/check-tmpl.md +6 -0
- package/scripts/__fixtures__/veto-checks/sweep-pod/workflows/wf-vc.smoke.json +10 -0
- package/scripts/__fixtures__/veto-checks/sweep-pod/workflows/wf-vc.yaml +19 -0
- package/scripts/__fixtures__/voz-do-dono/README.md +23 -0
- package/scripts/__fixtures__/voz-do-dono/dono-escalar.yaml +9 -0
- package/scripts/__fixtures__/voz-do-dono/dono-guia.yaml +10 -0
- package/scripts/__fixtures__/voz-do-dono/peca-3a-pessoa.md +6 -0
- package/scripts/__fixtures__/voz-do-dono/peca-com-lexico-proibido.md +6 -0
- package/scripts/__fixtures__/voz-do-dono/peca-limpa-1a-pessoa.md +6 -0
- package/scripts/__tests__/derive-ready-transitions.test.cjs +269 -0
- package/scripts/__tests__/enforce-cycle-authority.test.cjs +869 -0
- package/scripts/__tests__/enforce-git-push-authority.test.cjs +701 -0
- package/scripts/__tests__/enforce-ready-oracles.test.cjs +745 -0
- package/scripts/__tests__/motor-scripts.test.cjs +339 -0
- package/scripts/__tests__/pc-run-pod-counter.test.cjs +58 -0
- package/scripts/__tests__/pc-run-pod.test.cjs +578 -0
- package/scripts/__tests__/validate-pod-workflow.test.cjs +90 -0
- package/scripts/__tests__/validate-story-acs.test.cjs +607 -0
- package/scripts/anti-path.test.cjs +163 -0
- package/scripts/arena.cjs +514 -0
- package/scripts/arena.test.cjs +213 -0
- package/scripts/brief-leitura-obrigatoria.test.cjs +364 -0
- package/scripts/consolidate-knowledge-runner.test.cjs +249 -0
- package/scripts/default-funcional.test.cjs +153 -0
- package/scripts/derive-ready-transitions.cjs +325 -0
- package/scripts/forge-additive.test.cjs +158 -0
- package/scripts/forge-assess-tier.cjs +205 -0
- package/scripts/forge-assess-tier.test.cjs +114 -0
- package/scripts/forge-canonical.test.cjs +624 -0
- package/scripts/forge-generate.cjs +1303 -0
- package/scripts/forge-harden-learning.cjs +921 -0
- package/scripts/forge-harden-learning.test.cjs +242 -0
- package/scripts/forge-ingest-memory.cjs +136 -0
- package/scripts/forge-upgrade-pod.cjs +368 -0
- package/scripts/forge.test.cjs +609 -0
- package/scripts/harden-knowledge.test.cjs +612 -0
- package/scripts/harness-g5-lite.cjs +243 -0
- package/scripts/harness-g5-lite.test.cjs +134 -0
- package/scripts/hn-carousel-contrato-entrada.test.cjs +96 -0
- package/scripts/migrate-squad-orchestration.test.cjs +146 -0
- package/scripts/migration-manifest-sf3.2.test.cjs +382 -0
- package/scripts/migration-manifest-sf3.3.test.cjs +170 -0
- package/scripts/migration-manifest-sf5.5.test.cjs +189 -0
- package/scripts/migration-manifest.cjs +1146 -0
- package/scripts/migration-manifest.test.cjs +186 -0
- package/scripts/npm-scope-invocation.test.cjs +194 -0
- package/scripts/owner-layer.cjs +442 -0
- package/scripts/owner-layer.test.cjs +358 -0
- package/scripts/pc-run-pipeline.cjs +289 -0
- package/scripts/pc-run-pipeline.test.cjs +256 -0
- package/scripts/pc-run-pod-countgte.test.cjs +66 -0
- package/scripts/pc-run-pod.cjs +1355 -0
- package/scripts/phash-gate.test.cjs +433 -0
- package/scripts/pod-export-compile.cjs +487 -0
- package/scripts/pod-export-compile.test.cjs +312 -0
- package/scripts/pod-export-executor.cjs +678 -0
- package/scripts/pod-export-executor.test.cjs +1341 -0
- package/scripts/pod-export-hardening.test.cjs +531 -0
- package/scripts/pod-export-postprocess.cjs +427 -0
- package/scripts/pod-export-postprocess.test.cjs +558 -0
- package/scripts/pod-export-queue-race.test.cjs +865 -0
- package/scripts/pod-export-release.cjs +473 -0
- package/scripts/pod-export-release.test.cjs +267 -0
- package/scripts/pod-export-service.cjs +1297 -0
- package/scripts/pod-export-service.test.cjs +489 -0
- package/scripts/pod-export-tools.cjs +470 -0
- package/scripts/pod-export-ui.cjs +805 -0
- package/scripts/pod-export-ui.test.cjs +301 -0
- package/scripts/pod-memory-budget.test.cjs +309 -0
- package/scripts/pod-memory-note.cjs +357 -0
- package/scripts/pod-memory-note.test.cjs +452 -0
- package/scripts/pod-memory.cjs +1252 -0
- package/scripts/pod-memory.test.cjs +951 -0
- package/scripts/render-png.test.cjs +307 -0
- package/scripts/smoke-isolation.test.cjs +100 -0
- package/scripts/smoke-pod-workflow.cjs +755 -0
- package/scripts/smoke-sweep.test.cjs +170 -0
- package/scripts/validate-adopt.js +235 -0
- package/scripts/validate-branding.js +84 -0
- package/scripts/validate-budgets.js +140 -0
- package/scripts/validate-fidelity-output.cjs +267 -0
- package/scripts/validate-fidelity-output.test.cjs +101 -0
- package/scripts/validate-install.js +230 -0
- package/scripts/validate-no-clone.cjs +220 -0
- package/scripts/validate-no-clone.test.cjs +77 -0
- package/scripts/validate-pipeline.cjs +145 -0
- package/scripts/validate-pod-workflow.cjs +878 -0
- package/scripts/validate-source-audit.cjs +170 -0
- package/scripts/validate-source-audit.test.cjs +90 -0
- package/scripts/validate-story-acs.cjs +862 -0
- package/scripts/validate-update-scope-motor.js +421 -0
- package/scripts/veto-checks/html-valid.cjs +92 -0
- package/scripts/veto-checks/lexical-check.cjs +62 -0
- package/scripts/veto-checks/phash-gate.cjs +589 -0
- package/scripts/veto-checks/render-gate.cjs +165 -0
- package/scripts/veto-checks/render-png.cjs +358 -0
- package/scripts/veto-checks.test.cjs +219 -0
- package/scripts/watcher-audit.cjs +178 -0
- package/template/.claude/CLAUDE.md +103 -0
- package/template/.claude/agents/pc-analyst.md +100 -0
- package/template/.claude/agents/pc-architect.md +32 -0
- package/template/.claude/agents/pc-dev.md +27 -0
- package/template/.claude/agents/pc-devops.md +45 -0
- package/template/.claude/agents/pc-planner.md +32 -0
- package/template/.claude/agents/pc-po.md +25 -0
- package/template/.claude/agents/pc-qa.md +25 -0
- package/template/.claude/commands/power/academy.md +9 -0
- package/template/.claude/commands/power/automation.md +9 -0
- package/template/.claude/commands/power/content-carousel.md +267 -0
- package/template/.claude/commands/power/content.md +9 -0
- package/template/.claude/commands/power/dev.md +9 -0
- package/template/.claude/commands/power/forge.md +224 -0
- package/template/.claude/commands/power/hormozi.md +221 -0
- package/template/.claude/commands/power/modo.md +57 -0
- package/template/.claude/hooks/README.md +114 -0
- package/template/.claude/hooks/context-budget.cjs +64 -0
- package/template/.claude/hooks/enforce-cycle-authority.cjs +457 -0
- package/template/.claude/hooks/enforce-git-push-authority.cjs +925 -0
- package/template/.claude/hooks/enforce-ready-oracles.cjs +502 -0
- package/template/.claude/rules/authority.md +76 -0
- package/template/.claude/rules/curadoria-de-conhecimento.md +30 -0
- package/template/.claude/rules/model-matrix.md +34 -0
- package/template/.claude/rules/orchestration.md +133 -0
- package/template/.claude/settings.json +50 -0
- package/template/.claude/skills/pc-apply-qa-fixes/SKILL.md +108 -0
- package/template/.claude/skills/pc-apply-qa-fixes/references/fix-loop.md +40 -0
- package/template/.claude/skills/pc-apply-qa-fixes/references/fix-request-template.md +70 -0
- package/template/.claude/skills/pc-arena/SKILL.md +96 -0
- package/template/.claude/skills/pc-close-story/SKILL.md +105 -0
- package/template/.claude/skills/pc-commit/SKILL.md +108 -0
- package/template/.claude/skills/pc-develop-story/SKILL.md +116 -0
- package/template/.claude/skills/pc-full-cycle/SKILL.md +150 -0
- package/template/.claude/skills/pc-pipeline/SKILL.md +63 -0
- package/template/.claude/skills/pc-pipeline/references/gate-templates.md +46 -0
- package/template/.claude/skills/pc-review-story/SKILL.md +129 -0
- package/template/.claude/skills/pc-review-story/references/false-positive-detection.md +50 -0
- package/template/.claude/skills/pc-review-story/references/nfr-assess.md +47 -0
- package/template/.claude/skills/pc-review-story/references/risk-profile.md +75 -0
- package/template/.claude/skills/pc-review-story/references/security-checklist.md +69 -0
- package/template/.claude/skills/pc-review-story/references/test-design.md +37 -0
- package/template/.claude/skills/pc-review-story/references/trace-requirements.md +46 -0
- package/template/.claude/skills/pc-run-pod/SKILL.md +123 -0
- package/template/.claude/skills/pc-validate-story/SKILL.md +114 -0
- package/template/.claude/skills/pc-wave/SKILL.md +133 -0
- package/template/.env.example +10 -0
- package/template/knowledge/analyst/brainstorming.md +40 -0
- package/template/knowledge/analyst/brief-skeleton.md +32 -0
- package/template/knowledge/analyst/competitor-skeleton.md +39 -0
- package/template/knowledge/analyst/elicitation-menu.md +49 -0
- package/template/knowledge/analyst/market-research-skeleton.md +36 -0
- package/template/knowledge/analyst/research-prompt-structure.md +48 -0
- package/template/knowledge/analyst/roi-skeleton.md +51 -0
- package/template/knowledge/voice-dna/README.md +99 -0
- package/template/knowledge/voice-dna/voice-dna.example.yaml +157 -0
- package/template/pods/README.md +64 -0
- package/template/pods/academy/README.md +37 -0
- package/template/pods/academy/agents/academy-chief.md +27 -0
- package/template/pods/academy/examples/palestra.example.md +142 -0
- package/template/pods/academy/pod-spec.json +44 -0
- package/template/pods/academy/templates/materiais-tmpl.md +17 -0
- package/template/pods/academy/templates/revisao-didatica-tmpl.md +20 -0
- package/template/pods/academy/workflows/wf-materiais-revisao.yaml +30 -0
- package/template/pods/authority-content/README.md +43 -0
- package/template/pods/authority-content/agents/content-chief.md +28 -0
- package/template/pods/authority-content/pod-spec.json +45 -0
- package/template/pods/authority-content/templates/criacao-na-voz-tmpl.md +17 -0
- package/template/pods/authority-content/templates/red-team-factual-tmpl.md +23 -0
- package/template/pods/authority-content/workflows/wf-criacao-redteam.yaml +30 -0
- package/template/pods/automation/README.md +37 -0
- package/template/pods/automation/agents/langgraph-architect.md +30 -0
- package/template/pods/automation/agents/n8n-architect.md +30 -0
- package/template/pods/automation/examples/README.md +46 -0
- package/template/pods/automation/examples/n8n-content-radar.example.json +380 -0
- package/template/pods/automation/knowledge/langgraph-patterns.md +126 -0
- package/template/pods/automation/knowledge/n8n-patterns.md +131 -0
- package/template/pods/automation/memory/README.md +16 -0
- package/template/pods/automation/memory/learnings.consolidated.md +8 -0
- package/template/pods/automation/memory/learnings.jsonl +0 -0
- package/template/pods/automation/pod-spec.json +109 -0
- package/template/pods/automation/specs/wf-langgraph-build.spec.json +107 -0
- package/template/pods/automation/squad-io.yaml +28 -0
- package/template/pods/automation/templates/lg-build-tmpl.md +17 -0
- package/template/pods/automation/templates/lg-design-tmpl.md +23 -0
- package/template/pods/automation/templates/lg-discover-tmpl.md +20 -0
- package/template/pods/automation/templates/lg-handoff-tmpl.md +20 -0
- package/template/pods/automation/templates/lg-test-tmpl.md +20 -0
- package/template/pods/automation/templates/n8n-build-tmpl.md +14 -0
- package/template/pods/automation/templates/n8n-design-tmpl.md +23 -0
- package/template/pods/automation/templates/n8n-discover-tmpl.md +20 -0
- package/template/pods/automation/templates/n8n-handoff-tmpl.md +20 -0
- package/template/pods/automation/templates/n8n-test-tmpl.md +20 -0
- package/template/pods/automation/workflows/wf-langgraph-build.smoke.json +11 -0
- package/template/pods/automation/workflows/wf-langgraph-build.yaml +64 -0
- package/template/pods/automation/workflows/wf-n8n-build.smoke.json +11 -0
- package/template/pods/automation/workflows/wf-n8n-build.yaml +65 -0
- package/template/pods/content-carousel/README.md +91 -0
- package/template/pods/content-carousel/agents/carousel-builder.md +28 -0
- package/template/pods/content-carousel/agents/carousel-visual.md +24 -0
- package/template/pods/content-carousel/agents/hn-curator.md +74 -0
- package/template/pods/content-carousel/config/heuristic-watcher-rubric.yaml +59 -0
- package/template/pods/content-carousel/knowledge/aquisicao-ancora.md +443 -0
- package/template/pods/content-carousel/knowledge/cta-brief.md +25 -0
- package/template/pods/content-carousel/knowledge/dono.example.yaml +45 -0
- package/template/pods/content-carousel/knowledge/identidade-visual-mascote.md +62 -0
- package/template/pods/content-carousel/knowledge/image-generation.md +62 -0
- package/template/pods/content-carousel/knowledge/selecao-de-ancora.md +60 -0
- package/template/pods/content-carousel/knowledge/slides-html.md +56 -0
- package/template/pods/content-carousel/memory/README.md +18 -0
- package/template/pods/content-carousel/memory/learnings.consolidated.md +6 -0
- package/template/pods/content-carousel/memory/learnings.jsonl +0 -0
- package/template/pods/content-carousel/pod-spec.json +100 -0
- package/template/pods/content-carousel/squad-io.yaml +10 -0
- package/template/pods/content-carousel/templates/assembly-tmpl.md +23 -0
- package/template/pods/content-carousel/templates/digest-tmpl.md +29 -0
- package/template/pods/content-carousel/templates/visuals-tmpl.md +20 -0
- package/template/pods/content-carousel/workflows/wf-content-carousel.smoke.json +23 -0
- package/template/pods/content-carousel/workflows/wf-content-carousel.yaml +80 -0
- package/template/pods/dev-ia/README.md +45 -0
- package/template/pods/dev-ia/agents/db-architect.md +33 -0
- package/template/pods/dev-ia/agents/ux-architect.md +29 -0
- package/template/pods/dev-ia/knowledge/db/migration-protocol.md +95 -0
- package/template/pods/dev-ia/knowledge/db/rls-patterns.md +101 -0
- package/template/pods/dev-ia/knowledge/db/schema-review-checklist.md +76 -0
- package/template/pods/dev-ia/memory/README.md +16 -0
- package/template/pods/dev-ia/memory/learnings.consolidated.md +8 -0
- package/template/pods/dev-ia/memory/learnings.jsonl +0 -0
- package/template/pods/dev-ia/pod-spec.json +34 -0
- package/template/pods/dev-ia/templates/schema-review-tmpl.md +23 -0
- package/template/pods/dev-ia/templates/ux-flow-review-tmpl.md +23 -0
- package/template/pods/dev-ia/tools/db-ops/backup-manager.sh +321 -0
- package/template/pods/dev-ia/tools/db-ops/best-practices-auditor.sh +534 -0
- package/template/pods/dev-ia/tools/db-ops/bootstrap-runner.sh +255 -0
- package/template/pods/dev-ia/tools/db-ops/data-loader.sh +616 -0
- package/template/pods/dev-ia/tools/db-ops/detect-database.sh +113 -0
- package/template/pods/dev-ia/tools/db-ops/explain-analyzer.sh +285 -0
- package/template/pods/dev-ia/tools/db-ops/health-checker.sh +323 -0
- package/template/pods/dev-ia/tools/db-ops/migration-runner.sh +308 -0
- package/template/pods/dev-ia/tools/db-ops/postgresql-schema-loader.sh +334 -0
- package/template/pods/dev-ia/tools/db-ops/query-runner.sh +171 -0
- package/template/pods/dev-ia/tools/db-ops/rls-policy-installer.sh +480 -0
- package/template/pods/dev-ia/tools/db-ops/rls-test-suite.sh +172 -0
- package/template/pods/dev-ia/tools/db-ops/schema-context-loader.sh +176 -0
- package/template/pods/hormozi-method/README.md +52 -0
- package/template/pods/hormozi-method/agents/acquisition-strategist.md +33 -0
- package/template/pods/hormozi-method/agents/conversion-copywriter.md +34 -0
- package/template/pods/hormozi-method/agents/monetization-architect.md +35 -0
- package/template/pods/hormozi-method/agents/offer-engineer.md +37 -0
- package/template/pods/hormozi-method/knowledge/core-four-leads.md +51 -0
- package/template/pods/hormozi-method/knowledge/grand-slam-offer.md +66 -0
- package/template/pods/hormozi-method/knowledge/growth-decision.md +38 -0
- package/template/pods/hormozi-method/knowledge/hooks-and-ads.md +56 -0
- package/template/pods/hormozi-method/knowledge/launch-email.md +31 -0
- package/template/pods/hormozi-method/knowledge/money-model.md +46 -0
- package/template/pods/hormozi-method/knowledge/opportunity-screening.md +44 -0
- package/template/pods/hormozi-method/knowledge/pages.md +25 -0
- package/template/pods/hormozi-method/knowledge/pos-lancamento-leads.md +56 -0
- package/template/pods/hormozi-method/knowledge/pricing.md +36 -0
- package/template/pods/hormozi-method/knowledge/retention-ltv.md +37 -0
- package/template/pods/hormozi-method/knowledge/scale-roadmap.md +35 -0
- package/template/pods/hormozi-method/knowledge/swipefiles-curados.md +44 -0
- package/template/pods/hormozi-method/knowledge/value-equation-diagnostic.md +77 -0
- package/template/pods/hormozi-method/memory/README.md +16 -0
- package/template/pods/hormozi-method/memory/learnings.consolidated.md +6 -0
- package/template/pods/hormozi-method/memory/learnings.jsonl +0 -0
- package/template/pods/hormozi-method/pod-spec.json +50 -0
- package/template/pods/hormozi-method/specs/wf-full-launch-sequence.spec.json +149 -0
- package/template/pods/hormozi-method/specs/wf-lead-magnet-pipeline.spec.json +125 -0
- package/template/pods/hormozi-method/specs/wf-money-model-design.spec.json +117 -0
- package/template/pods/hormozi-method/specs/wf-paid-ads-campaign.spec.json +132 -0
- package/template/pods/hormozi-method/specs/wf-scaling-diagnostic.spec.json +121 -0
- package/template/pods/hormozi-method/squad-io.yaml +43 -0
- package/template/pods/hormozi-method/templates/conversion-copywriter-tmpl.md +20 -0
- package/template/pods/hormozi-method/templates/launch-execucao-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/launch-fechamento-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/launch-pos-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/launch-preparacao-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/lm-copy-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/lm-distribuicao-tmpl.md +18 -0
- package/template/pods/hormozi-method/templates/lm-estrategia-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/mm-arquitetura-tmpl.md +18 -0
- package/template/pods/hormozi-method/templates/mm-copy-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/mm-diagnostico-tmpl.md +14 -0
- package/template/pods/hormozi-method/templates/monetization-architect-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/offer-engineer-tmpl.md +20 -0
- package/template/pods/hormozi-method/templates/paid-criativos-tmpl.md +19 -0
- package/template/pods/hormozi-method/templates/paid-fundacao-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/paid-teste-escala-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/scaling-diagnostico-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/scaling-priorizacao-tmpl.md +17 -0
- package/template/pods/hormozi-method/templates/scaling-roadmap-tmpl.md +17 -0
- package/template/pods/hormozi-method/workflows/wf-full-launch-sequence.smoke.json +12 -0
- package/template/pods/hormozi-method/workflows/wf-full-launch-sequence.yaml +56 -0
- package/template/pods/hormozi-method/workflows/wf-grand-slam-offer.smoke.json +11 -0
- package/template/pods/hormozi-method/workflows/wf-grand-slam-offer.yaml +45 -0
- package/template/pods/hormozi-method/workflows/wf-lead-magnet-pipeline.smoke.json +9 -0
- package/template/pods/hormozi-method/workflows/wf-lead-magnet-pipeline.yaml +45 -0
- package/template/pods/hormozi-method/workflows/wf-money-model-design.smoke.json +11 -0
- package/template/pods/hormozi-method/workflows/wf-money-model-design.yaml +45 -0
- package/template/pods/hormozi-method/workflows/wf-paid-ads-campaign.smoke.json +9 -0
- package/template/pods/hormozi-method/workflows/wf-paid-ads-campaign.yaml +46 -0
- package/template/pods/hormozi-method/workflows/wf-scaling-diagnostic.smoke.json +11 -0
- package/template/pods/hormozi-method/workflows/wf-scaling-diagnostic.yaml +44 -0
- package/template/pods/squad-forge/README.md +53 -0
- package/template/pods/squad-forge/agents/forge-chief.md +31 -0
- package/template/pods/squad-forge/agents/mind-extractor.md +29 -0
- package/template/pods/squad-forge/agents/pod-critic.md +26 -0
- package/template/pods/squad-forge/config/heuristic-watcher-rubric.yaml +74 -0
- package/template/pods/squad-forge/knowledge/fidelity-rubric.yaml +176 -0
- package/template/pods/squad-forge/knowledge/g6-memory-check.md +17 -0
- package/template/pods/squad-forge/knowledge/memory-ingest.md +16 -0
- package/template/pods/squad-forge/knowledge/source-audit-rubric.yaml +60 -0
- package/template/pods/squad-forge/memory/README.md +16 -0
- package/template/pods/squad-forge/memory/learnings.consolidated.md +8 -0
- package/template/pods/squad-forge/memory/learnings.jsonl +0 -0
- package/template/pods/squad-forge/pod-spec.json +166 -0
- package/template/pods/squad-forge/squad-io.yaml +13 -0
- package/template/pods/squad-forge/tasks/pipeline.md +158 -0
- package/template/pods/squad-forge/templates/discovery-tmpl.md +40 -0
- package/template/pods/squad-forge/templates/generation-tmpl.md +18 -0
- package/template/pods/squad-forge/templates/red-team-tmpl.md +17 -0
- package/template/pods/squad-forge/templates/register-tmpl.md +17 -0
- package/template/pods/squad-forge/templates/workflow-tmpl.yaml +101 -0
- package/template/pods/squad-forge/workflows/wf-forge.smoke.json +12 -0
- package/template/pods/squad-forge/workflows/wf-forge.yaml +60 -0
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# RLS Policy Installer - Apply standardized RLS policies to tables
|
|
3
|
+
# Economia: ~80% dos tokens vs criaรงรฃo manual de polรญticas
|
|
4
|
+
# Uso: ./rls-policy-installer.sh <table_name> <policy_type> [owner_column]
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Colors
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
CYAN='\033[0;36m'
|
|
14
|
+
NC='\033[0m'
|
|
15
|
+
|
|
16
|
+
# Check requirements
|
|
17
|
+
if [ -z "${SUPABASE_DB_URL:-}" ]; then
|
|
18
|
+
echo -e "${RED}ERROR: SUPABASE_DB_URL not set${NC}"
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Parse arguments
|
|
23
|
+
TABLE_NAME="${1:-}"
|
|
24
|
+
POLICY_TYPE="${2:-}"
|
|
25
|
+
OWNER_COLUMN="${3:-user_id}"
|
|
26
|
+
|
|
27
|
+
if [ -z "$TABLE_NAME" ] || [ -z "$POLICY_TYPE" ]; then
|
|
28
|
+
echo "Usage: $0 <table_name> <policy_type> [owner_column]"
|
|
29
|
+
echo ""
|
|
30
|
+
echo "Policy types:"
|
|
31
|
+
echo " kiss - Simple KISS policy (all operations check owner)"
|
|
32
|
+
echo " read-only - Public read, owner write"
|
|
33
|
+
echo " private - Owner only for all operations"
|
|
34
|
+
echo " team - Team-based access with roles"
|
|
35
|
+
echo " custom - Interactive custom policy builder"
|
|
36
|
+
echo ""
|
|
37
|
+
echo "Examples:"
|
|
38
|
+
echo " $0 users kiss"
|
|
39
|
+
echo " $0 sources read-only user_id"
|
|
40
|
+
echo " $0 fragments private owner_id"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
echo "๐ RLS Policy Installer v1.0"
|
|
45
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
46
|
+
echo "Table: $TABLE_NAME"
|
|
47
|
+
echo "Policy Type: $POLICY_TYPE"
|
|
48
|
+
echo "Owner Column: $OWNER_COLUMN"
|
|
49
|
+
echo ""
|
|
50
|
+
|
|
51
|
+
# Step 1: Validate table exists
|
|
52
|
+
echo -e "${BLUE}[1/5] Validating table...${NC}"
|
|
53
|
+
|
|
54
|
+
TABLE_EXISTS=$(psql "$SUPABASE_DB_URL" -t -A -c "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = '$TABLE_NAME');" 2>/dev/null)
|
|
55
|
+
|
|
56
|
+
if [ "$TABLE_EXISTS" != "t" ]; then
|
|
57
|
+
echo -e "${RED}ERROR: Table '$TABLE_NAME' does not exist${NC}"
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Check if owner column exists
|
|
62
|
+
COLUMN_EXISTS=$(psql "$SUPABASE_DB_URL" -t -A -c "SELECT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '$TABLE_NAME' AND column_name = '$OWNER_COLUMN');" 2>/dev/null)
|
|
63
|
+
|
|
64
|
+
if [ "$COLUMN_EXISTS" != "t" ]; then
|
|
65
|
+
echo -e "${YELLOW}WARNING: Column '$OWNER_COLUMN' not found in table${NC}"
|
|
66
|
+
echo "Available columns:"
|
|
67
|
+
psql "$SUPABASE_DB_URL" -t -A -c "SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '$TABLE_NAME' ORDER BY ordinal_position;" 2>/dev/null | head -10
|
|
68
|
+
echo ""
|
|
69
|
+
read -p "Enter correct owner column name (or press Enter to skip): " NEW_COLUMN
|
|
70
|
+
if [ -n "$NEW_COLUMN" ]; then
|
|
71
|
+
OWNER_COLUMN="$NEW_COLUMN"
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
echo -e " ${GREEN}โ Table validated${NC}"
|
|
76
|
+
|
|
77
|
+
# Step 2: Check current RLS status
|
|
78
|
+
echo -e "${BLUE}[2/5] Checking current RLS status...${NC}"
|
|
79
|
+
|
|
80
|
+
RLS_ENABLED=$(psql "$SUPABASE_DB_URL" -t -A -c "SELECT rowsecurity FROM pg_tables WHERE schemaname = 'public' AND tablename = '$TABLE_NAME';" 2>/dev/null)
|
|
81
|
+
EXISTING_POLICIES=$(psql "$SUPABASE_DB_URL" -t -A -c "SELECT COUNT(*) FROM pg_policies WHERE schemaname = 'public' AND tablename = '$TABLE_NAME';" 2>/dev/null)
|
|
82
|
+
|
|
83
|
+
if [ "$RLS_ENABLED" = "t" ]; then
|
|
84
|
+
echo -e " RLS Status: ${GREEN}ENABLED${NC}"
|
|
85
|
+
echo " Existing Policies: $EXISTING_POLICIES"
|
|
86
|
+
|
|
87
|
+
if [ "$EXISTING_POLICIES" -gt 0 ]; then
|
|
88
|
+
echo ""
|
|
89
|
+
echo " Current policies:"
|
|
90
|
+
psql "$SUPABASE_DB_URL" -t -A -c "SELECT policyname, cmd, permissive FROM pg_policies WHERE tablename = '$TABLE_NAME';" 2>/dev/null | sed 's/|/ - /g' | sed 's/^/ /'
|
|
91
|
+
|
|
92
|
+
echo ""
|
|
93
|
+
read -p " Remove existing policies? (y/N): " REMOVE_EXISTING
|
|
94
|
+
if [ "${REMOVE_EXISTING,,}" = "y" ]; then
|
|
95
|
+
REMOVE_POLICIES=true
|
|
96
|
+
else
|
|
97
|
+
REMOVE_POLICIES=false
|
|
98
|
+
fi
|
|
99
|
+
fi
|
|
100
|
+
else
|
|
101
|
+
echo -e " RLS Status: ${YELLOW}DISABLED${NC}"
|
|
102
|
+
REMOVE_POLICIES=false
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Step 3: Generate policy SQL
|
|
106
|
+
echo -e "${BLUE}[3/5] Generating policy SQL...${NC}"
|
|
107
|
+
|
|
108
|
+
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
109
|
+
POLICY_FILE="/tmp/rls_policy_${TABLE_NAME}_${TIMESTAMP}.sql"
|
|
110
|
+
|
|
111
|
+
cat > "$POLICY_FILE" << SQL
|
|
112
|
+
-- RLS Policy Installation for $TABLE_NAME
|
|
113
|
+
-- Type: $POLICY_TYPE
|
|
114
|
+
-- Generated: $(date)
|
|
115
|
+
-- ============================================
|
|
116
|
+
|
|
117
|
+
BEGIN;
|
|
118
|
+
|
|
119
|
+
-- Enable RLS if not already enabled
|
|
120
|
+
ALTER TABLE $TABLE_NAME ENABLE ROW LEVEL SECURITY;
|
|
121
|
+
|
|
122
|
+
SQL
|
|
123
|
+
|
|
124
|
+
# Remove existing policies if requested
|
|
125
|
+
if [ "$REMOVE_POLICIES" = true ]; then
|
|
126
|
+
cat >> "$POLICY_FILE" << SQL
|
|
127
|
+
|
|
128
|
+
-- Remove existing policies
|
|
129
|
+
DO \$\$
|
|
130
|
+
DECLARE
|
|
131
|
+
pol record;
|
|
132
|
+
BEGIN
|
|
133
|
+
FOR pol IN SELECT policyname FROM pg_policies WHERE tablename = '$TABLE_NAME'
|
|
134
|
+
LOOP
|
|
135
|
+
EXECUTE format('DROP POLICY IF EXISTS %I ON $TABLE_NAME', pol.policyname);
|
|
136
|
+
END LOOP;
|
|
137
|
+
END \$\$;
|
|
138
|
+
|
|
139
|
+
SQL
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
# Add policies based on type
|
|
143
|
+
case "$POLICY_TYPE" in
|
|
144
|
+
"kiss")
|
|
145
|
+
cat >> "$POLICY_FILE" << SQL
|
|
146
|
+
|
|
147
|
+
-- KISS Policy: Simple owner-based access
|
|
148
|
+
CREATE POLICY "${TABLE_NAME}_kiss_policy"
|
|
149
|
+
ON $TABLE_NAME
|
|
150
|
+
FOR ALL
|
|
151
|
+
TO authenticated
|
|
152
|
+
USING (
|
|
153
|
+
$OWNER_COLUMN = auth.uid()
|
|
154
|
+
OR
|
|
155
|
+
$OWNER_COLUMN IS NULL -- Allow NULL for initial inserts
|
|
156
|
+
)
|
|
157
|
+
WITH CHECK (
|
|
158
|
+
$OWNER_COLUMN = auth.uid()
|
|
159
|
+
OR
|
|
160
|
+
$OWNER_COLUMN IS NULL -- Auto-set on insert
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
-- Service role bypass (for admin operations)
|
|
164
|
+
CREATE POLICY "${TABLE_NAME}_service_role_bypass"
|
|
165
|
+
ON $TABLE_NAME
|
|
166
|
+
FOR ALL
|
|
167
|
+
TO service_role
|
|
168
|
+
USING (true)
|
|
169
|
+
WITH CHECK (true);
|
|
170
|
+
|
|
171
|
+
SQL
|
|
172
|
+
;;
|
|
173
|
+
|
|
174
|
+
"read-only")
|
|
175
|
+
cat >> "$POLICY_FILE" << SQL
|
|
176
|
+
|
|
177
|
+
-- Read-Only Policy: Public read, owner write
|
|
178
|
+
|
|
179
|
+
-- Everyone can read
|
|
180
|
+
CREATE POLICY "${TABLE_NAME}_public_read"
|
|
181
|
+
ON $TABLE_NAME
|
|
182
|
+
FOR SELECT
|
|
183
|
+
TO authenticated
|
|
184
|
+
USING (true);
|
|
185
|
+
|
|
186
|
+
-- Only owners can insert
|
|
187
|
+
CREATE POLICY "${TABLE_NAME}_owner_insert"
|
|
188
|
+
ON $TABLE_NAME
|
|
189
|
+
FOR INSERT
|
|
190
|
+
TO authenticated
|
|
191
|
+
WITH CHECK ($OWNER_COLUMN = auth.uid());
|
|
192
|
+
|
|
193
|
+
-- Only owners can update their records
|
|
194
|
+
CREATE POLICY "${TABLE_NAME}_owner_update"
|
|
195
|
+
ON $TABLE_NAME
|
|
196
|
+
FOR UPDATE
|
|
197
|
+
TO authenticated
|
|
198
|
+
USING ($OWNER_COLUMN = auth.uid())
|
|
199
|
+
WITH CHECK ($OWNER_COLUMN = auth.uid());
|
|
200
|
+
|
|
201
|
+
-- Only owners can delete their records
|
|
202
|
+
CREATE POLICY "${TABLE_NAME}_owner_delete"
|
|
203
|
+
ON $TABLE_NAME
|
|
204
|
+
FOR DELETE
|
|
205
|
+
TO authenticated
|
|
206
|
+
USING ($OWNER_COLUMN = auth.uid());
|
|
207
|
+
|
|
208
|
+
SQL
|
|
209
|
+
;;
|
|
210
|
+
|
|
211
|
+
"private")
|
|
212
|
+
cat >> "$POLICY_FILE" << SQL
|
|
213
|
+
|
|
214
|
+
-- Private Policy: Owner-only access for all operations
|
|
215
|
+
|
|
216
|
+
-- Owners can select their records
|
|
217
|
+
CREATE POLICY "${TABLE_NAME}_owner_select"
|
|
218
|
+
ON $TABLE_NAME
|
|
219
|
+
FOR SELECT
|
|
220
|
+
TO authenticated
|
|
221
|
+
USING ($OWNER_COLUMN = auth.uid());
|
|
222
|
+
|
|
223
|
+
-- Owners can insert
|
|
224
|
+
CREATE POLICY "${TABLE_NAME}_owner_insert"
|
|
225
|
+
ON $TABLE_NAME
|
|
226
|
+
FOR INSERT
|
|
227
|
+
TO authenticated
|
|
228
|
+
WITH CHECK ($OWNER_COLUMN = auth.uid() OR $OWNER_COLUMN IS NULL);
|
|
229
|
+
|
|
230
|
+
-- Owners can update their records
|
|
231
|
+
CREATE POLICY "${TABLE_NAME}_owner_update"
|
|
232
|
+
ON $TABLE_NAME
|
|
233
|
+
FOR UPDATE
|
|
234
|
+
TO authenticated
|
|
235
|
+
USING ($OWNER_COLUMN = auth.uid())
|
|
236
|
+
WITH CHECK ($OWNER_COLUMN = auth.uid());
|
|
237
|
+
|
|
238
|
+
-- Owners can delete their records
|
|
239
|
+
CREATE POLICY "${TABLE_NAME}_owner_delete"
|
|
240
|
+
ON $TABLE_NAME
|
|
241
|
+
FOR DELETE
|
|
242
|
+
TO authenticated
|
|
243
|
+
USING ($OWNER_COLUMN = auth.uid());
|
|
244
|
+
|
|
245
|
+
SQL
|
|
246
|
+
;;
|
|
247
|
+
|
|
248
|
+
"team")
|
|
249
|
+
cat >> "$POLICY_FILE" << SQL
|
|
250
|
+
|
|
251
|
+
-- Team Policy: Role-based access with team membership
|
|
252
|
+
|
|
253
|
+
-- Team members can read
|
|
254
|
+
CREATE POLICY "${TABLE_NAME}_team_read"
|
|
255
|
+
ON $TABLE_NAME
|
|
256
|
+
FOR SELECT
|
|
257
|
+
TO authenticated
|
|
258
|
+
USING (
|
|
259
|
+
EXISTS (
|
|
260
|
+
SELECT 1 FROM team_members tm
|
|
261
|
+
WHERE tm.user_id = auth.uid()
|
|
262
|
+
AND tm.team_id = (
|
|
263
|
+
SELECT team_id FROM $TABLE_NAME t
|
|
264
|
+
WHERE t.id = $TABLE_NAME.id
|
|
265
|
+
)
|
|
266
|
+
)
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
-- Team admins can insert
|
|
270
|
+
CREATE POLICY "${TABLE_NAME}_team_insert"
|
|
271
|
+
ON $TABLE_NAME
|
|
272
|
+
FOR INSERT
|
|
273
|
+
TO authenticated
|
|
274
|
+
WITH CHECK (
|
|
275
|
+
EXISTS (
|
|
276
|
+
SELECT 1 FROM team_members tm
|
|
277
|
+
WHERE tm.user_id = auth.uid()
|
|
278
|
+
AND tm.role IN ('admin', 'owner')
|
|
279
|
+
AND tm.team_id = NEW.team_id
|
|
280
|
+
)
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
-- Team admins can update
|
|
284
|
+
CREATE POLICY "${TABLE_NAME}_team_update"
|
|
285
|
+
ON $TABLE_NAME
|
|
286
|
+
FOR UPDATE
|
|
287
|
+
TO authenticated
|
|
288
|
+
USING (
|
|
289
|
+
EXISTS (
|
|
290
|
+
SELECT 1 FROM team_members tm
|
|
291
|
+
WHERE tm.user_id = auth.uid()
|
|
292
|
+
AND tm.role IN ('admin', 'owner')
|
|
293
|
+
AND tm.team_id = OLD.team_id
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
WITH CHECK (
|
|
297
|
+
EXISTS (
|
|
298
|
+
SELECT 1 FROM team_members tm
|
|
299
|
+
WHERE tm.user_id = auth.uid()
|
|
300
|
+
AND tm.role IN ('admin', 'owner')
|
|
301
|
+
AND tm.team_id = NEW.team_id
|
|
302
|
+
)
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
-- Team owners can delete
|
|
306
|
+
CREATE POLICY "${TABLE_NAME}_team_delete"
|
|
307
|
+
ON $TABLE_NAME
|
|
308
|
+
FOR DELETE
|
|
309
|
+
TO authenticated
|
|
310
|
+
USING (
|
|
311
|
+
EXISTS (
|
|
312
|
+
SELECT 1 FROM team_members tm
|
|
313
|
+
WHERE tm.user_id = auth.uid()
|
|
314
|
+
AND tm.role = 'owner'
|
|
315
|
+
AND tm.team_id = OLD.team_id
|
|
316
|
+
)
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
SQL
|
|
320
|
+
;;
|
|
321
|
+
|
|
322
|
+
"custom")
|
|
323
|
+
echo " Interactive custom policy builder:"
|
|
324
|
+
echo ""
|
|
325
|
+
|
|
326
|
+
# Get operations
|
|
327
|
+
read -p " Allow SELECT? (y/N): " ALLOW_SELECT
|
|
328
|
+
read -p " Allow INSERT? (y/N): " ALLOW_INSERT
|
|
329
|
+
read -p " Allow UPDATE? (y/N): " ALLOW_UPDATE
|
|
330
|
+
read -p " Allow DELETE? (y/N): " ALLOW_DELETE
|
|
331
|
+
|
|
332
|
+
# Build custom policies
|
|
333
|
+
if [ "${ALLOW_SELECT,,}" = "y" ]; then
|
|
334
|
+
cat >> "$POLICY_FILE" << SQL
|
|
335
|
+
|
|
336
|
+
CREATE POLICY "${TABLE_NAME}_custom_select"
|
|
337
|
+
ON $TABLE_NAME
|
|
338
|
+
FOR SELECT
|
|
339
|
+
TO authenticated
|
|
340
|
+
USING ($OWNER_COLUMN = auth.uid());
|
|
341
|
+
|
|
342
|
+
SQL
|
|
343
|
+
fi
|
|
344
|
+
|
|
345
|
+
if [ "${ALLOW_INSERT,,}" = "y" ]; then
|
|
346
|
+
cat >> "$POLICY_FILE" << SQL
|
|
347
|
+
|
|
348
|
+
CREATE POLICY "${TABLE_NAME}_custom_insert"
|
|
349
|
+
ON $TABLE_NAME
|
|
350
|
+
FOR INSERT
|
|
351
|
+
TO authenticated
|
|
352
|
+
WITH CHECK ($OWNER_COLUMN = auth.uid());
|
|
353
|
+
|
|
354
|
+
SQL
|
|
355
|
+
fi
|
|
356
|
+
|
|
357
|
+
if [ "${ALLOW_UPDATE,,}" = "y" ]; then
|
|
358
|
+
cat >> "$POLICY_FILE" << SQL
|
|
359
|
+
|
|
360
|
+
CREATE POLICY "${TABLE_NAME}_custom_update"
|
|
361
|
+
ON $TABLE_NAME
|
|
362
|
+
FOR UPDATE
|
|
363
|
+
TO authenticated
|
|
364
|
+
USING ($OWNER_COLUMN = auth.uid())
|
|
365
|
+
WITH CHECK ($OWNER_COLUMN = auth.uid());
|
|
366
|
+
|
|
367
|
+
SQL
|
|
368
|
+
fi
|
|
369
|
+
|
|
370
|
+
if [ "${ALLOW_DELETE,,}" = "y" ]; then
|
|
371
|
+
cat >> "$POLICY_FILE" << SQL
|
|
372
|
+
|
|
373
|
+
CREATE POLICY "${TABLE_NAME}_custom_delete"
|
|
374
|
+
ON $TABLE_NAME
|
|
375
|
+
FOR DELETE
|
|
376
|
+
TO authenticated
|
|
377
|
+
USING ($OWNER_COLUMN = auth.uid());
|
|
378
|
+
|
|
379
|
+
SQL
|
|
380
|
+
fi
|
|
381
|
+
;;
|
|
382
|
+
|
|
383
|
+
*)
|
|
384
|
+
echo -e "${RED}ERROR: Unknown policy type: $POLICY_TYPE${NC}"
|
|
385
|
+
exit 1
|
|
386
|
+
;;
|
|
387
|
+
esac
|
|
388
|
+
|
|
389
|
+
# Add verification queries
|
|
390
|
+
cat >> "$POLICY_FILE" << SQL
|
|
391
|
+
|
|
392
|
+
-- Verify policies were created
|
|
393
|
+
DO \$\$
|
|
394
|
+
DECLARE
|
|
395
|
+
policy_count INTEGER;
|
|
396
|
+
BEGIN
|
|
397
|
+
SELECT COUNT(*) INTO policy_count
|
|
398
|
+
FROM pg_policies
|
|
399
|
+
WHERE tablename = '$TABLE_NAME';
|
|
400
|
+
|
|
401
|
+
RAISE NOTICE 'Created % policies for table $TABLE_NAME', policy_count;
|
|
402
|
+
END \$\$;
|
|
403
|
+
|
|
404
|
+
COMMIT;
|
|
405
|
+
|
|
406
|
+
-- Test queries (run these manually to verify)
|
|
407
|
+
-- SET role authenticated;
|
|
408
|
+
-- SET request.jwt.claims = '{"sub": "test-user-id", "role": "authenticated"}';
|
|
409
|
+
-- SELECT * FROM $TABLE_NAME LIMIT 1;
|
|
410
|
+
-- RESET role;
|
|
411
|
+
-- RESET request.jwt.claims;
|
|
412
|
+
SQL
|
|
413
|
+
|
|
414
|
+
echo -e " ${GREEN}โ Policy SQL generated${NC}"
|
|
415
|
+
|
|
416
|
+
# Step 4: Apply policies
|
|
417
|
+
echo -e "${BLUE}[4/5] Applying policies...${NC}"
|
|
418
|
+
|
|
419
|
+
psql "$SUPABASE_DB_URL" -f "$POLICY_FILE" > /tmp/policy_install_log_$$.txt 2>&1
|
|
420
|
+
|
|
421
|
+
if [ $? -eq 0 ]; then
|
|
422
|
+
echo -e " ${GREEN}โ Policies applied successfully${NC}"
|
|
423
|
+
else
|
|
424
|
+
echo -e " ${RED}โ Failed to apply policies${NC}"
|
|
425
|
+
echo " Error log:"
|
|
426
|
+
tail -20 /tmp/policy_install_log_$$.txt | sed 's/^/ /'
|
|
427
|
+
exit 1
|
|
428
|
+
fi
|
|
429
|
+
|
|
430
|
+
# Step 5: Test policies
|
|
431
|
+
echo -e "${BLUE}[5/5] Testing policies...${NC}"
|
|
432
|
+
|
|
433
|
+
# Quick validation test
|
|
434
|
+
TEST_RESULT=$(psql "$SUPABASE_DB_URL" -t -A << SQL 2>/dev/null
|
|
435
|
+
-- Check RLS is enabled
|
|
436
|
+
SELECT json_build_object(
|
|
437
|
+
'rls_enabled', (SELECT rowsecurity FROM pg_tables WHERE tablename = '$TABLE_NAME'),
|
|
438
|
+
'policy_count', (SELECT COUNT(*) FROM pg_policies WHERE tablename = '$TABLE_NAME'),
|
|
439
|
+
'policies', (
|
|
440
|
+
SELECT json_agg(json_build_object(
|
|
441
|
+
'name', policyname,
|
|
442
|
+
'operation', cmd,
|
|
443
|
+
'type', CASE WHEN permissive THEN 'PERMISSIVE' ELSE 'RESTRICTIVE' END
|
|
444
|
+
))
|
|
445
|
+
FROM pg_policies
|
|
446
|
+
WHERE tablename = '$TABLE_NAME'
|
|
447
|
+
)
|
|
448
|
+
);
|
|
449
|
+
SQL
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
# Display results
|
|
453
|
+
if [ -n "$TEST_RESULT" ]; then
|
|
454
|
+
RLS_STATUS=$(echo "$TEST_RESULT" | jq -r '.rls_enabled')
|
|
455
|
+
POLICY_COUNT=$(echo "$TEST_RESULT" | jq -r '.policy_count')
|
|
456
|
+
|
|
457
|
+
if [ "$RLS_STATUS" = "true" ] && [ "$POLICY_COUNT" -gt 0 ]; then
|
|
458
|
+
echo -e " ${GREEN}โ RLS enabled with $POLICY_COUNT policies${NC}"
|
|
459
|
+
else
|
|
460
|
+
echo -e " ${YELLOW}โ Verification needed${NC}"
|
|
461
|
+
fi
|
|
462
|
+
fi
|
|
463
|
+
|
|
464
|
+
# Summary
|
|
465
|
+
echo ""
|
|
466
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
467
|
+
echo -e "${GREEN}โ
Policy Installation Complete!${NC}"
|
|
468
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
469
|
+
echo ""
|
|
470
|
+
echo "๐ Files created:"
|
|
471
|
+
echo " โข Policy SQL: $POLICY_FILE"
|
|
472
|
+
echo " โข Install log: /tmp/policy_install_log_$$.txt"
|
|
473
|
+
echo ""
|
|
474
|
+
echo "๐งช Next steps:"
|
|
475
|
+
echo " 1. Test with real user: ./rls-test-suite.sh $TABLE_NAME"
|
|
476
|
+
echo " 2. Run full audit: *rls-audit"
|
|
477
|
+
echo " 3. Monitor performance: ./explain-analyzer.sh \"SELECT * FROM $TABLE_NAME\""
|
|
478
|
+
echo ""
|
|
479
|
+
echo "๐ Applied policies:"
|
|
480
|
+
echo "$TEST_RESULT" | jq -r '.policies[] | " โข \(.name): \(.operation) (\(.type))"' 2>/dev/null
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# RLS Test Suite - Teste automatizado de polรญticas RLS
|
|
3
|
+
# Economia: ~90% dos tokens vs teste manual
|
|
4
|
+
# Uso: ./rls-test-suite.sh <table_name> [user_id1,user_id2,...]
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
# Colors for output
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
NC='\033[0m'
|
|
13
|
+
|
|
14
|
+
# Check requirements
|
|
15
|
+
if [ -z "${SUPABASE_DB_URL:-}" ]; then
|
|
16
|
+
echo -e "${RED}ERROR: SUPABASE_DB_URL not set${NC}"
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Parse arguments
|
|
21
|
+
TABLE_NAME="${1:-}"
|
|
22
|
+
USER_IDS="${2:-00000000-0000-0000-0000-000000000000,11111111-1111-1111-1111-111111111111}"
|
|
23
|
+
|
|
24
|
+
if [ -z "$TABLE_NAME" ]; then
|
|
25
|
+
echo "Usage: $0 <table_name> [user_id1,user_id2,...]"
|
|
26
|
+
echo "Example: $0 users"
|
|
27
|
+
echo "Example: $0 sources 'uuid1,uuid2,uuid3'"
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Convert comma-separated to array
|
|
32
|
+
IFS=',' read -ra USER_ARRAY <<< "$USER_IDS"
|
|
33
|
+
|
|
34
|
+
echo "๐งช RLS Test Suite v1.0"
|
|
35
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
36
|
+
echo "Table: $TABLE_NAME"
|
|
37
|
+
echo "Testing with ${#USER_ARRAY[@]} users"
|
|
38
|
+
echo ""
|
|
39
|
+
|
|
40
|
+
# Create temp file for results
|
|
41
|
+
RESULTS_FILE="/tmp/rls_test_results_$$.json"
|
|
42
|
+
echo '{"tests": []}' > "$RESULTS_FILE"
|
|
43
|
+
|
|
44
|
+
# Function to test a single user
|
|
45
|
+
test_user_rls() {
|
|
46
|
+
local user_id="$1"
|
|
47
|
+
local test_num="$2"
|
|
48
|
+
|
|
49
|
+
echo -e "${YELLOW}[User $test_num]${NC} Testing: $user_id"
|
|
50
|
+
|
|
51
|
+
# Run simpler RLS tests without complex JSON
|
|
52
|
+
psql "$SUPABASE_DB_URL" -t -A << SQL 2>/dev/null
|
|
53
|
+
-- Set up user context
|
|
54
|
+
SET role authenticated;
|
|
55
|
+
SET request.jwt.claims = '{
|
|
56
|
+
"sub": "$user_id",
|
|
57
|
+
"role": "authenticated",
|
|
58
|
+
"aud": "authenticated"
|
|
59
|
+
}';
|
|
60
|
+
|
|
61
|
+
-- Simple test queries
|
|
62
|
+
SELECT 'AUTH_UID:' || COALESCE(auth.uid()::text, 'NULL');
|
|
63
|
+
SELECT 'CAN_SELECT:' || has_table_privilege('$TABLE_NAME', 'SELECT')::text;
|
|
64
|
+
SELECT 'CAN_INSERT:' || has_table_privilege('$TABLE_NAME', 'INSERT')::text;
|
|
65
|
+
SELECT 'CAN_UPDATE:' || has_table_privilege('$TABLE_NAME', 'UPDATE')::text;
|
|
66
|
+
SELECT 'CAN_DELETE:' || has_table_privilege('$TABLE_NAME', 'DELETE')::text;
|
|
67
|
+
SELECT 'VISIBLE_ROWS:' || COUNT(*)::text FROM $TABLE_NAME;
|
|
68
|
+
|
|
69
|
+
-- Reset session
|
|
70
|
+
RESET role;
|
|
71
|
+
RESET request.jwt.claims;
|
|
72
|
+
SQL
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# Test each user
|
|
76
|
+
user_num=1
|
|
77
|
+
for user_id in "${USER_ARRAY[@]}"; do
|
|
78
|
+
result=$(test_user_rls "$user_id" "$user_num")
|
|
79
|
+
|
|
80
|
+
if [ -n "$result" ]; then
|
|
81
|
+
# Parse simple text results
|
|
82
|
+
auth_uid=$(echo "$result" | grep "AUTH_UID:" | cut -d':' -f2)
|
|
83
|
+
can_select=$(echo "$result" | grep "CAN_SELECT:" | cut -d':' -f2)
|
|
84
|
+
can_insert=$(echo "$result" | grep "CAN_INSERT:" | cut -d':' -f2)
|
|
85
|
+
can_update=$(echo "$result" | grep "CAN_UPDATE:" | cut -d':' -f2)
|
|
86
|
+
can_delete=$(echo "$result" | grep "CAN_DELETE:" | cut -d':' -f2)
|
|
87
|
+
visible_rows=$(echo "$result" | grep "VISIBLE_ROWS:" | cut -d':' -f2)
|
|
88
|
+
|
|
89
|
+
# Display summary
|
|
90
|
+
echo -n " โ SELECT: "
|
|
91
|
+
[ "$can_select" = "true" ] && echo -e "${GREEN}โ${NC} ($visible_rows rows)" || echo -e "${RED}โ${NC}"
|
|
92
|
+
|
|
93
|
+
echo -n " โ INSERT: "
|
|
94
|
+
[ "$can_insert" = "true" ] && echo -e "${GREEN}โ${NC}" || echo -e "${RED}โ${NC}"
|
|
95
|
+
|
|
96
|
+
echo -n " โ UPDATE: "
|
|
97
|
+
[ "$can_update" = "true" ] && echo -e "${GREEN}โ${NC}" || echo -e "${RED}โ${NC}"
|
|
98
|
+
|
|
99
|
+
echo -n " โ DELETE: "
|
|
100
|
+
[ "$can_delete" = "true" ] && echo -e "${GREEN}โ${NC}" || echo -e "${RED}โ${NC}"
|
|
101
|
+
else
|
|
102
|
+
echo -e " ${RED}โ Test failed - check connection/permissions${NC}"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
echo ""
|
|
106
|
+
((user_num++))
|
|
107
|
+
done
|
|
108
|
+
|
|
109
|
+
# Cross-user isolation test
|
|
110
|
+
echo -e "${YELLOW}[Isolation Test]${NC} Checking data isolation between users..."
|
|
111
|
+
|
|
112
|
+
psql "$SUPABASE_DB_URL" -t -A << 'SQL' 2>/dev/null
|
|
113
|
+
-- Test if users can see each other's data
|
|
114
|
+
SET role authenticated;
|
|
115
|
+
|
|
116
|
+
-- User 1 context
|
|
117
|
+
SET request.jwt.claims = '{"sub": "'${USER_ARRAY[0]}'", "role": "authenticated"}';
|
|
118
|
+
\set user1_count `SELECT COUNT(*) FROM '${TABLE_NAME}'`
|
|
119
|
+
|
|
120
|
+
-- User 2 context
|
|
121
|
+
RESET request.jwt.claims;
|
|
122
|
+
SET request.jwt.claims = '{"sub": "'${USER_ARRAY[1]}'", "role": "authenticated"}';
|
|
123
|
+
\set user2_count `SELECT COUNT(*) FROM '${TABLE_NAME}'`
|
|
124
|
+
|
|
125
|
+
-- Check overlap (should be 0 for proper isolation)
|
|
126
|
+
SELECT json_build_object(
|
|
127
|
+
'user1_rows', :user1_count,
|
|
128
|
+
'user2_rows', :user2_count,
|
|
129
|
+
'isolation_check', CASE
|
|
130
|
+
WHEN :user1_count = 0 AND :user2_count = 0 THEN 'PASS - No data'
|
|
131
|
+
WHEN :user1_count > 0 AND :user2_count = 0 THEN 'PASS - Isolated'
|
|
132
|
+
WHEN :user1_count = 0 AND :user2_count > 0 THEN 'PASS - Isolated'
|
|
133
|
+
WHEN :user1_count = :user2_count THEN 'WARNING - Same count'
|
|
134
|
+
ELSE 'PASS - Different data'
|
|
135
|
+
END
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
RESET role;
|
|
139
|
+
RESET request.jwt.claims;
|
|
140
|
+
SQL
|
|
141
|
+
|
|
142
|
+
# Generate summary report
|
|
143
|
+
echo ""
|
|
144
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
145
|
+
echo "๐ Test Summary"
|
|
146
|
+
echo "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ"
|
|
147
|
+
|
|
148
|
+
# Check if RLS is enabled
|
|
149
|
+
RLS_ENABLED=$(psql "$SUPABASE_DB_URL" -t -A -c "SELECT rowsecurity FROM pg_tables WHERE tablename = '$TABLE_NAME' AND schemaname = 'public';" 2>/dev/null)
|
|
150
|
+
|
|
151
|
+
if [ "$RLS_ENABLED" = "t" ]; then
|
|
152
|
+
echo -e "RLS Status: ${GREEN}โ ENABLED${NC}"
|
|
153
|
+
|
|
154
|
+
# Count policies
|
|
155
|
+
POLICY_COUNT=$(psql "$SUPABASE_DB_URL" -t -A -c "SELECT COUNT(*) FROM pg_policies WHERE tablename = '$TABLE_NAME';" 2>/dev/null)
|
|
156
|
+
echo "Policies: $POLICY_COUNT active"
|
|
157
|
+
else
|
|
158
|
+
echo -e "RLS Status: ${RED}โ DISABLED${NC}"
|
|
159
|
+
echo -e "${RED}WARNING: Table $TABLE_NAME has no RLS protection!${NC}"
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
# Save full report
|
|
163
|
+
echo ""
|
|
164
|
+
echo "Full results saved to: $RESULTS_FILE"
|
|
165
|
+
echo ""
|
|
166
|
+
echo "๐ก Recommendations:"
|
|
167
|
+
if [ "$RLS_ENABLED" != "t" ]; then
|
|
168
|
+
echo " 1. Enable RLS: ALTER TABLE $TABLE_NAME ENABLE ROW LEVEL SECURITY;"
|
|
169
|
+
echo " 2. Add policies: Use *policy-apply command"
|
|
170
|
+
fi
|
|
171
|
+
echo " 3. Test with real user IDs for accurate results"
|
|
172
|
+
echo " 4. Run *rls-audit for comprehensive policy review"
|