use super::{write_file, Scaffold, ScaffoldArgs, ScaffoldResult};
use anyhow::Result;
pub struct ImportScaffold;
impl Scaffold for ImportScaffold {
fn name(&self) -> &'static str {
"import"
}
fn description(&self) -> &'static str {
"CSV/Excel import: row validation, error report, chunked processing, duplicate handling"
}
fn generate(&self, args: &ScaffoldArgs) -> Result<ScaffoldResult> {
let mut r = ScaffoldResult::default();
let d = args.dry_run;
write_file(
&mut r,
"src/app/controllers/import_controller.rs",
CONTROLLER,
d,
)?;
write_file(&mut r, "src/app/jobs/import_job.rs", JOB, d)?;
write_file(
&mut r,
"migrations/create_import_logs_table.sql",
MIGRATION,
d,
)?;
r.warnings.push("Register POST /imports route".into());
Ok(r)
}
}
const CONTROLLER: &str = r#"use axum::{extract::{Multipart, State}, response::IntoResponse};
use rok_auth::axum::{Ctx, Response};
pub async fn preview(ctx: Ctx, mut multipart: Multipart) -> impl IntoResponse {
// TODO: parse first N rows, validate, return preview with errors
Response::json(serde_json::json!({ "preview": [], "errors": [], "total_rows": 0 }))
}
pub async fn confirm(ctx: Ctx, State(pool): State<sqlx::PgPool>) -> impl IntoResponse {
// TODO: enqueue ImportJob with confirmed import_id
Response::json(serde_json::json!({ "job_id": null, "message": "Import queued" }))
}
"#;
const JOB: &str = r#"use rok_queue::Job;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct ImportJob {
pub import_log_id: i64,
pub strategy: String, // "skip" | "update" | "error"
pub chunk_size: usize,
}
#[async_trait::async_trait]
impl Job for ImportJob {
const QUEUE: &'static str = "imports";
async fn handle(&self) -> anyhow::Result<()> {
// TODO: read file from storage, process in chunks, handle duplicates per strategy
Ok(())
}
}
"#;
const MIGRATION: &str = r#"CREATE TABLE import_logs (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL,
filename TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
total_rows INTEGER,
imported_rows INTEGER DEFAULT 0,
error_rows INTEGER DEFAULT 0,
errors JSONB,
storage_key TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
"#;