Files
Investidor-V2/tools/investmoz/validate.py
T
nala 250ac35fd1
tests / ci (push) Canceled after 0s
first commit
2026-09-28 10:01:09 +02:00

55 lines
2.9 KiB
Python

"""Read-only structural consistency checks; no PostgreSQL execution claims."""
import csv, hashlib, json, re
from pathlib import Path
root=Path(__file__).resolve().parents[2]
base=root/'docs/investmoz'
schema=json.loads((base/'schema.json').read_text(encoding='utf-8'))
legacy=json.loads((base/'legacy-schema.json').read_text(encoding='utf-8'))
tables={t['name']:t for t in legacy['tables']+schema['tables']}
def rows(name):
return list(csv.DictReader((base/name).open(encoding='utf-8',newline='')))
catalog=rows('table-catalog.csv')
assert {r['Tabela'] for r in catalog}==set(tables)
dictionary=rows('data-dictionary.csv')
fields={(t,c['name']) for t,v in tables.items() for c in v['columns']}
assert {(r['Tabela'],r['Campo']) for r in dictionary}==fields
assert len(dictionary)==len(fields)
trace=rows('traceability.csv')
assert {(r['Tabela'],r['Campo']) for r in trace}==fields
erd=(base/'erd.mmd').read_text(encoding='utf-8')
erd_fields=set()
for table,body in re.findall(r'^\s+(\w+) \{\n(.*?)^\s+\}',erd,re.M|re.S):
for line in body.splitlines():
if line.strip(): erd_fields.add((table,line.split()[1]))
assert erd_fields==fields
seen=set(t['name'] for t in legacy['tables'])
for t in schema['tables']:
sql=(root/t['migration']).read_text(encoding='utf-8')
assert t['sql'] in sql
for rel in schema['relationships']:
if rel['table']!=t['name']: continue
assert rel['target'] in seen or rel['target']==t['name'],rel
target=tables[rel['target']]
ct=next(c['type'] for c in t['columns'] if c['name']==rel['column'])
rt=next(c['type'] for c in target['columns'] if c['name']==rel['target_column'])
assert ct==rt,(rel,ct,rt)
assert f"{rel['target']} "+('|o' if rel['nullable'] else '||')+f" --o{{ {rel['table']} : {rel['column']}" in erd
seen.add(t['name'])
for item in schema['indexes']:
assert item['sql'] in (root/item['migration']).read_text(encoding='utf-8')
names=[i['name'] for i in schema['indexes']]+[c['name'] for c in schema['constraints']]
assert len(names)==len(set(names))
assert all(len(n)<=63 for n in names)
migrations=list((root/'database/migrations').glob('2026_09_24_*_investmoz_*.php'))
assert len(migrations)==15,len(migrations)
for path in migrations:
php=path.read_text(encoding='utf-8')
down=php.split('public function down(): void')[1]
assert not re.search(r'DROP .* CASCADE|DROP EXTENSION',down)
assert php.count("<<<'SQL'")==php.count('\nSQL);')
for line in (base/'checksums.sha256').read_text(encoding='utf-8').splitlines():
digest,path=line.split(' ',1)
assert hashlib.sha256((root/path).read_bytes()).hexdigest()==digest,path
print(f"PASS: {len(tables)} tables, {len(fields)} columns, {len(schema['relationships'])+len(legacy['relationships'])} FKs, 15 migrations; catalogue/dictionary/ERD/checksums coherent.")
print("PostgreSQL/PostGIS lifecycle, authorization and performance are NOT validated by this static check.")