Date: 2026-04-26
This note fixes the technical `As-Is` picture from the provided HAR files and turns it into a `To-Be` MVP bridge design between two existing systems:
The goal of this analysis is not to restate the HAR files, but to identify:
Analyzed HAR files:
Important note:
These two files should be treated as weak evidence and not as the basis for integration design.
The current process is a two-system workflow with a manual human bridge in the middle.
The teacher today performs four different translations by hand:
The MVP bridge must therefore appear **after the faculty-side academic decision is approved** and **before the BRS-side statement is locked**.
In strict terms, the MVP should automate:
The MVP should **not** auto-sign a BRS statement in the first safe implementation.
| Business action | Method + endpoint | Interaction type | What is confirmed |
|---|---|---|---|
| Open teacher portfolio table | `GET https://gtifem.ru/portfolio/` | Server-rendered HTML page | The portfolio page arrives as full HTML with rows, action links, hidden moderation form, work ids, and row data. |
| Open review modal | No separate request | Pure UI action in browser | The moderation form is already embedded in the portfolio HTML as hidden block `id='moderate'`. |
| Preview work report before final approval | `POST https://gtifem.ru/portfolio/` with `id=<work_id>&action=print` | AJAX request returning HTML | The server returns printable HTML report. |
| Save teacher decision | `POST https://gtifem.ru/portfolio/` with multipart form data including `mod`, `RATING`, `THEME`, `COMMENTS`, `ACTION=edit`, `id`, `MOD_ID`, `moderate` | AJAX form submit | This is the real persistence call for the faculty-side decision. |
| Change competencies | `POST https://gtifem.ru/portfolio/` via `upd_competence(this)` | AJAX form submit | Competency editing is inline and asynchronous. |
| Delete work row | `POST https://gtifem.ru/portfolio/` with `ACTION=delete` | AJAX call | Deletion is row-level AJAX action. |
From the portfolio HTML and inline JS:
The preview window script does only this:
That means the real server-side approval is still the later `ACTION=edit` AJAX submission.
Faculty-side approval is a **two-step UI flow but a one-step persistence flow**:
For `mod=Y` / `Принято`, the preview window is part of the acceptance ritual.
For `mod=R` / `На доработку`, the JS hides preview and reveals direct submit instead, so the rejection/rework path is shorter.
This difference matters for MVP event detection.
| Business action | Method + endpoint | Interaction type | What is confirmed |
|---|---|---|---|
| Open new statement category screen | `GET https://xfem.ru/grade/report/custom/custom.php?courseid=12636` | Server-rendered HTML page | First page before choosing category. |
| Open statement creation form for concrete category | `GET https://xfem.ru/grade/report/custom/custom.php?categid=2&courseid=12636` | Server-rendered HTML page | Real HTML form with statement fields. |
| Save new statement | `POST https://xfem.ru/grade/report/custom/custom.php` | HTML form submit + redirect | Returns `303 See Other`, then redirects to score table page. |
| Open score table edit mode | `GET https://xfem.ru/grade/report/custom/index.php?plugin=custom&id=12636&sesskey=...&edit=1` | Server-rendered HTML page | Main edit form with hundreds of grade inputs. |
| Save score values | `POST https://xfem.ru/grade/report/custom/index.php` | Batch HTML form submit | Saves many grade fields at once and returns full HTML page. |
| Persist UI scroll preference | `POST https://xfem.ru/grade/report/custom/ajax_lock_preference.php` | AJAX call | Service call, not grade business logic. |
| Open non-edit table mode | `GET https://xfem.ru/grade/report/custom/index.php?plugin=custom&id=12636&sesskey=...&edit=0` | Server-rendered HTML page | Non-edit table view before signing flow. |
| Sign / lock filled statement column | `POST https://xfem.ru/grade/report/custom/ajax/lock.php` with `courseid`, `eid`, `action=locksaved` | AJAX JSON call | Real lock endpoint for official signature / blocking. |
- This button only manipulates the opener DOM and reveals the hidden submit button. - It is **not** the final persistence endpoint.
These are not clean JSON APIs. They are full HTML pages and must be treated as unstable UI contracts.
These are classical PHP form posts, not resource-oriented REST APIs.
The teacher portfolio page already contains enough local state to support the moderation workflow:
- `mod` - `RATING` - `THEME` - `COMMENTS` - `ACTION=edit` - `id` - `MOD_ID` - `moderate`
Example row evidence also shows:
This is important because `gtifem.ru` does expose a faculty-side student identity handle, but it is a **different namespace** from BRS-side student ids.
The concrete statement form on `xfem.ru` contains:
Observed save payload:
`id=0` means create, not update.
The server does **not** return a clean machine-readable created statement object. It redirects back to the table.
The edit page contains multiple forms, but the main one is:
with hidden fields:
and many cell fields of the form:
Observed counts in the captured save sample:
This confirms that saving one or a few values is still handled as a **batch form post**, not as a per-cell endpoint.
The same statement column is represented in several linked ways:
Strict conclusion:
This relation is critical for the MVP writer.
The visible UI link on the page may point to `saved_lock.php?id=...&eid=i493222`, but the actual lock operation in browser execution is an AJAX call:
with:
Observed JSON response keys:
Observed lock result:
Strict conclusion:
This file does **not** capture the actual `xfem.ru` login flow.
It contains:
Therefore it does not prove:
Any documentation that would claim these points from the provided file would be overstated.
This file is not useful for table-load mechanics.
It contains only websocket noise and does not capture the intended table-opening requests.
The bridge problem is not only “send score from A to B”.
There are at least seven different gaps.
`gtifem.ru` stores:
`xfem.ru` stores:
The systems do not share a native “same assessment object”.
Faculty-side uses one student identity namespace, for example:
BRS-side uses another namespace, for example:
These ids are not shown to be the same.
This means the MVP cannot safely rely on:
It needs a crosswalk.
`gtifem.ru` level values:
`xfem.ru` expects numeric values.
There is no evidence that a universal fixed mapping should be hardcoded for all work types, all disciplines, and all statement categories.
Therefore the MVP needs a configurable conversion layer, not a magic formula.
To write into BRS, the system must know:
The create-statement POST does not return a compact created object with `column_id`.
So after statement creation, the adapter must re-open or parse the returned table HTML and resolve the newly created column by stable attributes.
Faculty-side save is AJAX to a page endpoint returning non-structured content (`Array1` in captured sample).
BRS-side grade save is a large batch HTML form post.
This means the MVP bridge cannot be a thin “call two JSON APIs” service.
It must be a browser-aware or HTML-aware adapter.
Faculty-side officiality happens at `ACTION=edit` after teacher approval flow.
BRS-side officiality happens at `action=locksaved`.
The safe transfer window lies strictly between them:
Neither flow, in the captured form, provides a shared transfer id.
Without a dedicated bridge record, the system cannot safely answer:
The MVP therefore needs its own audit ledger.
The first technically realistic bridge should contain these modules:
The bridge should start from the first durable faculty-side approval event:
but should not immediately write to BRS in the safest first version.
The safest first boundary is:
Minimum bridge object:
transfer_id source_system = gtifem source_work_id faculty_student_id faculty_teacher_id student_fio group_code module_name work_type_name competencies[] faculty_status_code faculty_status_text faculty_level_code faculty_level_text review_text faculty_saved_at rule_pack_id rule_pack_version target_system = xfem xfem_courseid xfem_student_id xfem_categid xfem_typeid xfem_statement_description xfem_statement_date xfem_column_id desired_numeric_score existing_numeric_score transfer_mode transfer_status lock_state_before_write write_attempted_at write_result lock_state_after_write
This record should live outside both legacy systems.
Teacher checks work -> faculty-side approval saved on gtifem.ru -> bridge captures/reads approved decision -> bridge normalizes decision and resolves student identity -> bridge converts level to numeric score by rule pack -> bridge resolves target BRS statement/column -> bridge loads current BRS edit form -> bridge verifies column is not locked -> bridge compares current and desired value -> bridge writes score through batch form post -> bridge records audit trail -> teacher reviews BRS result -> teacher signs BRS statement manually
In the safest MVP, teacher approval should remain at two layers:
- teacher decides status, level, review text; - this remains the authoritative academic judgement.
- teacher still signs the statement/column after reviewing the transferred scores.
This keeps the AI/adapter out of the final official locking action in early rollout.
Do **not** hardcode one global conversion for all work types.
Instead use a versioned rule pack, for example:
rule_pack_id = vit_2025_2026_portfolio_practice_v1
if module = "Введение в информационные технологии"
and faculty_work_type in {portfolio work types mapped to practical/lab evaluation}
and faculty_level = "Продвинутый"
then numeric_score = ...
The exact numeric mapping must be approved by academic owners.
From an engineering perspective, the correct design is:
The adapter should not rely on free-text title only.
It should resolve target statement using a deterministic tuple:
Then it should re-open the BRS table and resolve:
This should be treated as the canonical resolved column identity.
Recommended write algorithm:
This is safer than synthesizing a “small custom POST” from scratch.
The MVP must be idempotent.
Suggested rules:
These constraints should be explicitly stated in any technical design.
What it does:
Best for:
What it does:
Best for:
What it does:
Best for:
The MVP should not:
Mandatory re-capture:
- current `3_xfem_login.har` does not contain the intended evidence. - reshoot from clean Network: - open login page; - submit credentials; - capture redirects; - open first authenticated page.
Optional but useful re-capture:
- current `4_xfem_open_scores_table.har` is not useful. - not critical for MVP because edit mode and save flow are already captured, but still useful for full documentation.
Optional only if deeper faculty-side automation is planned:
- opening modal; - previewing report; - clicking preview `Подписать`; - final `ACTION=edit` submission.
This is not strictly required anymore for endpoint mapping, because the current captures and inline JS are already enough to identify the real persistence boundary.
The MVP bridge should be placed here:
gtifem faculty approval saved -> approved transfer record created -> level-to-score conversion by rule pack -> student crosswalk resolution -> BRS statement resolution / creation -> unlocked BRS batch form write -> teacher reviews and signs in BRS
This is the first implementation point that is both:
The most important non-obvious conclusion from the HAR analysis is this:
**the bridge is not “AI checks work and writes grade”.**
The real bridge is:
**approved academic decision -> normalized transfer record -> rule-based numeric fixation in an unlocked BRS statement -> human official signature.**
That is the correct MVP boundary.