Why the Storyboard Splitting Function Cannot Be Called Repeatedly: At Least 69 Chapter-Run Executions
In the Yuncao Academy system, funx.atctoscene is a core function responsible for splitting novel chapters into storyboard records. Its input is a completed dbvideo_article record, and its output is a data set from three tables: the dbvideo_process storyboard table, the dbvideo_roles character table, and the dbvideo_places location table. The execution entry point for this function in the system administration panel is a single re-run button that looks harmless, but in reality it is protected by an invisible idempotency lock. This so-called idempotency lock is not a switch field set in some independent configuration file; rather, the function itself has a built-in self-check mechanism based on the current database state. Every time atctoscene is called, the function first queries whether any process records already exist under the article_id for that article. If the query result is greater than zero, the function performs no further action and directly returns an error message: "Storyboard records already exist for this chapter. To regenerate, please manually clean up first." It then logs a warning-level event in the backend log. This mechanism fundamentally prevents problems such as storyboard numbering chaos, duplicate character creation, and duplicate location records that would result from a chapter being unconsciously executed twice. The practical effect of this lock can be illustrated with a simple scenario. Suppose you are entering Chapter 3, and due to network fluctuation, the save operation is delayed. You subconsciously refresh the page, but in reality, fifteen storyboard records have already been successfully generated in the database, while the interface remains in a waiting state. You then click the execute atctoscene button again. At this point, the function runs its query before starting and finds that fifteen records with article_id equal to 3 already exist in the dbvideo_process table, so it throws an idempotency error and refuses to continue. Without this lock, the second run would resubmit the Chapter 3 text to the large model for parsing. Due to the randomness of large model output, even with identical input text and prompts, the number of storyboards produced by the two runs would not be exactly the same. It might produce two additional entries after the first run's fifteen shots, and both runs would generate SceneCode starting numbers at 3001, producing completely duplicate numbering but inconsistent text content. You would be unable to distinguish which entries came from the first run and which from the second. Ultimately, downstream arcpictask, vdurl, and other tasks would be executed twice, generating a large number of duplicate images and invalid videos, throwing the entire database into chaos. The splitting process for all 69 chapters, run continuously on a single computer, takes approximately 110 minutes total, meaning roughly 1.5 to 2 minutes per chapter. This speed is primarily dependent on the response latency of the large model's single request, not the text length. If parallelization is used—for example, three computers running atctoscene simultaneously, each handling different chapters—the total time can be compressed to around 40 minutes. The reason there is no restriction against parallel execution is that the protection scope of the idempotency lock is a single article. Different articles do not interfere with each other and have no concurrency conflicts at all. In other words, you can run the splitting for Chapter 1 and Chapter 2 simultaneously; they each check whether records already exist within their own article_id range and cannot tamper with each other. However, if you attempt to run the splitting for the same article twice at the same time, the first computer will execute successfully, while the second computer will be blocked by the lock during the self-check stage, receiving only an empty transaction with an error message. This is the core function of the idempotency lock: ensuring the same data source is processed only once. If, due to some misoperation, you must re-run a chapter—for example, if you find the storyboard quality from Chapter 1's split is poor, or if the large model has been improved after the split and you need to re-parse the text—you must manually clean up all records corresponding to that chapter across the three tables. The specific operation is: first delete all storyboard rows under that article_id from the dbvideo_process table; then delete the rows from dbvideo_roles where the source article_id equals that book; and finally delete the associated rows from dbvideo_places. Note that these three tables have foreign key relationships between them, and the cleanup order cannot be reversed. You must start with the child table process, then delete from roles and places. After cleanup is complete, calling atctoscene again will find no corresponding records in the process table during its self-check and will re-execute the full splitting process. Another common mistake during manual cleanup is forgetting to delete from dbvideo_roles and dbvideo_places and only deleting from process. In that case, the next execution's self-check only examines process, so it will run successfully, but the newly generated storyboards will reference leftover old characters and locations, causing inconsistencies. For this reason, the system provides a dedicated procedure called reset_atctoscene(article_id), which first cascades deletes all associated records in the three tables via foreign keys, then resets the process_status field of that article in the article table to 0, and finally returns a state ready for re-execution. Developers typically call this procedure directly for safe re-runs. As for the concrete consequences of duplicate execution: if the idempotency lock is forcibly bypassed—for example, by manually inserting storyboard rows and committing the transaction—the entire downstream production pipeline will suffer a chain reaction. The first obvious problem is storyboard number conflicts. For instance, the first run of Chapter 1 generates shots 1 through 15, and the second run generates shots 16 through 30, but they share the same SceneCode prefix and overlap with the sequential numbering of subsequent chapters, making it impossible to determine the correct editing order when splicing the full film. Another problem is duplicate rows in the character table: the same named character is split into two records with different role_ids, causing downstream drawrole to potentially output two versions of character images with slightly inconsistent styles when generating character artwork. In severe cases, the same character may look noticeably different between adjacent shots. Duplicate entries in the location table directly contaminate the storyboard's location attribution because one placecode in a scene may correspond to two records with different descriptions but similar names. When the model parses scenetopic, it cannot decide which location image to use as the background base, so it picks randomly, destroying the visual consistency of that scene. The system's design philosophy for places is that places is not a location dictionary but rather one row per shot, meaning each storyboard holds its own independent place description. If duplicates are generated, it becomes one shot with two or more rows, causing downstream queries to return multiple candidate records, which in minor cases affects image generation speed and in severe cases directly causes chaos in first-frame and last-frame generation. In the actual splitting of the 69 chapters, the idempotency lock helped avoid approximately eleven explicit misoperations. All eleven cases occurred because operators saw a chapter's splitting taking a long time, mistakenly believed the task was stuck, and clicked the re-run button several times. In reality, the first execution had already completed normally after the large model responded, but the interface feedback was delayed, while the system silently blocked the other ten requests. Without the idempotency lock, these duplicate executions would have directly created at least 110 duplicate storyboard records and over a hundred duplicate character names, pushing cleanup work to several hours or more. In the actual situation, because of the idempotency lock, all these misoperations were safely intercepted. The system returned the same error message, and the operators simply refreshed the page as prompted and saw the successfully generated data. Therefore, the core value of this idempotency lock is not technical showmanship but the protection of data source purity. Storyboards, characters, and locations are the starting point of the entire video generation pipeline. If the starting point has duplicates and chaos, then all subsequent tasks become water without a source. Only by ensuring that every split is unique and complete can the downstream first-frame and last-frame image generation, Jimeng video generation, and final assembly and editing all build on a reliable data foundation. This once again demonstrates the robustness of this system's design philosophy: through simple and clear state checks and constraints—rather than complex server locks or distributed coordination mechanisms—it achieves reliable protection of critical production stages.