Skip to content

feat: Add initial frontend#33

Merged
StoynovAngel merged 21 commits into
mainfrom
feat/add-initial-frontend
Apr 14, 2026
Merged

feat: Add initial frontend#33
StoynovAngel merged 21 commits into
mainfrom
feat/add-initial-frontend

Conversation

@StoynovAngel
Copy link
Copy Markdown
Owner

@StoynovAngel StoynovAngel commented Apr 14, 2026

Summary by CodeRabbit

  • New Features
    • Ship a mobile app with login/register flows, persistent token-based auth, navigation (auth + main tabs), Home screen, and responsive forms with field/server error handling
    • Added dark/light theme with persistence, accessibility menu (theme & language), and English + Bulgarian localizations
  • Chores
    • Backend server port changed to 8080 and debug logging enabled; added frontend environment example and project ignore rules

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 14, 2026

Warning

Rate limit exceeded

@StoynovAngel has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 37 minutes and 47 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 37 minutes and 47 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 277a761f-2827-4db7-89e3-fb6b0712ac47

📥 Commits

Reviewing files that changed from the base of the PR and between 36e56b2 and b74f3ca.

📒 Files selected for processing (6)
  • backend/.env.example
  • backend/src/main/java/com/angel/autonow/security/SecurityConfig.java
  • backend/src/main/java/com/angel/autonow/user/UserService.java
  • backend/src/main/resources/application.properties
  • backend/src/test/java/com/angel/autonow/AutoNowApplicationTests.java
  • backend/src/test/resources/application-test.properties
📝 Walkthrough

Walkthrough

This PR adds a new Expo React Native frontend (navigation, screens, API client, stores, hooks, localization, theme, accessibility UI, tooling/config) and updates backend configuration and logs: changes to server port, Spring logging levels, CORS bean, and additional logging in UserService.

Changes

Cohort / File(s) Summary
Backend Configuration & Security
backend/src/main/resources/application.properties, backend/src/main/java/com/angel/autonow/security/SecurityConfig.java
Changed server.port from 80818080; added logging.level.org.springframework.web=DEBUG and logging.level.com.angel.autonow=DEBUG; added CorsConfigurationSource bean allowing origins for localhost and Android emulator addresses.
Backend Service Logging
backend/src/main/java/com/angel/autonow/user/UserService.java
Added warning/info log statements around registration and login error/success paths (no API signature changes).
Frontend Project Manifest & Tooling
frontend/package.json, frontend/tsconfig.json, frontend/app.config.ts, frontend/app.json, frontend/metro.config.js, frontend/index.ts
Added Expo/TS project manifest, app config (injects extra.apiUrl), Metro alias for @src, entry registration, and npm scripts/dependencies.
Frontend Env & VCS
frontend/.env.example, frontend/.gitignore, frontend/.idea/.gitignore
Added .env.example with API_URL sample and gitignore rules for frontend and IDE artifacts.
App Entry & Runtime Config
frontend/App.tsx, frontend/src/constants/config.ts
Added root App with React Query provider, NavigationContainer, theme-aware StatusBar and hydration (theme/locale/auth); added runtime API_URL resolution (Expo extra or platform defaults).
HTTP Client, API Wrappers & Types
frontend/src/api/client.ts, frontend/src/api/auth.ts, frontend/src/types/api.ts
Added Axios client with Authorization injection, 401 handling (clears auth), ApiError class (fieldErrors), and login/register wrappers; added AuthRequest, AuthResponse, and ProblemDetail types.
State, Persistence & Stores
frontend/src/stores/*
Added Zustand stores: authStore (token/email/hydration + decodeEmail), themeStore (mode/colors + hydrateTheme), localeStore (locale + hydrateLocale), and token helpers (save/get/delete using secure store).
Hooks & Initialization
frontend/src/hooks/*
Added React Query hooks for login/register, useAuthState to hydrate/validate stored token, and useTranslation + global translate helper.
Localization Files
frontend/src/constants/locales/en.json, frontend/src/constants/locales/bg.json
Added English and Bulgarian translation dictionaries.
Design System & Theme
frontend/src/constants/theme.ts
Added typed light/dark color palettes and design tokens (spacing, font sizes, border radii, font weights).
Navigation, Styles & Types
frontend/src/navigation/..., frontend/src/types/navigation.ts, frontend/src/navigation/*styles.ts
Added RootNavigator (gated on hydration), AuthStack, MainTabs, header/tab style helpers, and navigation types.
Screens & Styles
frontend/src/screens/Login/..., frontend/src/screens/Register/..., frontend/src/screens/Home/...
Implemented Login, Register, Home screens with validation, API error handling, keyboard-aware layout, and themed styles.
Accessibility Component
frontend/src/components/AccessibilityMenu/...
Added modal-based AccessibilityMenu allowing theme toggle and language selection, positioned relative to trigger.
API Surface & Utilities
frontend/src/constants/config.ts, frontend/src/api/*, frontend/src/types/*
New exported constants/functions/types (API_URL, client, ApiError, AuthRequest/AuthResponse, ThemeColors, translate, etc.).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as App / Screens
    participant AuthHook as useAuth / React Query
    participant Client as Axios Client
    participant API as Backend API
    participant Store as Auth Store
    participant Nav as Navigation

    User->>UI: Submit credentials
    UI->>AuthHook: login.mutate(email,password)
    AuthHook->>Client: POST /api/auth/login
    Client->>API: HTTP request (Authorization if present)
    API->>Client: 200 { token } / error
    Client->>AuthHook: Return response or throw ApiError
    AuthHook->>Store: setAuth(token, decodedEmail)
    Store->>Store: persist token (secure storage)
    Store->>Nav: auth state updated
    Nav->>UI: Render authenticated MainTabs
Loading
sequenceDiagram
    participant App as App Startup
    participant Theme as Theme Store
    participant Locale as Locale Store
    participant AuthState as useAuthState
    participant Token as Secure Storage
    participant Store as Auth Store
    participant Nav as RootNavigator

    App->>Theme: hydrateTheme()
    Theme->>Token: read stored theme
    Theme->>Theme: setMode/colors

    App->>Locale: hydrateLocale()
    Locale->>Token: read stored locale
    Locale->>Locale: setLocale

    App->>AuthState: useAuthState()
    AuthState->>Token: getToken()
    Token-->>AuthState: token|null
    alt token present & valid
        AuthState->>Store: setAuth(token, email)
    else
        AuthState->>Store: clearAuth()
    end
    AuthState->>Store: setHydrated()
    App->>Nav: render RootNavigator (hydrated)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐇 I hopped through ports and mobiles bright,

New themes and tongues came into light,
Tokens tucked in secure nests,
Screens and tabs prepare their quests,
Backend now listens on eight-zero tonight.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Add initial frontend' clearly and concisely describes the main change: adding a new frontend application to the project.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-initial-frontend

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Nitpick comments (12)
frontend/src/hooks/useAuth.ts (1)

5-27: Consider extracting shared auth-mutation logic.

useLogin and useRegister differ only by mutationFn; extracting a small factory would reduce drift risk.

Refactor sketch
 export function useLogin() {
-  const setAuth = useAuthStore((s) => s.setAuth);
-
-  return useMutation({
-    mutationFn: loginUser,
-    onSuccess: (data) => {
-      const email = decodeEmail(data.token) ?? "";
-      setAuth(data.token, email);
-    },
-  });
+  return useAuthMutation(loginUser);
 }
 
 export function useRegister() {
+  return useAuthMutation(registerUser);
+}
+
+function useAuthMutation(
+  mutationFn: typeof loginUser | typeof registerUser
+) {
   const setAuth = useAuthStore((s) => s.setAuth);
 
   return useMutation({
-    mutationFn: registerUser,
+    mutationFn,
     onSuccess: (data) => {
       const email = decodeEmail(data.token) ?? "";
       setAuth(data.token, email);
     },
   });
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/hooks/useAuth.ts` around lines 5 - 27, Extract the duplicated
logic in useLogin and useRegister into a small factory like createAuthMutation
that accepts a mutationFn (e.g., loginUser or registerUser) and returns the
useMutation call that uses useAuthStore's setAuth and decodes the token with
decodeEmail on onSuccess; then replace useLogin and useRegister to simply call
createAuthMutation(loginUser) and createAuthMutation(registerUser) respectively
so setAuth, decodeEmail, and mutation result handling live in one place.
frontend/metro.config.js (1)

6-8: Merge aliases instead of replacing them.

Overwriting config.resolver.alias can unintentionally drop existing aliases from default config.

Suggested patch
 config.resolver.alias = {
+  ...(config.resolver.alias || {}),
   "@": path.resolve(__dirname, "src"),
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/metro.config.js` around lines 6 - 8, The PR currently replaces
config.resolver.alias which drops defaults; instead update metro.config.js to
merge the new alias into any existing resolver.alias (and ensure resolver
exists) rather than overwriting it: read the current config.resolver.alias (or
{}), spread its entries and add "@" => path.resolve(__dirname, "src") so
existing aliases remain intact while adding your alias for "@/..." imports.
frontend/src/screens/Home/HomeScreen.styles.ts (1)

29-33: Prefer theme spacing tokens over raw numeric padding.

Using a token here keeps spacing consistent and easier to tune globally.

♻️ Proposed change
     logoutButton: {
       paddingHorizontal: spacing.xl,
-      paddingVertical: 14,
+      paddingVertical: spacing.md,
       borderRadius: borderRadius.md,
       borderWidth: 1,
       borderColor: colors.error,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/screens/Home/HomeScreen.styles.ts` around lines 29 - 33, The
logoutButton style uses a raw numeric paddingVertical (14); replace that magic
number with the appropriate theme spacing token (e.g., spacing.md or spacing.lg)
to keep spacing consistent—update the logoutButton object in
HomeScreen.styles.ts to use the theme spacing token via the existing spacing
symbol so paddingVertical references spacing.<token> instead of 14.
frontend/src/screens/Register/RegisterScreen.styles.ts (1)

32-33: Consider replacing remaining numeric literals with theme tokens.

This keeps typography/spacing aligned with the rest of the theme system.

♻️ Proposed change
     input: {
       borderWidth: 1,
       borderColor: colors.inputBorder,
       borderRadius: borderRadius.md,
       paddingHorizontal: spacing.md,
-      paddingVertical: 14,
+      paddingVertical: spacing.md,
       fontSize: fontSize.lg,
       backgroundColor: colors.inputBackground,
       color: colors.text,
     },
@@
-    buttonText: { color: colors.white, fontSize: 17, fontWeight: "600" },
+    buttonText: { color: colors.white, fontSize: fontSize.lg, fontWeight: "600" },

Also applies to: 59-59

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/screens/Register/RegisterScreen.styles.ts` around lines 32 - 33,
Replace hard-coded numeric spacing with theme tokens: change the
paddingVertical: 14 in the RegisterScreen style object to use the theme spacing
token (e.g., spacing.sm or spacing.md) and replace the other remaining numeric
literal in this file (the second numeric occurrence in the styles) with the
appropriate theme spacing token as well; keep using the existing fontSize tokens
(fontSize.lg) and update imports/usage to pull spacing from the theme (e.g.,
spacing) so all typography/spacing align with the design system.
frontend/App.tsx (1)

18-21: Consider adding error handling for hydration failures.

hydrateLocale() and hydrateTheme() are called without error handling. If these async operations fail (e.g., storage access issues), the app would continue silently with default values. While this may be acceptable, adding a try-catch with logging could help diagnose issues in production.

♻️ Proposed improvement
   useEffect(() => {
-    hydrateLocale();
-    hydrateTheme();
+    Promise.all([hydrateLocale(), hydrateTheme()]).catch((err) => {
+      console.warn("Failed to hydrate persisted state:", err);
+    });
   }, []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/App.tsx` around lines 18 - 21, Wrap the hydrateLocale() and
hydrateTheme() calls inside the useEffect in a try-catch (or an async IIFE) so
any exceptions during hydration are caught; in the catch block, log the error
(using the app's logger or console.error) along with context like
"hydrateLocale/hydrateTheme failed" so failures don't fail silently; update the
effect that currently calls hydrateLocale() and hydrateTheme() to perform this
guarded/awaited invocation and ensure any returned Promises are awaited.
frontend/src/navigation/MainTabs.tsx (1)

25-29: Consider using translations for tab labels.

The tabBarLabel is hardcoded as "Home". Given the app already has localization infrastructure (useTranslation, locale store), this label should use the translation function for consistency.

+import { useTranslation } from "@/hooks/useTranslation";
 // ...inside MainTabs:
+const { t } = useTranslation();
 <Tab.Screen
   name="Home"
   component={HomeScreen}
-  options={{ tabBarLabel: "Home" }}
+  options={{ tabBarLabel: t("tabs.home") }}
 />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/navigation/MainTabs.tsx` around lines 25 - 29, The Home tab's
label is hardcoded in the Tab.Screen for name="Home" (component HomeScreen) via
options.tabBarLabel; update it to use the app's i18n instead: import and call
the translation hook (useTranslation) or locale store to retrieve the localized
string (e.g., t('tabs.home')) and pass that value to options.tabBarLabel so the
tab label is localized consistently with the rest of the app.
frontend/src/hooks/useAuthState.ts (1)

14-21: Duplicate JWT parsing logic.

The token payload is parsed twice:

  1. Lines 15-17: Manually parsing to extract exp
  2. Line 20: decodeEmail(stored) parses the same token again

Consider refactoring to parse once and extract both values, or extend decodeEmail to return more payload fields.

♻️ Proposed refactor

In authStore.ts, rename/extend the function to return more payload data:

export function decodeJwtPayload(token: string): { sub?: string; exp?: number } | null {
  try {
    const payload = token.split(".")[1];
    const decoded = JSON.parse(atob(payload));
    return { sub: decoded.sub, exp: decoded.exp };
  } catch {
    return null;
  }
}

Then in useAuthState.ts:

-        if (stored) {
-          const payload = stored.split(".")[1];
-          const decoded = JSON.parse(atob(payload));
-          const exp = decoded.exp;
-
-          if (exp && exp * 1000 > Date.now()) {
-            const email = decodeEmail(stored) ?? "";
-            setAuth(stored, email);
-          } else {
-            clearAuth();
-          }
-        }
+        if (stored) {
+          const payload = decodeJwtPayload(stored);
+          if (payload?.exp && payload.exp * 1000 > Date.now()) {
+            setAuth(stored, payload.sub ?? "");
+          } else {
+            clearAuth();
+          }
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/hooks/useAuthState.ts` around lines 14 - 21, The JWT payload is
being parsed twice in useAuthState (once inline to get exp and again via
decodeEmail); refactor to parse once by adding or extending a helper in
authStore (e.g., decodeJwtPayload or extend decodeEmail to return payload fields
like sub/email and exp) and then use that single result in useAuthState to
obtain exp and email before calling setAuth; update calls to replace inline
JSON.parse(atob(...)) and decodeEmail(stored) with the new helper (referencing
useAuthState, decodeEmail/decodeJwtPayload, and setAuth to locate changes).
frontend/src/screens/Login/LoginScreen.styles.ts (1)

27-36: Minor inconsistency: hardcoded values instead of theme constants.

The file uses theme constants (spacing, fontSize, borderRadius) consistently but has a few hardcoded values:

  • Line 32: paddingVertical: 14 instead of a spacing constant
  • Line 59: fontSize: 17 instead of a fontSize constant

For consistency with the rest of the styling approach, consider using theme constants.

♻️ Proposed fix
     input: {
       borderWidth: 1,
       borderColor: colors.inputBorder,
       borderRadius: borderRadius.md,
       paddingHorizontal: spacing.md,
-      paddingVertical: 14,
+      paddingVertical: spacing.md,
       fontSize: fontSize.lg,
       backgroundColor: colors.inputBackground,
       color: colors.text,
     },
     // ...
-    buttonText: { color: colors.white, fontSize: 17, fontWeight: "600" },
+    buttonText: { color: colors.white, fontSize: fontSize.lg, fontWeight: "600" },

Also applies to: 50-59

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/screens/Login/LoginScreen.styles.ts` around lines 27 - 36, The
styles use hardcoded numbers instead of theme constants; update the input style
object in LoginScreen.styles.ts to replace paddingVertical: 14 with an
appropriate spacing constant (e.g., spacing.md or spacing.lg) and replace any
hardcoded fontSize: 17 elsewhere in this file with the appropriate fontSize
constant (e.g., fontSize.md or fontSize.lg) so all spacing and font sizes use
the theme values; look for the 'input' style and any other style entries that
set fontSize: 17 and swap them to the matching spacing/fontSize tokens.
frontend/src/constants/theme.ts (1)

95-100: Minor inconsistency in as const usage.

Other constants use as const on the object itself (e.g., } as const;), but fontWeight applies as const to each value individually. This works but is inconsistent with the rest of the file.

♻️ For consistency
 export const fontWeight = {
-  regular: "400" as const,
-  medium: "500" as const,
-  semibold: "600" as const,
-  bold: "700" as const,
-};
+  regular: "400",
+  medium: "500",
+  semibold: "600",
+  bold: "700",
+} as const;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/constants/theme.ts` around lines 95 - 100, The fontWeight object
uses per-value "as const" which is inconsistent with other constants; update the
declaration for fontWeight (the fontWeight object) to apply a single "as const"
to the entire object (e.g., change per-value "as const" usage so the object ends
with "as const") so its readonly literal typing matches the rest of the file.
frontend/src/stores/themeStore.ts (1)

20-23: Consider handling potential storage errors.

SecureStore.setItemAsync is called without await or error handling. While fire-and-forget is acceptable for preferences, silent failures could lead to confusion if persistence doesn't work (e.g., on web where SecureStore may not be available).

🛡️ Optional: Add error handling
   setMode: (mode) => {
     set({ mode, colors: mode === "dark" ? darkColors : lightColors });
-    SecureStore.setItemAsync(THEME_KEY, mode);
+    SecureStore.setItemAsync(THEME_KEY, mode).catch(() => {
+      // Storage unavailable - preference won't persist
+    });
   },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/stores/themeStore.ts` around lines 20 - 23, The setMode setter
currently calls SecureStore.setItemAsync(THEME_KEY, mode) without awaiting or
handling errors; wrap the persistence call in a try/catch (inside setMode) and
await the promise (or handle returned promise) so failures are caught, log or
surface errors via console/error logger, and optionally fall back to another
storage (e.g., localStorage) if SecureStore is unavailable; update the setMode
function to try SecureStore.setItemAsync(THEME_KEY, mode) in a try block and
handle failures in catch to avoid silent persistence failures.
frontend/src/screens/Register/RegisterScreen.tsx (1)

22-49: Significant code duplication with LoginScreen.

RegisterScreen and LoginScreen share nearly identical form handling logic (state management, validation, error handling, submission pattern). Consider extracting a shared hook or form component to reduce duplication.

This could be addressed in a follow-up PR by extracting a useAuthForm hook or a shared AuthForm component.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/screens/Register/RegisterScreen.tsx` around lines 22 - 49,
RegisterScreen duplicates form state/validation/submission logic found in
LoginScreen (email, password, emailError, passwordError, handleRegister,
register.useRegister), so extract the shared logic into a reusable unit (either
a useAuthForm hook or an AuthForm component) that exposes/handles:
email/password state and setters, error state, a submit handler that accepts a
mutate function (useRegister/useLogin) and runs the same trim/validation and
ApiError fieldErrors mapping; then update RegisterScreen to use the new
hook/component and remove duplicated state and handleRegister implementation,
and do the same change in LoginScreen to consume the shared implementation.
frontend/src/components/AccessibilityMenu/AccessibilityMenu.tsx (1)

59-107: Modal overlay touch handling may prevent inner menu interactions.

Wrapping the entire overlay (including the menu) in TouchableWithoutFeedback could intercept touches on the menu content and close it prematurely if any touch falls outside the explicit TouchableOpacity elements inside the menu.

♻️ Recommended pattern: stop propagation on menu container
       <Modal
         visible={open}
         transparent
         animationType="fade"
         onRequestClose={() => setOpen(false)}
       >
         <TouchableWithoutFeedback onPress={() => setOpen(false)}>
           <View style={styles.overlay}>
-            <View style={[styles.menu, { top: menuTop }]}>
+            <TouchableWithoutFeedback>
+              <View style={[styles.menu, { top: menuTop }]}>
               {/* Dark Mode Section */}
               ...
-            </View>
+              </View>
+            </TouchableWithoutFeedback>
           </View>
         </TouchableWithoutFeedback>
       </Modal>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/AccessibilityMenu/AccessibilityMenu.tsx` around lines
59 - 107, The overlay's TouchableWithoutFeedback currently wraps the entire
overlay including the menu, causing taps inside the menu (e.g., on toggleMode or
handleSelectLocale) to close it via setOpen(false); change the structure so the
TouchableWithoutFeedback only wraps the backdrop (styles.overlay) and not the
menu View (styles.menu) — i.e., render the menu as a sibling inside the same
container so inner touches aren't intercepted — or alternatively add an event
blocker on the menu View (e.g., onStartShouldSetResponder returning true) to
stop propagation; ensure toggleMode, handleSelectLocale and LANGUAGES items
remain interactive and no longer trigger setOpen(false).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/.env.example`:
- Around line 1-3: Update the example comments for local dev servers so their
ports match the configured port (change references of 8081 to 8080) for the
Android emulator, iOS simulator, and physical device entries in the .env example
(the commented lines starting with "Android emulator:", "iOS simulator:", and
"Physical device:") so all sample URLs consistently use :8080.

In `@frontend/app.config.ts`:
- Around line 3-10: The current default export in frontend/app.config.ts
overwrites config.extra and uses an Android-emulator specific fallback; instead
merge existing extra keys and avoid the Android-only URL. Update the exported
config (the default function that takes { config }: ConfigContext and returns
ExpoConfig) so extra is built as { ...(config.extra ?? {}), apiUrl:
process.env.API_URL ?? "http://localhost:8080" } (or no fallback if you prefer),
ensuring config.extra's other keys are preserved and the Android-emulator URL is
not hardcoded.

In `@frontend/app.json`:
- Around line 34-36: Remove the unsupported packagerOpts.port entry from
app.json (the "packagerOpts" object and its "port" key) because Expo SDK v52+
ignores it; instead document configuring Metro using the CLI flag (`expo start
--port <port>`) or set the port in metro.config.js via `config.server.port` so
local dev runs on the intended port.

In `@frontend/package.json`:
- Around line 22-28: The package.json pins react-native to "0.81.5" which is
EoS; update the "react-native" version in frontend/package.json to a maintained
release (e.g., "0.84.x" or later) and run dependency reconciliation (npm/yarn
install + pod install for iOS) and test the app; ensure the "react" and
"react-dom" entries remain compatible with React 19.1.0 and adjust any breaking
changes in native modules (react-native-safe-area-context, react-native-screens,
react-native-web, zustand) after the upgrade.

In `@frontend/src/api/client.ts`:
- Around line 28-40: The interceptor currently re-throws raw Axios errors when
error.response exists but problem?.detail is missing; update the error-handling
branch (looking at problem, ApiError, and error.response) to detect HTTP
responses without a ProblemDetail.detail and reject with a user-friendly Error
instead of the raw Axios error — build a message using
translate("errors.server") (or fall back to error.response.statusText / status
if the translation key is absent) and return Promise.reject(new Error(message))
so the UI receives a consistent, localized error string.

In `@frontend/src/components/AccessibilityMenu/AccessibilityMenu.tsx`:
- Line 50: The displayed string "Accessibility" in the AccessibilityMenu
component is hardcoded; replace it with the localized string used elsewhere (use
the translation key, e.g. t("common.accessibility")) so the Text element
(styles.triggerText) uses the i18n translation function instead of a literal,
ensuring consistency with the label that already uses t("common.accessibility").

In `@frontend/src/navigation/navigation.styles.ts`:
- Line 10: The code calls AccessibilityMenu() directly which breaks React
hooks—change the headerRight value to return a JSX element instead of invoking
the function; e.g. replace headerRight: () => AccessibilityMenu() with
headerRight: () => <AccessibilityMenu /> (or headerRight: <AccessibilityMenu />
if the API expects a node) so the AccessibilityMenu component is rendered by
React and its hooks/refs work correctly.

In `@frontend/src/screens/Login/LoginScreen.tsx`:
- Around line 32-49: handleLogin currently returns silently when email or
password are empty; update the handleLogin function to set user-visible
validation errors instead of returning without feedback: when !email.trim()
setEmailError to a suitable message (e.g., "Email is required"), when !password
setPasswordError to a message (e.g., "Password is required"), and only call
login.mutate if both fields are valid; reference handleLogin, setEmailError,
setPasswordError, and login.mutate when making the change.

In `@frontend/src/screens/Register/RegisterScreen.tsx`:
- Around line 32-49: In handleRegister, avoid the silent early return when
inputs are empty: validate email and password before calling register.mutate and
set the appropriate field errors (call setEmailError and/or setPasswordError
with user-facing messages like "Email is required" and "Password is required")
so the user gets feedback; only call register.mutate when both fields are valid
and keep the existing onError handling for ApiError fieldErrors.

In `@frontend/src/stores/authStore.ts`:
- Around line 28-36: The setAuth and clearAuth functions call async helpers
saveToken and deleteToken without awaiting or handling failures; update setAuth
and clearAuth to be async (change their signatures in the AuthState interface to
return Promise<void>), await saveToken(token) and await deleteToken() inside
try/catch blocks, and handle/log errors (e.g., revert in-memory state or call a
fallback) so storage failures don't leave UI and persistence out of sync;
reference the setAuth and clearAuth functions and the saveToken/deleteToken
helpers when making these changes.

In `@frontend/src/stores/localeStore.ts`:
- Around line 25-39: The setLocale implementation fires SecureStore.setItemAsync
without handling rejections and hydrateLocale can throw from
SecureStore.getItemAsync and skip useLocaleStore.getState().setHydrated(); fix
both by adding error handling: in setLocale catch/log errors from
SecureStore.setItemAsync (or attach a .catch) so failures don't cause unhandled
rejections; in hydrateLocale wrap the await SecureStore.getItemAsync(LOCALE_KEY)
call in try/catch and ensure useLocaleStore.getState().setHydrated() is always
called (use a finally block) and only apply the stored value to
useLocaleStore.setState({ locale: stored }) when stored is valid ("en" or "bg").

---

Nitpick comments:
In `@frontend/App.tsx`:
- Around line 18-21: Wrap the hydrateLocale() and hydrateTheme() calls inside
the useEffect in a try-catch (or an async IIFE) so any exceptions during
hydration are caught; in the catch block, log the error (using the app's logger
or console.error) along with context like "hydrateLocale/hydrateTheme failed" so
failures don't fail silently; update the effect that currently calls
hydrateLocale() and hydrateTheme() to perform this guarded/awaited invocation
and ensure any returned Promises are awaited.

In `@frontend/metro.config.js`:
- Around line 6-8: The PR currently replaces config.resolver.alias which drops
defaults; instead update metro.config.js to merge the new alias into any
existing resolver.alias (and ensure resolver exists) rather than overwriting it:
read the current config.resolver.alias (or {}), spread its entries and add "@"
=> path.resolve(__dirname, "src") so existing aliases remain intact while adding
your alias for "@/..." imports.

In `@frontend/src/components/AccessibilityMenu/AccessibilityMenu.tsx`:
- Around line 59-107: The overlay's TouchableWithoutFeedback currently wraps the
entire overlay including the menu, causing taps inside the menu (e.g., on
toggleMode or handleSelectLocale) to close it via setOpen(false); change the
structure so the TouchableWithoutFeedback only wraps the backdrop
(styles.overlay) and not the menu View (styles.menu) — i.e., render the menu as
a sibling inside the same container so inner touches aren't intercepted — or
alternatively add an event blocker on the menu View (e.g.,
onStartShouldSetResponder returning true) to stop propagation; ensure
toggleMode, handleSelectLocale and LANGUAGES items remain interactive and no
longer trigger setOpen(false).

In `@frontend/src/constants/theme.ts`:
- Around line 95-100: The fontWeight object uses per-value "as const" which is
inconsistent with other constants; update the declaration for fontWeight (the
fontWeight object) to apply a single "as const" to the entire object (e.g.,
change per-value "as const" usage so the object ends with "as const") so its
readonly literal typing matches the rest of the file.

In `@frontend/src/hooks/useAuth.ts`:
- Around line 5-27: Extract the duplicated logic in useLogin and useRegister
into a small factory like createAuthMutation that accepts a mutationFn (e.g.,
loginUser or registerUser) and returns the useMutation call that uses
useAuthStore's setAuth and decodes the token with decodeEmail on onSuccess; then
replace useLogin and useRegister to simply call createAuthMutation(loginUser)
and createAuthMutation(registerUser) respectively so setAuth, decodeEmail, and
mutation result handling live in one place.

In `@frontend/src/hooks/useAuthState.ts`:
- Around line 14-21: The JWT payload is being parsed twice in useAuthState (once
inline to get exp and again via decodeEmail); refactor to parse once by adding
or extending a helper in authStore (e.g., decodeJwtPayload or extend decodeEmail
to return payload fields like sub/email and exp) and then use that single result
in useAuthState to obtain exp and email before calling setAuth; update calls to
replace inline JSON.parse(atob(...)) and decodeEmail(stored) with the new helper
(referencing useAuthState, decodeEmail/decodeJwtPayload, and setAuth to locate
changes).

In `@frontend/src/navigation/MainTabs.tsx`:
- Around line 25-29: The Home tab's label is hardcoded in the Tab.Screen for
name="Home" (component HomeScreen) via options.tabBarLabel; update it to use the
app's i18n instead: import and call the translation hook (useTranslation) or
locale store to retrieve the localized string (e.g., t('tabs.home')) and pass
that value to options.tabBarLabel so the tab label is localized consistently
with the rest of the app.

In `@frontend/src/screens/Home/HomeScreen.styles.ts`:
- Around line 29-33: The logoutButton style uses a raw numeric paddingVertical
(14); replace that magic number with the appropriate theme spacing token (e.g.,
spacing.md or spacing.lg) to keep spacing consistent—update the logoutButton
object in HomeScreen.styles.ts to use the theme spacing token via the existing
spacing symbol so paddingVertical references spacing.<token> instead of 14.

In `@frontend/src/screens/Login/LoginScreen.styles.ts`:
- Around line 27-36: The styles use hardcoded numbers instead of theme
constants; update the input style object in LoginScreen.styles.ts to replace
paddingVertical: 14 with an appropriate spacing constant (e.g., spacing.md or
spacing.lg) and replace any hardcoded fontSize: 17 elsewhere in this file with
the appropriate fontSize constant (e.g., fontSize.md or fontSize.lg) so all
spacing and font sizes use the theme values; look for the 'input' style and any
other style entries that set fontSize: 17 and swap them to the matching
spacing/fontSize tokens.

In `@frontend/src/screens/Register/RegisterScreen.styles.ts`:
- Around line 32-33: Replace hard-coded numeric spacing with theme tokens:
change the paddingVertical: 14 in the RegisterScreen style object to use the
theme spacing token (e.g., spacing.sm or spacing.md) and replace the other
remaining numeric literal in this file (the second numeric occurrence in the
styles) with the appropriate theme spacing token as well; keep using the
existing fontSize tokens (fontSize.lg) and update imports/usage to pull spacing
from the theme (e.g., spacing) so all typography/spacing align with the design
system.

In `@frontend/src/screens/Register/RegisterScreen.tsx`:
- Around line 22-49: RegisterScreen duplicates form state/validation/submission
logic found in LoginScreen (email, password, emailError, passwordError,
handleRegister, register.useRegister), so extract the shared logic into a
reusable unit (either a useAuthForm hook or an AuthForm component) that
exposes/handles: email/password state and setters, error state, a submit handler
that accepts a mutate function (useRegister/useLogin) and runs the same
trim/validation and ApiError fieldErrors mapping; then update RegisterScreen to
use the new hook/component and remove duplicated state and handleRegister
implementation, and do the same change in LoginScreen to consume the shared
implementation.

In `@frontend/src/stores/themeStore.ts`:
- Around line 20-23: The setMode setter currently calls
SecureStore.setItemAsync(THEME_KEY, mode) without awaiting or handling errors;
wrap the persistence call in a try/catch (inside setMode) and await the promise
(or handle returned promise) so failures are caught, log or surface errors via
console/error logger, and optionally fall back to another storage (e.g.,
localStorage) if SecureStore is unavailable; update the setMode function to try
SecureStore.setItemAsync(THEME_KEY, mode) in a try block and handle failures in
catch to avoid silent persistence failures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d8a892fa-41c2-4d95-8f49-b0ecdc544407

📥 Commits

Reviewing files that changed from the base of the PR and between b22c2a1 and 660bf87.

⛔ Files ignored due to path filters (5)
  • frontend/assets/adaptive-icon.png is excluded by !**/*.png
  • frontend/assets/favicon.png is excluded by !**/*.png
  • frontend/assets/icon.png is excluded by !**/*.png
  • frontend/assets/splash-icon.png is excluded by !**/*.png
  • frontend/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (39)
  • backend/src/main/resources/application.properties
  • frontend/.env.example
  • frontend/.gitignore
  • frontend/.idea/.gitignore
  • frontend/App.tsx
  • frontend/app.config.ts
  • frontend/app.json
  • frontend/index.ts
  • frontend/metro.config.js
  • frontend/package.json
  • frontend/src/api/auth.ts
  • frontend/src/api/client.ts
  • frontend/src/components/AccessibilityMenu/AccessibilityMenu.styles.ts
  • frontend/src/components/AccessibilityMenu/AccessibilityMenu.tsx
  • frontend/src/constants/config.ts
  • frontend/src/constants/locales/bg.json
  • frontend/src/constants/locales/en.json
  • frontend/src/constants/theme.ts
  • frontend/src/hooks/useAuth.ts
  • frontend/src/hooks/useAuthState.ts
  • frontend/src/hooks/useTranslation.ts
  • frontend/src/navigation/AuthStack.tsx
  • frontend/src/navigation/MainTabs.tsx
  • frontend/src/navigation/RootNavigator.styles.ts
  • frontend/src/navigation/RootNavigator.tsx
  • frontend/src/navigation/navigation.styles.ts
  • frontend/src/screens/Home/HomeScreen.styles.ts
  • frontend/src/screens/Home/HomeScreen.tsx
  • frontend/src/screens/Login/LoginScreen.styles.ts
  • frontend/src/screens/Login/LoginScreen.tsx
  • frontend/src/screens/Register/RegisterScreen.styles.ts
  • frontend/src/screens/Register/RegisterScreen.tsx
  • frontend/src/stores/authStore.ts
  • frontend/src/stores/localeStore.ts
  • frontend/src/stores/themeStore.ts
  • frontend/src/stores/token.ts
  • frontend/src/types/api.ts
  • frontend/src/types/navigation.ts
  • frontend/tsconfig.json

Comment thread frontend/.env.example Outdated
Comment thread frontend/app.config.ts
Comment thread frontend/app.json
Comment thread frontend/package.json
Comment thread frontend/src/api/client.ts
Comment thread frontend/src/navigation/navigation.styles.ts Outdated
Comment thread frontend/src/screens/Login/LoginScreen.tsx
Comment thread frontend/src/screens/Register/RegisterScreen.tsx
Comment thread frontend/src/stores/authStore.ts
Comment thread frontend/src/stores/localeStore.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
frontend/src/stores/localeStore.ts (2)

25-28: ⚠️ Potential issue | 🟠 Major

Handle SecureStore write failures in setLocale.

On Line 27, SecureStore.setItemAsync(...) is fire-and-forget with no rejection handling. If persistence fails, this can surface as an unhandled Promise rejection.

Proposed fix
   setLocale: (locale) => {
     set({ locale });
-    SecureStore.setItemAsync(LOCALE_KEY, locale);
+    void SecureStore.setItemAsync(LOCALE_KEY, locale).catch(() => {
+      // Optional: report non-fatal persistence error
+    });
   },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/stores/localeStore.ts` around lines 25 - 28, The setLocale
action currently calls SecureStore.setItemAsync(LOCALE_KEY, locale) without
handling rejections, causing possible unhandled Promise rejections; update
setLocale in localeStore.ts to await or attach a .catch to
SecureStore.setItemAsync(LOCALE_KEY, locale) and handle failures (e.g., log via
your logger or fallback behavior) while still updating in-memory state via set({
locale }); ensure you reference the setLocale function, LOCALE_KEY constant, and
SecureStore.setItemAsync when making the change.

33-41: ⚠️ Potential issue | 🟠 Major

Catch read errors in hydrateLocale to avoid startup unhandled rejections.

finally (Lines 39-40) correctly guarantees hydration completion, but an exception from Line 35 still rejects hydrateLocale(). Since hydrateLocale() is called fire-and-forget in frontend/App.tsx, this can become an unhandled rejection.

Proposed fix
 export async function hydrateLocale(): Promise<void> {
   try {
     const stored = await SecureStore.getItemAsync(LOCALE_KEY);
     if (stored === "en" || stored === "bg") {
       useLocaleStore.setState({ locale: stored });
     }
+  } catch {
+    // Optional: report non-fatal hydration error
   } finally {
     useLocaleStore.getState().setHydrated();
   }
 }
#!/bin/bash
# Verify unhandled SecureStore usage and fire-and-forget hydrate calls.
rg -nP --type=ts --type=tsx 'SecureStore\.(setItemAsync|getItemAsync)\(' -C2
rg -nP --type=ts --type=tsx '\bhydrateLocale\s*\(\s*\)\s*;' -C2
rg -nP --type=ts --type=tsx 'void\s+SecureStore\.setItemAsync\(|await\s+SecureStore\.setItemAsync\(|\.catch\s*\(' -C2
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/stores/localeStore.ts` around lines 33 - 41, hydrateLocale
currently leaves SecureStore.getItemAsync errors unhandled which can cause an
unhandled rejection when called fire-and-forget; wrap the await
SecureStore.getItemAsync(LOCALE_KEY) call in a try/catch inside hydrateLocale
(or add an inner try around the getItemAsync + state set) and on error simply
swallow/log the error (e.g., via console.error or your logger) before proceeding
to call useLocaleStore.getState().setHydrated(); ensure you still only call
useLocaleStore.setState({ locale: ... }) when stored is "en" or "bg" so behavior
is unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/navigation/MainTabs.tsx`:
- Around line 27-31: Replace the hardcoded tab label in the Tab.Screen for the
Home route by pulling the localized string from your i18n layer/store instead of
"Home"; locate the Tab.Screen with name="Home" and options={{ tabBarLabel:
"Home" }} and change options to use the translation accessor you use elsewhere
(e.g., useTranslation().t('home.tab') or the app's translation store getter) so
the tabBarLabel updates with runtime locale changes while keeping the component
prop (component={HomeScreen}) unchanged.

---

Duplicate comments:
In `@frontend/src/stores/localeStore.ts`:
- Around line 25-28: The setLocale action currently calls
SecureStore.setItemAsync(LOCALE_KEY, locale) without handling rejections,
causing possible unhandled Promise rejections; update setLocale in
localeStore.ts to await or attach a .catch to
SecureStore.setItemAsync(LOCALE_KEY, locale) and handle failures (e.g., log via
your logger or fallback behavior) while still updating in-memory state via set({
locale }); ensure you reference the setLocale function, LOCALE_KEY constant, and
SecureStore.setItemAsync when making the change.
- Around line 33-41: hydrateLocale currently leaves SecureStore.getItemAsync
errors unhandled which can cause an unhandled rejection when called
fire-and-forget; wrap the await SecureStore.getItemAsync(LOCALE_KEY) call in a
try/catch inside hydrateLocale (or add an inner try around the getItemAsync +
state set) and on error simply swallow/log the error (e.g., via console.error or
your logger) before proceeding to call useLocaleStore.getState().setHydrated();
ensure you still only call useLocaleStore.setState({ locale: ... }) when stored
is "en" or "bg" so behavior is unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: eebff7b1-96bd-495d-b2e4-e04f65397e8c

📥 Commits

Reviewing files that changed from the base of the PR and between 660bf87 and 5fda1db.

📒 Files selected for processing (10)
  • frontend/src/components/AccessibilityMenu/AccessibilityMenu.tsx
  • frontend/src/constants/locales/bg.json
  • frontend/src/constants/locales/en.json
  • frontend/src/constants/theme.ts
  • frontend/src/navigation/AuthStack.tsx
  • frontend/src/navigation/MainTabs.tsx
  • frontend/src/navigation/navigation.styles.ts
  • frontend/src/screens/Login/LoginScreen.tsx
  • frontend/src/screens/Register/RegisterScreen.tsx
  • frontend/src/stores/localeStore.ts
✅ Files skipped from review due to trivial changes (4)
  • frontend/src/constants/locales/bg.json
  • frontend/src/constants/locales/en.json
  • frontend/src/navigation/navigation.styles.ts
  • frontend/src/constants/theme.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • frontend/src/navigation/AuthStack.tsx
  • frontend/src/components/AccessibilityMenu/AccessibilityMenu.tsx
  • frontend/src/screens/Login/LoginScreen.tsx
  • frontend/src/screens/Register/RegisterScreen.tsx

Comment thread frontend/src/navigation/MainTabs.tsx
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
backend/src/main/java/com/angel/autonow/security/SecurityConfig.java (1)

75-89: Externalize CORS settings and narrow policy scope.

Line 78–Line 84 hardcode local origins and allow "*" methods/headers with credentials enabled. This is fine for local bootstrapping, but it is brittle across environments and broader than necessary.

♻️ Proposed refactor
+import org.springframework.beans.factory.annotation.Value;
+import java.util.List;
...
+	`@Value`("${app.cors.allowed-origins}")
+	private List<String> allowedOrigins;
...
 	`@Bean`
 	public CorsConfigurationSource corsConfigurationSource() {
 		CorsConfiguration config = new CorsConfiguration();
-		config.addAllowedOrigin("http://localhost:8080");
-		config.addAllowedOrigin("http://localhost:8081");
-		config.addAllowedOrigin("http://10.0.2.2:8080");
-		config.addAllowedOrigin("http://10.0.2.2:8081");
-		config.addAllowedMethod("*");
-		config.addAllowedHeader("*");
+		config.setAllowedOrigins(allowedOrigins);
+		config.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
+		config.setAllowedHeaders(List.of("Authorization", "Content-Type"));
 		config.setAllowCredentials(true);

 		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
 		source.registerCorsConfiguration("/**", config);
 		return source;
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/src/main/java/com/angel/autonow/security/SecurityConfig.java` around
lines 75 - 89, The Cors configuration in SecurityConfig.corsConfigurationSource
currently hardcodes origins and uses wildcard methods/headers with credentials
enabled; change it to read allowed origins/methods/headers from configuration
(e.g., application properties or environment variables) and parse them into the
CorsConfiguration, restrict the registered path pattern on
UrlBasedCorsConfigurationSource.registerCorsConfiguration from "/**" to the
minimal API path(s) that need CORS (e.g., "/api/**"), and ensure that when
setAllowCredentials(true) is used you do not leave allowed origins as a wildcard
but only the configured explicit origins; validate and fallback to safe defaults
if config is missing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/src/main/java/com/angel/autonow/user/UserService.java`:
- Around line 28-29: The UserService currently logs raw email addresses (e.g.,
in the log.warn("Registration failed: email already exists [{}]", email) call);
remove PII by replacing direct email logging with a redacted or hashed
identifier. Add a small helper (e.g., redactEmail(String email) or
hashIdentifier(String email)) in UserService or a shared util, call that helper
in all logging sites instead of the raw email, and keep exception messages
generic (throw new UserException("Account with this email already exists.") can
remain). Apply the change to every logging occurrence that currently uses the
email variable so logs only contain the redacted/hashed value.

---

Nitpick comments:
In `@backend/src/main/java/com/angel/autonow/security/SecurityConfig.java`:
- Around line 75-89: The Cors configuration in
SecurityConfig.corsConfigurationSource currently hardcodes origins and uses
wildcard methods/headers with credentials enabled; change it to read allowed
origins/methods/headers from configuration (e.g., application properties or
environment variables) and parse them into the CorsConfiguration, restrict the
registered path pattern on
UrlBasedCorsConfigurationSource.registerCorsConfiguration from "/**" to the
minimal API path(s) that need CORS (e.g., "/api/**"), and ensure that when
setAllowCredentials(true) is used you do not leave allowed origins as a wildcard
but only the configured explicit origins; validate and fallback to safe defaults
if config is missing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 36262e7b-13ea-4981-800c-37526c83127c

📥 Commits

Reviewing files that changed from the base of the PR and between 5fda1db and 36e56b2.

📒 Files selected for processing (9)
  • backend/src/main/java/com/angel/autonow/security/SecurityConfig.java
  • backend/src/main/java/com/angel/autonow/user/UserService.java
  • backend/src/main/resources/application.properties
  • frontend/.env.example
  • frontend/app.config.ts
  • frontend/src/constants/config.ts
  • frontend/src/constants/locales/bg.json
  • frontend/src/constants/locales/en.json
  • frontend/src/navigation/MainTabs.tsx
✅ Files skipped from review due to trivial changes (3)
  • frontend/.env.example
  • frontend/src/constants/locales/bg.json
  • frontend/src/constants/locales/en.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • backend/src/main/resources/application.properties
  • frontend/src/constants/config.ts
  • frontend/src/navigation/MainTabs.tsx
  • frontend/app.config.ts

Comment thread backend/src/main/java/com/angel/autonow/user/UserService.java Outdated
@sonarqubecloud
Copy link
Copy Markdown

@StoynovAngel StoynovAngel merged commit 9f08420 into main Apr 14, 2026
7 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Apr 30, 2026
This was referenced Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant