erich-oliveira-winnin/full-stack-fastapi-template
base
077c17d6a669 → head a3493f655be6analyzed 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 fileOverview
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)
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.
- 35 components/Sidebar/AppSidebar.tsx modified · high reach: used by 4 of 8 existing pages · 0% of changed lines covered
- 34 frontend/package.json manifest-changed: fields changed: scripts (+2 more)
- 17 components/Common/DataTable.tsx modified · medium reach: used by 2 of 8 existing pages · 0% of changed lines covered
- 12 components/Items/columns.tsx modified · medium reach: used by 1 of 8 existing pages · 0% of changed lines covered
- 12 routes/_layout/items.tsx modified · medium reach: used by 1 of 8 existing pages · 0% of changed lines covered
- 5 routeTree.gen.ts modified · low reach: 1 file(s) depend on it, no page reaches it · missing from the coverage report (+1 more)
- 5 lib/items.ts added · medium reach: new code already used by 1 existing page · 93% of changed lines covered
- 2 client/index.ts additive · low reach: additive change: nothing that existed changed · not measured
- 2 client/sdk.gen.ts additive · low reach: additive change: nothing that existed changed · missing from the coverage report
- 2 routes/_layout/insights.tsx added · low reach: new code not used by existing pages · 0% of changed lines covered
- 2 frontend/vitest.config.ts added · low reach: new code not used by existing pages · missing from the coverage report
and 5 more
Start here — riskiest first; tick a file once reviewed
-
components/Sidebar/AppSidebar.tsx modifiedused by 4 of 8 existing pages4/8 pages✍ Alejandra 100%0% covered35
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" 2 2 3 3 import { SidebarAppearance } from "@/components/Common/Appearance" 4 4 import { Logo } from "@/components/Common/Logo" @@ -15,6 +15,7 @@ import { User } from "./User" 15 15 const baseItems: Item[] = [ 16 16 { icon: Home, title: "Dashboard", path: "/" }, 17 17 { icon: Briefcase, title: "Items", path: "/items" }, 18 ○+ { icon: BarChart3, title: "Insights", path: "/insights" }, 18 19 ] 19 20 20 21 export function AppSidebar() { -
components/Common/DataTable.tsx modifiedused by 2 of 8 existing pages2/8 pages✍ Alejandra 77%0% covered17
Show diff (+6 −1)
@@ -41,11 +41,14 @@ export type DataTableFeatures = typeof dataTableFeatures 41 41 interface DataTableProps<TData extends RowData> { 42 42 columns: ColumnDef<DataTableFeatures, TData>[] 43 43 data: TData[] 44 + /** Rows on the server, when `data` is one page of them. */ 45 + total?: number 44 46 } 45 47 46 48 export function DataTable<TData extends RowData>({ 47 49 columns, 48 50 data, 51 ○+ total, 49 52 }: DataTableProps<TData>) { 50 53 const table = useTable({ 51 54 features: dataTableFeatures, @@ -113,7 +116,9 @@ export function DataTable<TData extends RowData>({ 113 116 data.length, 114 117 )}{" "} 115 118 of{" "} 116 - <span className="font-medium text-foreground">{data.length}</span>{" "} 119 ○+ <span className="font-medium text-foreground"> 120 ○+ {total ?? data.length} 121 ○+ </span>{" "} 117 122 entries 118 123 </div> 119 124 <div className="flex items-center gap-x-2"> -
components/Items/columns.tsx modifiedused by 1 of 8 existing pages1/8 pages✍ Alejandra 95%0% covered12
Show diff (+11 −0)
@@ -3,8 +3,10 @@ import { Check, Copy } from "lucide-react" 3 3 4 4 import type { ItemPublic } from "@/client" 5 5 import type { DataTableFeatures } from "@/components/Common/DataTable" 6 ○+import { Badge } from "@/components/ui/badge" 6 7 import { Button } from "@/components/ui/button" 7 8 import { useCopyToClipboard } from "@/hooks/useCopyToClipboard" 9 ○+import { statusLabel } from "@/lib/items" 8 10 import { cn } from "@/lib/utils" 9 11 import { ItemActionsMenu } from "./ItemActionsMenu" 10 12 @@ -45,6 +47,15 @@ export const columns: ColumnDef<DataTableFeatures, ItemPublic>[] = [ 45 47 <span className="font-medium">{row.original.title}</span> 46 48 ), 47 49 }, 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 ○+ }, 48 59 { 49 60 accessorKey: "description", 50 61 header: "Description", -
routes/_layout/items.tsx modifiedused by 1 of 8 existing pages1/8 pages✍ Alejandra 76%0% covered12
Show diff (+1 −1)
@@ -43,7 +43,7 @@ function ItemsTableContent() { 43 43 ) 44 44 } 45 45 46 - return <DataTable columns={columns} data={items.data} /> 46 ○+ return <DataTable columns={columns} data={items.data} total={items.total} /> 47 47 } 48 48 49 49 function ItemsTable() { -
lib/items.ts addednew code already used by 1 existing page1/8 pages✍ Alejandra 100%93% covered5
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 +} -
routeTree.gen.ts modified1 file(s) depend on it, no page reaches it✍ Alejandra 100%0% covered1 suppression5
Show diff (+21 −0)
@@ -16,6 +16,7 @@ import { Route as ResetPasswordRouteImport } from './routes/reset-password' 16 16 import { Route as SignupRouteImport } from './routes/signup' 17 17 import { Route as LayoutIndexRouteImport } from './routes/_layout/index' 18 18 import { Route as LayoutAdminRouteImport } from './routes/_layout/admin' 19 ○+import { Route as LayoutInsightsRouteImport } from './routes/_layout/insights' 19 20 import { Route as LayoutItemsRouteImport } from './routes/_layout/items' 20 21 import { Route as LayoutSettingsRouteImport } from './routes/_layout/settings' 21 22 @@ -53,6 +54,11 @@ const LayoutAdminRoute = LayoutAdminRouteImport.update({ 53 54 path: '/admin', 54 55 getParentRoute: () => LayoutRoute, 55 56 } as any) 57 ○+const LayoutInsightsRoute = LayoutInsightsRouteImport.update({ 58 ○+ id: '/insights', 59 ○+ path: '/insights', 60 ○+ getParentRoute: () => LayoutRoute, 61 ⚠+} as any) 56 62 const LayoutItemsRoute = LayoutItemsRouteImport.update({ 57 63 id: '/items', 58 64 path: '/items', @@ -71,6 +77,7 @@ export interface FileRoutesByFullPath { 71 77 '/reset-password': typeof ResetPasswordRoute 72 78 '/signup': typeof SignupRoute 73 79 '/admin': typeof LayoutAdminRoute 80 ○+ '/insights': typeof LayoutInsightsRoute 74 81 '/items': typeof LayoutItemsRoute 75 82 '/settings': typeof LayoutSettingsRoute 76 83 } @@ -80,6 +87,7 @@ export interface FileRoutesByTo { 80 87 '/reset-password': typeof ResetPasswordRoute 81 88 '/signup': typeof SignupRoute 82 89 '/admin': typeof LayoutAdminRoute 90 ○+ '/insights': typeof LayoutInsightsRoute 83 91 '/items': typeof LayoutItemsRoute 84 92 '/settings': typeof LayoutSettingsRoute 85 93 '/': typeof LayoutIndexRoute @@ -92,6 +100,7 @@ export interface FileRoutesById { 92 100 '/reset-password': typeof ResetPasswordRoute 93 101 '/signup': typeof SignupRoute 94 102 '/_layout/admin': typeof LayoutAdminRoute 103 ○+ '/_layout/insights': typeof LayoutInsightsRoute 95 104 '/_layout/items': typeof LayoutItemsRoute 96 105 '/_layout/settings': typeof LayoutSettingsRoute 97 106 '/_layout/': typeof LayoutIndexRoute @@ -105,6 +114,7 @@ export interface FileRouteTypes { 105 114 | '/reset-password' 106 115 | '/signup' 107 116 | '/admin' 117 ○+ | '/insights' 108 118 | '/items' 109 119 | '/settings' 110 120 fileRoutesByTo: FileRoutesByTo @@ -114,6 +124,7 @@ export interface FileRouteTypes { 114 124 | '/reset-password' 115 125 | '/signup' 116 126 | '/admin' 127 ○+ | '/insights' 117 128 | '/items' 118 129 | '/settings' 119 130 | '/' @@ -125,6 +136,7 @@ export interface FileRouteTypes { 125 136 | '/reset-password' 126 137 | '/signup' 127 138 | '/_layout/admin' 139 ○+ | '/_layout/insights' 128 140 | '/_layout/items' 129 141 | '/_layout/settings' 130 142 | '/_layout/' @@ -189,6 +201,13 @@ declare module '@tanstack/react-router' { 189 201 preLoaderRoute: typeof LayoutAdminRouteImport 190 202 parentRoute: typeof LayoutRoute 191 203 } 204 ○+ '/_layout/insights': { 205 ○+ id: '/_layout/insights' 206 ○+ path: '/insights' 207 ○+ fullPath: '/insights' 208 ○+ preLoaderRoute: typeof LayoutInsightsRouteImport 209 ○+ parentRoute: typeof LayoutRoute 210 ○+ } 192 211 '/_layout/items': { 193 212 id: '/_layout/items' 194 213 path: '/items' @@ -208,6 +227,7 @@ declare module '@tanstack/react-router' { 208 227 209 228 interface LayoutRouteChildren { 210 229 LayoutAdminRoute: typeof LayoutAdminRoute 230 ○+ LayoutInsightsRoute: typeof LayoutInsightsRoute 211 231 LayoutItemsRoute: typeof LayoutItemsRoute 212 232 LayoutSettingsRoute: typeof LayoutSettingsRoute 213 233 LayoutIndexRoute: typeof LayoutIndexRoute @@ -215,6 +235,7 @@ interface LayoutRouteChildren { 215 235 216 236 const LayoutRouteChildren: LayoutRouteChildren = { 217 237 LayoutAdminRoute: LayoutAdminRoute, 238 ○+ LayoutInsightsRoute: LayoutInsightsRoute, 218 239 LayoutItemsRoute: LayoutItemsRoute, 219 240 LayoutSettingsRoute: LayoutSettingsRoute, 220 241 LayoutIndexRoute: LayoutIndexRoute,
Then skim: 5 low-risk code files
-
client/index.ts additiveadditive change: nothing that existed changed8/8 pages✍ Yurii Motov 75%declarations only2
Show diff (+1 −1)
@@ -1,4 +1,4 @@ 1 1 // This file is auto-generated by @hey-api/openapi-ts 2 2 3 3 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'; -
client/sdk.gen.ts additiveadditive change: nothing that existed changed✍ Yurii Motov 70%0% covered2
Show diff (+15 −1)
@@ -2,7 +2,7 @@ 2 2 3 3 import { type Client, type Options as Options2, type TDataShape, urlSearchParamsBodySerializer } from './client'; 4 4 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'; 6 6 7 7 export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown> = Options2<TData, ThrowOnError, TResponse> & { 8 8 /** @@ -299,6 +299,20 @@ export class ItemsService { 299 299 }); 300 300 } 301 301 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 ○+ 302 316 /** 303 317 * Create Item 304 318 * -
new code not used by existing pages✍ Alejandra 96%0% covered2
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 ○+} -
new code not used by existing pages✍ Alejandra 77%0% covered2
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 ○+}) -
client/types.gen.ts modified✍ Yurii Motov 81%0% covered0
Show diff (+50 −2)
@@ -82,6 +82,33 @@ export type ItemPublic = { 82 82 * Created At 83 83 */ 84 84 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>; 85 112 }; 86 113 87 114 /** @@ -96,6 +123,7 @@ export type ItemUpdate = { 96 123 * Description 97 124 */ 98 125 description?: string | null; 126 ○+ status?: ItemStatus | null; 99 127 }; 100 128 101 129 /** @@ -107,9 +135,9 @@ export type ItemsPublic = { 107 135 */ 108 136 data: Array<ItemPublic>; 109 137 /** 110 - * Count 138 ○+ * Total 111 139 */ 112 - count: number; 140 ○+ total: number; 113 141 }; 114 142 115 143 /** @@ -784,6 +812,10 @@ export type itemsReadItemsData = { 784 812 * Limit 785 813 */ 786 814 limit?: number; 815 ○+ /** 816 ○+ * Status 817 ○+ */ 818 ○+ status?: ItemStatus | null; 787 819 }; 788 820 url: '/api/v1/items/'; 789 821 }; @@ -945,3 +977,19 @@ export type privateCreateUserResponses = { 945 977 }; 946 978 947 979 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.
Key findings — open one for its files and details
high1 package manifest changed beyond dependencies · 1 file
fields changed: scriptshighDiff coverage of 25.0% in the files present in the report · 6 files
75 changed executable lines not covered in 6 files.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).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.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).medium1 new file already used by existing pages · 1 file
New code that existing pages already run.low2 non-critical dependency changes · 1 file
Patch/minor bumps, range-only changes or new packages: @vitest/coverage-v8 added, vitest added.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.
| File | Change | Reach (existing pages) | Diff coverage | Findings | Risk points | Why |
|---|---|---|---|---|---|---|
| components/Sidebar/AppSidebar.tsx | modified | high 4 / 8 | 0% | 35 | used by 4 of 8 existing pages | |
| components/Common/DataTable.tsx | modified | medium 2 / 8 | 0% | 17 | used by 2 of 8 existing pages | |
| components/Items/columns.tsx | modified | medium 1 / 8 | 0% | 12 | used by 1 of 8 existing pages | |
| routes/_layout/items.tsx | modified | medium 1 / 8 | 0% | 12 | used by 1 of 8 existing pages | |
| lib/items.ts | added | medium 1 / 8 | 93% | 5 | new code already used by 1 existing page | |
| routeTree.gen.ts | modified | low 0 / 8 | 0% | 1 suppression | 5 | 1 file(s) depend on it, no page reaches it |
| client/index.ts | additive | low 8 / 8 | — | 2 | additive change: nothing that existed changed | |
| client/sdk.gen.ts | additive | low 0 / 8 | 0% | 2 | additive change: nothing that existed changed | |
| routes/_layout/insights.tsx | added | low 0 / 8 | 0% | 2 | new code not used by existing pages | |
| frontend/vitest.config.ts | added | low 0 / 8 | 0% | 2 | new code not used by existing pages | |
| frontend/README.md | modified | low 0 / 8 | — | 0 | nothing 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.
Manifest changes beyond dependencies
| Manifest | Change | |
|---|---|---|
| frontend/package.json | fields changed: scripts | critical |
Package changes
| Package | Manifest | Section | Change | From | To | Bump | |
|---|---|---|---|---|---|---|---|
@vitest/coverage-v8 | frontend/package.json | devDependencies | added | | 3.2.4 | not critical | |
vitest | frontend/package.json | devDependencies | added | | 3.2.4 | not critical |
Changed lockfiles
Coverage
Diff coverage
Files present in the report only: 25.0% (25 / 100).
| File | Changed executable lines | Covered | Uncovered ranges |
|---|---|---|---|
| routes/_layout/insights.tsx | 56 | 0 | 1–3, 5–8, 15–24, 26–31, 33–52, 54, 56–66, 68 |
| components/Items/columns.tsx | 10 | 0 | 6, 9, 50–56, 58 |
| components/Common/DataTable.tsx | 4 | 0 | 51, 119–121 |
| components/Sidebar/AppSidebar.tsx | 2 | 0 | 1, 18 |
| lib/items.ts | 27 | 25 | 33–34 |
| routes/_layout/items.tsx | 1 | 0 | 46 |
| client/types.gen.ts missing from the report | 50 | 0 | 85–111, 126, 138, 140, 815–818, 980–995 |
| frontend/vitest.config.ts missing from the report | 23 | 0 | 1–23 |
| routeTree.gen.ts missing from the report | 21 | 0 | 19, 57–61, 80, 90, 103, 117, 127, 139, 204–210, 230, 238 |
| client/sdk.gen.ts missing from the report | 15 | 0 | 5, 302–315 |
Lint on changed lines
Not verified no ESLint report given (--eslint or signals.eslint)
Added suppressions
| Location | Kind | Line |
|---|---|---|
| routeTree.gen.ts:61 | as-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.
- Alejandrawrote 87% of the changed codeAppSidebar.tsx 100%DataTable.tsx 77%columns.tsx 95%
- Yurii Motovwrote 9% of the changed codeDataTable.tsx 23%index.ts 75%sdk.gen.ts 70%
- Patrick Arminiowrote 4% of the changed codeitems.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)
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)
| File | Status | + | − | Additive rule |
|---|---|---|---|---|
| frontend/package.json | modified | 4 | 0 |
Lockfiles (1)
| File | Status | + | − | Additive rule |
|---|---|---|---|---|
| bun.lock | modified | 242 | 2 |
Source (11)
| File | Status | + | − | Additive rule |
|---|---|---|---|---|
| frontend/README.md | modified | 16 | 0 | |
| client/sdk.gen.ts | modified | 15 | 1 | additive |
| client/types.gen.ts | modified | 50 | 2 | |
| components/Common/DataTable.tsx | modified | 6 | 1 | not additive |
| components/Items/columns.tsx | modified | 11 | 0 | not additive |
| components/Sidebar/AppSidebar.tsx | modified | 2 | 1 | not additive |
| lib/items.ts | added | 36 | 0 | |
| routeTree.gen.ts | modified | 21 | 0 | not additive |
| routes/_layout/insights.tsx | added | 68 | 0 | |
| routes/_layout/items.tsx | modified | 1 | 1 | not additive |
| frontend/vitest.config.ts | added | 23 | 0 |
Barrels (1)
| File | Status | + | − | Additive rule |
|---|---|---|---|---|
| client/index.ts | modified | 1 | 1 | additive |
Tests (1)
| File | Status | + | − | Additive rule |
|---|---|---|---|---|
| lib/items.test.ts | added | 26 | 0 |
Excluded (6)
| File | Status | + | − | Additive rule |
|---|---|---|---|---|
| backend/README.md | modified | 5 | 0 | |
| backend/app/alembic/versions/3c9e1f2b7a41_add_status_to_item.py | added | 28 | 0 | |
| backend/app/api/routes/items.py | modified | 41 | 26 | |
| backend/app/models.py | modified | 19 | 1 | |
| backend/docs/item-status.md | added | 21 | 0 | |
| backend/tests/api/routes/test_items.py | modified | 22 | 0 |
Details
All reasons (23)
| Reason | File | Detail |
|---|---|---|
package manifest changed beyond dependenciesmanifest-changed | frontend/package.json | fields changed: scripts |
existing file modifiedexisting-file-modified | components/Common/DataTable.tsx | func frontend/src/components/Common/DataTable.tsx#DataTable changed: reached by 2 existing route(s): /_layout/admin; /_layout/items |
existing file modifiedexisting-file-modified | components/Items/columns.tsx | var frontend/src/components/Items/columns.tsx#columns changed: reached by 1 existing route(s): /_layout/items |
existing file modifiedexisting-file-modified | components/Sidebar/AppSidebar.tsx | var frontend/src/components/Sidebar/AppSidebar.tsx#baseItems changed: reached by 4 existing route(s): /_layout/; /_layout/admin; /_layout/items; and 1 more |
existing file modifiedexisting-file-modified | routes/_layout/items.tsx | func frontend/src/routes/_layout/items.tsx#ItemsTableContent changed: reached by 1 existing route(s): /_layout/items |
existing file modified, no route reaches itexisting-file-unreachable | frontend/README.md | modified, and it is not part of the import graph |
existing file modified, no route reaches itexisting-file-unreachable | routeTree.gen.ts | var 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 routenew-file-reached-by-existing-route | lib/items.ts | reached by 1 existing route(s): /_layout/items |
types-only file changed (erased at runtime)type-only-change | client/types.gen.ts | the file only declares types in both versions: nothing changes at runtime |
only new declarations, comments or formatting (Go)declarations-additive | client/sdk.gen.ts | only 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.json | vitest added 3.2.4 (devDependencies) |
lockfile changed with the manifestslockfile-changed | bun.lock | lockfile modified together with dependency changes |
new routeroute-added | routes/_layout/insights.tsx | /insights (/_layout/insights) renders frontend/src/routes/_layout/insights.tsx |
barrel only gained exportsbarrel-additive | client/index.ts | only new export declarations |
new file used only by new routesnew-file-in-new-route | routes/_layout/insights.tsx | reached only by new route(s): /insights |
new file no route reachesnew-file-disconnected | frontend/vitest.config.ts | new file that no route reaches |
file outside the projectoutside-project | backend/README.md | outside the project directory and not imported by the project |
file outside the projectoutside-project | backend/app/alembic/versions/3c9e1f2b7a41_add_status_to_item.py | outside the project directory and not imported by the project |
file outside the projectoutside-project | backend/app/api/routes/items.py | outside the project directory and not imported by the project |
file outside the projectoutside-project | backend/app/models.py | outside the project directory and not imported by the project |
file outside the projectoutside-project | backend/docs/item-status.md | outside the project directory and not imported by the project |
file outside the projectoutside-project | backend/tests/api/routes/test_items.py | outside the project directory and not imported by the project |
Diagnostics
Routes farol cannot read (0)
None.
Unresolved imports (4)
| Location | Import | Reason |
|---|---|---|
| components/Common/Logo.tsx:5 | /assets/images/fastapi-icon.svg | not-found |
| components/Common/Logo.tsx:6 | /assets/images/fastapi-icon-light.svg | not-found |
| components/Common/Logo.tsx:7 | /assets/images/fastapi-logo.svg | not-found |
| components/Common/Logo.tsx:8 | /assets/images/fastapi-logo-light.svg | not-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.