feat: Refactor service management scripts to use a unified dev script
- Added package.json to manage development scripts. - Updated restart-services.ps1 to call the new dev script for starting services. - Refactored start-admin.ps1, start-backend.ps1, start-frontend.ps1, and start-mcp.ps1 to utilize the dev script for starting respective services. - Enhanced stop-services.ps1 to improve process termination logic by matching command patterns.
This commit is contained in:
@@ -7,7 +7,10 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
controllers::{
|
||||
admin::{admin_username, check_auth, is_admin_logged_in, set_admin_logged_in, validate_admin_credentials},
|
||||
admin::{
|
||||
admin_username, check_auth, is_admin_logged_in, set_admin_logged_in,
|
||||
validate_admin_credentials,
|
||||
},
|
||||
site_settings::{self, SiteSettingsPayload},
|
||||
},
|
||||
models::_entities::{ai_chunks, comments, friend_links, posts, reviews},
|
||||
@@ -120,11 +123,15 @@ pub struct AdminSiteSettingsResponse {
|
||||
pub social_email: Option<String>,
|
||||
pub location: Option<String>,
|
||||
pub tech_stack: Vec<String>,
|
||||
pub music_playlist: Vec<site_settings::MusicTrackPayload>,
|
||||
pub ai_enabled: bool,
|
||||
pub paragraph_comments_enabled: bool,
|
||||
pub ai_provider: Option<String>,
|
||||
pub ai_api_base: Option<String>,
|
||||
pub ai_api_key: Option<String>,
|
||||
pub ai_chat_model: Option<String>,
|
||||
pub ai_providers: Vec<site_settings::AiProviderConfig>,
|
||||
pub ai_active_provider_id: Option<String>,
|
||||
pub ai_embedding_model: Option<String>,
|
||||
pub ai_system_prompt: Option<String>,
|
||||
pub ai_top_k: Option<i32>,
|
||||
@@ -140,6 +147,29 @@ pub struct AdminAiReindexResponse {
|
||||
pub last_indexed_at: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct AdminAiProviderTestRequest {
|
||||
pub provider: site_settings::AiProviderConfig,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct AdminAiProviderTestResponse {
|
||||
pub provider: String,
|
||||
pub endpoint: String,
|
||||
pub chat_model: String,
|
||||
pub reply_preview: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct AdminPostMetadataRequest {
|
||||
pub markdown: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct AdminPostPolishRequest {
|
||||
pub markdown: String,
|
||||
}
|
||||
|
||||
fn format_timestamp(
|
||||
value: Option<sea_orm::prelude::DateTimeWithTimeZone>,
|
||||
pattern: &str,
|
||||
@@ -166,10 +196,27 @@ fn tech_stack_values(value: &Option<serde_json::Value>) -> Vec<String> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn music_playlist_values(
|
||||
value: &Option<serde_json::Value>,
|
||||
) -> Vec<site_settings::MusicTrackPayload> {
|
||||
value
|
||||
.as_ref()
|
||||
.and_then(serde_json::Value::as_array)
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.filter_map(|item| serde_json::from_value::<site_settings::MusicTrackPayload>(item).ok())
|
||||
.filter(|item| !item.title.trim().is_empty() && !item.url.trim().is_empty())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn build_settings_response(
|
||||
item: crate::models::_entities::site_settings::Model,
|
||||
ai_chunks_count: u64,
|
||||
) -> AdminSiteSettingsResponse {
|
||||
let ai_providers = site_settings::ai_provider_configs(&item);
|
||||
let ai_active_provider_id = site_settings::active_ai_provider_id(&item);
|
||||
|
||||
AdminSiteSettingsResponse {
|
||||
id: item.id,
|
||||
site_name: item.site_name,
|
||||
@@ -188,11 +235,15 @@ fn build_settings_response(
|
||||
social_email: item.social_email,
|
||||
location: item.location,
|
||||
tech_stack: tech_stack_values(&item.tech_stack),
|
||||
music_playlist: music_playlist_values(&item.music_playlist),
|
||||
ai_enabled: item.ai_enabled.unwrap_or(false),
|
||||
paragraph_comments_enabled: item.paragraph_comments_enabled.unwrap_or(true),
|
||||
ai_provider: item.ai_provider,
|
||||
ai_api_base: item.ai_api_base,
|
||||
ai_api_key: item.ai_api_key,
|
||||
ai_chat_model: item.ai_chat_model,
|
||||
ai_providers,
|
||||
ai_active_provider_id,
|
||||
ai_embedding_model: item.ai_embedding_model,
|
||||
ai_system_prompt: item.ai_system_prompt,
|
||||
ai_top_k: item.ai_top_k,
|
||||
@@ -375,8 +426,9 @@ pub async fn update_site_settings(
|
||||
check_auth()?;
|
||||
|
||||
let current = site_settings::load_current(&ctx).await?;
|
||||
let mut item = current.into_active_model();
|
||||
let mut item = current;
|
||||
params.apply(&mut item);
|
||||
let item = item.into_active_model();
|
||||
let updated = item.update(&ctx.db).await?;
|
||||
let ai_chunks_count = ai_chunks::Entity::find().count(&ctx.db).await?;
|
||||
|
||||
@@ -390,10 +442,51 @@ pub async fn reindex_ai(State(ctx): State<AppContext>) -> Result<Response> {
|
||||
|
||||
format::json(AdminAiReindexResponse {
|
||||
indexed_chunks: summary.indexed_chunks,
|
||||
last_indexed_at: format_timestamp(summary.last_indexed_at.map(Into::into), "%Y-%m-%d %H:%M:%S UTC"),
|
||||
last_indexed_at: format_timestamp(
|
||||
summary.last_indexed_at.map(Into::into),
|
||||
"%Y-%m-%d %H:%M:%S UTC",
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn test_ai_provider(Json(payload): Json<AdminAiProviderTestRequest>) -> Result<Response> {
|
||||
check_auth()?;
|
||||
|
||||
let result = ai::test_provider_connectivity(
|
||||
&payload.provider.provider,
|
||||
payload.provider.api_base.as_deref().unwrap_or_default(),
|
||||
payload.provider.api_key.as_deref().unwrap_or_default(),
|
||||
payload.provider.chat_model.as_deref().unwrap_or_default(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
format::json(AdminAiProviderTestResponse {
|
||||
provider: result.provider,
|
||||
endpoint: result.endpoint,
|
||||
chat_model: result.chat_model,
|
||||
reply_preview: result.reply_preview,
|
||||
})
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn generate_post_metadata(
|
||||
State(ctx): State<AppContext>,
|
||||
Json(payload): Json<AdminPostMetadataRequest>,
|
||||
) -> Result<Response> {
|
||||
check_auth()?;
|
||||
format::json(ai::generate_post_metadata(&ctx, &payload.markdown).await?)
|
||||
}
|
||||
|
||||
#[debug_handler]
|
||||
pub async fn polish_post_markdown(
|
||||
State(ctx): State<AppContext>,
|
||||
Json(payload): Json<AdminPostPolishRequest>,
|
||||
) -> Result<Response> {
|
||||
check_auth()?;
|
||||
format::json(ai::polish_post_markdown(&ctx, &payload.markdown).await?)
|
||||
}
|
||||
|
||||
pub fn routes() -> Routes {
|
||||
Routes::new()
|
||||
.prefix("/api/admin")
|
||||
@@ -405,4 +498,7 @@ pub fn routes() -> Routes {
|
||||
.add("/site-settings", patch(update_site_settings))
|
||||
.add("/site-settings", put(update_site_settings))
|
||||
.add("/ai/reindex", post(reindex_ai))
|
||||
.add("/ai/test-provider", post(test_ai_provider))
|
||||
.add("/ai/post-metadata", post(generate_post_metadata))
|
||||
.add("/ai/polish-post", post(polish_post_markdown))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user