once both databases are there, the form becomes two rows of actions
A text box invites an edit nobody is here to make. Named and created, the two things somebody wants are per-database actions, so the inputs and the button go and each database becomes a label, a table count, and what can be done to it. Push schema runs the WEBSITE's own `db:push`. Not drizzle-kit driven from here with a config this plugin assembles — the schema, the drizzle version and the push command all belong to that repository, and reimplementing any of them would be a second definition of the site's database going stale on its own schedule. This supplies the connection and runs their script. The connection goes in the environment, which works because src/env-file.ts consults .env files first and process.env last. So an ambient value is used only where no file in the checkout sets that key, and this cannot quietly override a connection somebody wrote down. Their name guard still applies and should: env.ts refuses to connect unless the database name matches what FOFOS_ENV expects. A plugin that worked around that would be defeating the one check standing between development and live data. "Schema pushed" is a COUNT of tables in public, not a comparison against the site's expected tables — that list would be a second copy of the site's schema, stale the first time it gains a table, and the question being asked is only whether anything is in there yet. Restore is present and disabled, gated on the schema being pushed. It is not wired: which backup it reads from is not decided, and guessing at the source of a restore is not a thing to do with a client's data. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+17
-1
@@ -8,7 +8,8 @@ import { readMediaStatus, createMediaDir } from './media';
|
||||
import { readSync, startSync } from './sync';
|
||||
import { readRuns } from './ledger';
|
||||
import { reconcile } from './derive';
|
||||
import { createDatabases, readDatabases } from './databases';
|
||||
import { createDatabases, pushSchema, readDatabases } from './databases';
|
||||
import { join } from 'node:path';
|
||||
import { fofosRequest, FofosError, probe, type FofosResponse } from './fofos-client';
|
||||
|
||||
/**
|
||||
@@ -293,6 +294,21 @@ router.get('/_config/media/sync', async (ctx) => {
|
||||
*/
|
||||
router.get('/_config/databases', async (ctx) => ctx.json(await readDatabases()));
|
||||
|
||||
router.post('/_config/databases/:target/push-schema', async (ctx) => {
|
||||
const user = ctx.get('user');
|
||||
const target = ctx.req.param('target');
|
||||
if (target !== 'production' && target !== 'development') {
|
||||
return ctx.json({ error: 'Target must be production or development.' }, 400);
|
||||
}
|
||||
try {
|
||||
const settings = await readSettings(user.email);
|
||||
const result = await pushSchema(target, join(settings.rootPath, 'website'));
|
||||
return ctx.json({ ...result, status: await readDatabases() }, result.ok ? 200 : 400);
|
||||
} catch (error) {
|
||||
return ctx.json({ error: (error as Error).message }, 400);
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/_config/databases/create', async (ctx) => {
|
||||
// The names come with the request, so what gets created is what is on screen rather than what was
|
||||
// stored at some earlier point. They are saved first, by the same validation as the PUT above.
|
||||
|
||||
Reference in New Issue
Block a user