frontend architecture

Frontend Architecture

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "frontend architecture" with this command: npx skills add exceptionless/exceptionless/exceptionless-exceptionless-frontend-architecture

Frontend Architecture

Located in src/Exceptionless.Web/ClientApp . The Svelte SPA is the primary client.

Directory Structure

src/ ├── lib/ │ ├── features/ # Feature slices (vertical organization) │ │ ├── auth/ │ │ │ ├── api.svelte.ts │ │ │ ├── models/ │ │ │ ├── schemas.ts │ │ │ └── components/ │ │ ├── organizations/ │ │ ├── projects/ │ │ ├── events/ │ │ └── shared/ # Cross-feature shared code │ ├── components/ # App-wide shared components │ │ └── ui/ # shadcn-svelte components │ ├── generated/ # API-generated types │ └── utils/ # Utility functions ├── routes/ │ ├── (app)/ # Authenticated app routes │ ├── (auth)/ # Authentication routes │ └── (public)/ # Public routes └── app.html

Route Groups

Organize routes by authentication/layout requirements:

routes/ ├── (app)/ # Requires authentication │ ├── +layout.svelte # App layout with nav │ ├── organizations/ │ └── projects/ ├── (auth)/ # Login/signup flows │ ├── +layout.svelte # Minimal auth layout │ ├── login/ │ └── signup/ └── (public)/ # Public pages ├── +layout.svelte # Marketing layout └── pricing/

Feature Slices

Organize by feature, aligned with API controllers:

features/organizations/ ├── api.svelte.ts # TanStack Query hooks ├── models/ │ └── index.ts # Re-exports from generated ├── schemas.ts # Zod validation schemas ├── options.ts # Dropdown options, enums └── components/ ├── organization-card.svelte ├── organization-form.svelte └── dialogs/ └── create-organization-dialog.svelte

API Client Pattern

Centralize API calls per feature:

// features/organizations/api.svelte.ts import { createQuery, createMutation, useQueryClient, } from "@tanstack/svelte-query"; import { useFetchClient } from "@exceptionless/fetchclient"; import type { Organization, CreateOrganizationRequest } from "./models";

export function getOrganizationsQuery() { const client = useFetchClient();

return createQuery(() => ({
    queryKey: ["organizations"],
    queryFn: async () => {
        const response =
            await client.getJSON<Organization[]>("/organizations");
        if (!response.ok) throw response.problem;
        return response.data!;
    },
}));

}

export function postOrganizationMutation() { const client = useFetchClient(); const queryClient = useQueryClient();

return createMutation(() => ({
    mutationFn: async (data: CreateOrganizationRequest) => {
        const response = await client.postJSON<Organization>(
            "/organizations",
            data,
        );
        if (!response.ok) throw response.problem;
        return response.data!;
    },
    onSuccess: () => {
        queryClient.invalidateQueries({ queryKey: ["organizations"] });
    },
}));

}

Model Re-exports

Re-export generated models through feature model folders:

// features/organizations/models/index.ts export type { Organization, CreateOrganizationRequest, UpdateOrganizationRequest, } from "$lib/generated";

// Add feature-specific types export interface OrganizationWithStats extends Organization { eventCount: number; projectCount: number; }

Barrel Exports

Use index.ts for clean imports:

// features/organizations/index.ts export { getOrganizationsQuery, postOrganizationMutation } from "./api.svelte"; export type { Organization, CreateOrganizationRequest } from "./models"; export { organizationSchema } from "./schemas";

Shared Components

Place truly shared components in appropriate locations:

lib/ ├── features/shared/ # Shared between features │ ├── components/ │ │ ├── formatters/ # Boolean, date, number formatters │ │ ├── loading/ │ │ └── error/ │ └── utils/ └── components/ # App-wide components ├── ui/ # shadcn-svelte ├── layout/ └── dialogs/ # Global dialogs

Generated Types

When API contracts change:

npm run generate-models

Prefer regeneration over hand-writing DTOs. Generated types live in $lib/generated .

Import Aliases

// Configured in svelte.config.js import { Button } from "$comp/ui/button"; // $lib/components import { User } from "$features/users/models"; // $lib/features import { formatDate } from "$shared/formatters"; // $lib/features/shared

Composite Component Pattern

Study existing components before creating new ones:

  • Dialogs: See /components/dialogs/

  • Dropdowns: Use options.ts with DropdownItem<EnumType>[]

  • Forms: Follow TanStack Form patterns in svelte-forms skill

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

shadcn-svelte components

No summary provided by upstream source.

Repository SourceNeeds Review
General

tanstack-form

No summary provided by upstream source.

Repository SourceNeeds Review
General

frontend-architecture

No summary provided by upstream source.

Repository SourceNeeds Review