Skip to main content

Web Application Architecture

Overview

The OX Agry web application follows a modern React architecture using Remix framework, emphasizing maintainability, performance, and developer experience.

Architecture Overview

Core Concepts

1. Routing

  • File-based routing using Remix conventions
  • Nested routes for complex UI hierarchies
  • Loader functions for data fetching
  • Action functions for mutations
// app/routes/machinery/$id.tsx
import type { LoaderFunction } from '@remix-run/node';
import { json } from '@remix-run/node';

export const loader: LoaderFunction = async ({ params }) => {
const { id } = params;
// Fetch machinery data
return json({ machinery });
};

export default function MachineryRoute() {
const { machinery } = useLoaderData<typeof loader>();
return (
// JSX
);
}

2. Data Flow

Server-Side Data Loading

// Loader function for server-side data fetching
export const loader = async ({ request }: LoaderArgs) => {
const user = await authenticator.isAuthenticated(request);
const bookings = await getBookings(user.id);
return json({ bookings });
};

Client-Side Updates

// Action function for form submissions
export const action = async ({ request }: ActionArgs) => {
const formData = await request.formData();
const booking = await createBooking(formData);
return json({ booking });
};

3. Component Architecture

Atomic Design Pattern

components/
├── atoms/ # Basic building blocks
│ ├── Button/
│ ├── Input/
│ └── Text/
├── molecules/ # Combinations of atoms
│ ├── FormField/
│ └── SearchBar/
├── organisms/ # Complex UI components
│ ├── BookingForm/
│ └── MachineList/
└── templates/ # Page layouts
└── Dashboard/

Component Example

// app/components/molecules/FormField/index.tsx
interface FormFieldProps {
label: string;
error?: string;
children: React.ReactNode;
}

export function FormField({ label, error, children }: FormFieldProps) {
return (
<div className="form-field">
<label className="label">{label}</label>
{children}
{error && <span className="error">{error}</span>}
</div>
);
}

State Management

1. Form State

  • Use Remix Form components
  • Handle validation
  • Manage submission state
export function BookingForm() {
const actionData = useActionData<typeof action>();
const navigation = useNavigation();
const isSubmitting = navigation.state === "submitting";

return <Form method="post">{/* Form fields */}</Form>;
}

2. Global State

  • Session management
  • User preferences
  • Application settings
// app/state/session.server.ts
export async function getSession(request: Request) {
const session = await getSessionFromCookie(request);
return json({ user: session.user });
}

Performance Optimization

1. Code Splitting

  • Automatic route-based splitting
  • Dynamic imports for large components
  • Prefetching for faster navigation
const MachineryDetails = React.lazy(
() => import("~/components/organisms/MachineryDetails")
);

2. Caching Strategy

  • Browser caching
  • API response caching
  • Asset optimization
export const headers = () => {
return {
"Cache-Control": "max-age=300, s-maxage=3600",
};
};

Error Handling

1. Error Boundaries

export function ErrorBoundary({ error }: { error: Error }) {
return (
<div className="error-container">
<h1>Error</h1>
<p>{error.message}</p>
</div>
);
}

2. Form Validation

export const action = async ({ request }: ActionArgs) => {
const formData = await request.formData();
const validationResult = validateBooking(formData);

if (!validationResult.success) {
return json({ errors: validationResult.errors }, { status: 400 });
}

// Process valid data
};

Security

1. Authentication

  • JWT token management
  • Session handling
  • Protected routes

2. Data Security

  • Input sanitization
  • XSS prevention
  • CSRF protection

Testing Strategy

1. Component Testing

import { render, screen } from "@testing-library/react";
import { BookingForm } from "./BookingForm";

test("renders booking form", () => {
render(<BookingForm />);
expect(screen.getByRole("form")).toBeInTheDocument();
});

2. Integration Testing

import { createRemixStub } from "@remix-run/testing";

test("machinery booking flow", async () => {
const RemixStub = createRemixStub([
{
path: "/machinery/book",
Component: BookingRoute,
},
]);

render(<RemixStub />);
// Test user flow
});

Deployment

1. Build Process

# Production build
npm run build

# Type checking
npm run type-check

# Linting
npm run lint

2. Environment Configuration

  • Environment variables
  • API endpoints
  • Feature flags
  • Debug settings