first commit

This commit is contained in:
2026-03-14 20:50:05 -04:00
commit 0c9af957fe
25 changed files with 1122 additions and 0 deletions

14
shared/Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "shared"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
uuid = { workspace = true }
chrono = { workspace = true }
thiserror = { workspace = true }
axum = { workspace = true }
sqlx = { workspace = true }
tracing = { workspace = true }

40
shared/src/errors.rs Normal file
View File

@@ -0,0 +1,40 @@
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
Json,
};
use serde_json::json;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum AppError {
#[error("Database error: {0}")]
Database(#[from] sqlx::Error),
#[error("Unauthorized: {0}")]
Unauthorized(String),
#[error("Bad request: {0}")]
BadRequest(String),
#[error("Not found: {0}")]
NotFound(String),
#[error("Internal error: {0}")]
Internal(String),
}
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, message) = match &self {
AppError::Database(e) => {
tracing::error!("DB error: {e}");
(StatusCode::INTERNAL_SERVER_ERROR, "Database error".to_string())
}
AppError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg.clone()),
AppError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
AppError::NotFound(msg) => (StatusCode::NOT_FOUND, msg.clone()),
AppError::Internal(msg) => {
tracing::error!("Internal error: {msg}");
(StatusCode::INTERNAL_SERVER_ERROR, msg.clone())
}
};
(status, Json(json!({ "error": message }))).into_response()
}
}

2
shared/src/lib.rs Normal file
View File

@@ -0,0 +1,2 @@
pub mod errors;
pub mod models;

50
shared/src/models.rs Normal file
View File

@@ -0,0 +1,50 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, sqlx::Type)]
#[sqlx(type_name = "user_role", rename_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum UserRole {
Driver,
MechanicShop,
MobileMechanic,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, sqlx::Type)]
#[sqlx(type_name = "report_type", rename_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum ReportType {
Police,
Dot,
Hazard,
RoadCondition,
BreakdownRequest,
Other,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, sqlx::Type)]
#[sqlx(type_name = "service_status", rename_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum ServiceStatus {
Open,
Claimed,
Resolved,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
pub id: Uuid,
pub handle: String,
pub role: UserRole,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Claims {
pub sub: String, // user_id
pub handle: String,
pub role: UserRole,
pub exp: usize,
pub iat: usize,
}