pub fn extract_title(prompt: &str) -> String {
let first_line = prompt.lines().next().unwrap_or(prompt);
let trimmed = first_line.trim();
if trimmed.len() > 80 {
format!("{:.80}...", trimmed)
} else {
trimmed.to_string()
}
}
pub fn decompose_features(prompt: &str) -> Vec<String> {
let mut features = Vec::new();
let lower = prompt.to_lowercase();
let keywords: Vec<(&str, Vec<&str>)> = vec![
("auth", vec!["Authentication flow", "Session management"]),
("login", vec!["User login flow", "Credential validation"]),
("oauth", vec!["OAuth2 integration", "Token refresh mechanism"]),
(
"database",
vec!["Database schema", "Migration support", "Data access layer"],
),
(
"api",
vec!["REST API endpoints", "API documentation", "OpenAPI spec"],
),
(
"ui",
vec!["Frontend components", "User interface design", "Responsive layout"],
),
("test", vec!["Unit tests", "Integration tests", "E2E tests"]),
(
"deploy",
vec!["Deployment pipeline", "Infrastructure setup", "CI/CD workflow"],
),
(
"cache",
vec!["Caching layer", "Cache invalidation strategy", "Redis integration"],
),
(
"search",
vec!["Search indexing", "Query optimization", "Full-text search"],
),
(
"email",
vec!["Email notification", "SMTP integration", "Template rendering"],
),
(
"notification",
vec![
"Push notification",
"In-app notification",
"Notification queue",
],
),
(
"payment",
vec!["Payment gateway", "Billing logic", "Invoice generation"],
),
(
"report",
vec![
"Reporting engine",
"Analytics dashboard",
"Export to CSV/PDF",
],
),
(
"security",
vec!["Security audit", "Rate limiting", "Input sanitization"],
),
(
"monitor",
vec!["Health monitoring", "Alerting rules", "Log aggregation"],
),
(
"import",
vec!["Data import", "CSV/JSON parsing", "Validation rules"],
),
("export", vec!["Data export", "Format conversion", "Download API"]),
(
"admin",
vec!["Admin panel", "Role-based access", "Audit log"],
),
];
for (keyword, feats) in keywords {
if lower.contains(keyword) {
for feat in feats {
if !features.contains(&feat.to_string()) {
features.push(feat.to_string());
}
}
}
}
if features.is_empty() {
features.push("Core feature implementation".to_string());
}
features
}
pub fn slugify(s: &str) -> String {
s.to_lowercase()
.replace(|c: char| !c.is_alphanumeric() && c != ' ', "")
.replace(' ', "-")
.replace("--", "-")
.trim_matches('-')
.to_string()
}