Record the Studio schema migration atomically and support safe retries
waterfall-wiki CI and deployment / verify-and-deploy (push) Has been cancelled
waterfall-wiki CI and deployment / verify-and-deploy (push) Has been cancelled
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
CREATE TABLE studio_designs (
|
||||
BEGIN;
|
||||
CREATE TABLE IF NOT EXISTS studio_designs (
|
||||
id uuid PRIMARY KEY,
|
||||
layout_id text NOT NULL CHECK (layout_id ~ '^ref-(0[1-9]|1[0-9]|2[0-7])$'),
|
||||
name text NOT NULL CHECK (char_length(name) BETWEEN 1 AND 120),
|
||||
@@ -7,4 +8,6 @@ CREATE TABLE studio_designs (
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
CREATE INDEX studio_designs_layout_created ON studio_designs(layout_id,created_at DESC,id DESC);
|
||||
CREATE INDEX IF NOT EXISTS studio_designs_layout_created ON studio_designs(layout_id,created_at DESC,id DESC);
|
||||
INSERT INTO schema_migrations(version) VALUES('009_studio_designs');
|
||||
COMMIT;
|
||||
|
||||
@@ -57,6 +57,7 @@ test('real PostgreSQL + S3 notes, flat tags, resource sharing and video processi
|
||||
assert.equal((await db().query("SELECT count(*)::integer AS n FROM assets WHERE kind='audio' AND derivation='audio_track'")).rows[0].n,1,'Video soundtracks are ordinary reusable assets');
|
||||
const audio=join(dir,'audio.wav');await run('ffmpeg',['-y','-v','error','-f','lavfi','-i','sine=frequency=220','-t','0.2',audio]);await upload('audio',[{data:await readFile(audio),name:'audio.wav',mime:'audio/wav'}]);assert.equal((await request('/api/feed?section=audio')).posts.length,1);
|
||||
for(const removed of ['/library/assets','/library/tags'])assert.equal((await fetch(base+removed)).status,404);
|
||||
assert.equal((await db().query("SELECT 1 FROM schema_migrations WHERE version='009_studio_designs'")).rowCount,1,'Studio migration must be recorded for repeat deployments');
|
||||
// Studio owns no second database: designs use this same isolated PostgreSQL.
|
||||
for(let i=1;i<=27;i++){const layoutId='ref-'+String(i).padStart(2,'0'),saved=await request('/api/studio/designs',{layoutId,name:'布局 '+i,parameters:{}});assert.equal(saved.design.layoutId,layoutId);assert.equal(saved.design.revision,1);const read=await request('/api/studio/designs/'+saved.design.id);assert.deepEqual(read.design.parameters,{texts:{},images:{},decorations:{}});}
|
||||
const design=await request('/api/studio/designs',{layoutId:'ref-01',name:'可修改效果',parameters:{texts:{T01:{value:'新的标题'}},images:{I01:{assetId:first.assets[0],fit:'contain'}}}});
|
||||
|
||||
Reference in New Issue
Block a user