feat(guides) : add team transfer and visibility controls
CI / Verify (push) Successful in 1m5s
CI / Build immutable images and deploy (push) Successful in 1m55s

This commit is contained in:
2026-09-04 19:46:46 +07:00 Unverified
parent 50a2a5428d
commit dd87510d68
15 changed files with 3972 additions and 19 deletions
+24 -2
View File
@@ -74,6 +74,16 @@ export async function listGuideCards(includeTrash = false) {
return rows.map(({ guide, cover }) => ({ ...guide, coverUrl: publicMediaUrl(cover.objectKey) }));
}
export async function listPublicGuideCards() {
const rows = await getDb()
.select({ guide: guides, cover: media })
.from(guides)
.innerJoin(media, eq(media.id, guides.coverMediaId))
.where(and(eq(guides.isPublic, true), isNull(guides.trashedAt)))
.orderBy(asc(guides.sortOrder), asc(guides.name));
return rows.map(({ guide, cover }) => ({ ...guide, coverUrl: publicMediaUrl(cover.objectKey) }));
}
export async function getGuideByCharacterKey(characterKey: string) {
const [row] = await getDb()
.select({ guide: guides, cover: media })
@@ -86,13 +96,17 @@ export async function getGuideByCharacterKey(characterKey: string) {
return { ...row.guide, coverUrl: publicMediaUrl(row.cover.objectKey), sections };
}
export async function getPublicGuide(slug: string) {
async function getGuideContent(slug: string, publicOnly: boolean) {
const [row] = await getDb()
.select({ guide: guides, cover: media, character: catalogCharacters })
.from(guides)
.innerJoin(media, eq(media.id, guides.coverMediaId))
.innerJoin(catalogCharacters, eq(catalogCharacters.key, guides.characterKey))
.where(and(eq(guides.slug, slug), isNull(guides.trashedAt)))
.where(and(
eq(guides.slug, slug),
isNull(guides.trashedAt),
...(publicOnly ? [eq(guides.isPublic, true)] : []),
))
.limit(1);
if (!row) return null;
const [sections, weaponConditionsRows, groups, profile, constellationGroups, teams] = await Promise.all([
@@ -162,4 +176,12 @@ export async function getPublicGuide(slug: string) {
};
}
export function getPublicGuide(slug: string) {
return getGuideContent(slug, true);
}
export function getAdminGuideContent(slug: string) {
return getGuideContent(slug, false);
}
export type PublicGuide = NonNullable<Awaited<ReturnType<typeof getPublicGuide>>>;