feat(course-package): add publish/unpublish with snapshot locking

- Add published_snapshot (jsonb) and published_at (timestamp) columns
- New POST publish/{id} endpoint: stores snapshot JSON, locks editing
- New POST unpublish/{id} endpoint: clears published_at for editing
- Block update and sync_items when published_at is set
- Frontend detail page with conditional edit/publish/unpublish buttons

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-30 21:04:14 +08:00
parent b4a86071dc
commit 8afd3d9234
6 changed files with 108 additions and 2 deletions
@@ -0,0 +1,2 @@
ALTER TABLE course_package DROP COLUMN IF EXISTS published_snapshot;
ALTER TABLE course_package DROP COLUMN IF EXISTS published_at;
@@ -0,0 +1,2 @@
ALTER TABLE course_package ADD COLUMN published_snapshot jsonb;
ALTER TABLE course_package ADD COLUMN published_at timestamp;
+4
View File
@@ -747,6 +747,8 @@ pub struct CoursePackage {
pub updated_at: Option<NaiveDateTime>,
pub is_delete: Option<bool>,
pub org_id: Option<String>,
pub published_snapshot: Option<serde_json::Value>,
pub published_at: Option<NaiveDateTime>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -767,6 +769,8 @@ pub struct ReqCoursePackage {
pub updated_at: Option<NaiveDateTime>,
pub is_delete: Option<bool>,
pub org_id: Option<String>,
pub published_snapshot: Option<serde_json::Value>,
pub published_at: Option<NaiveDateTime>,
}
impl CoursePackage {
+2
View File
@@ -113,6 +113,8 @@ diesel::table! {
updated_at -> Nullable<Timestamp>,
is_delete -> Nullable<Bool>,
org_id -> Nullable<Varchar>,
published_snapshot -> Nullable<Jsonb>,
published_at -> Nullable<Timestamp>,
}
}