feat: implement authentication flow and session management

- Update RootLayout to handle authentication state and redirect users based on their auth status.
- Create an Index component to redirect unauthenticated users to the login page.
- Modify ApiAuthRepository to fetch user session data using access and refresh tokens.
- Introduce a new container file to manage use case instances for authentication and filament operations.
- Enhance authStore to validate tokens and fetch user data from the API.
- Add babel-plugin-module-resolver for improved module imports.
- Update package.json scripts for running the app on Android and iOS.
- Add expo-camera dependency for camera functionalities.
- Update tsconfig.json to include infrastructure path mapping.
This commit is contained in:
2026-03-14 13:22:17 -03:00
parent d7fb768d3b
commit 416e13893c
68 changed files with 1778 additions and 99 deletions
+1 -1
View File
@@ -361,7 +361,7 @@ O backend implementa **last-write-wins com timestamp**:
## Geração de QR Code e Etiqueta SVG
### QR Code (`GET /filaments/:id/qrcode`)
- Gera QR Code com deep link: `meowspool://filaments/:id`
- Gera QR Code com deep link: `meowspool://filament/:id` (singular)
- Retorna PNG (`image/png`) por padrão, ou SVG com `?format=svg`
- Biblioteca: crate `qrcode`
@@ -10,11 +10,6 @@ http:
type: bearer
token: "{{access_token}}"
runtime:
variables:
- name: filament_id
value: e1edc611-f020-4234-94e5-db5e1393dbf2
settings:
encodeUrl: true
timeout: 0
@@ -10,8 +10,8 @@ http:
type: json
data: |-
{
"name": "Carretel Customizado 350g",
"spool_weight_g": 350
"name": "Elegoo (Papelão)",
"spool_weight_g": 156
}
auth:
type: bearer
@@ -5,6 +5,6 @@ variables:
- secret: true
name: refresh_token
- name: preset_id
value: 0ffa808d-af09-4bc6-9a40-43df3a4c6dd0
value: 38e439ba-0289-4bf0-9f4b-f9cb12991167
- name: filament_id
value: e1edc611-f020-4234-94e5-db5e1393dbf2
value: 0b371f84-706a-4eaa-bff0-33556fa833b4
@@ -82,6 +82,15 @@ pub async fn create_preset_handler(
Ok((StatusCode::CREATED, Json(SpoolPresetResponse::from(preset))))
}
pub async fn get_preset_handler(
State(state): State<AppState>,
Extension(_user): Extension<CurrentUser>,
Path(id): Path<Uuid>,
) -> Result<impl IntoResponse, AppError> {
let preset = state.spool_preset_service.get_by_id(id).await?;
Ok(Json(SpoolPresetResponse::from(preset)))
}
pub async fn update_preset_handler(
State(state): State<AppState>,
Extension(user): Extension<CurrentUser>,
+1 -1
View File
@@ -228,7 +228,7 @@ impl FilamentService {
pub async fn generate_qrcode_png(&self, id: Uuid, user_id: Uuid) -> Result<Vec<u8>, AppError> {
self.get(id, user_id).await?;
let deep_link = format!("meowspool://filaments/{id}");
let deep_link = format!("meowspool://filament/{id}");
let code = qrcode::QrCode::new(deep_link.as_bytes())
.map_err(|e| AppError::Internal(anyhow::anyhow!("QR Code generation failed: {e}")))?;
@@ -23,6 +23,10 @@ impl SpoolPresetService {
self.repo.list_for_user(user_id).await
}
pub async fn get_by_id(&self, id: Uuid) -> Result<SpoolPreset, AppError> {
self.repo.find_by_id(id).await?.ok_or(AppError::NotFound)
}
pub async fn create(
&self,
user_id: Uuid,
+1
View File
@@ -88,6 +88,7 @@ pub fn build(db: PgPool, config: Config) -> Router {
// Spool Presets
.route("/spool-presets", get(spool_preset_handler::list_presets_handler))
.route("/spool-presets", post(spool_preset_handler::create_preset_handler))
.route("/spool-presets/:id", get(spool_preset_handler::get_preset_handler))
.route("/spool-presets/:id", put(spool_preset_handler::update_preset_handler))
.route("/spool-presets/:id", delete(spool_preset_handler::delete_preset_handler))
.route_layer(middleware::from_fn_with_state(state.clone(), auth_middleware));