Hotfixes into unstable#6046
Open
rtibbles wants to merge 30 commits into
Open
Conversation
…value Previously the editor emitted an `update` on every editor state change via a deep watcher on `editor.state`. This caused frequent re-serialization and required an `isUpdatingFromOutside` flag to break the feedback loop when applying parent-driven content updates. Now the markdown update is emitted only when the editor loses focus (blur), and the latest emitted markdown is cached. When `prop.value` changes, it is compared against the cache so an echoed-back value skips unnecessary re-rendering of the editor content. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-on-blur refactor(TipTapEditor): emit markdown on blur and cache last emitted value
Optimize query for user CSV export
Gate SubmissionDetailsModal review actions on isAdmin from the Vuex store rather than an adminReview prop, so admin users arriving via any route automatically see the Review button and side panel. Remove the adminReview prop and all call sites that set it; simplify administration/router.js to props: true.
…8385cb Route admins from notification "view more" into submission review mode
…inting - CI linting of new migrations on pull requests - Declarative dual-write trigger decorator (mirror_field) - Reusable batched-backfill command (idempotent, resumable, throttled) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LfZvkigk8hdsKdEif3hzBi
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LfZvkigk8hdsKdEif3hzBi
Expand stage of the zero-downtime int->bigint widening: - Add nullable file_size_bigint shadow column and its index (built CONCURRENTLY). - Mirror file_size into it via the change-guarded @mirror_field trigger. - Wire the online backfill as a commented deploy-migrate step. - Stage the cutover and contract steps as comments on the File model. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LfZvkigk8hdsKdEif3hzBi
…e_bigint Almost zero-downtime migration tooling; widen File.file_size to bigint (expand stage)
- supports_resumable flag on the GCS storage backends - get_stored_object_md5: dedup lookup against an object's GCS-computed md5 - create_resumable_upload_session: pins md5 + declared-size metadata - hex_to_base64 checksum helper Part of learningequality#5975. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UzUP3UYP4cLyouvssXyekj
- accept a `resumable` flag (defaults off) - GCS: skip when the stored md5 matches the checksum, else return a server-initiated resumable session URI - non-GCS backends fall back to single-PUT - reject non-resumable uploads over 500 MB - make `size` an IntegerField, dropping the redundant float casts Part of learningequality#5975. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UzUP3UYP4cLyouvssXyekj
Add opt-in resumable uploads to the file upload URL endpoint
…ar import The GCS storage backend imports utils.files at module load. files' top-level `from contentcuration.models import File / generate_object_storage_name` then re-entered a partially initialized contentcuration.models during app boot (DEFAULT_FILE_STORAGE=GCS), raising ImportError and crash-looping the pods. The test suite missed it: pytest imports models early, so models is complete before the storage modules load files. Move File and generate_object_storage_name imports into their call sites (create_file_from_contents, get_file_diff, get_thumbnail_encoding). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ineqU2EGLAcWW2WPWR3mE
…upload-circular-import Fix circular import breaking deploy
…objects The resumable upload_url path calls get_stored_object_md5(filepath) to dedup against a stored object's md5. On CompositeGCS this delegated to _get_readable_backend(name), which raises FileNotFoundError when the object is in no backend -- i.e. every not-yet-uploaded file -- 500ing upload_url for all new resumable uploads. Catch FileNotFoundError and return None, matching GoogleCloudStorage.get_stored_object_md5 for a missing blob. Add regression tests for the found and not-found cases; the not-found test fails against the pre-fix code (FileNotFoundError). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ineqU2EGLAcWW2WPWR3mE
…md5-missing-object Fix not found error for md5
Provides RENDERABLE_PRESETS_ORDER for the included_presets bitmask. The new le-utils adds a QTI question type to exercises.question_choices, which Django picks up as an assessmentitem.type AlterField migration. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a nullable included_presets IntegerField to the abstract kolibri_content.base_models.File, inherited by both the kolibri_content (sqlite export) and kolibri_public (import-metadata API) File mirrors. It holds a bitmask of the renderable presets a device needs to render a file. The column is additive and nullable, so old Kolibri ignores it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
In create_associated_file_objects, set each renderable (non-supplementary) file's own-preset bit (2 ** RENDERABLE_PRESETS_ORDER.index(preset_id)) and leave supplementary files NULL. A preset missing from the append-only ordering is logged and skipped rather than aborting the channel publish. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add VERSION_6 carrying included_presets and set it as CONTENT_SCHEMA_VERSION so new Kolibri knows an export carries the column. MIN_CONTENT_SCHEMA_VERSION stays VERSION_5 since the column is additive and returned regardless. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…1973c5 feat: export included_presets renderable bitmask for content-schema import gating
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e45197 feat: export 64-bit file_size_bigint at publish
Conflicts: .github/workflows/pythontest.yml contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue contentcuration/contentcuration/migrations/0168_alter_assessmentitem_type.py contentcuration/contentcuration/models.py requirements.in requirements.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merge hotfixes into unstable
Conflicts:
We had conflicted migrations (repeated 0168 migrations for the same field) - I prefered unstable, then made a migration merge to resolve the migration histories.
Reviewer guidance
Verify that the conflicts have been resolved properly - the TipTapEditor is the most complicated, the others were straight forward.
AI usage
I used Claude Code to resolve the conflicts, under my direction of how to resolve the trickier parts, particularly the TipTapEditor and the migrations.