erich-oliveira-winnin/full-stack-fastapi-template

Shadow-mode PR reading: farol only informs, it never approves or blocks.

base 077c17d6a669 → head a3493f655be6
analyzed at 2026-10-22 19:54 UTC
Paths relative to frontend/src/
Mark files as reviewed

Tick the files you already reviewed (or match them with a regular expression): pages whose changed files are all reviewed are hidden, so what is left is what still needs review, and the merge risk score drops by their part. Saved in this browser for this commit. Behind a feature flag? Use 🚩 on a page in the pages/operations section: the files only it uses leave the review.

🚩 Pages/operations behind a feature flag

Mark the pages, routes or operations that are entirely behind a feature flag: changed files that only they use leave the review (score, Start here, files left). Same state as the 🚩 buttons in the pages/operations section.

/1 changed file
/admin2 changed files
/items5 changed files
/settings1 changed file
/insightsnew1 changed file

Overview

Review plan
⚠ Careful review

This can break things widely or silently: read the files below closely and test what they reach before approving.

  • merge risk score 77/100
  • 1 central file(s) with little or no diff coverage: AppSidebar.tsx
  • a global file, manifest or critical dependency changed: everything may be affected
  • existing code changed: 4 existing page(s) run it
  • diff coverage 12%
  • 1 new suppression(s) (lint/type/security ignores)
Merge risk score
77/100
high
What adds to it (11) and how it is computed

0–100, higher is riskier: the chance that at least one risky thing breaks, as if they were independent. Each changed code file counts by its reach (existing pages/operations that run it, centrality) times what its diff coverage leaves: 100% covered keeps 30% of the risk, uncovered (or coverage not verified) all of it, and a change made only of declarations (types, fields, constants: nothing executable to test) half of it. Security findings, lint errors, suppressions, removed tests, critical dependency changes, vulnerable dependencies and global or unknown reasons add to it too. Marking files as reviewed takes their part out; vulnerabilities and analysis problems stay. High from 60, medium from 30. Numbers are each file's risk on its own.

  1. 35 components/Sidebar/AppSidebar.tsx modified · high reach: used by 4 of 8 existing pages · 0% of changed lines covered
  2. 34 frontend/package.json manifest-changed: fields changed: scripts (+2 more)
  3. 17 components/Common/DataTable.tsx modified · medium reach: used by 2 of 8 existing pages · 0% of changed lines covered
  4. 12 components/Items/columns.tsx modified · medium reach: used by 1 of 8 existing pages · 0% of changed lines covered
  5. 12 routes/_layout/items.tsx modified · medium reach: used by 1 of 8 existing pages · 0% of changed lines covered
  6. 5 routeTree.gen.ts modified · low reach: 1 file(s) depend on it, no page reaches it · missing from the coverage report (+1 more)

and 5 more

Start here — riskiest first; tick a file once reviewed

  1. used by 4 of 8 existing pages
    4/8 pages✍ Alejandra 100%0% covered
    35
    Show diff (+2 −1)
    @@ -1,4 +1,4 @@
    1-import { Briefcase, Home, Users } from "lucide-react"
    1○+import { BarChart3, Briefcase, Home, Users } from "lucide-react"
    22
    33 import { SidebarAppearance } from "@/components/Common/Appearance"
    44 import { Logo } from "@/components/Common/Logo"
    @@ -15,6 +15,7 @@ import { User } from "./User"
    1515 const baseItems: Item[] = [
    1616 { icon: Home, title: "Dashboard", path: "/" },
    1717 { icon: Briefcase, title: "Items", path: "/items" },
    18○+ { icon: BarChart3, title: "Insights", path: "/insights" },
    1819 ]
    1920
    2021 export function AppSidebar() {
  2. used by 2 of 8 existing pages
    2/8 pages✍ Alejandra 77%0% covered
    17
    Show diff (+6 −1)
    @@ -41,11 +41,14 @@ export type DataTableFeatures = typeof dataTableFeatures
    4141 interface DataTableProps<TData extends RowData> {
    4242 columns: ColumnDef<DataTableFeatures, TData>[]
    4343 data: TData[]
    44+ /** Rows on the server, when `data` is one page of them. */
    45+ total?: number
    4446 }
    4547
    4648 export function DataTable<TData extends RowData>({
    4749 columns,
    4850 data,
    51○+ total,
    4952 }: DataTableProps<TData>) {
    5053 const table = useTable({
    5154 features: dataTableFeatures,
    @@ -113,7 +116,9 @@ export function DataTable<TData extends RowData>({
    113116 data.length,
    114117 )}{" "}
    115118 of{" "}
    116- <span className="font-medium text-foreground">{data.length}</span>{" "}
    119○+ <span className="font-medium text-foreground">
    120○+ {total ?? data.length}
    121○+ </span>{" "}
    117122 entries
    118123 </div>
    119124 <div className="flex items-center gap-x-2">
  3. used by 1 of 8 existing pages
    1/8 pages✍ Alejandra 95%0% covered
    12
    Show diff (+11 −0)
    @@ -3,8 +3,10 @@ import { Check, Copy } from "lucide-react"
    33
    44 import type { ItemPublic } from "@/client"
    55 import type { DataTableFeatures } from "@/components/Common/DataTable"
    6○+import { Badge } from "@/components/ui/badge"
    67 import { Button } from "@/components/ui/button"
    78 import { useCopyToClipboard } from "@/hooks/useCopyToClipboard"
    9○+import { statusLabel } from "@/lib/items"
    810 import { cn } from "@/lib/utils"
    911 import { ItemActionsMenu } from "./ItemActionsMenu"
    1012
    @@ -45,6 +47,15 @@ export const columns: ColumnDef<DataTableFeatures, ItemPublic>[] = [
    4547 <span className="font-medium">{row.original.title}</span>
    4648 ),
    4749 },
    50○+ {
    51○+ accessorKey: "status",
    52○+ header: "Status",
    53○+ cell: ({ row }) => (
    54○+ <Badge variant={row.original.status === "done" ? "default" : "secondary"}>
    55○+ {statusLabel(row.original.status)}
    56○+ </Badge>
    57+ ),
    58○+ },
    4859 {
    4960 accessorKey: "description",
    5061 header: "Description",
  4. used by 1 of 8 existing pages
    1/8 pages✍ Alejandra 76%0% covered
    12
    Show diff (+1 −1)
    @@ -43,7 +43,7 @@ function ItemsTableContent() {
    4343 )
    4444 }
    4545
    46- return <DataTable columns={columns} data={items.data} />
    46○+ return <DataTable columns={columns} data={items.data} total={items.total} />
    4747 }
    4848
    4949 function ItemsTable() {
  5. new code already used by 1 existing page
    1/8 pages✍ Alejandra 100%93% covered
    5
    Show diff (+36 −0)
    @@ -0,0 +1,36 @@
    1+import type { ItemStatus, ItemStatusCount } from "@/client"
    2+
    3+export const STATUS_LABELS: Record<ItemStatus, string> = {
    4+ todo: "To do",
    5+ in_progress: "In progress",
    6+ done: "Done",
    7+}
    8+
    9+export const STATUSES = Object.keys(STATUS_LABELS) as ItemStatus[]
    10+
    11+/** Label of an item's status; items created before statuses existed are "To do". */
    12+export function statusLabel(status: ItemStatus | undefined): string {
    13+ return STATUS_LABELS[status ?? "todo"]
    14+}
    15+
    16+/** Items per status, with every status present (0 when the API returns no row for it). */
    17+export function totalsByStatus(
    18+ rows: ItemStatusCount[],
    19+): Record<ItemStatus, number> {
    20+ const totals: Record<ItemStatus, number> = {
    21+ todo: 0,
    22+ in_progress: 0,
    23+ done: 0,
    24+ }
    25+ for (const row of rows) totals[row.status] += row.total
    26+ return totals
    27+}
    28+
    29+/** Share of the items that are done, in percent. */
    30+export function completion(totals: Record<ItemStatus, number>): number {
    31+ const all = totals.todo + totals.in_progress + totals.done
    32+ if (all === 0) {
    33○+ return 0
    34○+ }
    35+ return Math.round((totals.done / all) * 100)
    36+}
  6. 1 file(s) depend on it, no page reaches it
    ✍ Alejandra 100%0% covered1 suppression
    5
    Show diff (+21 −0)
    @@ -16,6 +16,7 @@ import { Route as ResetPasswordRouteImport } from './routes/reset-password'
    1616 import { Route as SignupRouteImport } from './routes/signup'
    1717 import { Route as LayoutIndexRouteImport } from './routes/_layout/index'
    1818 import { Route as LayoutAdminRouteImport } from './routes/_layout/admin'
    19○+import { Route as LayoutInsightsRouteImport } from './routes/_layout/insights'
    1920 import { Route as LayoutItemsRouteImport } from './routes/_layout/items'
    2021 import { Route as LayoutSettingsRouteImport } from './routes/_layout/settings'
    2122
    @@ -53,6 +54,11 @@ const LayoutAdminRoute = LayoutAdminRouteImport.update({
    5354 path: '/admin',
    5455 getParentRoute: () => LayoutRoute,
    5556 } as any)
    57○+const LayoutInsightsRoute = LayoutInsightsRouteImport.update({
    58○+ id: '/insights',
    59○+ path: '/insights',
    60○+ getParentRoute: () => LayoutRoute,
    61⚠+} as any)
    5662 const LayoutItemsRoute = LayoutItemsRouteImport.update({
    5763 id: '/items',
    5864 path: '/items',
    @@ -71,6 +77,7 @@ export interface FileRoutesByFullPath {
    7177 '/reset-password': typeof ResetPasswordRoute
    7278 '/signup': typeof SignupRoute
    7379 '/admin': typeof LayoutAdminRoute
    80○+ '/insights': typeof LayoutInsightsRoute
    7481 '/items': typeof LayoutItemsRoute
    7582 '/settings': typeof LayoutSettingsRoute
    7683 }
    @@ -80,6 +87,7 @@ export interface FileRoutesByTo {
    8087 '/reset-password': typeof ResetPasswordRoute
    8188 '/signup': typeof SignupRoute
    8289 '/admin': typeof LayoutAdminRoute
    90○+ '/insights': typeof LayoutInsightsRoute
    8391 '/items': typeof LayoutItemsRoute
    8492 '/settings': typeof LayoutSettingsRoute
    8593 '/': typeof LayoutIndexRoute
    @@ -92,6 +100,7 @@ export interface FileRoutesById {
    92100 '/reset-password': typeof ResetPasswordRoute
    93101 '/signup': typeof SignupRoute
    94102 '/_layout/admin': typeof LayoutAdminRoute
    103○+ '/_layout/insights': typeof LayoutInsightsRoute
    95104 '/_layout/items': typeof LayoutItemsRoute
    96105 '/_layout/settings': typeof LayoutSettingsRoute
    97106 '/_layout/': typeof LayoutIndexRoute
    @@ -105,6 +114,7 @@ export interface FileRouteTypes {
    105114 | '/reset-password'
    106115 | '/signup'
    107116 | '/admin'
    117○+ | '/insights'
    108118 | '/items'
    109119 | '/settings'
    110120 fileRoutesByTo: FileRoutesByTo
    @@ -114,6 +124,7 @@ export interface FileRouteTypes {
    114124 | '/reset-password'
    115125 | '/signup'
    116126 | '/admin'
    127○+ | '/insights'
    117128 | '/items'
    118129 | '/settings'
    119130 | '/'
    @@ -125,6 +136,7 @@ export interface FileRouteTypes {
    125136 | '/reset-password'
    126137 | '/signup'
    127138 | '/_layout/admin'
    139○+ | '/_layout/insights'
    128140 | '/_layout/items'
    129141 | '/_layout/settings'
    130142 | '/_layout/'
    @@ -189,6 +201,13 @@ declare module '@tanstack/react-router' {
    189201 preLoaderRoute: typeof LayoutAdminRouteImport
    190202 parentRoute: typeof LayoutRoute
    191203 }
    204○+ '/_layout/insights': {
    205○+ id: '/_layout/insights'
    206○+ path: '/insights'
    207○+ fullPath: '/insights'
    208○+ preLoaderRoute: typeof LayoutInsightsRouteImport
    209○+ parentRoute: typeof LayoutRoute
    210○+ }
    192211 '/_layout/items': {
    193212 id: '/_layout/items'
    194213 path: '/items'
    @@ -208,6 +227,7 @@ declare module '@tanstack/react-router' {
    208227
    209228 interface LayoutRouteChildren {
    210229 LayoutAdminRoute: typeof LayoutAdminRoute
    230○+ LayoutInsightsRoute: typeof LayoutInsightsRoute
    211231 LayoutItemsRoute: typeof LayoutItemsRoute
    212232 LayoutSettingsRoute: typeof LayoutSettingsRoute
    213233 LayoutIndexRoute: typeof LayoutIndexRoute
    @@ -215,6 +235,7 @@ interface LayoutRouteChildren {
    215235
    216236 const LayoutRouteChildren: LayoutRouteChildren = {
    217237 LayoutAdminRoute: LayoutAdminRoute,
    238○+ LayoutInsightsRoute: LayoutInsightsRoute,
    218239 LayoutItemsRoute: LayoutItemsRoute,
    219240 LayoutSettingsRoute: LayoutSettingsRoute,
    220241 LayoutIndexRoute: LayoutIndexRoute,
Then skim: 5 low-risk code files
  1. additive change: nothing that existed changed
    8/8 pages✍ Yurii Motov 75%declarations only
    2
    Show diff (+1 −1)
    @@ -1,4 +1,4 @@
    11 // This file is auto-generated by @hey-api/openapi-ts
    22
    33 export { ItemsService, LoginService, type Options, PrivateService, UsersService, UtilsService } from './sdk.gen';
    4-export type { Body_login_login_access_token, ClientOptions, HTTPValidationError, ItemCreate, ItemPublic, itemsCreateItemData, itemsCreateItemError, itemsCreateItemErrors, itemsCreateItemResponse, itemsCreateItemResponses, itemsDeleteItemData, itemsDeleteItemError, itemsDeleteItemErrors, itemsDeleteItemResponse, itemsDeleteItemResponses, ItemsPublic, itemsReadItemData, itemsReadItemError, itemsReadItemErrors, itemsReadItemResponse, itemsReadItemResponses, itemsReadItemsData, itemsReadItemsError, itemsReadItemsErrors, itemsReadItemsResponse, itemsReadItemsResponses, itemsUpdateItemData, itemsUpdateItemError, itemsUpdateItemErrors, itemsUpdateItemResponse, itemsUpdateItemResponses, ItemUpdate, loginLoginAccessTokenData, loginLoginAccessTokenError, loginLoginAccessTokenErrors, loginLoginAccessTokenResponse, loginLoginAccessTokenResponses, loginRecoverPasswordData, loginRecoverPasswordError, loginRecoverPasswordErrors, loginRecoverPasswordHtmlContentData, loginRecoverPasswordHtmlContentError, loginRecoverPasswordHtmlContentErrors, loginRecoverPasswordHtmlContentResponse, loginRecoverPasswordHtmlContentResponses, loginRecoverPasswordResponse, loginRecoverPasswordResponses, loginResetPasswordData, loginResetPasswordError, loginResetPasswordErrors, loginResetPasswordResponse, loginResetPasswordResponses, loginTestTokenData, loginTestTokenResponse, loginTestTokenResponses, Message, NewPassword, privateCreateUserData, privateCreateUserError, privateCreateUserErrors, privateCreateUserResponse, privateCreateUserResponses, PrivateUserCreate, Token, UpdatePassword, UserCreate, UserPublic, UserRegister, usersCreateUserData, usersCreateUserError, usersCreateUserErrors, usersCreateUserResponse, usersCreateUserResponses, usersDeleteUserData, usersDeleteUserError, usersDeleteUserErrors, usersDeleteUserMeData, usersDeleteUserMeResponse, usersDeleteUserMeResponses, usersDeleteUserResponse, usersDeleteUserResponses, UsersPublic, usersReadUserByIdData, usersReadUserByIdError, usersReadUserByIdErrors, usersReadUserByIdResponse, usersReadUserByIdResponses, usersReadUserMeData, usersReadUserMeResponse, usersReadUserMeResponses, usersReadUsersData, usersReadUsersError, usersReadUsersErrors, usersReadUsersResponse, usersReadUsersResponses, usersRegisterUserData, usersRegisterUserError, usersRegisterUserErrors, usersRegisterUserResponse, usersRegisterUserResponses, usersUpdatePasswordMeData, usersUpdatePasswordMeError, usersUpdatePasswordMeErrors, usersUpdatePasswordMeResponse, usersUpdatePasswordMeResponses, usersUpdateUserData, usersUpdateUserError, usersUpdateUserErrors, usersUpdateUserMeData, usersUpdateUserMeError, usersUpdateUserMeErrors, usersUpdateUserMeResponse, usersUpdateUserMeResponses, usersUpdateUserResponse, usersUpdateUserResponses, UserUpdate, UserUpdateMe, utilsHealthCheckData, utilsHealthCheckResponse, utilsHealthCheckResponses, utilsTestEmailData, utilsTestEmailError, utilsTestEmailErrors, utilsTestEmailResponse, utilsTestEmailResponses, ValidationError } from './types.gen';
    4+export type { Body_login_login_access_token, ClientOptions, HTTPValidationError, ItemCreate, ItemPublic, itemsCreateItemData, itemsCreateItemError, itemsCreateItemErrors, itemsCreateItemResponse, itemsCreateItemResponses, itemsDeleteItemData, itemsDeleteItemError, itemsDeleteItemErrors, itemsDeleteItemResponse, itemsDeleteItemResponses, ItemsPublic, ItemStatus, ItemStatusCount, ItemsStats, itemsReadItemData, itemsReadItemError, itemsReadItemErrors, itemsReadItemResponse, itemsReadItemResponses, itemsReadItemsData, itemsReadItemsError, itemsReadItemsErrors, itemsReadItemsResponse, itemsReadItemsResponses, itemsReadItemsStatsData, itemsReadItemsStatsResponse, itemsReadItemsStatsResponses, itemsUpdateItemData, itemsUpdateItemError, itemsUpdateItemErrors, itemsUpdateItemResponse, itemsUpdateItemResponses, ItemUpdate, loginLoginAccessTokenData, loginLoginAccessTokenError, loginLoginAccessTokenErrors, loginLoginAccessTokenResponse, loginLoginAccessTokenResponses, loginRecoverPasswordData, loginRecoverPasswordError, loginRecoverPasswordErrors, loginRecoverPasswordHtmlContentData, loginRecoverPasswordHtmlContentError, loginRecoverPasswordHtmlContentErrors, loginRecoverPasswordHtmlContentResponse, loginRecoverPasswordHtmlContentResponses, loginRecoverPasswordResponse, loginRecoverPasswordResponses, loginResetPasswordData, loginResetPasswordError, loginResetPasswordErrors, loginResetPasswordResponse, loginResetPasswordResponses, loginTestTokenData, loginTestTokenResponse, loginTestTokenResponses, Message, NewPassword, privateCreateUserData, privateCreateUserError, privateCreateUserErrors, privateCreateUserResponse, privateCreateUserResponses, PrivateUserCreate, Token, UpdatePassword, UserCreate, UserPublic, UserRegister, usersCreateUserData, usersCreateUserError, usersCreateUserErrors, usersCreateUserResponse, usersCreateUserResponses, usersDeleteUserData, usersDeleteUserError, usersDeleteUserErrors, usersDeleteUserMeData, usersDeleteUserMeResponse, usersDeleteUserMeResponses, usersDeleteUserResponse, usersDeleteUserResponses, UsersPublic, usersReadUserByIdData, usersReadUserByIdError, usersReadUserByIdErrors, usersReadUserByIdResponse, usersReadUserByIdResponses, usersReadUserMeData, usersReadUserMeResponse, usersReadUserMeResponses, usersReadUsersData, usersReadUsersError, usersReadUsersErrors, usersReadUsersResponse, usersReadUsersResponses, usersRegisterUserData, usersRegisterUserError, usersRegisterUserErrors, usersRegisterUserResponse, usersRegisterUserResponses, usersUpdatePasswordMeData, usersUpdatePasswordMeError, usersUpdatePasswordMeErrors, usersUpdatePasswordMeResponse, usersUpdatePasswordMeResponses, usersUpdateUserData, usersUpdateUserError, usersUpdateUserErrors, usersUpdateUserMeData, usersUpdateUserMeError, usersUpdateUserMeErrors, usersUpdateUserMeResponse, usersUpdateUserMeResponses, usersUpdateUserResponse, usersUpdateUserResponses, UserUpdate, UserUpdateMe, utilsHealthCheckData, utilsHealthCheckResponse, utilsHealthCheckResponses, utilsTestEmailData, utilsTestEmailError, utilsTestEmailErrors, utilsTestEmailResponse, utilsTestEmailResponses, ValidationError } from './types.gen';
  2. additive change: nothing that existed changed
    ✍ Yurii Motov 70%0% covered
    2
    Show diff (+15 −1)
    @@ -2,7 +2,7 @@
    22
    33 import { type Client, type Options as Options2, type TDataShape, urlSearchParamsBodySerializer } from './client';
    44 import { client } from './client.gen';
    5-import type { itemsCreateItemData, itemsCreateItemErrors, itemsCreateItemResponses, itemsDeleteItemData, itemsDeleteItemErrors, itemsDeleteItemResponses, itemsReadItemData, itemsReadItemErrors, itemsReadItemResponses, itemsReadItemsData, itemsReadItemsErrors, itemsReadItemsResponses, itemsUpdateItemData, itemsUpdateItemErrors, itemsUpdateItemResponses, loginLoginAccessTokenData, loginLoginAccessTokenErrors, loginLoginAccessTokenResponses, loginRecoverPasswordData, loginRecoverPasswordErrors, loginRecoverPasswordHtmlContentData, loginRecoverPasswordHtmlContentErrors, loginRecoverPasswordHtmlContentResponses, loginRecoverPasswordResponses, loginResetPasswordData, loginResetPasswordErrors, loginResetPasswordResponses, loginTestTokenData, loginTestTokenResponses, privateCreateUserData, privateCreateUserErrors, privateCreateUserResponses, usersCreateUserData, usersCreateUserErrors, usersCreateUserResponses, usersDeleteUserData, usersDeleteUserErrors, usersDeleteUserMeData, usersDeleteUserMeResponses, usersDeleteUserResponses, usersReadUserByIdData, usersReadUserByIdErrors, usersReadUserByIdResponses, usersReadUserMeData, usersReadUserMeResponses, usersReadUsersData, usersReadUsersErrors, usersReadUsersResponses, usersRegisterUserData, usersRegisterUserErrors, usersRegisterUserResponses, usersUpdatePasswordMeData, usersUpdatePasswordMeErrors, usersUpdatePasswordMeResponses, usersUpdateUserData, usersUpdateUserErrors, usersUpdateUserMeData, usersUpdateUserMeErrors, usersUpdateUserMeResponses, usersUpdateUserResponses, utilsHealthCheckData, utilsHealthCheckResponses, utilsTestEmailData, utilsTestEmailErrors, utilsTestEmailResponses } from './types.gen';
    5○+import type { itemsCreateItemData, itemsCreateItemErrors, itemsCreateItemResponses, itemsDeleteItemData, itemsDeleteItemErrors, itemsDeleteItemResponses, itemsReadItemData, itemsReadItemErrors, itemsReadItemResponses, itemsReadItemsData, itemsReadItemsErrors, itemsReadItemsResponses, itemsReadItemsStatsData, itemsReadItemsStatsResponses, itemsUpdateItemData, itemsUpdateItemErrors, itemsUpdateItemResponses, loginLoginAccessTokenData, loginLoginAccessTokenErrors, loginLoginAccessTokenResponses, loginRecoverPasswordData, loginRecoverPasswordErrors, loginRecoverPasswordHtmlContentData, loginRecoverPasswordHtmlContentErrors, loginRecoverPasswordHtmlContentResponses, loginRecoverPasswordResponses, loginResetPasswordData, loginResetPasswordErrors, loginResetPasswordResponses, loginTestTokenData, loginTestTokenResponses, privateCreateUserData, privateCreateUserErrors, privateCreateUserResponses, usersCreateUserData, usersCreateUserErrors, usersCreateUserResponses, usersDeleteUserData, usersDeleteUserErrors, usersDeleteUserMeData, usersDeleteUserMeResponses, usersDeleteUserResponses, usersReadUserByIdData, usersReadUserByIdErrors, usersReadUserByIdResponses, usersReadUserMeData, usersReadUserMeResponses, usersReadUsersData, usersReadUsersErrors, usersReadUsersResponses, usersRegisterUserData, usersRegisterUserErrors, usersRegisterUserResponses, usersUpdatePasswordMeData, usersUpdatePasswordMeErrors, usersUpdatePasswordMeResponses, usersUpdateUserData, usersUpdateUserErrors, usersUpdateUserMeData, usersUpdateUserMeErrors, usersUpdateUserMeResponses, usersUpdateUserResponses, utilsHealthCheckData, utilsHealthCheckResponses, utilsTestEmailData, utilsTestEmailErrors, utilsTestEmailResponses } from './types.gen';
    66
    77 export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown> = Options2<TData, ThrowOnError, TResponse> & {
    88 /**
    @@ -299,6 +299,20 @@ export class ItemsService {
    299299 });
    300300 }
    301301
    302○+ /**
    303○+ * Read Items Stats
    304○+ *
    305○+ * Number of items per status.
    306○+ */
    307○+ public static readItemsStats<ThrowOnError extends boolean = true>(options?: Options<itemsReadItemsStatsData, ThrowOnError>) {
    308○+ return (options?.client ?? client).get<itemsReadItemsStatsResponses, unknown, ThrowOnError>({
    309○+ responseType: 'json',
    310○+ security: [{ scheme: 'bearer', type: 'http' }],
    311○+ url: '/api/v1/items/stats',
    312○+ ...options
    313○+ });
    314○+ }
    315○+
    302316 /**
    303317 * Create Item
    304318 *
  3. new code not used by existing pages
    ✍ Alejandra 96%0% covered
    2
    Show diff (+68 −0)
    @@ -0,0 +1,68 @@
    1○+import { useSuspenseQuery } from "@tanstack/react-query"
    2○+import { createFileRoute } from "@tanstack/react-router"
    3○+import { Suspense } from "react"
    4+
    5○+import { ItemsService } from "@/client"
    6○+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
    7○+import { Skeleton } from "@/components/ui/skeleton"
    8○+import {
    9+ completion,
    10+ STATUS_LABELS,
    11+ STATUSES,
    12+ totalsByStatus,
    13+} from "@/lib/items"
    14+
    15○+export const Route = createFileRoute("/_layout/insights")({
    16○+ component: Insights,
    17○+ head: () => ({
    18○+ meta: [
    19○+ {
    20○+ title: "Insights - FastAPI Template",
    21○+ },
    22○+ ],
    23○+ }),
    24○+})
    25+
    26○+function StatusCards() {
    27○+ const { data } = useSuspenseQuery({
    28○+ queryFn: async () => (await ItemsService.readItemsStats()).data,
    29○+ queryKey: ["items", "stats"],
    30○+ })
    31○+ const totals = totalsByStatus(data.data)
    32+
    33○+ return (
    34○+ <div className="flex flex-col gap-4">
    35○+ <p className="text-sm text-muted-foreground">
    36○+ {completion(totals)}% of your items are done
    37○+ </p>
    38○+ <div className="grid gap-4 sm:grid-cols-3">
    39○+ {STATUSES.map((status) => (
    40○+ <Card key={status}>
    41○+ <CardHeader>
    42○+ <CardTitle className="text-sm text-muted-foreground">
    43○+ {STATUS_LABELS[status]}
    44○+ </CardTitle>
    45○+ </CardHeader>
    46○+ <CardContent className="text-3xl font-bold">
    47○+ {totals[status]}
    48○+ </CardContent>
    49○+ </Card>
    50○+ ))}
    51○+ </div>
    52○+ </div>
    53+ )
    54○+}
    55+
    56○+function Insights() {
    57○+ return (
    58○+ <div className="flex flex-col gap-6">
    59○+ <div>
    60○+ <h1 className="text-2xl font-bold tracking-tight">Insights</h1>
    61○+ <p className="text-muted-foreground">Your items by status</p>
    62○+ </div>
    63○+ <Suspense fallback={<Skeleton className="h-28 w-full" />}>
    64○+ <StatusCards />
    65○+ </Suspense>
    66○+ </div>
    67+ )
    68○+}
  4. new code not used by existing pages
    ✍ Alejandra 77%0% covered
    2
    Show diff (+23 −0)
    @@ -0,0 +1,23 @@
    1○+import path from "node:path"
    2○+import { defineConfig } from "vitest/config"
    3○+
    4○+export default defineConfig({
    5○+ resolve: {
    6○+ alias: {
    7○+ "@": path.resolve(import.meta.dirname, "./src"),
    8○+ },
    9○+ },
    10○+ test: {
    11○+ include: ["src/**/*.test.ts"],
    12○+ coverage: {
    13○+ provider: "v8",
    14○+ // Every source file, so the ones no test loads show up as untested.
    15○+ include: ["src/**/*.{ts,tsx}"],
    16○+ exclude: [
    17○+ "src/client/**",
    18○+ "src/routeTree.gen.ts",
    19○+ "src/components/ui/**",
    20○+ ],
    21○+ },
    22○+ },
    23○+})
  5. ✍ Yurii Motov 81%0% covered
    0
    Show diff (+50 −2)
    @@ -82,6 +82,33 @@ export type ItemPublic = {
    8282 * Created At
    8383 */
    8484 created_at?: string | null;
    85○+ status?: ItemStatus;
    86○+};
    87○+
    88○+/**
    89○+ * ItemStatus
    90○+ */
    91○+export type ItemStatus = 'todo' | 'in_progress' | 'done';
    92○+
    93○+/**
    94○+ * ItemStatusCount
    95○+ */
    96○+export type ItemStatusCount = {
    97○+ status: ItemStatus;
    98○+ /**
    99○+ * Total
    100○+ */
    101○+ total: number;
    102○+};
    103○+
    104○+/**
    105○+ * ItemsStats
    106○+ */
    107○+export type ItemsStats = {
    108○+ /**
    109○+ * Data
    110○+ */
    111○+ data: Array<ItemStatusCount>;
    85112 };
    86113
    87114 /**
    @@ -96,6 +123,7 @@ export type ItemUpdate = {
    96123 * Description
    97124 */
    98125 description?: string | null;
    126○+ status?: ItemStatus | null;
    99127 };
    100128
    101129 /**
    @@ -107,9 +135,9 @@ export type ItemsPublic = {
    107135 */
    108136 data: Array<ItemPublic>;
    109137 /**
    110- * Count
    138○+ * Total
    111139 */
    112- count: number;
    140○+ total: number;
    113141 };
    114142
    115143 /**
    @@ -784,6 +812,10 @@ export type itemsReadItemsData = {
    784812 * Limit
    785813 */
    786814 limit?: number;
    815○+ /**
    816○+ * Status
    817○+ */
    818○+ status?: ItemStatus | null;
    787819 };
    788820 url: '/api/v1/items/';
    789821 };
    @@ -945,3 +977,19 @@ export type privateCreateUserResponses = {
    945977 };
    946978
    947979 export type privateCreateUserResponse = privateCreateUserResponses[keyof privateCreateUserResponses];
    980○+
    981○+export type itemsReadItemsStatsData = {
    982○+ body?: never;
    983○+ path?: never;
    984○+ query?: never;
    985○+ url: '/api/v1/items/stats';
    986○+};
    987○+
    988○+export type itemsReadItemsStatsResponses = {
    989○+ /**
    990○+ * Successful Response
    991○+ */
    992○+ 200: ItemsStats;
    993○+};
    994○+
    995○+export type itemsReadItemsStatsResponse = itemsReadItemsStatsResponses[keyof itemsReadItemsStatsResponses];
Probably no review needed: 4 files (not code, dependencies, tests)

Docs, assets, lockfiles and tests. Dependency changes are judged in Dependencies, tests in Coverage.

Not code (1)
Manifests and lockfiles (2)

Key findings — open one for its files and details

  1. high1 package manifest changed beyond dependencies · 1 file
    fields changed: scripts
  2. highDiff coverage of 25.0% in the files present in the report · 6 files
    75 changed executable lines not covered in 6 files.
  3. high1 high-risk change: central files used by many existing pages · 1 file
    Review carefully and test the pages that use them: AppSidebar.tsx (4/8 pages, 3 dependents).
  4. medium1 added suppression · 1 file
    Kinds: as-any.
  5. medium4 changed files missing from the coverage report · 4 files
    No test loaded these files, or the Vitest coverage configuration excludes them (coverage.exclude). They count as fully uncovered in the total.
  6. medium4 medium-risk changes · 4 files
    Review carefully and test the pages that use them: DataTable.tsx (2/8 pages, 4 dependents), items.ts (1/8 pages, 5 dependents), columns.tsx (1/8 pages, 3 dependents), items.tsx (1/8 pages, 2 dependents).
  7. medium1 new file already used by existing pages · 1 file
    New code that existing pages already run.
  8. low2 non-critical dependency changes · 1 file
    Patch/minor bumps, range-only changes or new packages: @vitest/coverage-v8 added, vitest added.
  9. lowDependency audit not verified
    no audit report given (--audit or signals.audit)
  10. lowLint not verified
    no ESLint report given (--eslint or signals.eslint)
  11. low2 modified existing files no route reaches · 2 files
    Still a change to existing code (utilities, configuration, code outside the import graph).

Test plan

Try these pages by hand before approving: new ones first, then the affected ones whose changed file carries the most risk. Ticks are kept in this browser for this commit.

0 of 5 tested

/insights 1 to test
/ 1 to test
/admin 1 to test
/items 1 to test
/settings 1 to test

Risk

Every changed code file, riskiest first. Risk points (0–100, as in the merge risk score) combine its reach with what its diff coverage leaves and its findings. Reach: centrality of each changed file in the import graph: who uses it directly, how many files depend on it through any chain of imports, and how many of the 8 existing pages reach it. High: used by at least half of the pages (or 10+ pages). Medium: used by some page, or by 10+ files, or new code inside existing pages, or deleted. Low: additive, or not used by existing pages.

1
high reach
4
medium reach
6
low reach
Risk: Change:
FileChangeReach (existing pages)Diff coverageFindingsRisk pointsWhy
components/Sidebar/AppSidebar.tsxmodifiedhigh 4 / 8
0%35used by 4 of 8 existing pages
components/Common/DataTable.tsxmodifiedmedium 2 / 8
0%17used by 2 of 8 existing pages
components/Items/columns.tsxmodifiedmedium 1 / 8
0%12used by 1 of 8 existing pages
routes/_layout/items.tsxmodifiedmedium 1 / 8
0%12used by 1 of 8 existing pages
lib/items.tsaddedmedium 1 / 8
93%5new code already used by 1 existing page
routeTree.gen.tsmodifiedlow 0 / 8
0%1 suppression51 file(s) depend on it, no page reaches it
client/index.tsadditivelow 8 / 8
—2additive change: nothing that existed changed
client/sdk.gen.tsadditivelow 0 / 8
0%2additive change: nothing that existed changed
routes/_layout/insights.tsxaddedlow 0 / 8
0%2new code not used by existing pages
frontend/vitest.config.tsaddedlow 0 / 8
0%2new code not used by existing pages
frontend/README.mdmodifiedlow 0 / 8
—0nothing imports it

Security

Static analysis of added lines

XSS sinks, dynamic code execution, hard-coded credentials, javascript: URLs, unsafe cross-window messaging, links without rel=noopener and plain-HTTP URLs on the lines this PR adds (tests and stories excluded).

None.

Vulnerabilities in added or changed dependencies

From the npm/pnpm audit report of the head: advisories on packages this PR added or changed (direct) or on packages they bring in (transitive).

Not verified no audit report given (--audit or signals.audit)

Dependencies

Removing a dependency, a major bump, a breaking 0.x minor bump, a version farol cannot compare, a change to other manifest fields (exports, scripts, overrides…) or a lockfile change without manifest changes is critical. Patch and minor bumps, range-only changes and new dependencies are not.

0
critical
0
major
0
minor
0
patch
2
added
0
removed

Manifest changes beyond dependencies

ManifestChange
frontend/package.jsonfields changed: scriptscritical

Package changes

PackageManifestSectionChangeFromToBump
@vitest/coverage-v8frontend/package.jsondevDependenciesadded3.2.4not critical
vitestfrontend/package.jsondevDependenciesadded3.2.4not critical

Changed lockfiles

Coverage

Diff coverage

12.0%
25 / 209

Files present in the report only: 25.0% (25 / 100).

FileChanged executable linesCoveredUncovered ranges
routes/_layout/insights.tsx5601–3, 5–8, 15–24, 26–31, 33–52, 54, 56–66, 68
components/Items/columns.tsx1006, 9, 50–56, 58
components/Common/DataTable.tsx4051, 119–121
components/Sidebar/AppSidebar.tsx201, 18
lib/items.ts272533–34
routes/_layout/items.tsx1046
client/types.gen.ts missing from the report50085–111, 126, 138, 140, 815–818, 980–995
frontend/vitest.config.ts missing from the report2301–23
routeTree.gen.ts missing from the report21019, 57–61, 80, 90, 103, 117, 127, 139, 204–210, 230, 238
client/sdk.gen.ts missing from the report1505, 302–315

Lint on changed lines

Not verified no ESLint report given (--eslint or signals.eslint)

Added suppressions

LocationKindLine
routeTree.gen.ts:61as-any} as any)

Modified existing tests

None.

Reviewers

Suggested reviewers — Who wrote the code this PR changes (git blame at the base, weighed by each file's risk). PR authors and bots are left out.

  1. Alejandrawrote 87% of the changed code
    AppSidebar.tsx 100%DataTable.tsx 77%columns.tsx 95%
  2. Yurii Motovwrote 9% of the changed code
    DataTable.tsx 23%index.ts 75%sdk.gen.ts 70%
  3. Patrick Arminiowrote 4% of the changed code
    items.tsx 22%index.ts 25%sdk.gen.ts 9%

Routes

Pages with changes: 4 affected, 1 new

Open a page to see how the changed files reach it: page → module → … → changed file. Changed files are highlighted; every box links to GitHub.

Mark files as reviewed ↑ (top of the page)

pageunchanged file (only on the import path)modified in this PRnew in this PRhigh riskmedium riskA → B: A imports B
affected/1 changed filehigh
flowchart LR
  route(["/"]):::route
  n1["routes/_layout.tsx"]:::module
  n2["components/Sidebar/AppSidebar.tsx<br/><small>high risk · 4/8 pages</small>"]:::changed
  style n2 stroke:#ff2d2d,stroke-width:6px
  route --> n1
  n1 --> n2
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout.tsx" _blank
  click n2 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-0b4962fd6e2a808d8a7dd8c897c3984f36346813031385cefd01c791cd8a57be" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

affected/admin2 changed fileshigh
flowchart LR
  route(["/admin"]):::route
  n1["routes/_layout/admin.tsx"]:::module
  n2["components/Common/DataTable.tsx<br/><small>medium risk · 2/8 pages</small>"]:::changed
  style n2 stroke:#ffd60a,stroke-width:4px
  n3["routes/_layout.tsx"]:::module
  n4["components/Sidebar/AppSidebar.tsx<br/><small>high risk · 4/8 pages</small>"]:::changed
  style n4 stroke:#ff2d2d,stroke-width:6px
  route --> n1
  n1 --> n2
  route --> n3
  n3 --> n4
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout/admin.tsx" _blank
  click n2 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-d1989fc697d2d7848580fa921bbe798d838b8c5a07f27d1d6263c49bd58f8dd4" _blank
  click n3 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout.tsx" _blank
  click n4 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-0b4962fd6e2a808d8a7dd8c897c3984f36346813031385cefd01c791cd8a57be" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

affected/items5 changed fileshigh
flowchart LR
  route(["/items"]):::route
  n1["routes/_layout/items.tsx<br/><small>medium risk · 1/8 pages</small>"]:::changed
  style n1 stroke:#ffd60a,stroke-width:4px
  n2["components/Common/DataTable.tsx<br/><small>medium risk · 2/8 pages</small>"]:::changed
  style n2 stroke:#ffd60a,stroke-width:4px
  n3["components/Items/columns.tsx<br/><small>medium risk · 1/8 pages</small>"]:::changed
  style n3 stroke:#ffd60a,stroke-width:4px
  n4["routes/_layout.tsx"]:::module
  n5["components/Sidebar/AppSidebar.tsx<br/><small>high risk · 4/8 pages</small>"]:::changed
  style n5 stroke:#ff2d2d,stroke-width:6px
  n6["lib/items.ts<br/><small>medium risk · 1/8 pages</small>"]:::added
  style n6 stroke:#ffd60a,stroke-width:4px
  route --> n1
  n1 --> n2
  n1 --> n3
  route --> n4
  n4 --> n5
  n3 --> n6
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-05b07461311f035e3f6571e902cf36d0a8a9de17954c251216730608beae30ec" _blank
  click n2 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-d1989fc697d2d7848580fa921bbe798d838b8c5a07f27d1d6263c49bd58f8dd4" _blank
  click n3 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-5655db97cc0617561886a6320b5933026ea03b253187d6b4bb7eda712094de3e" _blank
  click n4 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout.tsx" _blank
  click n5 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-0b4962fd6e2a808d8a7dd8c897c3984f36346813031385cefd01c791cd8a57be" _blank
  click n6 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-516fecf336eadebca203ed540d7aa789bbff3f3210345277cd1b9ac326096e80" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

affected/settings1 changed filehigh
flowchart LR
  route(["/settings"]):::route
  n1["routes/_layout.tsx"]:::module
  n2["components/Sidebar/AppSidebar.tsx<br/><small>high risk · 4/8 pages</small>"]:::changed
  style n2 stroke:#ff2d2d,stroke-width:6px
  route --> n1
  n1 --> n2
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout.tsx" _blank
  click n2 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-0b4962fd6e2a808d8a7dd8c897c3984f36346813031385cefd01c791cd8a57be" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

new/insights1 changed filelow
flowchart LR
  route(["/insights"]):::route
  n1["routes/_layout/insights.tsx<br/><small>low risk · 0/8 pages</small>"]:::added
  style n1 stroke-width:1px
  route --> n1
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-11c7f74f4b157449759ce65d1eb893933b67ce1b294171ee2a0208117c2c2a17" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

affected/1 changed filehigh
flowchart LR
  route(["/"]):::route
  n1["routes/_layout.tsx"]:::module
  n2["components/Sidebar/AppSidebar.tsx<br/><small>high risk · 4/8 pages</small>"]:::changed
  style n2 stroke:#ff2d2d,stroke-width:6px
  route --> n1
  n1 --> n2
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout.tsx" _blank
  click n2 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-0b4962fd6e2a808d8a7dd8c897c3984f36346813031385cefd01c791cd8a57be" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

affected/admin2 changed fileshigh
flowchart LR
  route(["/admin"]):::route
  n1["routes/_layout/admin.tsx"]:::module
  n2["components/Common/DataTable.tsx<br/><small>medium risk · 2/8 pages</small>"]:::changed
  style n2 stroke:#ffd60a,stroke-width:4px
  n3["routes/_layout.tsx"]:::module
  n4["components/Sidebar/AppSidebar.tsx<br/><small>high risk · 4/8 pages</small>"]:::changed
  style n4 stroke:#ff2d2d,stroke-width:6px
  route --> n1
  n1 --> n2
  route --> n3
  n3 --> n4
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout/admin.tsx" _blank
  click n2 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-d1989fc697d2d7848580fa921bbe798d838b8c5a07f27d1d6263c49bd58f8dd4" _blank
  click n3 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout.tsx" _blank
  click n4 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-0b4962fd6e2a808d8a7dd8c897c3984f36346813031385cefd01c791cd8a57be" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

affected/items5 changed fileshigh
flowchart LR
  route(["/items"]):::route
  n1["routes/_layout/items.tsx<br/><small>medium risk · 1/8 pages</small>"]:::changed
  style n1 stroke:#ffd60a,stroke-width:4px
  n2["components/Common/DataTable.tsx<br/><small>medium risk · 2/8 pages</small>"]:::changed
  style n2 stroke:#ffd60a,stroke-width:4px
  n3["components/Items/columns.tsx<br/><small>medium risk · 1/8 pages</small>"]:::changed
  style n3 stroke:#ffd60a,stroke-width:4px
  n4["routes/_layout.tsx"]:::module
  n5["components/Sidebar/AppSidebar.tsx<br/><small>high risk · 4/8 pages</small>"]:::changed
  style n5 stroke:#ff2d2d,stroke-width:6px
  n6["lib/items.ts<br/><small>medium risk · 1/8 pages</small>"]:::added
  style n6 stroke:#ffd60a,stroke-width:4px
  route --> n1
  n1 --> n2
  n1 --> n3
  route --> n4
  n4 --> n5
  n3 --> n6
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-05b07461311f035e3f6571e902cf36d0a8a9de17954c251216730608beae30ec" _blank
  click n2 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-d1989fc697d2d7848580fa921bbe798d838b8c5a07f27d1d6263c49bd58f8dd4" _blank
  click n3 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-5655db97cc0617561886a6320b5933026ea03b253187d6b4bb7eda712094de3e" _blank
  click n4 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout.tsx" _blank
  click n5 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-0b4962fd6e2a808d8a7dd8c897c3984f36346813031385cefd01c791cd8a57be" _blank
  click n6 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-516fecf336eadebca203ed540d7aa789bbff3f3210345277cd1b9ac326096e80" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

affected/settings1 changed filehigh
flowchart LR
  route(["/settings"]):::route
  n1["routes/_layout.tsx"]:::module
  n2["components/Sidebar/AppSidebar.tsx<br/><small>high risk · 4/8 pages</small>"]:::changed
  style n2 stroke:#ff2d2d,stroke-width:6px
  route --> n1
  n1 --> n2
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/blob/a3493f655be6131f28317d62490bfe6dd82691d7/frontend/src/routes/_layout.tsx" _blank
  click n2 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-0b4962fd6e2a808d8a7dd8c897c3984f36346813031385cefd01c791cd8a57be" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

new/insights1 changed filelow
flowchart LR
  route(["/insights"]):::route
  n1["routes/_layout/insights.tsx<br/><small>low risk · 0/8 pages</small>"]:::added
  style n1 stroke-width:1px
  route --> n1
  click n1 href "https://github.com/erich-oliveira-winnin/full-stack-fastapi-template/pull/1/files#diff-11c7f74f4b157449759ce65d1eb893933b67ce1b294171ee2a0208117c2c2a17" _blank
  classDef route fill:#2457c5,stroke:#2457c5,color:#fff
  classDef changed fill:#5c3317,stroke:#a8642a,color:#fff
  classDef added fill:#14532d,stroke:#2f8f55,color:#fff
  classDef module fill:transparent,stroke:#9aa4b1,stroke-dasharray:3 3,color:#8a94a3

Loading the diagram (needs internet access to load Mermaid).

New files no route reaches

Files

Package manifests (1)
FileStatus+−Additive rule
frontend/package.jsonmodified40
Lockfiles (1)
FileStatus+−Additive rule
bun.lockmodified2422
Source (11)
FileStatus+−Additive rule
frontend/README.mdmodified160
client/sdk.gen.tsmodified151additive
client/types.gen.tsmodified502
components/Common/DataTable.tsxmodified61not additive
components/Items/columns.tsxmodified110not additive
components/Sidebar/AppSidebar.tsxmodified21not additive
lib/items.tsadded360
routeTree.gen.tsmodified210not additive
routes/_layout/insights.tsxadded680
routes/_layout/items.tsxmodified11not additive
frontend/vitest.config.tsadded230
Barrels (1)
FileStatus+−Additive rule
client/index.tsmodified11additive
Tests (1)
FileStatus+−Additive rule
lib/items.test.tsadded260
Excluded (6)
FileStatus+−Additive rule
backend/README.mdmodified50
backend/app/alembic/versions/3c9e1f2b7a41_add_status_to_item.pyadded280
backend/app/api/routes/items.pymodified4126
backend/app/models.pymodified191
backend/docs/item-status.mdadded210
backend/tests/api/routes/test_items.pymodified220

Details

All reasons (23)
ReasonFileDetail
package manifest changed beyond dependencies
manifest-changed
frontend/package.jsonfields changed: scripts
existing file modified
existing-file-modified
components/Common/DataTable.tsxfunc frontend/src/components/Common/DataTable.tsx#DataTable changed: reached by 2 existing route(s): /_layout/admin; /_layout/items
existing file modified
existing-file-modified
components/Items/columns.tsxvar frontend/src/components/Items/columns.tsx#columns changed: reached by 1 existing route(s): /_layout/items
existing file modified
existing-file-modified
components/Sidebar/AppSidebar.tsxvar frontend/src/components/Sidebar/AppSidebar.tsx#baseItems changed: reached by 4 existing route(s): /_layout/; /_layout/admin; /_layout/items; and 1 more
existing file modified
existing-file-modified
routes/_layout/items.tsxfunc frontend/src/routes/_layout/items.tsx#ItemsTableContent changed: reached by 1 existing route(s): /_layout/items
existing file modified, no route reaches it
existing-file-unreachable
frontend/README.mdmodified, and it is not part of the import graph
existing file modified, no route reaches it
existing-file-unreachable
routeTree.gen.tsvar frontend/src/routeTree.gen.ts#LayoutRouteChildren changed; module frontend/src/routeTree.gen.ts#<module> changed; no route reaches it
new file reached by an existing route
new-file-reached-by-existing-route
lib/items.tsreached by 1 existing route(s): /_layout/items
types-only file changed (erased at runtime)
type-only-change
client/types.gen.tsthe file only declares types in both versions: nothing changes at runtime
only new declarations, comments or formatting (Go)
declarations-additive
client/sdk.gen.tsonly additions: new declarations frontend/src/client/sdk.gen.ts#ItemsService.readItemsStats
dependency change (not critical)
dependency-changed
frontend/package.json@vitest/coverage-v8 added 3.2.4 (devDependencies)
dependency change (not critical)
dependency-changed
frontend/package.jsonvitest added 3.2.4 (devDependencies)
lockfile changed with the manifests
lockfile-changed
bun.locklockfile modified together with dependency changes
new route
route-added
routes/_layout/insights.tsx/insights (/_layout/insights) renders frontend/src/routes/_layout/insights.tsx
barrel only gained exports
barrel-additive
client/index.tsonly new export declarations
new file used only by new routes
new-file-in-new-route
routes/_layout/insights.tsxreached only by new route(s): /insights
new file no route reaches
new-file-disconnected
frontend/vitest.config.tsnew file that no route reaches
file outside the project
outside-project
backend/README.mdoutside the project directory and not imported by the project
file outside the project
outside-project
backend/app/alembic/versions/3c9e1f2b7a41_add_status_to_item.pyoutside the project directory and not imported by the project
file outside the project
outside-project
backend/app/api/routes/items.pyoutside the project directory and not imported by the project
file outside the project
outside-project
backend/app/models.pyoutside the project directory and not imported by the project
file outside the project
outside-project
backend/docs/item-status.mdoutside the project directory and not imported by the project
file outside the project
outside-project
backend/tests/api/routes/test_items.pyoutside the project directory and not imported by the project
Diagnostics

Routes farol cannot read (0)

None.

Unresolved imports (4)

LocationImportReason
components/Common/Logo.tsx:5/assets/images/fastapi-icon.svgnot-found
components/Common/Logo.tsx:6/assets/images/fastapi-icon-light.svgnot-found
components/Common/Logo.tsx:7/assets/images/fastapi-logo.svgnot-found
components/Common/Logo.tsx:8/assets/images/fastapi-logo-light.svgnot-found

Syntax errors (0)

None.

Time per stage (ms)

diff 39 · readTree 16 · program 239 · graph 150 · routes 12 · base 638 · classify 7 · signals 81 · diffs 9

Result

What you marked in this report, as Markdown to paste in the pull request: the initial risk, the risk left, flags, reviewed files and checked findings. It updates as you mark things.