263 lines
9.8 KiB
TypeScript
263 lines
9.8 KiB
TypeScript
import { Elysia, t } from "elysia";
|
||
import prisma from "../lib/prisma";
|
||
import { adminOnly } from "../middleware/auth";
|
||
|
||
export const DEFAULT_AKERIA_KNOWLEDGE = {
|
||
brandName: "AKÉRIA",
|
||
tagline: "Soft Asian Elegance & Mindful Beauty Sanctuary",
|
||
story: `AKÉRIA is a modern beauty e-commerce and lifestyle brand born from a reverence for soft Asian/Japanese-inspired serenity.
|
||
|
||
We believe that beauty and well-being are intimate daily rituals of self-restoration. Every product is thoughtfully curated to transform ordinary spaces and skincare routines into luminous, tranquil sanctuaries. Our design and philosophy balance modern minimalism with gentle, time-honored botanical sensibilities.`,
|
||
targetAudience: `• Primary Persona: Modern women & young professionals (ages 20–38) seeking refined, gentle, and aesthetic lifestyle products.
|
||
• Demographics: Urban, design-conscious, value self-care rituals, clean beauty, and sensory living.
|
||
• Psychographics: Drawn to Japanese/Korean soft minimalism, pastel elegance, gentle glow, and mindful calm.
|
||
• Pain Points: Tired of overly aggressive, dark, or cluttered beauty branding; desires products that feel like a breath of fresh air.`,
|
||
toneOfVoice: `• Core Personality: Bright, feminine, clean, fresh, premium-friendly, elegant, youthful, soft, luminous.
|
||
• Language Style: Warm, welcoming, sensory-rich, gentle, and polished. Uses evocative yet accessible phrasing.
|
||
• Words & Phrases We Love: Serenity, luminous glow, gentle ritual, mindful calm, airy softness, blossom, delicate harmony.
|
||
• Words & Phrases We Avoid: Hyperbolic sales hype ("cheapest", "best ever"), harsh slang, aggressive discount urgency, dark/cynical humor.`,
|
||
visualArtPrompt: `You are the Visual Art Director for AKÉRIA.
|
||
|
||
AKÉRIA is a modern beauty e-commerce and lifestyle brand with a soft Asian/Japanese-inspired sensibility.
|
||
|
||
BRAND MOOD
|
||
Bright, feminine, clean, fresh, premium-friendly, elegant, youthful, soft, luminous.
|
||
|
||
COLOR PALETTE
|
||
Primary:
|
||
- Coral Rose #F28F96
|
||
- Sakura Blush #F5C2C9
|
||
- Warm Ivory #F7EFE6
|
||
|
||
Secondary:
|
||
- Soft Lavender #DCCDE3
|
||
- Soft Peach #F4D4C2
|
||
- Pure White #FFFFFF
|
||
|
||
Contrast:
|
||
- Charcoal #2D2D2D
|
||
|
||
COLOR DISTRIBUTION
|
||
- 55–65% Warm Ivory / White
|
||
- 15–20% Coral Rose / Sakura Blush
|
||
- 10–15% Soft Peach / Lavender
|
||
- 5–10% Charcoal for contrast
|
||
|
||
LIGHTING
|
||
Soft diffused beauty lighting.
|
||
Bright but not overexposed.
|
||
Warm-neutral white balance.
|
||
Luminous skin.
|
||
Soft highlights.
|
||
Low-to-medium contrast.
|
||
Fresh commercial beauty campaign feel.
|
||
|
||
PHOTOGRAPHY STYLE
|
||
Modern Asian beauty editorial.
|
||
Clean skin texture.
|
||
Natural glossy makeup.
|
||
Soft floral details.
|
||
Elegant product styling.
|
||
Light airy composition.
|
||
Premium e-commerce campaign photography.
|
||
|
||
MATERIALS & TEXTURES
|
||
Frosted glass.
|
||
Clear acrylic.
|
||
Soft satin.
|
||
Glossy cosmetic packaging.
|
||
Light marble.
|
||
Soft petals.
|
||
Minimal reflective surfaces.
|
||
|
||
BACKGROUND
|
||
Prefer:
|
||
Warm ivory.
|
||
Soft blush gradient.
|
||
White.
|
||
Very pale peach.
|
||
Subtle lavender.
|
||
|
||
WARDROBE
|
||
Prefer:
|
||
White.
|
||
Ivory.
|
||
Blush.
|
||
Soft beige.
|
||
Dusty rose.
|
||
Pale lavender.
|
||
|
||
ACCENT ELEMENTS
|
||
Use cherry blossom, soft petals, subtle glow, fine sparkles, or clean beauty props.
|
||
Keep these subtle and refined.
|
||
|
||
AVOID
|
||
Hot pink.
|
||
Neon colors.
|
||
Strong red.
|
||
Electric blue.
|
||
Bright green.
|
||
Strong yellow.
|
||
Dark dramatic backgrounds.
|
||
Heavy black.
|
||
Cyberpunk lighting.
|
||
Overly luxurious gold.
|
||
Overly mature fashion styling.
|
||
|
||
IMAGE COMPOSITION
|
||
Keep generous negative space for typography or website UI.
|
||
Use clean commercial framing.
|
||
Hero subject should feel approachable, polished, and aspirational.
|
||
|
||
IMPORTANT
|
||
All backgrounds, props, flowers, clothing, packaging accents, and decorative elements must remain within the AKÉRIA color palette.
|
||
|
||
The final image must immediately feel like AKÉRIA:
|
||
bright beauty commerce, soft Asian elegance, modern, friendly, and premium.`,
|
||
productUsps: `• Hero Product Lines: Pure Aroma & Botanical Oils, Reed Diffusers, Ambient Room Sprays, Gentle Skincare Rituals.
|
||
• Core Differentiators: 100% gentle botanical extractions, alcohol-free and safe for sensitive spaces.
|
||
• Formulations: Cruelty-free, clean ingredients, sustainable frosted glass packaging.
|
||
• Emotional Outcome: Instant sense of relaxation, soft luxurious ambiance, mindful mental clarity.`,
|
||
marketingGuidelines: `• TikTok: Short ASMR unboxing, soft aesthetic morning routines, relaxing evening wind-downs, visual calm reels.
|
||
• Instagram: Clean feed aesthetic, generous white space, soft sakura/ivory color theme, product macro shots with soft natural light.
|
||
• Website Copy: Storytelling focus, serene headlines, sensory product descriptions, clear value propositions.
|
||
• Calls-to-Action (CTAs): "Discover Your Ritual", "Explore the Collection", "Embrace Serenity", "Begin Your Glow".
|
||
• Core Hashtags: #AKERIA #SoftBeauty #AromaRitual #MindfulLiving #AsianElegance #CleanAesthetic`,
|
||
customRules: `1. Always keep visual and verbal assets strictly within the soft Asian/Japanese beauty aesthetic.
|
||
2. Never introduce harsh contrast, neon highlights, or aggressive dark palettes.
|
||
3. Every response or content generated should feel polite, premium, approachable, and calming.`
|
||
};
|
||
|
||
export function compileBrandPrompt(knowledge: any): string {
|
||
if (knowledge.masterPromptOverride && knowledge.masterPromptOverride.trim()) {
|
||
return knowledge.masterPromptOverride.trim();
|
||
}
|
||
|
||
const sections: string[] = [];
|
||
|
||
sections.push(`# BRAND KNOWLEDGE DIRECTIVE: ${knowledge.brandName || "AKÉRIA"}`);
|
||
if (knowledge.tagline) {
|
||
sections.push(`**Tagline:** ${knowledge.tagline}`);
|
||
}
|
||
|
||
if (knowledge.story) {
|
||
sections.push(`## 1. BRAND STORY & CORE PHILOSOPHY\n${knowledge.story.trim()}`);
|
||
}
|
||
|
||
if (knowledge.targetAudience) {
|
||
sections.push(`## 2. TARGET AUDIENCE & PERSONA\n${knowledge.targetAudience.trim()}`);
|
||
}
|
||
|
||
if (knowledge.toneOfVoice) {
|
||
sections.push(`## 3. TONE OF VOICE & MESSAGING STYLE\n${knowledge.toneOfVoice.trim()}`);
|
||
}
|
||
|
||
if (knowledge.visualArtPrompt) {
|
||
sections.push(`## 4. VISUAL ART DIRECTION & PHOTOGRAPHY DIRECTIVE\n${knowledge.visualArtPrompt.trim()}`);
|
||
}
|
||
|
||
if (knowledge.productUsps) {
|
||
sections.push(`## 5. PRODUCTS, SIGNATURE NOTES & USPs\n${knowledge.productUsps.trim()}`);
|
||
}
|
||
|
||
if (knowledge.marketingGuidelines) {
|
||
sections.push(`## 6. MARKETING CHANNELS & CONTENT GUIDELINES\n${knowledge.marketingGuidelines.trim()}`);
|
||
}
|
||
|
||
if (knowledge.customRules) {
|
||
sections.push(`## 7. STRICT BRAND COMPLIANCE & RULES\n${knowledge.customRules.trim()}`);
|
||
}
|
||
|
||
sections.push(`---\n*This document is the single source of truth for all LLM, AI Image, and Copywriting tasks representing ${knowledge.brandName || "AKÉRIA"}.*`);
|
||
|
||
return sections.join("\n\n");
|
||
}
|
||
|
||
export const brandKnowledgeRoute = new Elysia({ prefix: "/brand-knowledge" })
|
||
.get("/", async () => {
|
||
let knowledge = await prisma.brandKnowledge.findFirst();
|
||
if (!knowledge) {
|
||
knowledge = await prisma.brandKnowledge.create({
|
||
data: DEFAULT_AKERIA_KNOWLEDGE,
|
||
});
|
||
}
|
||
return {
|
||
...knowledge,
|
||
compiledPrompt: compileBrandPrompt(knowledge),
|
||
};
|
||
})
|
||
.get("/compiled-prompt", async () => {
|
||
let knowledge = await prisma.brandKnowledge.findFirst();
|
||
if (!knowledge) {
|
||
knowledge = await prisma.brandKnowledge.create({
|
||
data: DEFAULT_AKERIA_KNOWLEDGE,
|
||
});
|
||
}
|
||
return {
|
||
brandName: knowledge.brandName,
|
||
compiledPrompt: compileBrandPrompt(knowledge),
|
||
updatedAt: knowledge.updatedAt,
|
||
};
|
||
})
|
||
.use(adminOnly)
|
||
.put(
|
||
"/",
|
||
async ({ body, set }) => {
|
||
try {
|
||
const data = body as any;
|
||
let knowledge = await prisma.brandKnowledge.findFirst();
|
||
|
||
if (!knowledge) {
|
||
knowledge = await prisma.brandKnowledge.create({
|
||
data: {
|
||
...DEFAULT_AKERIA_KNOWLEDGE,
|
||
...data,
|
||
},
|
||
});
|
||
} else {
|
||
knowledge = await prisma.brandKnowledge.update({
|
||
where: { id: knowledge.id },
|
||
data: {
|
||
brandName: data.brandName !== undefined ? data.brandName : knowledge.brandName,
|
||
tagline: data.tagline !== undefined ? data.tagline : knowledge.tagline,
|
||
story: data.story !== undefined ? data.story : knowledge.story,
|
||
targetAudience: data.targetAudience !== undefined ? data.targetAudience : knowledge.targetAudience,
|
||
toneOfVoice: data.toneOfVoice !== undefined ? data.toneOfVoice : knowledge.toneOfVoice,
|
||
visualArtPrompt: data.visualArtPrompt !== undefined ? data.visualArtPrompt : knowledge.visualArtPrompt,
|
||
productUsps: data.productUsps !== undefined ? data.productUsps : knowledge.productUsps,
|
||
marketingGuidelines: data.marketingGuidelines !== undefined ? data.marketingGuidelines : knowledge.marketingGuidelines,
|
||
customRules: data.customRules !== undefined ? data.customRules : knowledge.customRules,
|
||
masterPromptOverride: data.masterPromptOverride !== undefined ? data.masterPromptOverride : knowledge.masterPromptOverride,
|
||
},
|
||
});
|
||
}
|
||
|
||
return {
|
||
success: true,
|
||
data: {
|
||
...knowledge,
|
||
compiledPrompt: compileBrandPrompt(knowledge),
|
||
},
|
||
};
|
||
} catch (err) {
|
||
console.error("[BrandKnowledge] Update error:", err);
|
||
set.status = 500;
|
||
return { success: false, error: "Failed to update brand knowledge" };
|
||
}
|
||
},
|
||
{
|
||
body: t.Object({
|
||
brandName: t.Optional(t.String()),
|
||
tagline: t.Optional(t.Nullable(t.String())),
|
||
story: t.Optional(t.Nullable(t.String())),
|
||
targetAudience: t.Optional(t.Nullable(t.String())),
|
||
toneOfVoice: t.Optional(t.Nullable(t.String())),
|
||
visualArtPrompt: t.Optional(t.Nullable(t.String())),
|
||
productUsps: t.Optional(t.Nullable(t.String())),
|
||
marketingGuidelines: t.Optional(t.Nullable(t.String())),
|
||
customRules: t.Optional(t.Nullable(t.String())),
|
||
masterPromptOverride: t.Optional(t.Nullable(t.String())),
|
||
}),
|
||
}
|
||
);
|