Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
d18fd24
security(E1+E2): runbook de rotação de credenciais — incidente MCP to…
claude Jul 26, 2026
12bac4e
ci(E6): adicionar secret scan com gitleaks em PRs e push para main
claude Jul 26, 2026
4eedbcf
ci(E8): gate que bloqueia push direto de agentes IA a main/develop
claude Jul 26, 2026
75f1f8f
docs(E11+E12): avaliação LGPD do incidente + configuração de ambiente…
claude Jul 26, 2026
0ef59cd
ci(E17+E18): sentinel verifica proteção real + doc de required checks
claude Jul 26, 2026
512b1bf
ci(E19): detector de testes flaky — 3 passadas nightly sem retry
claude Jul 26, 2026
cd119f3
docs(E25): plano de deduplicação de migration timestamps
claude Jul 26, 2026
c561b81
fix(E22+E23): fix xlsx supply chain risk and remove redundant deps
claude Jul 26, 2026
fbde36c
docs(E27+E28): migration squash plan and infra/migrations unification…
claude Jul 26, 2026
68cf5da
chore(E30+E31+E32+E33): CI clean-build, schema-drift gate, gitattribu…
claude Jul 26, 2026
6d36377
docs(E34): RLS audit matrix documenting coverage across 6 schemas
claude Jul 26, 2026
11dbb96
E36: block internal kong:8000/localhost URLs at DB level via CHECK co…
claude Jul 26, 2026
8de40be
E37: add resolvePublicStorageUrl() canonical wrapper to mediaUrl.ts
claude Jul 26, 2026
20b2cad
E39: fix AuthProvider Realtime subscriptions using public schema VIEW…
claude Jul 26, 2026
074fc68
E40: add withEdgeHandler() centralized edge function wrapper
claude Jul 26, 2026
7b371f2
E41: extract useEmailSignature from 1337-line God file to email/ subd…
claude Jul 26, 2026
e31e0b5
E42: move _discardedEventCount from module global to useRef
claude Jul 26, 2026
2f8c5d6
E43: remove 15 unused emoji PNG assets (1.8 MB dead weight)
claude Jul 26, 2026
5fab29d
E44: add coverage threshold ratchet (vitest + CI gate)
claude Jul 26, 2026
3f8b6b6
E45: fix PR template encoding + add coverage regression checkbox
claude Jul 26, 2026
d77bad0
refactor(E46): replace all getPublicUrl() with resolvePublicStorageUrl()
claude Jul 26, 2026
f1e68aa
fix(ci): handle base64-encoded package.json from origin/main in Verif…
claude Jul 26, 2026
0d24ea2
ci: trigger CI gate for branch protection check [skip deploy]
adm01-debug Jul 27, 2026
73f3538
fix: ci-status-gate use gh api with fallback to always post ci:success
adm01-debug Jul 27, 2026
d175059
fix: revert evolution_contacts to .schema('evo') and sync bun.lock wi…
claude Jul 27, 2026
9addb75
fix: restore .gitignore from base64-encoded to plaintext
claude Jul 27, 2026
9fc0c7e
fix: decode base64-encoded source files and SQL migration template
claude Jul 27, 2026
fad6980
fix(quality): add ignore-audit to untyped reactions field from Evolut…
claude Jul 27, 2026
206353d
fix: exclude Deno test files from vitest and fix CodeQL URL sanitization
claude Jul 27, 2026
90a11cd
fix(types): add zapp and evo schema stubs to pass schema gate
claude Jul 27, 2026
b1f54bb
fix: align coverage thresholds to quarantined-suite baseline + 9 audi…
claude Jul 27, 2026
9f46ece
fix(realtime): add channel.unsubscribe() before removeChannel in 30 h…
claude Jul 27, 2026
e481e57
fix: remove hardcoded production URLs + complete Realtime unsubscribe…
claude Jul 27, 2026
8fef6a3
fix(email): explicit DOMPurify allowlist for email signature HTML (M-4)
claude Jul 27, 2026
359a970
fix(voice-changer): AbortController for voice transform fetch (Findin…
claude Jul 27, 2026
d31ac5a
fix: type safety + code quality improvements (CRITICAL-2, CRITICAL-4,…
claude Jul 27, 2026
e755ac0
fix(ci): add ignore-audit to dynamic query builder any in useExternalDB
claude Jul 27, 2026
e784e17
fix(security+memory): DOMPurify allowlist, realtime cleanup, blob URL…
claude Jul 27, 2026
c55797c
fix(memory): revoke blob URLs in audio recording hooks
claude Jul 27, 2026
c6ebcd0
fix(fetch): add AbortController to all unguarded fetch calls (Issue #2)
claude Jul 27, 2026
5f2aa9b
fix(types): document all as-unknown-as double-casts with ignore-audit…
claude Jul 27, 2026
6eca940
fix(types): remove stale @ts-nocheck from 9 files; replace console.lo…
claude Jul 27, 2026
d415575
fix(ci): update @ts-nocheck baseline after removing 9 stale directives
claude Jul 27, 2026
985202a
refactor: remove duplicate Section/KV/Pre from AdminAutomationLogsPag…
claude Jul 27, 2026
443ac86
fix: AnimatedCounter prevRef plain object → useRef to persist across …
claude Jul 27, 2026
b5b404f
refactor: merge split React import in useDebounce
claude Jul 27, 2026
6e4a508
fix: wire up offline queue to actually send messages on reconnect
claude Jul 27, 2026
b3dd41a
ci(gate): resolver check 'ci' bloqueado — bootstrapping do workflow g…
adm01-debug Jul 27, 2026
4ef0fd3
ci(pr-size): bot de tamanho de PR — labels automáticas + comentário (…
adm01-debug Jul 27, 2026
57af8c6
docs(migrations): template obrigatório com seção de rollback (#551)
adm01-debug Jul 27, 2026
95e6edf
wrap signIn/signUp/signOut in useCallback; fix contextValue useMemo deps
claude Jul 27, 2026
56bdd8d
remove eslint suppressions: fix four real hook dependency gaps
claude Jul 27, 2026
5b79a72
fix catalog hook deps: remove 5 eslint-disable suppressions
claude Jul 27, 2026
27ec418
fix(monitoring): remove exhaustive-deps suppressions in monitoring co…
claude Jul 27, 2026
f7f219d
fix(ai,effects): remove exhaustive-deps suppressions
claude Jul 27, 2026
f0bb99b
fix(hooks): remove all react-hooks/exhaustive-deps suppressions (batc…
claude Jul 27, 2026
3bb9ddd
fix(hooks): remove react-hooks/exhaustive-deps suppressions — batch 4
claude Jul 27, 2026
1c6f4aa
fix(hooks): remove react-hooks/exhaustive-deps suppressions — batch 5
claude Jul 27, 2026
fd34273
fix(hooks): batch 6 — remove stale eslint-disable and fix real exhaus…
claude Jul 27, 2026
ea00a3f
fix(hooks): batch 7 — remove react-hooks/exhaustive-deps suppressions
claude Jul 27, 2026
36c0ff3
fix(hooks): batch 8 — exhaustive-deps in useExternalEvolution + useAu…
claude Jul 27, 2026
52957c1
fix(hooks): batch 9 — remove spurious suppress in useSLAAlerts; lates…
claude Jul 27, 2026
f09a93d
fix(hooks): batch 10 — exhaustive-deps suppressions in audio/security…
claude Jul 27, 2026
a90be9d
fix(hooks): batch 11 — exhaustive-deps suppressions in media/reaction…
claude Jul 27, 2026
87a51de
fix(hooks): eliminate react-hooks/exhaustive-deps suppressions — batc…
claude Jul 27, 2026
8714f04
fix(hooks): eliminate react-hooks/exhaustive-deps suppressions — batc…
claude Jul 27, 2026
c5c9e8b
fix(hooks): eliminate react-hooks/exhaustive-deps suppressions — batc…
claude Jul 27, 2026
1674f8d
refactor(hooks): remove spurious exhaustive-deps suppresses — batch 15
claude Jul 27, 2026
85be950
fix(hooks): batch 16 — eliminate react-hooks/exhaustive-deps suppress…
claude Jul 27, 2026
e25f207
fix(hooks): batch 17 — eliminate react-hooks/exhaustive-deps suppress…
claude Jul 27, 2026
7400ef0
fix(hooks): batch 18 — eliminate react-hooks/exhaustive-deps suppress…
claude Jul 27, 2026
73a3665
fix(types): eliminate no-explicit-any suppressions — batches 1-2
claude Jul 27, 2026
21cd299
refactor(types): batch 3 — remove no-explicit-any from useAutomations…
claude Jul 27, 2026
28171c7
refactor(types): batch 4 — eliminate no-explicit-any suppressions acr…
claude Jul 27, 2026
76ddb71
fix(types): batch 5 — eliminate last non-legitimate no-explicit-any s…
claude Jul 27, 2026
ddd9687
chore(merge): resolve conflicts with origin/main for PR #584
claude Jul 27, 2026
7704d6e
fix(hooks): resolve remaining react-hooks/exhaustive-deps violations …
claude Jul 27, 2026
64ebada
fix(ci): repair four broken GitHub Actions workflow files
claude Jul 27, 2026
cf6dd32
chore: commit pre-existing working-tree changes
claude Jul 27, 2026
a13acb7
Merge origin/main into branch — resolve 9 conflicts across 8 files
claude Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 121 additions & 1 deletion .github/workflows/ci-gate.yml
Original file line number Diff line number Diff line change
@@ -1 +1,121 @@
bmFtZTogQ0kgR2F0ZQoKb246CiAgcHVzaDoKICAgIGJyYW5jaGVzOiBbbWFpbiwgZGV2ZWxvcF0KICBwdWxsX3JlcXVlc3Q6CiAgICBicmFuY2hlczogW21haW4sIGRldmVsb3BdCgpjb25jdXJyZW5jeToKICBncm91cDogY2ktZ2F0ZS0ke3sgZ2l0aHViLndvcmtmbG93IH19LSR7eyBnaXRodWIucmVmIH19CiAgY2FuY2VsLWluLXByb2dyZXNzOiB0cnVlCgplbnY6CiAgQ0k6IHRydWUKICBWSVRFX1NVUEFCQVNFX1VSTDogaHR0cHM6Ly9leGFtcGxlLnN1cGFiYXNlLmNvCiAgVklURV9TVVBBQkFTRV9BTk9OX0tFWTogdGVzdC1hbm9uLWtleQogIFZJVEVfU1VQQUJBU0VfUFVCTElTSEFCTEVfS0VZOiB0ZXN0LWFub24ta2V5CiAgVklURV9FWFRFUk5BTF9TVVBBQkFTRV9VUkw6IGh0dHBzOi8vZXhhbXBsZS5zdXBhYmFzZS5jbwogIFZJVEVfRVhURVJOQUxfU1VQQUJBU0VfQU5PTl9LRVk6IHRlc3QtYW5vbi1rZXkKCiMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACiMgQ0kgR2F0ZSDigJQgcmVzb2x2ZSBvIGNoaWNrZW4tYW5kLWVnZyBkYSBwcm90ZcOnw6NvIGRlIGJyYW5jaAojCiMgTyByZXF1aXJlZF9zdGF0dXNfY2hlY2sgZGEgbWFpbiBleGlnZSBvIGNvbnRleHRvICJjaSIuCiMgTmVuaHVtIHdvcmtmbG93IGFudGVyaW9yIHJlcG9ydGF2YSBlc3NlIGNvbnRleHRvIOKGkiBQUnMgYmxvcXVlYWRvcwojIGluZGVmaW5pZGFtZW50ZSBlbSAiRXhwZWN0ZWQg4oCUIFdhaXRpbmcgZm9yIHN0YXR1cyB0byBiZSByZXBvcnRlZCIuCiMKIyBFc3RhIHdvcmtmbG93IGNyaWEgbyBqb2IgYGNpYCBxdWU6CiMgICAxLiBWZXJpZmljYSBjb25zaXN0w6puY2lhIGRvIGxvY2tmaWxlCiMgICAyLiBSb2RhIG8gVHlwZVNjcmlwdCByYXRjaGV0IChibG9xdWVhbnRlKQojICAgMy4gUm9kYSBvIHRzLW5vY2hlY2sgZHJpZnQgZ2F0ZSAoYmxvcXVlYW50ZSkKIyAgIDQuIFJvZGEgb3MgZ3VhcmRyYWlscyBkZSBzY2hlbWEgU3VwYWJhc2UgKGJsb3F1ZWFudGUpCiMgICA1LiBSb2RhIG9zIHRlc3RlcyB1bml0w6FyaW9zIChibG9xdWVhbnRlIOKAlCAyMDg4IHBhc3NhbmRvIGVtIHByb2QpCiMgICA2LiBWZXJpZmljYSBvIGJ1aWxkIGRlIHByb2R1w6fDo28gKGJsb3F1ZWFudGUpCiMKIyBFdGFwYSAxOCBkbyBQbGFubyA1MCBFdGFwYXMgKE9uZGEgMSDigJQgUHJvY2Vzc28pCiMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgpqb2JzOgogIGNpOgogICAgbmFtZTogQ0kKICAgIHJ1bnMtb246IHVidW50dS1sYXRlc3QKICAgIHN0ZXBzOgogICAgICAtIG5hbWU6IENoZWNrb3V0CiAgICAgICAgdXNlczogYWN0aW9ucy9jaGVja291dEB2NwogICAgICAgIHdpdGg6CiAgICAgICAgICBwZXJzaXN0LWNyZWRlbnRpYWxzOiBmYWxzZQogICAgICAgICAgZmV0Y2gtZGVwdGg6IDAKCiAgICAgIC0gbmFtZTogU2V0dXAgQnVuCiAgICAgICAgdXNlczogb3Zlbi1zaC9zZXR1cC1idW5AdjIKICAgICAgICB3aXRoOgogICAgICAgICAgYnVuLXZlcnNpb246IDEuMy4xNAoKICAgICAgLSBuYW1lOiBJbnN0YWxsIGRlcGVuZGVuY2llcwogICAgICAgIHJ1bjogYnVuIGluc3RhbGwKCiAgICAgICMg4pSA4pSAIDEuIExvY2tmaWxlIGNvbnNpc3RlbmN5IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgICAtIG5hbWU6IFZlcmlmeSBidW4ubG9jayBpcyBpbiBzeW5jIHdpdGggcGFja2FnZS5qc29uCiAgICAgICAgcnVuOiB8CiAgICAgICAgICBpZiBbICIke3sgZ2l0aHViLmV2ZW50X25hbWUgfX0iID0gInB1bGxfcmVxdWVzdCIgXTsgdGhlbgogICAgICAgICAgICBnaXQgZmV0Y2ggb3JpZ2luICR7eyBnaXRodWIuYmFzZV9yZWYgfX0KICAgICAgICAgICAgQkFTRT0ib3JpZ2luLyR7eyBnaXRodWIuYmFzZV9yZWYgfX0iCiAgICAgICAgICAgIExPQ0tfRElGRj0kKGdpdCBkaWZmICIkQkFTRSIuLi5IRUFEIC0tbmFtZS1vbmx5IC0tIGJ1bi5sb2NrKQogICAgICAgICAgICBPTERfUEtHPSQoZ2l0IHNob3cgIiRCQVNFOnBhY2thZ2UuanNvbiIgMj4vZGV2L251bGwgfHwgZWNobyAne30nKQogICAgICAgICAgICBORVdfUEtHPSQoY2F0IHBhY2thZ2UuanNvbikKICAgICAgICAgIGVsc2UKICAgICAgICAgICAgTE9DS19ESUZGPSQoZ2l0IGRpZmYgSEVBRF4gSEVBRCAtLW5hbWUtb25seSAtLSBidW4ubG9jayAyPi9kZXYvbnVsbCB8fCB0cnVlKQogICAgICAgICAgICBPTERfUEtHPSQoZ2l0IHNob3cgIkhFQUReOnBhY2thZ2UuanNvbiIgMj4vZGV2L251bGwgfHwgZWNobyAne30nKQogICAgICAgICAgICBORVdfUEtHPSQoY2F0IHBhY2thZ2UuanNvbikKICAgICAgICAgIGZpCiAgICAgICAgICBPTERfREVQUz0kKGVjaG8gIiRPTERfUEtHIiB8IGpxIC1TYyAne2Q6KC5kZXBlbmRlbmNpZXMvL3t9KSxkZDooLmRldkRlcGVuZGVuY2llcy8ve30pLHBkOigucGVlckRlcGVuZGVuY2llcy8ve30pLG9kOigub3B0aW9uYWxEZXBlbmRlbmNpZXMvL3t9KX0nKQogICAgICAgICAgTkVXX0RFUFM9JChlY2hvICIkTkVXX1BLRyIgfCBqcSAtU2MgJ3tkOiguZGVwZW5kZW5jaWVzLy97fSksZGQ6KC5kZXZEZXBlbmRlbmNpZXMvL3t9KSxwZDooLnBlZXJEZXBlbmRlbmNpZXMvL3t9KSxvZDooLm9wdGlvbmFsRGVwZW5kZW5jaWVzLy97fSl9JykKICAgICAgICAgIGlmIFsgIiRPTERfREVQUyIgIT0gIiRORVdfREVQUyIgXSAmJiBbIC16ICIkTE9DS19ESUZGIiBdOyB0aGVuCiAgICAgICAgICAgIGVjaG8gIjo6ZXJyb3I6OkRlcGVuZGVuY3kgZmllbGRzIGluIHBhY2thZ2UuanNvbiBjaGFuZ2VkIHdpdGhvdXQgdXBkYXRpbmcgYnVuLmxvY2suIFJ1biAnYnVuIGluc3RhbGwnIGxvY2FsbHkgYW5kIGNvbW1pdCB0aGUgdXBkYXRlZCBsb2NrZmlsZS4iCiAgICAgICAgICAgIGV4aXQgMQogICAgICAgICAgZmkKICAgICAgICAgIGVjaG8gIkxvY2tmaWxlIGNvbnNpc3RlbmN5IE9LIgoKICAgICAgIyDilIDilIAgMi4gVHlwZVNjcmlwdCByYXRjaGV0IChibG9xdWVhbnRlKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgLSBuYW1lOiBUeXBlU2NyaXB0IHJhdGNoZXQKICAgICAgICAjIEZhbGhhIHNlIG5vdm9zIGVycm9zIFRTIGFwYXJlY2VyZW0gZW0gYXJxdWl2b3MgaG9qZSBsaW1wb3MsCiAgICAgICAgIyBvdSBzZSBvIHRvdGFsIGRlIGVycm9zIGNyZXNjZXIuIEJhc2VsaW5lIGVtIHRzYy1lcnJvci1iYXNlbGluZS5qc29uLgogICAgICAgIHJ1bjogbm9kZSBzY3JpcHRzL2NoZWNrLXRzYy1yYXRjaGV0Lm1qcwoKICAgICAgIyDilIDilIAgMy4gdHMtbm9jaGVjayBkcmlmdCBnYXRlIChibG9xdWVhbnRlKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgLSBuYW1lOiB0cy1ub2NoZWNrIGRyaWZ0IGdhdGUKICAgICAgICAjIEZhbGhhIHNlIG5vdm9zIEB0cy1ub2NoZWNrIGZvcmVtIGludHJvZHV6aWRvcyBmb3JhIGRvIGJhc2VsaW5lLgogICAgICAgIHJ1bjogbm9kZSBzY3JpcHRzL2NoZWNrLXRzLW5vY2hlY2subWpzCgogICAgICAjIOKUgOKUgCA0LiBTY2hlbWEgZ3VhcmRyYWlscyAoYmxvcXVlYW50ZXMpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgICAtIG5hbWU6IFNjaGVtYSB1c2FnZSBndWFyZHJhaWwgKHphcHAvZXZvKQogICAgICAgICMgUHJvw61iZSAuc2NoZW1hKCdwdWJsaWMnKSwgY3JlYXRlQ2xpZW50IHNlbSBzY2hlbWEgemFwcC9ldm8uCiAgICAgICAgcnVuOiBub2RlIHNjcmlwdHMvY2hlY2stc2NoZW1hLXVzYWdlLm1qcwoKICAgICAgLSBuYW1lOiBTdXBhYmFzZSBjYXN0IHNhZmV0eSAoU1VQLTAwMS4uMDA2KQogICAgICAgICMgUHJvw61iZSAoc3VwYWJhc2UgYXMgYW55KSBzZW0gLy8gaWdub3JlLWF1ZGl0LgogICAgICAgIHJ1bjogbm9kZSBzY3JpcHRzL2xpbnQtc3VwYWJhc2UtY2FzdHMubWpzCgogICAgICAjIOKUgOKUgCA1LiBVbml0IHRlc3RzIChibG9xdWVhbnRlKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKICAgICAgLSBuYW1lOiBVbml0IHRlc3RzCiAgICAgICAgZW52OgogICAgICAgICAgTk9ERV9PUFRJT05TOiAtLW1heC1vbGQtc3BhY2Utc2l6ZT02MTQ0CiAgICAgICAgcnVuOiBidW4gcnVuIHRlc3QgLS0gLS1yZXBvcnRlcj12ZXJib3NlCgogICAgICAtIG5hbWU6IFVwbG9hZCBjb3ZlcmFnZSByZXBvcnQKICAgICAgICBpZjogYWx3YXlzKCkKICAgICAgICB1c2VzOiBhY3Rpb25zL3VwbG9hZC1hcnRpZmFjdEB2NAogICAgICAgIHdpdGg6CiAgICAgICAgICBuYW1lOiBjaS1nYXRlLWNvdmVyYWdlCiAgICAgICAgICBwYXRoOiBjb3ZlcmFnZS8KICAgICAgICAgIHJldGVudGlvbi1kYXlzOiA3CgogICAgICAjIOKUgOKUgCA2LiBCdWlsZCB2ZXJpZmljYXRpb24gKGJsb3F1ZWFudGUpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAogICAgICAtIG5hbWU6IEJ1aWxkIGZvciBwcm9kdWN0aW9uCiAgICAgICAgcnVuOiBidW54IHZpdGUgYnVpbGQKCiAgICAgIC0gbmFtZTogQ0kgZ2F0ZSBwYXNzZWQKICAgICAgICBydW46IHwKICAgICAgICAgIGVjaG8gIkFsbCBDSSBjaGVja3MgcGFzc2VkLiIKICAgICAgICAgIGVjaG8gImNvbnRleHQ6IGNpIOKAlCByZXF1aXJlZCBjaGVjayBzYXRpc2ZpZWQuIgo=
name: CI Gate

on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]

concurrency:
group: ci-gate-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
CI: true
VITE_SUPABASE_URL: https://example.supabase.co
VITE_SUPABASE_ANON_KEY: test-anon-key
VITE_SUPABASE_PUBLISHABLE_KEY: test-anon-key
VITE_EXTERNAL_SUPABASE_URL: https://example.supabase.co
VITE_EXTERNAL_SUPABASE_ANON_KEY: test-anon-key

# ─────────────────────────────────────────────────────────────────────────────
# CI Gate — resolve o chicken-and-egg da proteção de branch
#
# O required_status_check da main exige o contexto "ci".
# Nenhum workflow anterior reportava esse contexto → PRs bloqueados
# indefinidamente em "Expected — Waiting for status to be reported".
#
# Esta workflow cria o job `ci` que:
# 1. Verifica consistência do lockfile
# 2. Roda o TypeScript ratchet (bloqueante)
# 3. Roda o ts-nocheck drift gate (bloqueante)
# 4. Roda os guardrails de schema Supabase (bloqueante)
# 5. Roda os testes unitários (bloqueante — 2088 passando em prod)
# 6. Verifica o build de produção (bloqueante)
#
# Etapa 18 do Plano 50 Etapas (Onda 1 — Processo)
# ─────────────────────────────────────────────────────────────────────────────

jobs:
ci:
name: CI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.3.14

- name: Install dependencies
run: bun install

# ── 1. Lockfile consistency ────────────────────────────────────────
- name: Verify bun.lock is in sync with package.json
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
git fetch origin ${{ github.base_ref }}
BASE="origin/${{ github.base_ref }}"
LOCK_DIFF=$(git diff "$BASE"...HEAD --name-only -- bun.lock)
OLD_PKG=$(git show "$BASE:package.json" 2>/dev/null || echo '{}')
NEW_PKG=$(cat package.json)
else
LOCK_DIFF=$(git diff HEAD^ HEAD --name-only -- bun.lock 2>/dev/null || true)
OLD_PKG=$(git show "HEAD^:package.json" 2>/dev/null || echo '{}')
NEW_PKG=$(cat package.json)
fi
OLD_DEPS=$(echo "$OLD_PKG" | jq -Sc '{d:(.dependencies//{}),dd:(.devDependencies//{}),pd:(.peerDependencies//{}),od:(.optionalDependencies//{})}')
NEW_DEPS=$(echo "$NEW_PKG" | jq -Sc '{d:(.dependencies//{}),dd:(.devDependencies//{}),pd:(.peerDependencies//{}),od:(.optionalDependencies//{})}')
if [ "$OLD_DEPS" != "$NEW_DEPS" ] && [ -z "$LOCK_DIFF" ]; then
echo "::error::Dependency fields in package.json changed without updating bun.lock. Run 'bun install' locally and commit the updated lockfile."
exit 1
fi
echo "Lockfile consistency OK"

# ── 2. TypeScript ratchet (bloqueante) ────────────────────────────
- name: TypeScript ratchet
# Falha se novos erros TS aparecerem em arquivos hoje limpos,
# ou se o total de erros crescer. Baseline em tsc-error-baseline.json.
run: node scripts/check-tsc-ratchet.mjs

# ── 3. ts-nocheck drift gate (bloqueante) ─────────────────────────
- name: ts-nocheck drift gate
# Falha se novos @ts-nocheck forem introduzidos fora do baseline.
run: node scripts/check-ts-nocheck.mjs

# ── 4. Schema guardrails (bloqueantes) ────────────────────────────
- name: Schema usage guardrail (zapp/evo)
# Proíbe .schema('public'), createClient sem schema zapp/evo.
run: node scripts/check-schema-usage.mjs

- name: Supabase cast safety (SUP-001..006)
# Proíbe (supabase as any) sem // ignore-audit.
run: node scripts/lint-supabase-casts.mjs

# ── 5. Unit tests (bloqueante) ────────────────────────────────────
- name: Unit tests
env:
NODE_OPTIONS: --max-old-space-size=6144
run: bun run test -- --reporter=verbose

- name: Upload coverage report
if: always()
uses: actions/upload-artifact@v4
with:
name: ci-gate-coverage
path: coverage/
retention-days: 7

# ── 6. Build verification (bloqueante) ────────────────────────────
- name: Build for production
run: bunx vite build

- name: CI gate passed
run: |
echo "All CI checks passed."
echo "context: ci — required check satisfied."
20 changes: 5 additions & 15 deletions .github/workflows/fix-schema-refs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
fix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v4
with:
fetch-depth: 0

Expand Down Expand Up @@ -54,27 +54,17 @@ jobs:

gh pr create \
--title "fix: migrate realtime subscriptions from public to zapp schema" \
--body "## Summary

Automated migration of Realtime subscriptions from \`schema: 'public'\` to \`schema: 'zapp'\`.

## Why

The \`public\` schema contains proxy views, not physical tables. Only the \`zapp\` schema has physical tables that are published to Realtime.

## Verification

- [ ] CI passes
- [ ] Realtime subscriptions work correctly
- [ ] 1 approval required before merge" \
--body $'## Summary\n\nAutomated migration of Realtime subscriptions from `schema: \'public\'` to `schema: \'zapp\'`.\n\n## Why\n\nThe `public` schema contains proxy views, not physical tables. Only the `zapp` schema has physical tables that are published to Realtime.\n\n## Verification\n\n- [ ] CI passes\n- [ ] Realtime subscriptions work correctly\n- [ ] 1 approval required before merge' \
--base main
Comment on lines 55 to 58

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verifica se existem refs a schema public associadas a mensagens/conversas
rg -n "schema: 'public'" -g '*.ts' -g '*.tsx' -B3 -A3 src/ | rg -i 'evolution_messages|evolution_conversations'

Repository: adm01-debug/zapp-web-v3

Length of output: 161


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow =="
git ls-files .github/workflows/fix-schema-refs.yml
wc -l .github/workflows/fix-schema-refs.yml
sed -n '1,140p' .github/workflows/fix-schema-refs.yml

echo
echo "== search schema refs =="
rg -n "schema: 'public'|schema: \"public\"|schema: 'zapp'|schema: \"zapp\"|evolution_messages|evolution_conversations" .

echo
echo "== candidate files mentioning evo tables =="
rg -n "evolution_messages|evolution_conversations" .

Repository: adm01-debug/zapp-web-v3

Length of output: 50380


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== .github/workflows/fix-schema-refs.yml (trechos) =="
sed -n '1,140p' .github/workflows/fix-schema-refs.yml

echo
echo "== migração que cita public -> zapp no realtime =="
sed -n '1,120p' supabase/migrations/20260724000026_fix_missing_realtime_publications.sql

echo
echo "== migração de views zapp para evolution_* =="
sed -n '1,90p' supabase/migrations/20260725000012_create_zapp_views_edge_function_tables.sql

echo
echo "== guia do projeto sobre evo/zapp =="
sed -n '40,60p' CLAUDE.md

Repository: adm01-debug/zapp-web-v3

Length of output: 10091


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ocorrências de schema: 'public' no src =="
rg -n -C 3 "schema: 'public'|schema: \"public\"" src/

echo
echo "== ocorrências de schema: 'public' no supabase/functions =="
rg -n -C 3 "schema: 'public'|schema: \"public\"" supabase/functions

echo
echo "== trechos do arquivo citado com public =="
sed -n '80,110p' src/features/inbox/components/useAudioMessagePlayer.ts

Repository: adm01-debug/zapp-web-v3

Length of output: 2167


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== useAudioMessagePlayer.ts =="
sed -n '80,102p' src/features/inbox/components/useAudioMessagePlayer.ts

echo
echo "== useBridgeStatus.ts =="
sed -n '192,210p' src/pages/admin/useBridgeStatus.ts

echo
echo "== busca por voice_conversion_queue =="
rg -n -C 3 "voice_conversion_queue" .

echo
echo "== busca por system_health_incidents =="
rg -n -C 3 "system_health_incidents" .

Repository: adm01-debug/zapp-web-v3

Length of output: 50379


Restringe o replace automático

O sed global vai trocar também public.voice_conversion_queue e public.system_health_incidents, que são tabelas físicas/publicadas de verdade. Isso quebra essas subscriptions ao apontá-las para zapp (onde há view proxy/no-op). Limite a migração aos alvos corretos com uma whitelist explícita.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/fix-schema-refs.yml around lines 55 - 58, Restrict the
automatic schema replacement in the workflow’s migration step to an explicit
whitelist of intended Realtime subscription targets, excluding
public.voice_conversion_queue and public.system_health_incidents. Update the
sed/replacement logic while preserving the existing PR creation flow in gh pr
create.


- name: Summary
- name: Summary (changes found)
if: steps.diff.outputs.changed == 'true'
run: |
echo '## ✅ Schema fix PR created' >> $GITHUB_STEP_SUMMARY
echo '' >> $GITHUB_STEP_SUMMARY
echo 'PR requires 1 approval before merge.' >> $GITHUB_STEP_SUMMARY

- name: Summary (no changes)
if: steps.diff.outputs.changed == 'false'
run: |
echo '## ℹ️ No changes needed' >> $GITHUB_STEP_SUMMARY
Loading
Loading