Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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 src/webapp/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ class InstTable(Base):
legacy_id: Mapped[str | None] = mapped_column(
String(VAR_CHAR_LENGTH), nullable=True
)
# Only populated for GenAI onboarding schools (loose uploads; mapping pipeline).
genai_id: Mapped[str | None] = mapped_column(
String(VAR_CHAR_LENGTH), nullable=True, unique=True
)
created_at: Mapped[datetime.datetime] = mapped_column(
DateTime(timezone=True),
server_default=func.now(),
Expand Down
15 changes: 9 additions & 6 deletions src/webapp/routers/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1264,7 +1264,7 @@ def _infer_allowed_schemas_from_filename(file_name: str, inst: Any) -> List[str]

Args:
file_name: Name of the file (used for keyword inference).
inst: Institution row (must have legacy_id attr for legacy fallback).
inst: Institution row (legacy_id or genai_id enables arbitrary-name UNKNOWN fallback).

Returns:
Sorted list of allowed schema names (e.g. ["COURSE"], ["STUDENT"], ["UNKNOWN"]).
Expand All @@ -1291,7 +1291,7 @@ def _infer_allowed_schemas_from_filename(file_name: str, inst: Any) -> List[str]
if has_semester:
inferred_from_name.add("SEMESTER")
if not inferred_from_name:
if getattr(inst, "legacy_id", None):
if getattr(inst, "legacy_id", None) or getattr(inst, "genai_id", None):
return ["UNKNOWN"]
raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
Expand Down Expand Up @@ -1408,27 +1408,30 @@ def _resolve_schema_namespace_and_extension(
base_schema_id: Any,
file_name: str,
) -> Tuple[str, Optional[Dict[str, Any]]]:
"""Resolve schema_namespace and updated_inst_schema by institution type (edvise/pdp/legacy)."""
"""Resolve schema_namespace and updated_inst_schema by institution type (edvise/pdp/legacy/genai)."""
pdp_id = getattr(inst, "pdp_id", None)
edvise_id = getattr(inst, "edvise_id", None)
legacy_id = getattr(inst, "legacy_id", None)
if not has_at_most_one_school_type(pdp_id, edvise_id, legacy_id):
genai_id = getattr(inst, "genai_id", None)
if not has_at_most_one_school_type(pdp_id, edvise_id, legacy_id, genai_id):
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Institution configuration error: cannot have more than one of "
"pdp_id, edvise_id, or legacy_id set",
"pdp_id, edvise_id, legacy_id, or genai_id set",
)
if edvise_id:
return _resolve_edvise_schema(sess, now)
if pdp_id:
return _resolve_pdp_schema(sess, now)
if legacy_id:
return ("legacy", None)
if genai_id:
return ("legacy", None)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=(
"Institution configuration error: institution has no pdp_id, edvise_id, "
"or legacy_id; cannot resolve validation schema."
"legacy_id, or genai_id; cannot resolve validation schema."
),
)

Expand Down
11 changes: 6 additions & 5 deletions src/webapp/routers/data_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1376,7 +1376,7 @@ def test_validation_helper_pdp_and_edvise_mutual_exclusivity(

assert response.status_code == 500
assert (
"cannot have more than one of pdp_id, edvise_id, or legacy_id set"
"cannot have more than one of pdp_id, edvise_id, legacy_id, or genai_id set"
in response.json()["detail"]
)

Expand All @@ -1388,14 +1388,15 @@ def test_validation_helper_pdp_and_edvise_mutual_exclusivity(
def test_validation_helper_rejects_institution_without_school_type(
edvise_client: TestClient, edvise_session: sqlalchemy.orm.Session
) -> None:
"""Upload validation requires pdp_id, edvise_id, or legacy_id on the institution."""
"""Upload validation requires a school-type id on the institution."""
inst = edvise_session.execute(
select(InstTable).where(InstTable.id == EDVISE_INST_UUID)
).scalar_one()
saved = (inst.edvise_id, inst.pdp_id, inst.legacy_id)
saved = (inst.edvise_id, inst.pdp_id, inst.legacy_id, inst.genai_id)
inst.edvise_id = None # type: ignore
inst.pdp_id = None # type: ignore
inst.legacy_id = None # type: ignore
inst.genai_id = None # type: ignore
edvise_session.commit()

from .data import STATE
Expand All @@ -1408,9 +1409,9 @@ def test_validation_helper_rejects_institution_without_school_type(
+ "/input/validate-upload/test_student_file.csv",
)
assert response.status_code == 500
assert "no pdp_id, edvise_id, or legacy_id" in response.json()["detail"]
assert "no pdp_id, edvise_id, legacy_id, or genai_id" in response.json()["detail"]

inst.edvise_id, inst.pdp_id, inst.legacy_id = saved
inst.edvise_id, inst.pdp_id, inst.legacy_id, inst.genai_id = saved
edvise_session.commit()


Expand Down
Loading
Loading