fix: QA sweep fixes across migration, security, lint, and e2e tests

- fix(db): migration 0012 column order mismatch causing NOT NULL
  constraint failure on existing databases; use explicit column
  mapping instead of SELECT *
- fix(db): disable FK checks during migrations to allow SQLite
  table-recreation pattern (DROP + RENAME)
- fix(security): filter cookie_secret and instance_id from settings
  API response for non-admin users
- fix(lint): resolve all 7 API lint warnings (noParameterAssign,
  noImplicitAnyLet) in compose, image-enhancement, and workspace
- fix(docs): correct permission count from 16 to 14 in CLAUDE.md
- fix(e2e): resolve 44 Playwright test failures across 8 spec files
  including locator specificity, compress mode defaults, format count,
  restore-photo UI drift, stitch image count, GIF animated fixtures,
  submit button timing, and processing timeouts
This commit is contained in:
SnapOtter
2026-05-15 22:41:22 +08:00
parent 3b181dd1ac
commit 51bc2d5732
15 changed files with 248 additions and 244 deletions
+8
View File
@@ -17,16 +17,20 @@ const settingsBodySchema = z.record(z.string().min(1), z.unknown());
const HTML_TAG_PATTERN = /<[a-z/!?][^>]*>/i;
const SENSITIVE_KEYS = new Set(["cookie_secret", "instance_id"]);
export async function settingsRoutes(app: FastifyInstance): Promise<void> {
// GET /api/v1/settings — Get all settings as a key-value object
app.get("/api/v1/settings", async (request: FastifyRequest, reply: FastifyReply) => {
const user = requireAuth(request, reply);
if (!user) return;
const isAdmin = user.role === "admin";
const rows = db.select().from(schema.settings).all();
const settings: Record<string, string> = {};
for (const row of rows) {
if (!isAdmin && SENSITIVE_KEYS.has(row.key)) continue;
settings[row.key] = row.value;
}
@@ -94,6 +98,10 @@ export async function settingsRoutes(app: FastifyInstance): Promise<void> {
const { key } = request.params;
if (SENSITIVE_KEYS.has(key) && user.role !== "admin") {
return reply.status(403).send({ error: "Forbidden", code: "FORBIDDEN" });
}
const row = db.select().from(schema.settings).where(eq(schema.settings.key, key)).get();
if (!row) {