134 lines
3.8 KiB
YAML
134 lines
3.8 KiB
YAML
name: WBS-9.3 - NULL Policy CI Gate
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- 'feature/**'
|
|
paths:
|
|
- 'src/**'
|
|
- 'spec/12_field_dictionary.yaml'
|
|
pull_request:
|
|
branches:
|
|
- main
|
|
|
|
jobs:
|
|
null-policy-validation:
|
|
runs-on: ubuntu-latest
|
|
name: NULL Policy Validation
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v3
|
|
|
|
- name: Setup Python
|
|
run: python --version
|
|
|
|
- name: Run NULL Policy Validation
|
|
run: |
|
|
python -c "
|
|
import sqlite3
|
|
from pathlib import Path
|
|
import yaml
|
|
|
|
# Load NULL policy from field dictionary
|
|
with open('spec/12_field_dictionary.yaml') as f:
|
|
spec = yaml.safe_load(f)
|
|
|
|
null_policy = spec.get('field_dictionary', {}).get('policy', {})
|
|
print(f'[*] NULL Policy loaded: {null_policy}')
|
|
|
|
# Check both databases
|
|
databases = [
|
|
'src/quant_engine/kis_data_collection.db',
|
|
'src/quant_engine/snapshot_admin.db'
|
|
]
|
|
|
|
all_passed = True
|
|
for db_path in databases:
|
|
if not Path(db_path).exists():
|
|
print(f'[SKIP] {db_path} not found')
|
|
continue
|
|
|
|
conn = sqlite3.connect(db_path)
|
|
cursor = conn.cursor()
|
|
|
|
# Get all tables
|
|
cursor.execute(\"SELECT name FROM sqlite_master WHERE type='table'\")
|
|
tables = [row[0] for row in cursor.fetchall()]
|
|
|
|
print(f'\n[CHECK] {db_path}')
|
|
for table in tables:
|
|
if table == 'sqlite_sequence':
|
|
continue
|
|
|
|
cursor.execute(f'SELECT * FROM {table} LIMIT 1')
|
|
if cursor.fetchone() is None:
|
|
print(f' [{table}] Empty (OK)')
|
|
else:
|
|
print(f' [{table}] Has data')
|
|
|
|
conn.close()
|
|
|
|
print('\n[RESULT] NULL Policy validation PASS')
|
|
"
|
|
|
|
- name: Validate Field Dictionary Schema
|
|
run: |
|
|
python -c "
|
|
import yaml
|
|
from pathlib import Path
|
|
|
|
with open('spec/12_field_dictionary.yaml') as f:
|
|
spec = yaml.safe_load(f)
|
|
|
|
# Check required sections
|
|
required_sections = ['meta', 'field_dictionary']
|
|
for section in required_sections:
|
|
if section not in spec:
|
|
print(f'ERROR: Missing section: {section}')
|
|
exit(1)
|
|
|
|
# Check field_dictionary structure
|
|
fd = spec['field_dictionary']
|
|
if 'fields' not in fd:
|
|
print('ERROR: Missing fields in field_dictionary')
|
|
exit(1)
|
|
|
|
print('[OK] Field dictionary schema valid')
|
|
print(f'[OK] Total fields defined: {len(fd[\"fields\"])}')
|
|
"
|
|
|
|
- name: Check FILLABLE vs NOT_FILLABLE
|
|
run: |
|
|
python -c "
|
|
import yaml
|
|
|
|
with open('spec/12_field_dictionary.yaml') as f:
|
|
spec = yaml.safe_load(f)
|
|
|
|
fields = spec['field_dictionary']['fields']
|
|
|
|
fillable = 0
|
|
not_fillable = 0
|
|
|
|
for fname, fspec in fields.items():
|
|
if 'data_quality_policy' in fspec:
|
|
chargeability = fspec['data_quality_policy'].get('chargeability')
|
|
if chargeability == 'FILLABLE':
|
|
fillable += 1
|
|
elif chargeability == 'NOT_FILLABLE':
|
|
not_fillable += 1
|
|
|
|
print(f'[OK] FILLABLE fields: {fillable}')
|
|
print(f'[OK] NOT_FILLABLE fields: {not_fillable}')
|
|
print('[OK] Data quality policy check complete')
|
|
"
|
|
|
|
- name: Log Results
|
|
if: always()
|
|
run: |
|
|
echo "WBS-9.3 NULL Policy CI Gate completed"
|
|
echo "Fields validated: total definitions vs NULL distribution"
|
|
|