Skip to content

Reconcile OData documentation with service metadata contract - #6

Open
tgilkison1 wants to merge 11 commits into
masterfrom
feature/add-missing-delivery-odata-feeds
Open

Reconcile OData documentation with service metadata contract#6
tgilkison1 wants to merge 11 commits into
masterfrom
feature/add-missing-delivery-odata-feeds

Conversation

@tgilkison1

Copy link
Copy Markdown

Reconcile OData documentation with the service $metadata contract

This PR audits and corrects the Delivery OData (v3) and Authoring OData (v4) documentation against each service's $metadata contract, adds re-runnable reconciliation tooling, and records the supporting decisions.


Summary of Changes

Area Files Changed What Was Done
Delivery OData docs src/deliveryodata/*.rst Added missing feeds/types/properties/actions; fixed keys, casing, EDM types, nullability, navigation targets; corrected HTTP-method and example-URL claims; fixed version history
Authoring OData docs src/authoringodata/*.rst Added missing properties; corrected ModifiedDateTime types; removed nonexistent TopicPath, added TopicId; fixed composite-key filter docs
Reconciliation tooling ai-scripts/ $metadata-vs-RST reconciler (v3+v4), baseline fetcher
Decision log ai-docs/adrs/ Architecture decisions: docs-follow-code, tooling rationale, Results redirect, metadata-gap handling
Guardrails ai-docs/rails/ How to run reconciliation and edit od: directives safely
Audit trail ai-docs/proposed-fixes/ Per-finding classification with before/after diffs
Built HTML docs/ Regenerated from corrected source

What Was Fixed (Delivery OData highlights)

78 total findings reconciled against $metadata baseline (tenant 406611, captured 2026-07-13):

  • Case-sensitive naming (would cause 404s): AttemptMetadata.AttemptId (not AttemptID), Timezone.CurrentUTCTime (not CurrentUtcTime), Role.Name key (not ID)
  • Missing properties (7): ActionableSchedule.AssessmentID, Appointment.ExternalAppointmentData, AssessmentTranslation.Description, RulesOfConduct.AllowedResources, RulesOfConductTranslation.AllowedResources, Schedule.ExternalProctoringID, PrintBatchUpload (entire property set)
  • Wrong EDM types: Rubric.ShowParticipant (Double, not String), ReplayResultsByDateRange params (String, not DateTime)
  • Missing action return types: Upsert, ScheduleAndLaunch, UpsertParticipantAndSchedule, ReplayResultsByIDList
  • Missing action parameters: ActionableSchedulesForObservation.ScheduleID, ActionableSchedules.ShowHidden
  • Missing :notnull: flags: 21 properties
  • Missing :collection: flags: Attempt.BranchedResults, Question.Rubric
  • Broken cross-references: Administrator Upsert action links
  • HTTP method corrections: PrintBatchUploads supports POST
  • Example URL fixes: Corrected singular→plural entity set names

Full item-by-item breakdown: ai-docs/delivery-odata-affected-areas.md


Verification

Quality gates (all passing):

  • sphinx-build -b html src docs — clean (0 errors)
  • Reconciler: Delivery 17 accepted residual findings, Authoring 0

Methodology:

  1. Structural reconciliation via ai-scripts/reconcile_odata.py against $metadata
  2. Controller-code pass for HTTP methods, filterability, action returns not in metadata
  3. Independent line-by-line review of each applied change
  4. Version archaeology to verify versionadded stamps against git tags

Expected Reconciler Residuals (17 findings — intentionally kept)

These are service-side bugs, not doc errors. The docs describe the intended contract:

Residual Count Explanation
GetAccessUrl, CanLiveProctor return type missing 2 Service $metadata omits return type (registration bug)
AvailableAppointments + List_1OfDateTime 2 Service mangles List<DateTime> into fake type
PracticeAttempts / PracticeAttempt extra 2 Deployment lag — valid code, not yet on baseline tenant
[NOTNULL EXTRA] (11 properties) 11 Service enforces via validators, but v3 metadata can't express it

Service Tickets to Raise (Delivery QM / Firestar)

# Defect Root Cause
E1 GetAccessUrl emits no ReturnType .Returns<string>() chained on wrong variable
E2 CanLiveProctor emits no ReturnType .Returns<bool>() chained on wrong variable
E3 AvailableAppointments returns List_1OfDateTime Should use ReturnsCollection<DateTime>()
E4 PrintBatchUpload.PrecessedDateTime misspelling Typo in C# entity (should be "Processed")
E5 Rubric.ShowParticipant typed as double Looks like a flag mis-typed as float
E6 11 properties nullable in metadata but required Add [Required] or non-nullable CLR types

How to Reproduce Verification

# Reconcile (expect Delivery 17, Authoring 0)
python ai-scripts/reconcile_odata.py `
    --metadata ignore/metadata-baselines/delivery.2026-07-13.metadata.xml `
    --rst-dir src/deliveryodata --product Delivery

python ai-scripts/reconcile_odata.py `
    --metadata ignore/metadata-baselines/authoring.2026-07-13.metadata.xml `
    --rst-dir src/authoringodata --product Authoring

# Build docs
sphinx-build -b html src docs

Key Files for Review

tgilkison1 and others added 11 commits June 29, 2026 14:30
Closes gap between ODataConfig.cs (38 entity sets) and documentation.

Naming fixes (URL-breaking):
- TimeZones -> Timezones
- SessionAuditLog -> SessionAuditLogs

New od:feed definitions:
- AnswerAuditLogs, AssessmentOutcomes, AssessmentMetadata (+ type),
  AssessmentTranslations, Appointments, PrintBatchUploads, Roles,
  RulesOfConductTranslations

feeds.rst index:
- Added 12 missing entries (now 38 total)

New properties:
- Administrator: PeopleSyncID, Blocked
- Participant: JobTitle, PeopleSyncID, Blocked
- Schedule: IsDeleted, MinMinutesBetweenAttempts
- MonitoringType: TranslationToolLangs, TextToSpeech, RequireObserver,
  RequireConfirmation, RequirePasscode, Category
- RulesOfConduct: AllowedResources

Navigation property:
- Assessment.AssessmentMetadata

OData actions:
- Participants: Upsert, ScheduleAndLaunch, UpsertParticipantAndSchedule
- Participant: ActionableScheduleForObservation
- Administrator: GetAccessUrl (+ Upsert params update)
- Schedule: CanLiveProctor, GetLiveProctorUrl
- Results: SubmitResultsByAdministrator

Fixes:
- RulesOfConductTranslation composite key (Language 🔑)
- Action param typos in monitoring_type.rst

Infra:
- README.md: Full documentation (92 lines)
- AGENTS.md: Agent guidance with durable lessons (95 lines)
Align the Delivery OData documentation with the qm-DeliveryOData service
code (ODataConfig.cs and the entity classes):

- Add PracticeAttempts feed and PracticeAttempt type page; register it
  in the types toctree and the feeds index.
- Fix 12 malformed entries in the feeds index that used broken
  :od:feed: role syntax (missing backticks / literal newlines).
- Document five previously missing actions with code-accurate inputs:
  Participants.Upsert, Participant.ScheduleAndLaunch,
  Participants.UpsertParticipantAndSchedule,
  Participant.ActionableScheduleForObservation, Administrator.GetAccessUrl.
- Mark RulesOfConductTranslation.Language as part of the composite key.
- Fix invalid Edm.RulesOfConduct type reference (now RulesOfConduct).

Rebuild the committed HTML output under docs/.
Phase 2 of OData documentation audit - Delivery OData service.

DOC fixes (A-series):
- A1: ResultAuditLog.IsInQueue stray quote typo
- A2: Role key=Name (not ID), add Administrators nav property
- A3: Rubric.ShowParticipant type Edm.Double (not String)
- A4: AttemptMetadata.AttemptId casing (lowercase d)
- A5: Timezone.CurrentUTCTime casing
- A6: TestCenter.ID add missing 🔑 flag
- A7: Qualify ambiguous Upsert xrefs in Administrators feed

DOC-ADD (B-series - undocumented properties):
- B1: ActionableSchedule.AssessmentID
- B2: Appointment.ExternalAppointmentData
- B3: AssessmentTranslation.Description
- B4: PrintBatchUpload (5 members including PrecessedDateTime typo)
- B5-B6: RulesOfConduct/Translation.AllowedResources
- B7: Schedule.ExternalProctoringID

DOC-ADD (C-series - response types):
- UpsertParticipantResponse, UpsertAdministratorResponse
- UpsertParticipantAndScheduleResponse, CustomScheduleAndLaunchResponse
- PublishResultResponse

DOC-ADD (D-series - action return types/params):
- Wire return types for Upsert, ScheduleAndLaunch, etc.
- D6: ActionableSchedulesForObservation add ScheduleID input

Verification addendum (G-series):
- G1: ReplayResultsByDateRange params Edm.String (not DateTime)
- G2: ActionableSchedules add ShowHidden input
- G3: Fix RulesOfConductTranslations nav (remove Edm. prefix, add :collection:)
- G5: Remove duplicate sentence in ExceptionSchedules

Upgraded reconciler findings (H-series):
- H1: Add missing :notnull: flags (21 properties)
- H3: Add :collection: to BranchedResults, Question.Rubric
- H4: Fix Edm.-prefixed nav targets in scoringtask.rst

Adds reconciliation tooling (ai-scripts/) and documentation (ai-docs/)
for reproducible audits.

Remaining 16 findings are intentional:
- E1-E3: Service metadata bugs (docs correct)
- F1: PracticeAttempt deployment lag
- H2: 10 props where docs mark :notnull: but metadata nullable (docs correct)
Phase 3 of OData documentation audit - Authoring OData service.

Type fixes (A-series):
- A1-A3: ModifiedDateTime type Edm.DateTimeOffset (not String) in
  AssessmentRevision, QuestionRevision, Topic

Missing properties (B-series):
- B1-B9: AssessmentAML full property set (9 props including nav)
- B10-B18: QuestionQML full property set (9 props including nav)
- B19: AssessmentRevision.AssessmentName
- B20-B21: QuestionRevision.TopicId + Topic nav property

Removed (C-series):
- C1: QuestionRevision.TopicPath (not in metadata; replaced by TopicId/Topic)

Nullability flags (D-series):
- Added :notnull: to 13 properties across all 5 entity types
- Composite keys (AssessmentRevisionId, Language, QuestionRevisionId)
- Non-nullable CLR types (CreatedDateTime, ModifiedDateTime, IsDeleted, etc.)

Remaining 2 findings are intentional:
- AssessmentAML.AssessmentRevisionId: composite key, metadata doesn't
  explicitly mark Nullable=false (implicit per OData v4 spec)
- QuestionQML.QuestionRevisionId: same pattern
- Mark Delivery and Authoring audits as complete
- Add audit summary table with findings breakdown
- Reference Firestar ticket for service-side bugs
Includes all Delivery and Authoring documentation fixes from the
reconciliation audit (Phases 2-3).
- Add shields.io badges with consistent black (#1a1a1a) / gold (#D4AF37) styling
- Add emoji icons for visual hierarchy
- Restructure sections with clear headers
- Add reconciliation tooling quick reference
- Include source-of-truth diagram
- Add centered feedback section with contact badges

Also fix edmx_parser.py to treat key properties as non-nullable per OData spec
(CSDL 6.2.1) - resolves false NOTNULL EXTRA on composite keys.
…fects

Pre-merge review found factually wrong statements in the reconciled docs
that would mislead integrators. Fixed against the service source of truth:

- versionadded: replace fabricated 2021.08 placeholders with release-tag-
  verified versions; drop unconfirmable post-2024.09 stamps rather than guess.
- HTTP methods: correct three feeds documented read-only that are writable
  (AssessmentMetadata full CRUD; Appointments POST+DELETE;
  RulesOfConductTranslations POST+PATCH), verified against controllers.
- example URLs: use registered plural entity-set names (singular forms 404);
  fix a copy-paste Groups->Roles $links target.
- literal-block :: typo that broke the Sphinx build; present-tense ShowHidden
  note; consumer-facing metadata-gap notes; add AssessmentMetadata.Value
  :notnull:. Authoring: drop nonexistent TopicPath, fix composite-key filters.

Reconciler residual is now the accepted set only (Delivery 17, Authoring 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds pr-report.md (single-page audit briefing for the PR author and
reviewers: methodology, accepted-residual guide, service tickets E1-E6) and
branch-review-remediation.md (the pre-merge review findings and their
resolution). Links both from the ai-docs and proposed-fixes indexes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebuild docs/ from the corrected source (sphinx-build -b html src docs).
Supersedes the earlier rebuild that baked in the literal-block build error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant