ci: add pull request quality gates
CI / install-and-build (pull_request) Successful in 1m29s
CI / format (pull_request) Successful in 51s
CI / typecheck-source (pull_request) Successful in 41s
CI / typecheck-tests (pull_request) Successful in 39s
CI / test (pull_request) Successful in 51s
CI / lint (pull_request) Successful in 21s

Co-Authored-By: gpt-5.6-terra <noreply@openai.com>
This commit was merged in pull request #12.
This commit is contained in:
2026-07-22 21:50:29 +00:00
co-authored by Codex
parent b9fa79ff1f
commit 31d4636dde
80 changed files with 2007 additions and 398 deletions
+28 -28
View File
@@ -110,7 +110,7 @@ export class SqliteInterface implements BackendDbInterface {
SELECT "uid", "email", "name", json("flags") AS "flags", "created_at", "updated_at", "password"
FROM "users"
WHERE "email" = ${{ text: email }}
`
`,
);
if (!rawUser) throw new NotFoundAbodeError();
if (rawUser.password.startsWith("#")) throw new ConflictAbodeError();
@@ -124,7 +124,7 @@ export class SqliteInterface implements BackendDbInterface {
sql`
DELETE FROM "users"
WHERE "uid" = ${{ uuid: id }}
`
`,
);
if (!changes) throw new NotFoundAbodeError();
}
@@ -142,10 +142,10 @@ export class SqliteInterface implements BackendDbInterface {
${{ text: user.email }},
${{ text: user.name }},
${{ text: user.password }},${{ jsonb: user.flags }})
`
`,
);
return this.#getUserById(uid);
})
}),
);
}
async updateUser(user: UpdateUser): Promise<ClientUser> {
@@ -179,11 +179,11 @@ export class SqliteInterface implements BackendDbInterface {
"updated_at" = datetime('now', 'localtime', 'subsec'),
${joinSql(updates, sql`, `)}
WHERE "uid" = ${{ uuid: user.uid }}
`
`,
);
if (!changes) throw new NotFoundAbodeError();
return this.#getUserById(user.uid);
})
}),
);
}
@@ -204,7 +204,7 @@ export class SqliteInterface implements BackendDbInterface {
sql`
DELETE FROM "abodes"
WHERE "aid" = ${{ uuid: id }}
`
`,
);
if (!changes) throw new NotFoundAbodeError();
}
@@ -222,10 +222,10 @@ export class SqliteInterface implements BackendDbInterface {
${{ uuid: ctx.uid }},
${{ uuid: ctx.uid }}
)
`
`,
);
return this.#getAbodeById(aid);
})
}),
);
}
async updateAbode(abode: UpdateAbode, ctx: { uid: string }): Promise<Abode> {
@@ -244,11 +244,11 @@ export class SqliteInterface implements BackendDbInterface {
"updated_by" = ${{ uuid: ctx.uid }},
${joinSql(updates, sql`, `)}
WHERE "aid" = ${{ uuid: abode.aid }}
`
`,
);
if (!changes) throw new NotFoundAbodeError();
return this.#getAbodeById(abode.aid);
})
}),
);
}
@@ -264,7 +264,7 @@ export class SqliteInterface implements BackendDbInterface {
#getResidentById(uid: string, aid: string): Resident {
const resident = selectResident(
this.#db,
sql`"uid" = ${{ uuid: uid }} AND "aid" = ${{ uuid: aid }}`
sql`"uid" = ${{ uuid: uid }} AND "aid" = ${{ uuid: aid }}`,
);
if (!resident) throw new NotFoundAbodeError();
return resident;
@@ -278,13 +278,13 @@ export class SqliteInterface implements BackendDbInterface {
sql`
DELETE FROM "residents"
WHERE "uid" = ${{ uuid: uid }} AND "aid" = ${{ uuid: aid }}
`
`,
);
if (!changes) throw new NotFoundAbodeError();
}
async createResident(
resident: CreateResident,
ctx: { uid: string }
ctx: { uid: string },
): Promise<Resident> {
this.#checkReadonly();
return this.#db.rethrow(() =>
@@ -299,15 +299,15 @@ export class SqliteInterface implements BackendDbInterface {
${{ uuid: ctx.uid }},
${{ uuid: ctx.uid }}
)
`
`,
);
return this.#getResidentById(resident.uid, resident.aid);
})
}),
);
}
async updateResident(
resident: updateResident,
ctx: { uid: string }
ctx: { uid: string },
): Promise<Resident> {
this.#checkReadonly();
const updates = calcUpdates({
@@ -326,11 +326,11 @@ export class SqliteInterface implements BackendDbInterface {
WHERE
"uid" = ${{ uuid: resident.uid }}
AND "aid" = ${{ uuid: resident.aid }}
`
`,
);
if (!changes) throw new NotFoundAbodeError();
return this.#getResidentById(resident.uid, resident.aid);
})
}),
);
}
@@ -340,7 +340,7 @@ export class SqliteInterface implements BackendDbInterface {
sql`
JOIN "residents" r ON u."uid" = r."uid"
WHERE r."aid" = ${{ uuid: id }}
`
`,
);
}
async listAbodesByUserId(id: string): Promise<Abode[]> {
@@ -349,7 +349,7 @@ export class SqliteInterface implements BackendDbInterface {
sql`
JOIN "residents" r ON a."aid" = r."aid"
WHERE r."uid" = ${{ uuid: id }}
`
`,
);
}
@@ -405,13 +405,13 @@ export class SqliteInterface implements BackendDbInterface {
#getApikeyByToken(token: `at_${string}`): ClientApikey {
const apikey = selectClientApikey(
this.#db,
sql`"token" = ${{ text: token }}`
sql`"token" = ${{ text: token }}`,
);
if (!apikey) throw new NotFoundAbodeError();
return apikey;
}
async getUserByApikey(
token: `at_${string}`
token: `at_${string}`,
): Promise<[ClientUser, ClientApikey]> {
const apikey = this.#getApikeyByToken(token);
if (
@@ -431,7 +431,7 @@ export class SqliteInterface implements BackendDbInterface {
return apikey;
}
async createApikey(
apikey: CreateApikey
apikey: CreateApikey,
): Promise<[ClientApikey, `at_${string}`]> {
this.#checkReadonly();
const token = createApikeyToken();
@@ -439,7 +439,7 @@ export class SqliteInterface implements BackendDbInterface {
let expires = apikey.expires_at;
if (expires === undefined)
expires = new Date(
new Date().getTime() + 1000 * 60 * 60 * 24 * 365
new Date().getTime() + 1000 * 60 * 60 * 24 * 365,
).toISOString();
if (expires && new Date(expires).getTime() < Date.now())
throw new InvalidAbodeError();
@@ -480,7 +480,7 @@ export class SqliteInterface implements BackendDbInterface {
async deleteNoteById(nid: string): Promise<void> {
this.#checkReadonly();
const { changes } = this.#db.run(
sql`DELETE FROM "notes" WHERE "nid" = ${{ uuid: nid }}`
sql`DELETE FROM "notes" WHERE "nid" = ${{ uuid: nid }}`,
);
if (!changes) throw new NotFoundAbodeError();
}
@@ -502,7 +502,7 @@ export class SqliteInterface implements BackendDbInterface {
)
`);
return this.#getNoteById(nid);
})
}),
);
}
async updateNote(note: UpdateNote, ctx: { uid: string }): Promise<Note> {
@@ -525,7 +525,7 @@ export class SqliteInterface implements BackendDbInterface {
`);
if (!changes) throw new NotFoundAbodeError();
return this.#getNoteById(note.nid);
})
}),
);
}
async listNotesByAbodeId(aid: string): Promise<PartialNote[]> {