feat(image-export) : capture guide sections in browser
CI / Verify (push) Successful in 58s
CI / Build immutable images and deploy (push) Successful in 2m54s

This commit is contained in:
2026-09-02 22:28:28 +07:00 Unverified
parent ded10ebb36
commit dd672e5331
6 changed files with 272 additions and 1266 deletions
-98
View File
@@ -187,102 +187,4 @@ export async function getPublicTeamExport(teamId: string) {
};
}
export async function getPublicWeaponExport(guideId: string) {
const [row] = await getDb()
.select({ guide: guides, note: guideSections.note })
.from(guides)
.innerJoin(
guideSections,
and(
eq(guideSections.guideId, guides.id),
eq(guideSections.slug, "weapon"),
eq(guideSections.enabled, true),
),
)
.where(and(eq(guides.id, guideId), isNull(guides.trashedAt)))
.limit(1);
if (!row) return null;
const weapons = await getDb()
.select({ recommendation: weaponRecommendations, weapon: catalogWeapons })
.from(weaponRecommendations)
.innerJoin(
catalogWeapons,
eq(catalogWeapons.key, weaponRecommendations.weaponKey),
)
.where(eq(weaponRecommendations.guideId, guideId))
.orderBy(asc(weaponRecommendations.sortOrder));
return {
guideName: row.guide.name,
note: row.note,
weapons: weapons.map(({ recommendation, weapon }) => ({
...recommendation,
weapon: { ...weapon, imageUrl: publicMediaUrl(weapon.imageKey) },
})),
};
}
export async function getPublicArtifactExport(guideId: string) {
const [row] = await getDb()
.select({ guide: guides, character: catalogCharacters })
.from(guides)
.innerJoin(
guideSections,
and(
eq(guideSections.guideId, guides.id),
eq(guideSections.slug, "artifact"),
eq(guideSections.enabled, true),
),
)
.innerJoin(
catalogCharacters,
eq(catalogCharacters.key, guides.characterKey),
)
.where(and(eq(guides.id, guideId), isNull(guides.trashedAt)))
.limit(1);
if (!row) return null;
const [groups, profile] = await Promise.all([
getDb().select().from(artifactGroups).where(eq(artifactGroups.guideId, guideId)).orderBy(asc(artifactGroups.sortOrder)),
getDb().select().from(artifactProfiles).where(eq(artifactProfiles.guideId, guideId)).limit(1),
]);
const recommendations = groups.length
? await getDb()
.select({ recommendation: artifactRecommendations, artifact: catalogArtifacts })
.from(artifactRecommendations)
.innerJoin(
catalogArtifacts,
eq(catalogArtifacts.key, artifactRecommendations.firstArtifactKey),
)
.where(inArray(artifactRecommendations.groupId, groups.map((group) => group.id)))
.orderBy(asc(artifactRecommendations.sortOrder))
: [];
const secondKeys = recommendations
.map(({ recommendation }) => recommendation.secondArtifactKey)
.filter((key): key is string => Boolean(key));
const secondArtifacts = secondKeys.length
? await getDb().select().from(catalogArtifacts).where(inArray(catalogArtifacts.key, secondKeys))
: [];
return {
guideName: row.guide.name,
character: catalogCharacterWithUrls(row.character),
groups: groups.map((group) => ({
...group,
rows: recommendations
.filter(({ recommendation }) => recommendation.groupId === group.id)
.map(({ recommendation, artifact }) => {
const second = secondArtifacts.find((item) => item.key === recommendation.secondArtifactKey);
return {
...recommendation,
first: { ...artifact, imageUrl: publicMediaUrl(artifact.imageKey) },
second: second ? { ...second, imageUrl: publicMediaUrl(second.imageKey) } : null,
};
}),
})),
profile: profile[0] ?? null,
};
}
export type PublicGuide = NonNullable<Awaited<ReturnType<typeof getPublicGuide>>>;