@@ -210,20 +210,30 @@ users.patch('/me/bookmarks/:itineraryId/visibility', userAuthMiddleware, async (
210210 return c . json ( { success : false , error : { code : 'NOT_FOUND' , message : 'Bookmark not found' } } , 404 ) ;
211211 }
212212
213- // 公開にした場合、パスワードなしのしおりのみ共有スナップショットを自動生成する
214- // パスワード付きしおりはしおりトークンが必要なため、ここでは自動生成しない
215- if ( input . is_visible ) {
216- try {
217- const itineraryService = new ItineraryService ( c . env . DB ) ;
218- const itinerary = await itineraryService . get ( itineraryId ) ;
219- if ( itinerary && ! itinerary . password ) {
213+ // スナップショットの公開状態を元しおりと連動させる
214+ try {
215+ const itineraryService = new ItineraryService ( c . env . DB ) ;
216+ const itinerary = await itineraryService . get ( itineraryId ) ;
217+ if ( itinerary ) {
218+ if ( input . is_visible ) {
219+ // 公開にした場合、共有スナップショットを自動生成する
220+ // スナップショットの password は常に NULL なので鍵付きしおりでも安全
220221 const snapshot = await itineraryService . publish ( itineraryId ) ;
221222 await service . syncBookmarks ( userId , [ snapshot . id ] ) ;
222223 await service . updateBookmarkVisibility ( userId , snapshot . id , true ) ;
224+ } else {
225+ // 非公開にした場合、スナップショットのブックマークも非公開にする
226+ const snapshotRow = await c . env . DB
227+ . prepare ( 'SELECT id FROM itineraries WHERE source_itinerary_id = ?' )
228+ . bind ( itineraryId )
229+ . first < { id : string } > ( ) ;
230+ if ( snapshotRow ) {
231+ await service . updateBookmarkVisibility ( userId , snapshotRow . id , false ) ;
232+ }
223233 }
224- } catch {
225- // 非致命的: 元しおりの公開状態は変更済み、スナップショット生成は後から同期可能
226234 }
235+ } catch {
236+ // 非致命的: 元しおりの公開状態は変更済み、スナップショット連動は後から同期可能
227237 }
228238
229239 return c . json ( { success : true , data : result } ) ;
0 commit comments