Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
31aafe6
feat: Approval Request
bidhan-nagarro Mar 9, 2026
2cc2ccb
refactor: Enable approval/rejection of individual Giga Sync uploads
bidhan-nagarro Jan 19, 2026
869b476
refactor: Enable approval/rejection of individual Giga Sync uploads
bidhan-nagarro Jan 19, 2026
97e0c91
feature: adls metadata writing logic (#201)
brianmusisi Feb 26, 2026
96cb37d
refactor: Enable approval/rejection of individual Giga Sync uploads
bidhan-nagarro Jan 19, 2026
d211ca0
refactor: DQ checks
bidhan-nagarro Feb 9, 2026
529d525
refactor: DQ checks
bidhan-nagarro Feb 9, 2026
af6062c
refactor: DQ checks
bidhan-nagarro Feb 9, 2026
ef847c2
feat: Data Quality Checks
bidhan-nagarro Mar 5, 2026
14c7fab
feat(upload): move school-data submit API call to step 4 and add revi…
shubham-gupta-nagarro Mar 9, 2026
cb75c14
feature: adls metadata writing logic (#201)
brianmusisi Feb 26, 2026
e210516
refactor: Enable approval/rejection of individual Giga Sync uploads
bidhan-nagarro Jan 19, 2026
7443c04
feature: adls metadata writing logic (#201)
brianmusisi Feb 26, 2026
51a9f21
feature: adls metadata writing logic (#201)
brianmusisi Feb 26, 2026
a5f358e
feat: Error table API
bidhan-nagarro Mar 10, 2026
670e849
Merge branch 'main' into feature/error-table
bidhan-nagarro Mar 10, 2026
afc79c8
feat: DQ changes
bidhan-nagarro Mar 13, 2026
11a160e
feat: Fuzzy Match
bidhan-nagarro Feb 23, 2026
5e28daa
feat: Fuzzy Logic
bidhan-nagarro Mar 10, 2026
312a517
feat: Fuzzy Logic
bidhan-nagarro Mar 11, 2026
0bf6e43
feat: Fuzzy Logic
bidhan-nagarro Mar 11, 2026
46850e9
feat: Fuzzy Logic
bidhan-nagarro Mar 12, 2026
f7d7c06
feat: Fuzzy Match FE
bidhan-nagarro Mar 16, 2026
6277bdd
feat: added missing fuzzy modal
shubham-gupta-nagarro Mar 16, 2026
d4d89b7
chore: fix pre-commit hook failures
Mar 16, 2026
352060a
chore: fuzzy match migration issues fixed
Mar 16, 2026
558d2fa
feat: Added env Variables for NOCODB
bidhan-nagarro Mar 17, 2026
9b858aa
chore: poetry.lock file updated
Mar 17, 2026
e8d7211
Merge branch 'main' into feature/dq
bidhan-nagarro Mar 18, 2026
e801e0b
chore: poetry.lock file pydentic issues fixed
Mar 18, 2026
66cdb3d
feat: Approval Request Changes
bidhan-nagarro Mar 18, 2026
c0e9428
Feature/tech 8534 reorder master columns (#200)
Javiershenbc Mar 12, 2026
0c840a1
feat: adding helper text as placeholder and metadata form redesign (#…
Javiershenbc Mar 12, 2026
221b0ce
feature: tech 8532 remove or replace uploaded file (#196)
Javiershenbc Mar 12, 2026
d628cc1
feat: adapt submit buttons to be more intuituve for users (#211)
Javiershenbc Mar 12, 2026
648a292
Feature/tech 6769 upload table tabs based on data source (#197)
Javiershenbc Mar 12, 2026
3edaafc
Revert 197 feature/tech 6769 upload table tabs based on data source (…
Javiershenbc Mar 13, 2026
23c0613
Fix/minor UI fixes (#215)
Javiershenbc Mar 18, 2026
6685d2a
feat: Error table changes
bidhan-nagarro Mar 19, 2026
bf75e5c
Merge branch 'main' into feature/approval-request-changes
bidhan-nagarro Mar 19, 2026
6e56ec3
Merge branch 'main' into feature/dq
bidhan-nagarro Mar 19, 2026
02ce128
Merge branch 'main' into feature/error-table
bidhan-nagarro Mar 19, 2026
f9cc002
Merge branch 'main' into feature/fuzzy-match
bidhan-nagarro Mar 19, 2026
d3cc13d
fix: fix lint errors on import orders from ruff
Javiershenbc Mar 19, 2026
755932a
feat: restored deleted css
shubham-gupta-nagarro Mar 20, 2026
79f0c02
fix: fix ruff errors
Javiershenbc Mar 20, 2026
93fd6c0
feat: DQ code fixes
bidhan-nagarro Mar 21, 2026
ebc4f44
feat: DQ code fixes
bidhan-nagarro Mar 21, 2026
fb6abdc
feat: Review Comments addressed
bidhan-nagarro Mar 21, 2026
826575f
feat: Bugs Fixed
bidhan-nagarro Mar 23, 2026
54acfe7
feat: added intermediatory screen to list the uploaded list before mo…
shubham-gupta-nagarro Jan 22, 2026
2fbc87d
fix: Review Comments addressed
bidhan-nagarro Mar 27, 2026
166af28
feat: enhance success component with review mode functionality
shubham-gupta-nagarro Mar 27, 2026
65c7477
chore: pre-commit issues fixed
Mar 30, 2026
9c75293
chore: pre-commit issues fixed
Mar 30, 2026
7cc6f2c
chore: pre-commit issues fixed
Mar 30, 2026
a8eb173
fix: review comments addressed
bidhan-nagarro Mar 31, 2026
87191eb
feat: added UI changes
bidhan-nagarro Mar 31, 2026
b1feabf
fix: Error table
bidhan-nagarro Apr 1, 2026
0c2ead5
fix: Fuzzy logic
bidhan-nagarro Apr 1, 2026
5e627b6
chore: pre-commit issues fixed
Apr 1, 2026
660b0af
chore: pre-commit issues fixed
Apr 1, 2026
0e42c8f
feat: TECH-9186 School Registration Feature Added
Apr 1, 2026
61bc987
fix: review comments addressed
bidhan-nagarro Apr 6, 2026
fef2423
fix: review comments addressed
bidhan-nagarro Apr 6, 2026
5547f35
fix: fuzzy match changes
bidhan-nagarro Apr 8, 2026
ad8c34d
fix: fuzzy issue
bidhan-nagarro Apr 8, 2026
347a213
fix: error table api
bidhan-nagarro Apr 8, 2026
142e0e5
feat: Fuzzy Match Fix
Apr 8, 2026
1ab1147
feat: Migrations Clean
Apr 9, 2026
8f264b1
fix: approval listing
bidhan-nagarro Apr 10, 2026
9c2ec5e
fix: DQ server error fix
bidhan-nagarro Apr 10, 2026
a3c82c9
fix: error api
bidhan-nagarro Apr 13, 2026
706ff29
feat: DQ UI Changes
Apr 14, 2026
ed2656e
fix: error table api
bidhan-nagarro Apr 14, 2026
ec3f3a2
Merge branch 'main' into feature/fuzzy-match
bidhan-nagarro Apr 15, 2026
1623dd5
fix: fuzzy matching changes
bidhan-nagarro Apr 16, 2026
099c4cc
feat: DQ Checks
Apr 17, 2026
d25645d
Merge branch 'main' into feature/dq
bidhan-nagarro Apr 20, 2026
db2b81f
fix: pre-commit fixes
bidhan-nagarro Apr 20, 2026
145f4ef
fix: add fuzzy branch
bidhan-nagarro Apr 20, 2026
55e45da
fix: merge error table
bidhan-nagarro Apr 20, 2026
4a341b0
fix: added approval request
bidhan-nagarro Apr 20, 2026
3377203
fix: npm bugs
bidhan-nagarro Apr 20, 2026
8c17a82
fix: re-instate approval request changes dropped
brianmusisi Apr 20, 2026
135514c
fix: DQ enhancements
bidhan-nagarro Apr 21, 2026
7326b7b
fix: DQ enhancements
bidhan-nagarro Apr 21, 2026
4103bf0
fix: DQ enhancements
bidhan-nagarro Apr 21, 2026
5ffe10e
fix: DQ enhancements
bidhan-nagarro Apr 21, 2026
f28eaca
fix: DQ enhancements
bidhan-nagarro Apr 21, 2026
f2c3ca8
fix: DQ fixes and removal of approval code
bidhan-nagarro Apr 21, 2026
384cc27
fix: DQ fixes and review comments addressed
bidhan-nagarro Apr 22, 2026
f1c0ac2
fix: dq branch added
bidhan-nagarro Apr 22, 2026
02754fa
fix: remove migrate job
bidhan-nagarro Apr 22, 2026
62c74db
fix: remove migrate job
bidhan-nagarro Apr 22, 2026
8c01dde
fix: error fix
bidhan-nagarro Apr 22, 2026
cfc9a90
fix: error fix
bidhan-nagarro Apr 22, 2026
9a7e2fc
fix: error fix
bidhan-nagarro Apr 22, 2026
5c0a629
fix: error fix
bidhan-nagarro Apr 22, 2026
0a3f1cd
fix: error fix
bidhan-nagarro Apr 23, 2026
b432304
fix: Merge branch 'feature/dq' into dev-testing-new
bidhan-nagarro Apr 23, 2026
3695390
fix: fuzzy match fixes
bidhan-nagarro Apr 24, 2026
8019724
fix: Merge branch 'feature/fuzzy-match' into dev-testing-new
bidhan-nagarro Apr 24, 2026
713b85f
fix: fuzzy fix
bidhan-nagarro Apr 24, 2026
4957b94
fix: fuzzy fix
bidhan-nagarro Apr 24, 2026
e53ab38
feat: Merged school registration
Apr 24, 2026
8c33334
fix: Merge branch 'feature/fuzzy-match' into dev-testing-new
bidhan-nagarro Apr 24, 2026
0f5464a
fix: dq UI fixes
bidhan-nagarro Apr 24, 2026
1cdea69
feat: Merged main branch
Apr 28, 2026
08e8ea4
feat: TECH-9186 School Registration Feature Added
Apr 28, 2026
07e0533
feat: TECH-9186 School Registration Feature Added
Apr 28, 2026
fa2dba2
feat: Merged School Registration with main
Apr 28, 2026
37dda9a
feat: duplicate validate_fuzzy issue fixed
Apr 28, 2026
063a455
fix: dq UI fixes
bidhan-nagarro Apr 29, 2026
4785b78
fix: Merge branch 'feature/dq' into dev-testing-new
bidhan-nagarro Apr 29, 2026
7f2641f
feat: TECH-9186 School Registration Feature Added
Apr 29, 2026
fd90cf2
feat: Merged School Registration
Apr 29, 2026
6d48409
feat: TECH-9186 School Registration Feature Added
Apr 29, 2026
211f142
feat: Merged School Registration
Apr 29, 2026
09043a1
feat: TECH-9186 School Registration Feature Added
Apr 29, 2026
7b7dcc7
feat: Merged School Registration
Apr 29, 2026
c291d62
feat: TECH-9186 School Registration Feature Added
May 1, 2026
3352436
feat: Merged School Registration
May 1, 2026
c5bc10c
feat: TECH-9186 School Registration Feature Added
May 7, 2026
9b3dcf9
feat: Merged School Registration
May 7, 2026
942226f
feat: TECH-9186 School Registration Feature Added
May 7, 2026
37944a4
feat: Merged School Registration
May 7, 2026
b6d719d
feat: TECH-9186 School Registration Feature Added
May 7, 2026
8b718a8
feat: Merged School Registration
May 7, 2026
8e5ab79
feat: TECH-9186 School Registration Feature Added
May 7, 2026
d516e2c
feat: Merged School Registration
May 7, 2026
e28f1ad
feat: TECH-9186 School Registration Feature Added
May 7, 2026
4372851
feat: Merged School Registration
May 7, 2026
964d51c
feat: TECH-9186 School Registration
May 12, 2026
0e2c354
feat: Merged School Registration
May 12, 2026
de19518
feat: TECH-9186 School Registration -nocodb hook payload format changed
May 14, 2026
8ab5aad
feat: Merged School Registration
May 14, 2026
adccb68
feat: TECH-9186 School Registration -nocodb hook payload format changed
May 14, 2026
b861986
feat: Merged School Registration
May 14, 2026
bc86c6a
feat: add quality assessment step and assessment page for uploaded files
niteshbhardwaj02 May 19, 2026
5c2bfa9
feat: Lint issues fixed
May 19, 2026
3473580
feat: Merged DQ Branch
May 19, 2026
4d8f558
feat: Logging added
May 19, 2026
9dfbedc
feat: Merged School Registration
May 19, 2026
6e9d6ae
feat: add assessment route for upload group upload type
niteshbhardwaj02 May 19, 2026
aec7fc3
feat: add assessment route for upload group upload type
niteshbhardwaj02 May 19, 2026
570e847
Merge branch 'feature/dq' into dev-testing-new
niteshbhardwaj02 May 19, 2026
2f92664
Merge branch 'main' into feature/dq
bidhan-nagarro May 20, 2026
6808ce1
Merge branch 'main' into feature/dq
bidhan-nagarro May 21, 2026
2b2d761
fix: DQ enhancements
bidhan-nagarro May 21, 2026
a4ece9b
fix: Merge branch 'feature/dq' into dev-testing-new
bidhan-nagarro May 21, 2026
de2c0b8
fix: DQ enhancement
bidhan-nagarro May 21, 2026
784a4e6
fix: Merge branch 'feature/dq' into dev-testing-new
bidhan-nagarro May 21, 2026
c83a77b
fix: DQ enhancements
bidhan-nagarro May 21, 2026
d2061f2
fix: Merge branch 'feature/dq' into dev-testing-new
bidhan-nagarro May 21, 2026
14ff109
feat: TECH-9186 School Registration - NocoDD payload format changed
May 21, 2026
a36608b
feat: Merged School Registration
May 21, 2026
144f656
fix: DQ enhancements
bidhan-nagarro May 21, 2026
133d14d
fix: DQ enhancements
bidhan-nagarro May 21, 2026
1040c36
fix: DQ enhancements
bidhan-nagarro May 22, 2026
3e75c4d
fix: Merge branch 'feature/dq' into dev-testing-new
bidhan-nagarro May 22, 2026
b0552d9
fix: DQ enhancements
bidhan-nagarro May 22, 2026
8fd938f
fix: Merge branch 'feature/dq' into dev-testing-new
bidhan-nagarro May 22, 2026
bcf571b
fix: DQ enhancements
bidhan-nagarro May 22, 2026
52b4b17
fix: Merge branch 'feature/dq' into dev-testing-new
bidhan-nagarro May 22, 2026
ea3501a
fix: Merge branch 'feature/dq' into dev-testing-new
bidhan-nagarro May 22, 2026
0f86391
feat: TECH - 6338 Download DQ Kit button added
May 26, 2026
3a28552
feat: Merged TECH 6338 - Download DQ Button
May 26, 2026
57b95a3
feat: TECH - 6338: File path issue fixed
May 27, 2026
9b8b0b1
feat: Merged TECH - 6338
May 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
4 changes: 4 additions & 0 deletions api/data_ingestion/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
core,
deletion_requests,
email,
error_table,
groups,
qos,
roles,
schema,
school_registration,
upload,
users,
utils,
Expand Down Expand Up @@ -136,10 +138,12 @@ async def _ensure_local_dev_user():
app.include_router(core.router)
app.include_router(deletion_requests.router)
app.include_router(email.router)
app.include_router(error_table.router)
app.include_router(groups.router)
app.include_router(qos.router)
app.include_router(roles.router)
app.include_router(schema.router)
app.include_router(school_registration.router)
app.include_router(upload.router)
app.include_router(users.router)
app.include_router(utils.router)
Expand Down
111 changes: 111 additions & 0 deletions api/data_ingestion/internal/school_registration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import csv
import io
import json
import logging

import requests

from data_ingestion.internal.storage import storage_client
from data_ingestion.settings import settings
from data_ingestion.utils.data_quality import get_metadata_path

logger = logging.getLogger(__name__)


GEOLOCATION_CSV_COLUMNS = [
"school_id_giga",
"school_id_govt",
"school_name",
"latitude",
"longitude",
"education_level",
"contact_name",
"contact_email",
"verification_status",
]


def write_registration_csv_to_adls(
payload: dict,
file_upload,
registration_metadata: dict,
mode: str = "create",
) -> None:
"""
Formats the school registration payload as a single-row CSV and uploads it to ADLS.
"""
row = {
"school_id_giga": payload.get("giga_id_school", ""),
"school_id_govt": payload.get("school_id", ""),
"school_name": payload.get("school_name", ""),
"latitude": payload.get("latitude", ""),
"longitude": payload.get("longitude", ""),
"education_level": payload.get("education_level", ""),
"contact_name": payload.get("contact_name", ""),
"contact_email": payload.get("contact_email", ""),
"verification_status": registration_metadata.get(
"verification_status", "unverified"
),
}

output = io.StringIO()
writer = csv.DictWriter(output, fieldnames=GEOLOCATION_CSV_COLUMNS)
writer.writeheader()
writer.writerow(row)
csv_bytes = output.getvalue().encode("utf-8")

blob_client = storage_client.get_blob_client(file_upload.upload_path)
blob_client.upload_blob(
csv_bytes,
overwrite=True,
metadata={
"country": file_upload.country,
"uploader_email": file_upload.uploader_email,
"school_id_giga": payload.get("giga_id_school", ""),
"mode": mode,
},
)

metadata_payload = {
"country": file_upload.country,
"uploader_email": file_upload.uploader_email,
"dataset": "geolocation",
"mode": mode,
**registration_metadata,
}
metadata_path = get_metadata_path(file_upload.upload_path)
metadata_blob_client = storage_client.get_blob_client(metadata_path)
metadata_blob_client.upload_blob(
json.dumps(metadata_payload, indent=2).encode(),
overwrite=True,
)


def call_meter_soft_delete(school_id_giga: str, rejection_reason: str = None) -> None:
"""
Calls the GigaMeter API to soft-delete a school_new_registration record.
"""
if not settings.GIGAMETER_API_BASE_URL or not settings.GIGAMETER_API_TOKEN:
logger.warning(
"GIGAMETER_API_BASE_URL or GIGAMETER_API_TOKEN not configured. "
"Skipping soft-delete callback for school_id_giga=%s",
school_id_giga,
)
return

url = f"{settings.GIGAMETER_API_BASE_URL}/api/v1/school-registrations/rejection"
headers = {
"Authorization": f"Bearer {settings.GIGAMETER_API_TOKEN}",
"Content-Type": "application/json",
}
payload = {
"giga_id_school": school_id_giga,
"is_deleted": True,
"rejection_reason": rejection_reason or "Rejected by admin",
}

response = requests.put(url, headers=headers, json=payload, timeout=10)
logger.info(
"GigaMeter soft-delete successful for school_id_giga=%s", school_id_giga
)
return response.json()
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""

Revision ID: 49a684bb43f3
Revises: a3c6ab14b3f8
Create Date: 2025-11-27 10:50:01.201361

"""
from collections.abc import Sequence

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision: str = '49a684bb43f3'
down_revision: str | None = 'a3c6ab14b3f8'
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('approval_requests', sa.Column('upload_id', sa.String(), nullable=True))
op.create_index(op.f('ix_approval_requests_upload_id'), 'approval_requests', ['upload_id'], unique=False)
op.create_foreign_key('fk_approval_requests_upload_id_file_uploads', 'approval_requests', 'file_uploads', ['upload_id'], ['id'])
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint('fk_approval_requests_upload_id_file_uploads', 'approval_requests', type_='foreignkey')
op.drop_index(op.f('ix_approval_requests_upload_id'), table_name='approval_requests')
op.drop_column('approval_requests', 'upload_id')
# ### end Alembic commands ###
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
"""

Revision ID: 7b89fb20822f
Revises: 49a684bb43f3
Create Date: 2026-03-30 12:01:25.183717

"""
from collections.abc import Sequence

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision: str = '7b89fb20822f'
down_revision: str | None = '49a684bb43f3'
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.execute("DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'dq_mode') THEN CREATE TYPE dq_mode AS ENUM ('uploaded', 'master'); END IF; END $$;")
op.execute("DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'dqmodeenum') THEN CREATE TYPE dqmodeenum AS ENUM ('uploaded', 'master'); END IF; END $$;")

conn = op.get_bind()
inspector = sa.inspect(conn)
tables = inspector.get_table_names()
if 'dq_runs' not in tables:
op.create_table('dq_runs',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('upload_id', sa.String(), nullable=False),
sa.Column('dq_mode', postgresql.ENUM('uploaded', 'master', name='dq_mode', create_type=False), nullable=False, server_default='uploaded'),
sa.Column('status', sa.String(), nullable=False),
sa.Column('dagster_run_id', sa.String(), nullable=True),
sa.Column('result_path', sa.String(), nullable=True),
sa.ForeignKeyConstraint(['upload_id'], ['file_uploads.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_dq_runs_upload_id'), 'dq_runs', ['upload_id'], unique=False)

columns_audit = [c['name'] for c in inspector.get_columns('approval_request_audit_log')]
if 'dq_mode' not in columns_audit:
op.add_column('approval_request_audit_log',
sa.Column('dq_mode', postgresql.ENUM('uploaded', 'master', name='dqmodeenum', create_type=False), nullable=False, server_default='uploaded')
)

columns_req = [c['name'] for c in inspector.get_columns('approval_requests')]
if 'dq_mode' not in columns_req:
op.add_column('approval_requests',
sa.Column('dq_mode', postgresql.ENUM('uploaded', 'master', name='dqmodeenum', create_type=False), nullable=False, server_default='uploaded')
)

op.drop_constraint(op.f('uq_country_dataset'), 'approval_requests', type_='unique')
op.create_unique_constraint('uq_country_dataset', 'approval_requests', ['country', 'dataset', 'upload_id'])
op.alter_column('file_uploads', 'dq_full_path',
existing_type=sa.TEXT(),
type_=sa.String(),
existing_nullable=True)
op.alter_column('file_uploads', 'bronze_path',
existing_type=sa.TEXT(),
type_=sa.String(),
existing_nullable=True)
op.alter_column('file_uploads', 'is_processed_in_staging',
existing_type=sa.BOOLEAN(),
nullable=False,
existing_server_default=sa.text('false'))
op.alter_column('qos_school_connectivity', 'send_date_in',
existing_type=postgresql.ENUM('BODY', 'QUERY_PARAMETERS', 'NONE', name='senddateinenum'),
nullable=False,
existing_server_default=sa.text("'NONE'::senddateinenum"))
op.alter_column('qos_school_connectivity', 'school_id_giga_govt_key',
existing_type=sa.TEXT(),
type_=sa.String(),
existing_nullable=False,
existing_server_default=sa.text("'school_id_giga'::text"))
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column('qos_school_connectivity', 'school_id_giga_govt_key',
existing_type=sa.String(),
type_=sa.TEXT(),
existing_nullable=False,
existing_server_default=sa.text("'school_id_giga'::text"))
op.alter_column('qos_school_connectivity', 'send_date_in',
existing_type=postgresql.ENUM('BODY', 'QUERY_PARAMETERS', 'NONE', name='senddateinenum'),
nullable=True,
existing_server_default=sa.text("'NONE'::senddateinenum"))
op.alter_column('file_uploads', 'is_processed_in_staging',
existing_type=sa.BOOLEAN(),
nullable=True,
existing_server_default=sa.text('false'))
op.alter_column('file_uploads', 'bronze_path',
existing_type=sa.String(),
type_=sa.TEXT(),
existing_nullable=True)
op.alter_column('file_uploads', 'dq_full_path',
existing_type=sa.String(),
type_=sa.TEXT(),
existing_nullable=True)
op.drop_constraint('uq_country_dataset', 'approval_requests', type_='unique')
op.create_unique_constraint(op.f('uq_country_dataset'), 'approval_requests', ['country', 'dataset'], postgresql_nulls_not_distinct=False)
op.drop_column('approval_requests', 'dq_mode')
op.drop_column('approval_request_audit_log', 'dq_mode')
op.drop_index(op.f('ix_dq_runs_upload_id'), table_name='dq_runs')
op.drop_table('dq_runs')
# ### end Alembic commands ###
2 changes: 2 additions & 0 deletions api/data_ingestion/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .approval_requests import ApprovalRequest
from .base import BaseModel
from .deletion_requests import DeletionRequest
from .dq_run import DQRun
from .file_upload import FileUpload
from .ingest_api_qos import ApiConfiguration, SchoolConnectivity, SchoolList
from .users import Role, User, UserRoleAssociation
Expand All @@ -16,4 +17,5 @@
"User",
"Role",
"UserRoleAssociation",
"DQRun",
]
8 changes: 7 additions & 1 deletion api/data_ingestion/models/approval_requests.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
from datetime import datetime

from pydantic import UUID4
from sqlalchemy import VARCHAR, DateTime, ForeignKey, UniqueConstraint, func
from sqlalchemy import (
VARCHAR,
DateTime,
ForeignKey,
UniqueConstraint,
func,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship

from .base import BaseModel
Expand Down
36 changes: 36 additions & 0 deletions api/data_ingestion/models/dq_run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from enum import Enum

from sqlalchemy import ForeignKey
from sqlalchemy.dialects.postgresql import ENUM as SQLEnum
from sqlalchemy.orm import Mapped, mapped_column

from .base import BaseModel


class DQModeEnum(str, Enum):
uploaded = "uploaded"
master = "master"


class DQRun(BaseModel):
__tablename__ = "dq_runs"

id: Mapped[int] = mapped_column(primary_key=True)

upload_id: Mapped[str] = mapped_column(
ForeignKey("file_uploads.id", ondelete="CASCADE"),
index=True,
nullable=False,
)

dq_mode: Mapped[DQModeEnum] = mapped_column(
SQLEnum(DQModeEnum, name="dq_mode"),
nullable=False,
default=DQModeEnum.uploaded,
)

status: Mapped[str] = mapped_column(nullable=False)

dagster_run_id: Mapped[str | None] = mapped_column(nullable=True)

result_path: Mapped[str | None] = mapped_column(nullable=True)
24 changes: 24 additions & 0 deletions api/data_ingestion/routers/approval_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from data_ingestion.db.primary import get_db as get_primary_db
from data_ingestion.db.trino import get_db
from data_ingestion.internal.auth import azure_scheme
from data_ingestion.internal.school_registration import call_meter_soft_delete
from data_ingestion.internal.storage import storage_client
from data_ingestion.models import (
ApprovalRequest,
Expand All @@ -27,6 +28,7 @@
UploadListing,
)
from data_ingestion.schemas.core import PagedResponseSchema
from data_ingestion.utils.nocodb import update_nocodb_record_by_field

router = APIRouter(
prefix="/api/approval-requests",
Expand Down Expand Up @@ -480,6 +482,28 @@ async def submit_upload_review(
body.rejected_rows, staging, upload_id, db
)

# Call GigaMeter soft-delete and update NocoDB for rejected GigaMeter registrations
if rejected_change_ids and file_upload.source == "gigameter":
# Extract school_id_giga from rejected change_ids
for change_id in rejected_change_ids:
school_id_giga = change_id.split("|")[0]
# Update NocoDB status to rejected
update_nocodb_record_by_field(
table_name="SchoolRegistrations",
field_name="giga_id_school",
field_value=school_id_giga,
update_data={
"verification_status": "rejected",
"rejected_on": str(datetime.now(UTC)),
"rejection_reason": "Rejected by admin during manual review",
},
)
# Call GigaMeter soft-delete
call_meter_soft_delete(
school_id_giga=school_id_giga,
rejection_reason="Rejected by admin during manual review",
)

# Create the audit log first so its ID can be included in the approval payload.
approval_request_log_id = None
if approval_request:
Expand Down
Loading