More api and database cleanup
This commit is contained in:
@@ -8,6 +8,7 @@ export async function up(db: Kysely<any>): Promise<void> {
|
|||||||
.$call(addDefaultColumns)
|
.$call(addDefaultColumns)
|
||||||
.addColumn("assessment_id", "bigint", (cb) => cb.notNull().unique())
|
.addColumn("assessment_id", "bigint", (cb) => cb.notNull().unique())
|
||||||
.addColumn("status", "text", (cb) => cb.notNull().defaultTo("draft")) // draft | submitted | in_review | action_requested | completed
|
.addColumn("status", "text", (cb) => cb.notNull().defaultTo("draft")) // draft | submitted | in_review | action_requested | completed
|
||||||
|
.addColumn("submitted_at", "timestamptz")
|
||||||
.addColumn("completed_at", "timestamptz")
|
.addColumn("completed_at", "timestamptz")
|
||||||
.addColumn("completed_by", "uuid")
|
.addColumn("completed_by", "uuid")
|
||||||
.addColumn("media_key_back_squat", "text")
|
.addColumn("media_key_back_squat", "text")
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
Printful,
|
Printful,
|
||||||
Webflow,
|
Webflow,
|
||||||
} from "@blade-and-brawn/commerce";
|
} from "@blade-and-brawn/commerce";
|
||||||
import { BigIntIdSchema, DEFAULT_NAME, DUMMY_PASSWORD_HASH, env, log } from "./util";
|
import { AccountIdSchema, BigIntIdSchema, DEFAULT_NAME, DUMMY_PASSWORD_HASH, env, log } from "./util";
|
||||||
import serverTiming from "@elysia/server-timing";
|
import serverTiming from "@elysia/server-timing";
|
||||||
import jwt from "@elysia/jwt";
|
import jwt from "@elysia/jwt";
|
||||||
import { CommerceService, WOrderStatusSchema } from "./services/commerce";
|
import { CommerceService, WOrderStatusSchema } from "./services/commerce";
|
||||||
@@ -471,7 +471,7 @@ export const app = new Elysia()
|
|||||||
if (!stats) return status(404, { error: "Account stats not found" });
|
if (!stats) return status(404, { error: "Account stats not found" });
|
||||||
return stats;
|
return stats;
|
||||||
}, {
|
}, {
|
||||||
params: t.Object({ id: t.String() })
|
params: t.Object({ id: AccountIdSchema })
|
||||||
})
|
})
|
||||||
.guard({ authAdmin: true }, (app) => app
|
.guard({ authAdmin: true }, (app) => app
|
||||||
.get("/:id", async ({ params: { id } }) => {
|
.get("/:id", async ({ params: { id } }) => {
|
||||||
@@ -479,7 +479,7 @@ export const app = new Elysia()
|
|||||||
if (!account) return status(404, { error: "Account not found" });
|
if (!account) return status(404, { error: "Account not found" });
|
||||||
return account;
|
return account;
|
||||||
}, {
|
}, {
|
||||||
params: t.Object({ id: t.String() })
|
params: t.Object({ id: AccountIdSchema })
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.group("/me", { auth: true }, (app) => app
|
.group("/me", { auth: true }, (app) => app
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ export class VerificationsService {
|
|||||||
.where("status", "in", ALLOWED_FROM.update)
|
.where("status", "in", ALLOWED_FROM.update)
|
||||||
.set({
|
.set({
|
||||||
status: "draft" satisfies VerificationStatus,
|
status: "draft" satisfies VerificationStatus,
|
||||||
|
submitted_at: null,
|
||||||
assessment_id: assessmentId,
|
assessment_id: assessmentId,
|
||||||
media_key_back_squat: activityMediaKeys[Activity.BackSquat],
|
media_key_back_squat: activityMediaKeys[Activity.BackSquat],
|
||||||
media_key_deadlift: activityMediaKeys[Activity.Deadlift],
|
media_key_deadlift: activityMediaKeys[Activity.Deadlift],
|
||||||
@@ -96,6 +97,7 @@ export class VerificationsService {
|
|||||||
.$if(opt.filter?.status !== undefined, (qb) => qb
|
.$if(opt.filter?.status !== undefined, (qb) => qb
|
||||||
.where("verifications.status", "=", opt.filter!.status!)
|
.where("verifications.status", "=", opt.filter!.status!)
|
||||||
)
|
)
|
||||||
|
.orderBy("verifications.submitted_at", (ob) => ob.desc().nullsLast())
|
||||||
.orderBy("verifications.created_at", "desc")
|
.orderBy("verifications.created_at", "desc")
|
||||||
.$if(opt.limit !== undefined, (qb) => qb.limit(opt.limit!))
|
.$if(opt.limit !== undefined, (qb) => qb.limit(opt.limit!))
|
||||||
.$if(opt.offset !== undefined, (qb) => qb.offset(opt.offset!))
|
.$if(opt.offset !== undefined, (qb) => qb.offset(opt.offset!))
|
||||||
@@ -109,7 +111,7 @@ export class VerificationsService {
|
|||||||
.where((eb) => eb.and(
|
.where((eb) => eb.and(
|
||||||
REQUIRED_MEDIA_ACTIVITIES.map((activity) => eb(MEDIA_KEY_COLUMN[activity], "is not", null))
|
REQUIRED_MEDIA_ACTIVITIES.map((activity) => eb(MEDIA_KEY_COLUMN[activity], "is not", null))
|
||||||
))
|
))
|
||||||
.set({ status: "submitted" satisfies VerificationStatus })
|
.set({ status: "submitted" satisfies VerificationStatus, submitted_at: new Date() })
|
||||||
.returning(["id", "status"])
|
.returning(["id", "status"])
|
||||||
.executeTakeFirst();
|
.executeTakeFirst();
|
||||||
}
|
}
|
||||||
@@ -159,6 +161,7 @@ export class VerificationsService {
|
|||||||
"verifications.assessment_id",
|
"verifications.assessment_id",
|
||||||
"verifications.status",
|
"verifications.status",
|
||||||
"verifications.created_at",
|
"verifications.created_at",
|
||||||
|
"verifications.submitted_at",
|
||||||
"verifications.completed_at",
|
"verifications.completed_at",
|
||||||
"verifications.completed_by",
|
"verifications.completed_by",
|
||||||
"verifications.reviewer_notes",
|
"verifications.reviewer_notes",
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export const DEFAULT_NAME = "Default";
|
|||||||
export const DUMMY_PASSWORD_HASH = await Bun.password.hash("Dummy");
|
export const DUMMY_PASSWORD_HASH = await Bun.password.hash("Dummy");
|
||||||
|
|
||||||
export const BigIntIdSchema = t.String({ pattern: "^\\d+$" });
|
export const BigIntIdSchema = t.String({ pattern: "^\\d+$" });
|
||||||
|
export const AccountIdSchema = t.String({ pattern: "^(@.+|[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$" });
|
||||||
|
|
||||||
function requireEnv(key: string): string {
|
function requireEnv(key: string): string {
|
||||||
const val = Bun.env[key];
|
const val = Bun.env[key];
|
||||||
|
|||||||
@@ -137,7 +137,7 @@
|
|||||||
<th>Player</th>
|
<th>Player</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>Videos</th>
|
<th>Videos</th>
|
||||||
<th>Requested</th>
|
<th>Submitted</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{videoCount(row)} / {Object.values(Activity).length}</td>
|
<td>{videoCount(row)} / {Object.values(Activity).length}</td>
|
||||||
<td class="whitespace-nowrap">{formatDate(row.created_at)}</td>
|
<td class="whitespace-nowrap">{formatDate(row.submitted_at)}</td>
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a
|
||||||
class="btn btn-primary btn-xs"
|
class="btn btn-primary btn-xs"
|
||||||
|
|||||||
Reference in New Issue
Block a user