diff --git a/.claude/settings.json b/.claude/settings.json index 17e7b3e..2f1e3fc 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -17,7 +17,19 @@ "Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\('Scripts:', d.get\\('scripts',{}\\)\\); print\\('Deps:', list\\(d.get\\('dependencies',{}\\).keys\\(\\)\\)\\)\")", "Bash(podman-compose down *)", "Bash(podman-compose up *)", - "Bash(podman logs *)" + "Bash(podman logs *)", + "Bash(apt-cache show *)", + "Bash(dpkg -l)", + "Bash(REACT_NATIVE_DEVTOOLS=false npx expo start)", + "Bash(REACT_NATIVE_DEVTOOLS=false npx expo start --port 8082)", + "Read(//home/dev/.cache/dotslash/cb/2a59c5919ce27ef30b55119edf89e556e015ef/React Native DevTools-linux-x64/**)", + "Bash(perl -i -0pe 's/ try \\\\{/ try {\\\\n const db = await dbPromise;/g' /home/dev/projetos/toptran/toptran-app/src/services/db.ts)", + "Bash(python3 -c \"import reportlab\")", + "Bash(python3 -c \"import weasyprint\")", + "Read(//usr/bin/**)", + "Bash(chromium --headless --disable-gpu --no-sandbox --print-to-pdf=proposta-toptran.pdf --no-pdf-header-footer file:///home/dev/projetos/toptran/proposta-toptran.html)", + "Bash(npx tsc *)", + "Bash(echo \"exit=$?\")" ] } } diff --git a/README.md b/README.md index 8cca035..b9e2d29 100644 --- a/README.md +++ b/README.md @@ -100,17 +100,20 @@ model companies { } model rides { - id String @id - user_id String - company String - km Decimal @db.Decimal(10, 2) - cost_per_km Decimal @db.Decimal(10, 2) - total Decimal @db.Decimal(10, 2) - ride_date String - synced Int? @default(0) @db.SmallInt - createdAt DateTime? @default(now()) @db.Timestamptz(6) - updatedAt DateTime? @default(now()) @db.Timestamptz(6) - users users @relation(fields: [user_id], references: [id], onDelete: Cascade) + id String @id + user_id String + company String + km Decimal @db.Decimal(10, 2) + cost_per_km Decimal @db.Decimal(10, 2) + total Decimal @db.Decimal(10, 2) + ride_date String + departures Int? @default(0) + failed_service Int? @default(0) + idle_hours Decimal? @default(0) @db.Decimal(10, 2) + synced Int? @default(0) @db.SmallInt + createdAt DateTime? @default(now()) @db.Timestamptz(6) + updatedAt DateTime? @default(now()) @db.Timestamptz(6) + users users @relation(fields: [user_id], references: [id], onDelete: Cascade) } enum TokenType { @@ -120,21 +123,32 @@ enum TokenType { ### Variáveis de ambiente -Crie o arquivo `backend/.env` com as variáveis abaixo: +O backend trabalha com **dois bancos** — um de homologação (`toptrandev`) e um de produção (`toptranprod`) — e dois arquivos `.env` separados: + +| Arquivo | Banco | Porta | +|---|---|---| +| `backend/.env.development` | `toptrandev` | `4000` | +| `backend/.env.production` | `toptranprod` | `5000` | + +Modelo do `.env.development`: ```env -DB_USER=postgres -DB_PASSWORD=postgres -DB_HOST=localhost +DATABASE_URL=postgresql://USER:PASS@HOST:5432/toptrandev +DB_USER=... +DB_PASSWORD=... +DB_HOST=... DB_PORT=5432 -DB_NAME=toptran - -DATABASE_URL="postgresql://postgres:postgres@localhost:5432/toptran" +DB_NAME=toptrandev PORT=4000 -JWT_SECRET=sua_chave_secreta_aqui +NODE_ENV=development + +JWT_SECRET=... +JWT_REFRESH_SECRET=... ``` +Modelo do `.env.production`: idêntico, trocando `DB_NAME=toptranprod`, `PORT=5000` e `NODE_ENV=production`. + > `JWT_SECRET` é obrigatório em produção. O access token expira em **15 minutos** e o refresh token em **7 dias**. ### Instalação e execução @@ -148,15 +162,28 @@ npm install # Gerar cliente Prisma npx prisma generate -# Rodar migrations -npx prisma migrate deploy - -# Iniciar em modo desenvolvimento +# Rodar a API apontando pro banco de homologação (toptrandev) npm run dev -# Build de produção +# Rodar a API apontando pro banco de produção (toptranprod) +npm run dev:prod + +# Build + start em produção npm run build -npm start +npm start # usa .env.production por padrão +npm run start:dev # caso queira o build rodando contra o banco de dev +``` + +**Migrations e Prisma CLI por ambiente** (via `dotenv-cli`): + +```bash +# Homologação +npm run prisma:dev migrate dev +npm run prisma:dev studio + +# Produção +npm run prisma:prod migrate deploy +npm run prisma:prod studio ``` ### API Reference @@ -365,7 +392,19 @@ Retorna todas as corridas cadastradas no servidor. { "success": true, "data": [ - { "id": "uuid", "user_id": "uuid", "company": "Empresa X", "km": "12.5", "total": "31.25", ... } + { + "id": "uuid", + "user_id": "uuid", + "company": "Empresa X", + "km": "12.5", + "cost_per_km": "2.50", + "total": "31.25", + "ride_date": "2026-05-01", + "departures": 3, + "failed_service": 1, + "idle_hours": "1.50", + "synced": 1 + } ] } ``` @@ -374,13 +413,24 @@ Retorna todas as corridas cadastradas no servidor. **POST `/sync/rides`** -Sincroniza (upsert) uma lista de corridas no servidor. +Sincroniza (upsert) uma lista de corridas no servidor. Os campos `departures`, `failed_service` e `idle_hours` são opcionais e assumem `0` por padrão. ```json // Request body { "rides": [ - { "id": "uuid", "user_id": "uuid", "company": "Empresa X", "km": 12.5, "cost_per_km": 2.50, "total": 31.25, "ride_date": "2026-05-01" } + { + "id": "uuid", + "user_id": "uuid", + "company": "Empresa X", + "km": 12.5, + "cost_per_km": 2.50, + "total": 31.25, + "ride_date": "2026-05-01", + "departures": 3, + "failed_service": 1, + "idle_hours": 1.5 + } ] } @@ -392,6 +442,22 @@ Sincroniza (upsert) uma lista de corridas no servidor. } ``` +**Campos da corrida:** + +| Campo | Tipo | Descrição | +|---|---|---| +| `id` | string | Identificador único da corrida | +| `user_id` | string | ID do usuário dono da corrida | +| `company` | string | Nome da empresa | +| `km` | number\|string | Quilômetros rodados | +| `cost_per_km` | number\|string | Custo por km no momento da corrida | +| `total` | number\|string | Valor total da corrida | +| `ride_date` | string | Data da corrida (formato `YYYY-MM-DD`) | +| `departures` | number? | Quantidade de partidas/saídas (default `0`) | +| `failed_service` | number? | Quantidade de serviços não realizados (default `0`) | +| `idle_hours` | number\|string? | Horas ociosas, com 2 casas decimais (default `0`) | +| `synced` | number? | Flag de sincronização (`0` ou `1`) | + --- #### Respostas de erro @@ -507,6 +573,34 @@ A tela `/sincronizar` executa três etapas em sequência com feedback visual em 2. **Download de empresas** — baixa empresas do servidor se o cadastro local estiver vazio 3. **Upload de corridas** — compara IDs locais com os do servidor e envia apenas as corridas ausentes via `POST /sync/rides` +### Ambientes (dev / prod) + +O app não conversa direto com o PostgreSQL — ele consome a API do backend. Alternar de banco no app significa apontar pra um backend diferente via `EXPO_PUBLIC_API_URL`. + +| Arquivo | API | Banco | +|---|---|---| +| `toptran-app/.env.development` | `http://175.15.15.93:4000/api` | `toptrandev` | +| `toptran-app/.env.production` | `https://toptran.olymp.com.br/api` | `toptranprod` | + +O Expo carrega o arquivo certo automaticamente conforme o modo: + +| Comando | Arquivo carregado | +|---|---| +| `npx expo start` (dev) | `.env.development` | +| `npx expo export` / EAS Build production | `.env.production` | + +> Variáveis `EXPO_PUBLIC_*` são inlined no bundle em build time. Reinicie sempre com `npx expo start -c` após trocar o `.env`. + +#### Perfis EAS + +Configurados em [`toptran-app/eas.json`](toptran-app/eas.json): + +| Perfil | Formato | API/Banco | Comando | Pra quê serve | +|---|---|---|---|---| +| `development` | APK + dev client | dev (`:4000` → `toptrandev`) | `eas build --profile development` | Rodar com `expo start` plugado, hot reload | +| `preview` | APK standalone | prod (`toptranprod`) | `eas build --profile preview` | APK pra testar/distribuir fora da Play | +| `production` | AAB | prod (`toptranprod`) | `eas build --profile production` | Bundle pra Google Play (`eas submit`) | + ### Execução ```bash @@ -515,7 +609,7 @@ cd toptran-app # Instalar dependências npm install -# Iniciar o servidor Expo +# Iniciar o servidor Expo (carrega .env.development → backend dev) npm start # Build e abrir no Android @@ -528,8 +622,8 @@ npm run ios ### Conectar ao dispositivo Android via AVD na VM 1. Ligue o dispositivo Android (AVD) -2. Rodar o comando - ```bash +2. Rodar o comando + ```bash adb tcpip 5555 ``` 3. No terminal local, crie o túnel SSH reverso: diff --git a/backend/[teste.env] b/backend/[teste.env] new file mode 100644 index 0000000..bebc774 --- /dev/null +++ b/backend/[teste.env] @@ -0,0 +1,11 @@ +DB_USER=toptranadm +DB_PASSWORD=ft7zJdVNk8FivQUk +DB_HOST=175.15.15.90 +DB_PORT=5432 +DB_NAME=toptrandev + +DATABASE_URL="postgresql://toptranadm:ft7zJdVNk8FivQUk@175.15.15.90:5432/toptrandev" + +PORT=4000 + +JWT_SECRET=iDgji2sbBKqmPerRHnQXFK0iHwmfNTNb5zreuetUecD diff --git a/backend/package-lock.json b/backend/package-lock.json index 46e104c..0235997 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -26,6 +26,7 @@ "@types/jsonwebtoken": "^9.0.10", "@types/node": "^25.6.0", "dotenv": "^17.4.2", + "dotenv-cli": "^11.0.0", "prisma": "^7.8.0", "ts-node-dev": "^2.0.0", "tsx": "^4.21.0" @@ -1627,6 +1628,51 @@ "url": "https://dotenvx.com" } }, + "node_modules/dotenv-cli": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-11.0.0.tgz", + "integrity": "sha512-r5pA8idbk7GFWuHEU7trSTflWcdBpQEK+Aw17UrSHjS6CReuhrrPcyC3zcQBPQvhArRHnBo/h6eLH1fkCvNlww==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.6", + "dotenv": "^17.1.0", + "dotenv-expand": "^12.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "dotenv": "cli.js" + } + }, + "node_modules/dotenv-expand": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.3.tgz", + "integrity": "sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", diff --git a/backend/package.json b/backend/package.json index 4c0f08a..b5459e2 100644 --- a/backend/package.json +++ b/backend/package.json @@ -4,10 +4,14 @@ "description": "", "main": "index.js", "scripts": { - "dev": "tsx watch src/server.ts", + "dev": "tsx watch --env-file=.env.development src/server.ts", + "dev:prod": "tsx watch --env-file=.env.production src/server.ts", "build": "tsc", - "start": "node dist/server.js", - "typecheck": "tsc --noEmit" + "start": "node --env-file=.env.production dist/server.js", + "start:dev": "node --env-file=.env.development dist/server.js", + "typecheck": "tsc --noEmit", + "prisma:dev": "dotenv -e env.development -- prisma migrate dev", + "prisma:prod": "dotenv -e env.production -- prisma migrate deploy" }, "keywords": [], "author": "Rayan", @@ -20,6 +24,7 @@ "@types/jsonwebtoken": "^9.0.10", "@types/node": "^25.6.0", "dotenv": "^17.4.2", + "dotenv-cli": "^11.0.0", "prisma": "^7.8.0", "ts-node-dev": "^2.0.0", "tsx": "^4.21.0" diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index e0a9527..647d7f0 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -33,28 +33,34 @@ model users { } model companies { - id String @id - name String - cost_per_km Decimal @db.Decimal(10, 2) - notes String? @default("") - createdAt DateTime? @default(now()) @db.Timestamptz(6) - updatedAt DateTime? @default(now()) @db.Timestamptz(6) + id String @id + name String + cost_per_km Decimal @db.Decimal(10, 2) + departures Int? @default(0) + failed_service Int? @default(0) + idle_hours Decimal @default(0.0) @db.Decimal(10, 2) + notes String? @default("") + createdAt DateTime? @default(now()) @db.Timestamptz(6) + updatedAt DateTime? @default(now()) @db.Timestamptz(6) @@index([name], map: "idx_companies_name") } model rides { - id String @id - user_id String - company String - km Decimal @db.Decimal(10, 2) - cost_per_km Decimal @db.Decimal(10, 2) - total Decimal @db.Decimal(10, 2) - ride_date String - synced Int? @default(0) @db.SmallInt - createdAt DateTime? @default(now()) @db.Timestamptz(6) - updatedAt DateTime? @default(now()) @db.Timestamptz(6) - users users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction) + id String @id + user_id String + company String + km Decimal @db.Decimal(10, 2) + cost_per_km Decimal @db.Decimal(10, 2) + total Decimal @db.Decimal(10, 2) + ride_date String + departures Int? @default(0) + failed_service Int? @default(0) + idle_hours Decimal? @default(0) @db.Decimal(10, 2) + synced Int? @default(0) @db.SmallInt + createdAt DateTime? @default(now()) @db.Timestamptz(6) + updatedAt DateTime? @default(now()) @db.Timestamptz(6) + users users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction) @@index([synced], map: "idx_rides_synced") @@index([user_id], map: "idx_rides_user_id") diff --git a/backend/src/generated/prisma/commonInputTypes.ts b/backend/src/generated/prisma/commonInputTypes.ts index 2f567c9..5930639 100644 --- a/backend/src/generated/prisma/commonInputTypes.ts +++ b/backend/src/generated/prisma/commonInputTypes.ts @@ -138,6 +138,17 @@ export type DecimalFilter<$PrismaModel = never> = { not?: Prisma.NestedDecimalFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string } +export type IntNullableFilter<$PrismaModel = never> = { + equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null + in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null + notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null + lt?: number | Prisma.IntFieldRefInput<$PrismaModel> + lte?: number | Prisma.IntFieldRefInput<$PrismaModel> + gt?: number | Prisma.IntFieldRefInput<$PrismaModel> + gte?: number | Prisma.IntFieldRefInput<$PrismaModel> + not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null +} + export type DateTimeNullableFilter<$PrismaModel = never> = { equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null @@ -165,31 +176,6 @@ export type DecimalWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedDecimalFilter<$PrismaModel> } -export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = { - equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null - in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null - notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null - lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> - lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> - gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> - gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> - not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null - _count?: Prisma.NestedIntNullableFilter<$PrismaModel> - _min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> - _max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> -} - -export type IntNullableFilter<$PrismaModel = never> = { - equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null - in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null - notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null - lt?: number | Prisma.IntFieldRefInput<$PrismaModel> - lte?: number | Prisma.IntFieldRefInput<$PrismaModel> - gt?: number | Prisma.IntFieldRefInput<$PrismaModel> - gte?: number | Prisma.IntFieldRefInput<$PrismaModel> - not?: Prisma.NestedIntNullableFilter<$PrismaModel> | number | null -} - export type IntNullableWithAggregatesFilter<$PrismaModel = never> = { equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null @@ -206,6 +192,47 @@ export type IntNullableWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedIntNullableFilter<$PrismaModel> } +export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null + in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null + notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null + lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> + lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> + gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> + gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> + not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> + _max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> +} + +export type DecimalNullableFilter<$PrismaModel = never> = { + equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null + in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + not?: Prisma.NestedDecimalNullableFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null +} + +export type DecimalNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null + in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + not?: Prisma.NestedDecimalNullableWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _avg?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _sum?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _min?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _max?: Prisma.NestedDecimalNullableFilter<$PrismaModel> +} + export type NestedStringFilter<$PrismaModel = never> = { equals?: string | Prisma.StringFieldRefInput<$PrismaModel> in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> @@ -370,20 +397,6 @@ export type NestedDecimalWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedDecimalFilter<$PrismaModel> } -export type NestedDateTimeNullableWithAggregatesFilter<$PrismaModel = never> = { - equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null - in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null - notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null - lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> - lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> - gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> - gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> - not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null - _count?: Prisma.NestedIntNullableFilter<$PrismaModel> - _min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> - _max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> -} - export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = { equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null @@ -411,4 +424,45 @@ export type NestedFloatNullableFilter<$PrismaModel = never> = { not?: Prisma.NestedFloatNullableFilter<$PrismaModel> | number | null } +export type NestedDateTimeNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null + in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null + notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null + lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> + lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> + gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> + gte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> + not?: Prisma.NestedDateTimeNullableWithAggregatesFilter<$PrismaModel> | Date | string | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _min?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> + _max?: Prisma.NestedDateTimeNullableFilter<$PrismaModel> +} + +export type NestedDecimalNullableFilter<$PrismaModel = never> = { + equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null + in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + not?: Prisma.NestedDecimalNullableFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null +} + +export type NestedDecimalNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> | null + in?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + notIn?: runtime.Decimal[] | runtime.DecimalJsLike[] | number[] | string[] | Prisma.ListDecimalFieldRefInput<$PrismaModel> | null + lt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + lte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gt?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + gte?: runtime.Decimal | runtime.DecimalJsLike | number | string | Prisma.DecimalFieldRefInput<$PrismaModel> + not?: Prisma.NestedDecimalNullableWithAggregatesFilter<$PrismaModel> | runtime.Decimal | runtime.DecimalJsLike | number | string | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _avg?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _sum?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _min?: Prisma.NestedDecimalNullableFilter<$PrismaModel> + _max?: Prisma.NestedDecimalNullableFilter<$PrismaModel> +} + diff --git a/backend/src/generated/prisma/internal/class.ts b/backend/src/generated/prisma/internal/class.ts index 9465508..f55d637 100644 --- a/backend/src/generated/prisma/internal/class.ts +++ b/backend/src/generated/prisma/internal/class.ts @@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = { "clientVersion": "7.8.0", "engineVersion": "3c6e192761c0362d496ed980de936e2f3cebcd3a", "activeProvider": "postgresql", - "inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"../src/generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel tokens {\n id String @id\n token String @unique\n type TokenType\n userId String\n expiresAt DateTime\n createdAt DateTime @default(now())\n users users @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel users {\n id String @id\n name String\n email String @unique\n password String\n profilePhoto String? @default(\"\")\n bio String? @default(\"\")\n createdAt DateTime @default(now())\n updatedAt DateTime\n rides rides[]\n tokens tokens[]\n\n @@index([email], map: \"idx_users_email\")\n}\n\nmodel companies {\n id String @id\n name String\n cost_per_km Decimal @db.Decimal(10, 2)\n notes String? @default(\"\")\n createdAt DateTime? @default(now()) @db.Timestamptz(6)\n updatedAt DateTime? @default(now()) @db.Timestamptz(6)\n\n @@index([name], map: \"idx_companies_name\")\n}\n\nmodel rides {\n id String @id\n user_id String\n company String\n km Decimal @db.Decimal(10, 2)\n cost_per_km Decimal @db.Decimal(10, 2)\n total Decimal @db.Decimal(10, 2)\n ride_date String\n synced Int? @default(0) @db.SmallInt\n createdAt DateTime? @default(now()) @db.Timestamptz(6)\n updatedAt DateTime? @default(now()) @db.Timestamptz(6)\n users users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction)\n\n @@index([synced], map: \"idx_rides_synced\")\n @@index([user_id], map: \"idx_rides_user_id\")\n}\n\nenum TokenType {\n REFRESH\n}\n", + "inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"../src/generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\nmodel tokens {\n id String @id\n token String @unique\n type TokenType\n userId String\n expiresAt DateTime\n createdAt DateTime @default(now())\n users users @relation(fields: [userId], references: [id], onDelete: Cascade)\n}\n\nmodel users {\n id String @id\n name String\n email String @unique\n password String\n profilePhoto String? @default(\"\")\n bio String? @default(\"\")\n createdAt DateTime @default(now())\n updatedAt DateTime\n rides rides[]\n tokens tokens[]\n\n @@index([email], map: \"idx_users_email\")\n}\n\nmodel companies {\n id String @id\n name String\n cost_per_km Decimal @db.Decimal(10, 2)\n departures Int? @default(0)\n failed_service Int? @default(0)\n idle_hours Decimal @default(0.0) @db.Decimal(10, 2)\n notes String? @default(\"\")\n createdAt DateTime? @default(now()) @db.Timestamptz(6)\n updatedAt DateTime? @default(now()) @db.Timestamptz(6)\n\n @@index([name], map: \"idx_companies_name\")\n}\n\nmodel rides {\n id String @id\n user_id String\n company String\n km Decimal @db.Decimal(10, 2)\n cost_per_km Decimal @db.Decimal(10, 2)\n total Decimal @db.Decimal(10, 2)\n ride_date String\n departures Int? @default(0)\n failed_service Int? @default(0)\n idle_hours Decimal? @default(0) @db.Decimal(10, 2)\n synced Int? @default(0) @db.SmallInt\n createdAt DateTime? @default(now()) @db.Timestamptz(6)\n updatedAt DateTime? @default(now()) @db.Timestamptz(6)\n users users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction)\n\n @@index([synced], map: \"idx_rides_synced\")\n @@index([user_id], map: \"idx_rides_user_id\")\n}\n\nenum TokenType {\n REFRESH\n}\n", "runtimeDataModel": { "models": {}, "enums": {}, @@ -32,10 +32,10 @@ const config: runtime.GetPrismaClientConfig = { } } -config.runtimeDataModel = JSON.parse("{\"models\":{\"tokens\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"TokenType\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"users\",\"relationName\":\"tokensTousers\"}],\"dbName\":null},\"users\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profilePhoto\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"rides\",\"kind\":\"object\",\"type\":\"rides\",\"relationName\":\"ridesTousers\"},{\"name\":\"tokens\",\"kind\":\"object\",\"type\":\"tokens\",\"relationName\":\"tokensTousers\"}],\"dbName\":null},\"companies\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cost_per_km\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"notes\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"rides\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user_id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"company\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"km\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"cost_per_km\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"total\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"ride_date\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"synced\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"users\",\"relationName\":\"ridesTousers\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"tokens\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"type\",\"kind\":\"enum\",\"type\":\"TokenType\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"users\",\"relationName\":\"tokensTousers\"}],\"dbName\":null},\"users\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"profilePhoto\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bio\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"rides\",\"kind\":\"object\",\"type\":\"rides\",\"relationName\":\"ridesTousers\"},{\"name\":\"tokens\",\"kind\":\"object\",\"type\":\"tokens\",\"relationName\":\"tokensTousers\"}],\"dbName\":null},\"companies\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"cost_per_km\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"departures\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"failed_service\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"idle_hours\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"notes\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":null},\"rides\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user_id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"company\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"km\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"cost_per_km\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"total\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"ride_date\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"departures\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"failed_service\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"idle_hours\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"synced\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"users\",\"relationName\":\"ridesTousers\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}") config.parameterizationSchema = { - strings: JSON.parse("[\"where\",\"orderBy\",\"cursor\",\"users\",\"rides\",\"tokens\",\"_count\",\"tokens.findUnique\",\"tokens.findUniqueOrThrow\",\"tokens.findFirst\",\"tokens.findFirstOrThrow\",\"tokens.findMany\",\"data\",\"tokens.createOne\",\"tokens.createMany\",\"tokens.createManyAndReturn\",\"tokens.updateOne\",\"tokens.updateMany\",\"tokens.updateManyAndReturn\",\"create\",\"update\",\"tokens.upsertOne\",\"tokens.deleteOne\",\"tokens.deleteMany\",\"having\",\"_min\",\"_max\",\"tokens.groupBy\",\"tokens.aggregate\",\"users.findUnique\",\"users.findUniqueOrThrow\",\"users.findFirst\",\"users.findFirstOrThrow\",\"users.findMany\",\"users.createOne\",\"users.createMany\",\"users.createManyAndReturn\",\"users.updateOne\",\"users.updateMany\",\"users.updateManyAndReturn\",\"users.upsertOne\",\"users.deleteOne\",\"users.deleteMany\",\"users.groupBy\",\"users.aggregate\",\"companies.findUnique\",\"companies.findUniqueOrThrow\",\"companies.findFirst\",\"companies.findFirstOrThrow\",\"companies.findMany\",\"companies.createOne\",\"companies.createMany\",\"companies.createManyAndReturn\",\"companies.updateOne\",\"companies.updateMany\",\"companies.updateManyAndReturn\",\"companies.upsertOne\",\"companies.deleteOne\",\"companies.deleteMany\",\"_avg\",\"_sum\",\"companies.groupBy\",\"companies.aggregate\",\"rides.findUnique\",\"rides.findUniqueOrThrow\",\"rides.findFirst\",\"rides.findFirstOrThrow\",\"rides.findMany\",\"rides.createOne\",\"rides.createMany\",\"rides.createManyAndReturn\",\"rides.updateOne\",\"rides.updateMany\",\"rides.updateManyAndReturn\",\"rides.upsertOne\",\"rides.deleteOne\",\"rides.deleteMany\",\"rides.groupBy\",\"rides.aggregate\",\"AND\",\"OR\",\"NOT\",\"id\",\"user_id\",\"company\",\"km\",\"cost_per_km\",\"total\",\"ride_date\",\"synced\",\"createdAt\",\"updatedAt\",\"equals\",\"in\",\"notIn\",\"lt\",\"lte\",\"gt\",\"gte\",\"not\",\"contains\",\"startsWith\",\"endsWith\",\"name\",\"notes\",\"email\",\"password\",\"profilePhoto\",\"bio\",\"every\",\"some\",\"none\",\"token\",\"TokenType\",\"type\",\"userId\",\"expiresAt\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"createMany\",\"set\",\"disconnect\",\"delete\",\"connect\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"), - graph: "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-ACFWEAB-ACFXEAB-ACFYAQB9ACFZAgCRAQAhWkAAgAEAIVtAAIABACECAAAABQAgDAAAwQEAIAIAAAC_AQAgDAAAwAEAIA1PAAC-AQAwUAAAvwEAEFEAAL4BADBSAQB9ACFTAQB9ACFUAQB9ACFVEAB-ACFWEAB-ACFXEAB-ACFYAQB9ACFZAgCRAQAhWkAAgAEAIVtAAIABACENTwAAvgEAMFAAAL8BABBRAAC-AQAwUgEAfQAhUwEAfQAhVAEAfQAhVRAAfgAhVhAAfgAhVxAAfgAhWAEAfQAhWQIAkQEAIVpAAIABACFbQACAAQAhCVIBAJgBACFUAQCYAQAhVRAAmQEAIVYQAJkBACFXEACZAQAhWAEAmAEAIVkCAJoBACFaQACbAQAhW0AAmwEAIQlSAQCYAQAhVAEAmAEAIVUQAJkBACFWEACZAQAhVxAAmQEAIVgBAJgBACFZAgCaAQAhWkAAmwEAIVtAAJsBACEJUgEAAAABVAEAAAABVRAAAAABVhAAAAABVxAAAAABWAEAAAABWQIAAAABWkAAAAABW0AAAAABBBMAALcBADB3AAC4AQAweQAAugEAIH0AALsBADAEEwAAqgEAMHcAAKsBADB5AACtAQAgfQAArgEAMAAAAAAABRMAAM0BACAUAADQAQAgdwAAzgEAIHgAAM8BACB9AAAhACADEwAAzQEAIHcAAM4BACB9AAAhACAEBAAAxQEAIAUAAMYBACBrAACSAQAgbAAAkgEAIAkEAADDAQAgUgEAAAABWkAAAAABW0AAAAABZwEAAAABaQEAAAABagEAAAABawEAAAABbAEAAAABAgAAACEAIBMAAM0BACADAAAAJAAgEwAAzQEAIBQAANEBACALAAAAJAAgBAAAqAEAIAwAANEBACBSAQCYAQAhWkAApwEAIVtAAKcBACFnAQCYAQAhaQEAmAEAIWoBAJgBACFrAQCjAQAhbAEAowEAIQkEAACoAQAgUgEAmAEAIVpAAKcBACFbQACnAQAhZwEAmAEAIWkBAJgBACFqAQCYAQAhawEAowEAIWwBAKMBACEJUgEAAAABVAEAAAABVRAAAAABVhAAAAABVxAAAAABWAEAAAABWQIAAAABWkAAAAABW0AAAAABBVIBAAAAAVpAAAAAAXABAAAAAXIAAAByAnRAAAAAAQkFAADEAQAgUgEAAAABWkAAAAABW0AAAAABZwEAAAABaQEAAAABagEAAAABawEAAAABbAEAAAABAgAAACEAIBMAANQBACADAAAAJAAgEwAA1AEAIBQAANgBACALAAAAJAAgBQAAqQEAIAwAANgBACBSAQCYAQAhWkAApwEAIVtAAKcBACFnAQCYAQAhaQEAmAEAIWoBAJgBACFrAQCjAQAhbAEAowEAIQkFAACpAQAgUgEAmAEAIVpAAKcBACFbQACnAQAhZwEAmAEAIWkBAJgBACFqAQCYAQAhawEAowEAIWwBAKMBACEBAwACAwQGAwUJAQYABAEDAAICBAoABQsAAAEDAAIBAwACAwYACRkAChoACwAAAAMGAAkZAAoaAAsAAAMGABAZABEaABIAAAADBgAQGQARGgASAAAABQYAGBkAGxoAHDsAGTwAGgAAAAAABQYAGBkAGxoAHDsAGTwAGgEDAAIBAwACBQYAIRkAJBoAJTsAIjwAIwAAAAAABQYAIRkAJBoAJTsAIjwAIwcCAQgMAQkNAQoOAQsPAQ0RAQ4TBQ8UBhAWAREYBRIZBxUaARYbARccBRsfCBwgDB0iAh4jAh8mAiAnAiEoAiIqAiMsBSQtDSUvAiYxBScyDigzAik0Aio1BSs4Dyw5Ey07FC48FC8_FDBAFDFBFDJDFDNFBTRGFTVIFDZKBTdLFjhMFDlNFDpOBT1RFz5SHT9TA0BUA0FVA0JWA0NXA0RZA0VbBUZcHkdeA0hgBUlhH0piA0tjA0xkBU1nIE5oJg" + strings: JSON.parse("[\"where\",\"orderBy\",\"cursor\",\"users\",\"rides\",\"tokens\",\"_count\",\"tokens.findUnique\",\"tokens.findUniqueOrThrow\",\"tokens.findFirst\",\"tokens.findFirstOrThrow\",\"tokens.findMany\",\"data\",\"tokens.createOne\",\"tokens.createMany\",\"tokens.createManyAndReturn\",\"tokens.updateOne\",\"tokens.updateMany\",\"tokens.updateManyAndReturn\",\"create\",\"update\",\"tokens.upsertOne\",\"tokens.deleteOne\",\"tokens.deleteMany\",\"having\",\"_min\",\"_max\",\"tokens.groupBy\",\"tokens.aggregate\",\"users.findUnique\",\"users.findUniqueOrThrow\",\"users.findFirst\",\"users.findFirstOrThrow\",\"users.findMany\",\"users.createOne\",\"users.createMany\",\"users.createManyAndReturn\",\"users.updateOne\",\"users.updateMany\",\"users.updateManyAndReturn\",\"users.upsertOne\",\"users.deleteOne\",\"users.deleteMany\",\"users.groupBy\",\"users.aggregate\",\"companies.findUnique\",\"companies.findUniqueOrThrow\",\"companies.findFirst\",\"companies.findFirstOrThrow\",\"companies.findMany\",\"companies.createOne\",\"companies.createMany\",\"companies.createManyAndReturn\",\"companies.updateOne\",\"companies.updateMany\",\"companies.updateManyAndReturn\",\"companies.upsertOne\",\"companies.deleteOne\",\"companies.deleteMany\",\"_avg\",\"_sum\",\"companies.groupBy\",\"companies.aggregate\",\"rides.findUnique\",\"rides.findUniqueOrThrow\",\"rides.findFirst\",\"rides.findFirstOrThrow\",\"rides.findMany\",\"rides.createOne\",\"rides.createMany\",\"rides.createManyAndReturn\",\"rides.updateOne\",\"rides.updateMany\",\"rides.updateManyAndReturn\",\"rides.upsertOne\",\"rides.deleteOne\",\"rides.deleteMany\",\"rides.groupBy\",\"rides.aggregate\",\"AND\",\"OR\",\"NOT\",\"id\",\"user_id\",\"company\",\"km\",\"cost_per_km\",\"total\",\"ride_date\",\"departures\",\"failed_service\",\"idle_hours\",\"synced\",\"createdAt\",\"updatedAt\",\"equals\",\"in\",\"notIn\",\"lt\",\"lte\",\"gt\",\"gte\",\"not\",\"contains\",\"startsWith\",\"endsWith\",\"name\",\"notes\",\"email\",\"password\",\"profilePhoto\",\"bio\",\"every\",\"some\",\"none\",\"token\",\"TokenType\",\"type\",\"userId\",\"expiresAt\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"createMany\",\"set\",\"disconnect\",\"delete\",\"connect\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"), + graph: "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_ADBQAAA9ABBRAAB_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-ACAaAAB-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-Uh0_UwNAVANBVQNCVgNDVwNEWQNFWwVGXB5HXgNIYAVJYR9KYgNLYwNMZAVNZyBOaCY" } async function decodeBase64AsWasm(wasmBase64: string): Promise { diff --git a/backend/src/generated/prisma/internal/prismaNamespace.ts b/backend/src/generated/prisma/internal/prismaNamespace.ts index ce4e9c4..eb8c73b 100644 --- a/backend/src/generated/prisma/internal/prismaNamespace.ts +++ b/backend/src/generated/prisma/internal/prismaNamespace.ts @@ -772,6 +772,9 @@ export const CompaniesScalarFieldEnum = { id: 'id', name: 'name', cost_per_km: 'cost_per_km', + departures: 'departures', + failed_service: 'failed_service', + idle_hours: 'idle_hours', notes: 'notes', createdAt: 'createdAt', updatedAt: 'updatedAt' @@ -788,6 +791,9 @@ export const RidesScalarFieldEnum = { cost_per_km: 'cost_per_km', total: 'total', ride_date: 'ride_date', + departures: 'departures', + failed_service: 'failed_service', + idle_hours: 'idle_hours', synced: 'synced', createdAt: 'createdAt', updatedAt: 'updatedAt' diff --git a/backend/src/generated/prisma/internal/prismaNamespaceBrowser.ts b/backend/src/generated/prisma/internal/prismaNamespaceBrowser.ts index d72e48a..5f1499e 100644 --- a/backend/src/generated/prisma/internal/prismaNamespaceBrowser.ts +++ b/backend/src/generated/prisma/internal/prismaNamespaceBrowser.ts @@ -103,6 +103,9 @@ export const CompaniesScalarFieldEnum = { id: 'id', name: 'name', cost_per_km: 'cost_per_km', + departures: 'departures', + failed_service: 'failed_service', + idle_hours: 'idle_hours', notes: 'notes', createdAt: 'createdAt', updatedAt: 'updatedAt' @@ -119,6 +122,9 @@ export const RidesScalarFieldEnum = { cost_per_km: 'cost_per_km', total: 'total', ride_date: 'ride_date', + departures: 'departures', + failed_service: 'failed_service', + idle_hours: 'idle_hours', synced: 'synced', createdAt: 'createdAt', updatedAt: 'updatedAt' diff --git a/backend/src/generated/prisma/models/companies.ts b/backend/src/generated/prisma/models/companies.ts index 63a623e..24c359b 100644 --- a/backend/src/generated/prisma/models/companies.ts +++ b/backend/src/generated/prisma/models/companies.ts @@ -28,16 +28,25 @@ export type AggregateCompanies = { export type CompaniesAvgAggregateOutputType = { cost_per_km: runtime.Decimal | null + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal | null } export type CompaniesSumAggregateOutputType = { cost_per_km: runtime.Decimal | null + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal | null } export type CompaniesMinAggregateOutputType = { id: string | null name: string | null cost_per_km: runtime.Decimal | null + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal | null notes: string | null createdAt: Date | null updatedAt: Date | null @@ -47,6 +56,9 @@ export type CompaniesMaxAggregateOutputType = { id: string | null name: string | null cost_per_km: runtime.Decimal | null + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal | null notes: string | null createdAt: Date | null updatedAt: Date | null @@ -56,6 +68,9 @@ export type CompaniesCountAggregateOutputType = { id: number name: number cost_per_km: number + departures: number + failed_service: number + idle_hours: number notes: number createdAt: number updatedAt: number @@ -65,16 +80,25 @@ export type CompaniesCountAggregateOutputType = { export type CompaniesAvgAggregateInputType = { cost_per_km?: true + departures?: true + failed_service?: true + idle_hours?: true } export type CompaniesSumAggregateInputType = { cost_per_km?: true + departures?: true + failed_service?: true + idle_hours?: true } export type CompaniesMinAggregateInputType = { id?: true name?: true cost_per_km?: true + departures?: true + failed_service?: true + idle_hours?: true notes?: true createdAt?: true updatedAt?: true @@ -84,6 +108,9 @@ export type CompaniesMaxAggregateInputType = { id?: true name?: true cost_per_km?: true + departures?: true + failed_service?: true + idle_hours?: true notes?: true createdAt?: true updatedAt?: true @@ -93,6 +120,9 @@ export type CompaniesCountAggregateInputType = { id?: true name?: true cost_per_km?: true + departures?: true + failed_service?: true + idle_hours?: true notes?: true createdAt?: true updatedAt?: true @@ -189,6 +219,9 @@ export type CompaniesGroupByOutputType = { id: string name: string cost_per_km: runtime.Decimal + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal notes: string | null createdAt: Date | null updatedAt: Date | null @@ -221,6 +254,9 @@ export type companiesWhereInput = { id?: Prisma.StringFilter<"companies"> | string name?: Prisma.StringFilter<"companies"> | string cost_per_km?: Prisma.DecimalFilter<"companies"> | runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: Prisma.IntNullableFilter<"companies"> | number | null + failed_service?: Prisma.IntNullableFilter<"companies"> | number | null + idle_hours?: Prisma.DecimalFilter<"companies"> | runtime.Decimal | runtime.DecimalJsLike | number | string notes?: Prisma.StringNullableFilter<"companies"> | string | null createdAt?: Prisma.DateTimeNullableFilter<"companies"> | Date | string | null updatedAt?: Prisma.DateTimeNullableFilter<"companies"> | Date | string | null @@ -230,6 +266,9 @@ export type companiesOrderByWithRelationInput = { id?: Prisma.SortOrder name?: Prisma.SortOrder cost_per_km?: Prisma.SortOrder + departures?: Prisma.SortOrderInput | Prisma.SortOrder + failed_service?: Prisma.SortOrderInput | Prisma.SortOrder + idle_hours?: Prisma.SortOrder notes?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrderInput | Prisma.SortOrder updatedAt?: Prisma.SortOrderInput | Prisma.SortOrder @@ -242,6 +281,9 @@ export type companiesWhereUniqueInput = Prisma.AtLeast<{ NOT?: Prisma.companiesWhereInput | Prisma.companiesWhereInput[] name?: Prisma.StringFilter<"companies"> | string cost_per_km?: Prisma.DecimalFilter<"companies"> | runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: Prisma.IntNullableFilter<"companies"> | number | null + failed_service?: Prisma.IntNullableFilter<"companies"> | number | null + idle_hours?: Prisma.DecimalFilter<"companies"> | runtime.Decimal | runtime.DecimalJsLike | number | string notes?: Prisma.StringNullableFilter<"companies"> | string | null createdAt?: Prisma.DateTimeNullableFilter<"companies"> | Date | string | null updatedAt?: Prisma.DateTimeNullableFilter<"companies"> | Date | string | null @@ -251,6 +293,9 @@ export type companiesOrderByWithAggregationInput = { id?: Prisma.SortOrder name?: Prisma.SortOrder cost_per_km?: Prisma.SortOrder + departures?: Prisma.SortOrderInput | Prisma.SortOrder + failed_service?: Prisma.SortOrderInput | Prisma.SortOrder + idle_hours?: Prisma.SortOrder notes?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrderInput | Prisma.SortOrder updatedAt?: Prisma.SortOrderInput | Prisma.SortOrder @@ -268,6 +313,9 @@ export type companiesScalarWhereWithAggregatesInput = { id?: Prisma.StringWithAggregatesFilter<"companies"> | string name?: Prisma.StringWithAggregatesFilter<"companies"> | string cost_per_km?: Prisma.DecimalWithAggregatesFilter<"companies"> | runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: Prisma.IntNullableWithAggregatesFilter<"companies"> | number | null + failed_service?: Prisma.IntNullableWithAggregatesFilter<"companies"> | number | null + idle_hours?: Prisma.DecimalWithAggregatesFilter<"companies"> | runtime.Decimal | runtime.DecimalJsLike | number | string notes?: Prisma.StringNullableWithAggregatesFilter<"companies"> | string | null createdAt?: Prisma.DateTimeNullableWithAggregatesFilter<"companies"> | Date | string | null updatedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"companies"> | Date | string | null @@ -277,6 +325,9 @@ export type companiesCreateInput = { id: string name: string cost_per_km: runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: number | null + failed_service?: number | null + idle_hours?: runtime.Decimal | runtime.DecimalJsLike | number | string notes?: string | null createdAt?: Date | string | null updatedAt?: Date | string | null @@ -286,6 +337,9 @@ export type companiesUncheckedCreateInput = { id: string name: string cost_per_km: runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: number | null + failed_service?: number | null + idle_hours?: runtime.Decimal | runtime.DecimalJsLike | number | string notes?: string | null createdAt?: Date | string | null updatedAt?: Date | string | null @@ -295,6 +349,9 @@ export type companiesUpdateInput = { id?: Prisma.StringFieldUpdateOperationsInput | string name?: Prisma.StringFieldUpdateOperationsInput | string cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -304,6 +361,9 @@ export type companiesUncheckedUpdateInput = { id?: Prisma.StringFieldUpdateOperationsInput | string name?: Prisma.StringFieldUpdateOperationsInput | string cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -313,6 +373,9 @@ export type companiesCreateManyInput = { id: string name: string cost_per_km: runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: number | null + failed_service?: number | null + idle_hours?: runtime.Decimal | runtime.DecimalJsLike | number | string notes?: string | null createdAt?: Date | string | null updatedAt?: Date | string | null @@ -322,6 +385,9 @@ export type companiesUpdateManyMutationInput = { id?: Prisma.StringFieldUpdateOperationsInput | string name?: Prisma.StringFieldUpdateOperationsInput | string cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -331,6 +397,9 @@ export type companiesUncheckedUpdateManyInput = { id?: Prisma.StringFieldUpdateOperationsInput | string name?: Prisma.StringFieldUpdateOperationsInput | string cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string notes?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -340,6 +409,9 @@ export type companiesCountOrderByAggregateInput = { id?: Prisma.SortOrder name?: Prisma.SortOrder cost_per_km?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder notes?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -347,12 +419,18 @@ export type companiesCountOrderByAggregateInput = { export type companiesAvgOrderByAggregateInput = { cost_per_km?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder } export type companiesMaxOrderByAggregateInput = { id?: Prisma.SortOrder name?: Prisma.SortOrder cost_per_km?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder notes?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -362,6 +440,9 @@ export type companiesMinOrderByAggregateInput = { id?: Prisma.SortOrder name?: Prisma.SortOrder cost_per_km?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder notes?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -369,6 +450,9 @@ export type companiesMinOrderByAggregateInput = { export type companiesSumOrderByAggregateInput = { cost_per_km?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder } export type DecimalFieldUpdateOperationsInput = { @@ -379,6 +463,14 @@ export type DecimalFieldUpdateOperationsInput = { divide?: runtime.Decimal | runtime.DecimalJsLike | number | string } +export type NullableIntFieldUpdateOperationsInput = { + set?: number | null + increment?: number + decrement?: number + multiply?: number + divide?: number +} + export type NullableDateTimeFieldUpdateOperationsInput = { set?: Date | string | null } @@ -389,6 +481,9 @@ export type companiesSelect = runtime.Types.Extensions.GetOmit<"id" | "name" | "cost_per_km" | "notes" | "createdAt" | "updatedAt", ExtArgs["result"]["companies"]> +export type companiesOmit = runtime.Types.Extensions.GetOmit<"id" | "name" | "cost_per_km" | "departures" | "failed_service" | "idle_hours" | "notes" | "createdAt" | "updatedAt", ExtArgs["result"]["companies"]> export type $companiesPayload = { name: "companies" @@ -430,6 +534,9 @@ export type $companiesPayload readonly name: Prisma.FieldRef<"companies", 'String'> readonly cost_per_km: Prisma.FieldRef<"companies", 'Decimal'> + readonly departures: Prisma.FieldRef<"companies", 'Int'> + readonly failed_service: Prisma.FieldRef<"companies", 'Int'> + readonly idle_hours: Prisma.FieldRef<"companies", 'Decimal'> readonly notes: Prisma.FieldRef<"companies", 'String'> readonly createdAt: Prisma.FieldRef<"companies", 'DateTime'> readonly updatedAt: Prisma.FieldRef<"companies", 'DateTime'> diff --git a/backend/src/generated/prisma/models/rides.ts b/backend/src/generated/prisma/models/rides.ts index 18b28f7..8220d11 100644 --- a/backend/src/generated/prisma/models/rides.ts +++ b/backend/src/generated/prisma/models/rides.ts @@ -30,6 +30,9 @@ export type RidesAvgAggregateOutputType = { km: runtime.Decimal | null cost_per_km: runtime.Decimal | null total: runtime.Decimal | null + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal | null synced: number | null } @@ -37,6 +40,9 @@ export type RidesSumAggregateOutputType = { km: runtime.Decimal | null cost_per_km: runtime.Decimal | null total: runtime.Decimal | null + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal | null synced: number | null } @@ -48,6 +54,9 @@ export type RidesMinAggregateOutputType = { cost_per_km: runtime.Decimal | null total: runtime.Decimal | null ride_date: string | null + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal | null synced: number | null createdAt: Date | null updatedAt: Date | null @@ -61,6 +70,9 @@ export type RidesMaxAggregateOutputType = { cost_per_km: runtime.Decimal | null total: runtime.Decimal | null ride_date: string | null + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal | null synced: number | null createdAt: Date | null updatedAt: Date | null @@ -74,6 +86,9 @@ export type RidesCountAggregateOutputType = { cost_per_km: number total: number ride_date: number + departures: number + failed_service: number + idle_hours: number synced: number createdAt: number updatedAt: number @@ -85,6 +100,9 @@ export type RidesAvgAggregateInputType = { km?: true cost_per_km?: true total?: true + departures?: true + failed_service?: true + idle_hours?: true synced?: true } @@ -92,6 +110,9 @@ export type RidesSumAggregateInputType = { km?: true cost_per_km?: true total?: true + departures?: true + failed_service?: true + idle_hours?: true synced?: true } @@ -103,6 +124,9 @@ export type RidesMinAggregateInputType = { cost_per_km?: true total?: true ride_date?: true + departures?: true + failed_service?: true + idle_hours?: true synced?: true createdAt?: true updatedAt?: true @@ -116,6 +140,9 @@ export type RidesMaxAggregateInputType = { cost_per_km?: true total?: true ride_date?: true + departures?: true + failed_service?: true + idle_hours?: true synced?: true createdAt?: true updatedAt?: true @@ -129,6 +156,9 @@ export type RidesCountAggregateInputType = { cost_per_km?: true total?: true ride_date?: true + departures?: true + failed_service?: true + idle_hours?: true synced?: true createdAt?: true updatedAt?: true @@ -229,6 +259,9 @@ export type RidesGroupByOutputType = { cost_per_km: runtime.Decimal total: runtime.Decimal ride_date: string + departures: number | null + failed_service: number | null + idle_hours: runtime.Decimal | null synced: number | null createdAt: Date | null updatedAt: Date | null @@ -265,6 +298,9 @@ export type ridesWhereInput = { cost_per_km?: Prisma.DecimalFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFilter<"rides"> | string + departures?: Prisma.IntNullableFilter<"rides"> | number | null + failed_service?: Prisma.IntNullableFilter<"rides"> | number | null + idle_hours?: Prisma.DecimalNullableFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.IntNullableFilter<"rides"> | number | null createdAt?: Prisma.DateTimeNullableFilter<"rides"> | Date | string | null updatedAt?: Prisma.DateTimeNullableFilter<"rides"> | Date | string | null @@ -279,6 +315,9 @@ export type ridesOrderByWithRelationInput = { cost_per_km?: Prisma.SortOrder total?: Prisma.SortOrder ride_date?: Prisma.SortOrder + departures?: Prisma.SortOrderInput | Prisma.SortOrder + failed_service?: Prisma.SortOrderInput | Prisma.SortOrder + idle_hours?: Prisma.SortOrderInput | Prisma.SortOrder synced?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrderInput | Prisma.SortOrder updatedAt?: Prisma.SortOrderInput | Prisma.SortOrder @@ -296,6 +335,9 @@ export type ridesWhereUniqueInput = Prisma.AtLeast<{ cost_per_km?: Prisma.DecimalFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFilter<"rides"> | string + departures?: Prisma.IntNullableFilter<"rides"> | number | null + failed_service?: Prisma.IntNullableFilter<"rides"> | number | null + idle_hours?: Prisma.DecimalNullableFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.IntNullableFilter<"rides"> | number | null createdAt?: Prisma.DateTimeNullableFilter<"rides"> | Date | string | null updatedAt?: Prisma.DateTimeNullableFilter<"rides"> | Date | string | null @@ -310,6 +352,9 @@ export type ridesOrderByWithAggregationInput = { cost_per_km?: Prisma.SortOrder total?: Prisma.SortOrder ride_date?: Prisma.SortOrder + departures?: Prisma.SortOrderInput | Prisma.SortOrder + failed_service?: Prisma.SortOrderInput | Prisma.SortOrder + idle_hours?: Prisma.SortOrderInput | Prisma.SortOrder synced?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrderInput | Prisma.SortOrder updatedAt?: Prisma.SortOrderInput | Prisma.SortOrder @@ -331,6 +376,9 @@ export type ridesScalarWhereWithAggregatesInput = { cost_per_km?: Prisma.DecimalWithAggregatesFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalWithAggregatesFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringWithAggregatesFilter<"rides"> | string + departures?: Prisma.IntNullableWithAggregatesFilter<"rides"> | number | null + failed_service?: Prisma.IntNullableWithAggregatesFilter<"rides"> | number | null + idle_hours?: Prisma.DecimalNullableWithAggregatesFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.IntNullableWithAggregatesFilter<"rides"> | number | null createdAt?: Prisma.DateTimeNullableWithAggregatesFilter<"rides"> | Date | string | null updatedAt?: Prisma.DateTimeNullableWithAggregatesFilter<"rides"> | Date | string | null @@ -343,6 +391,9 @@ export type ridesCreateInput = { cost_per_km: runtime.Decimal | runtime.DecimalJsLike | number | string total: runtime.Decimal | runtime.DecimalJsLike | number | string ride_date: string + departures?: number | null + failed_service?: number | null + idle_hours?: runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: number | null createdAt?: Date | string | null updatedAt?: Date | string | null @@ -357,6 +408,9 @@ export type ridesUncheckedCreateInput = { cost_per_km: runtime.Decimal | runtime.DecimalJsLike | number | string total: runtime.Decimal | runtime.DecimalJsLike | number | string ride_date: string + departures?: number | null + failed_service?: number | null + idle_hours?: runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: number | null createdAt?: Date | string | null updatedAt?: Date | string | null @@ -369,6 +423,9 @@ export type ridesUpdateInput = { cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFieldUpdateOperationsInput | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.NullableIntFieldUpdateOperationsInput | number | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -383,6 +440,9 @@ export type ridesUncheckedUpdateInput = { cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFieldUpdateOperationsInput | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.NullableIntFieldUpdateOperationsInput | number | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -396,6 +456,9 @@ export type ridesCreateManyInput = { cost_per_km: runtime.Decimal | runtime.DecimalJsLike | number | string total: runtime.Decimal | runtime.DecimalJsLike | number | string ride_date: string + departures?: number | null + failed_service?: number | null + idle_hours?: runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: number | null createdAt?: Date | string | null updatedAt?: Date | string | null @@ -408,6 +471,9 @@ export type ridesUpdateManyMutationInput = { cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFieldUpdateOperationsInput | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.NullableIntFieldUpdateOperationsInput | number | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -421,6 +487,9 @@ export type ridesUncheckedUpdateManyInput = { cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFieldUpdateOperationsInput | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.NullableIntFieldUpdateOperationsInput | number | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -444,6 +513,9 @@ export type ridesCountOrderByAggregateInput = { cost_per_km?: Prisma.SortOrder total?: Prisma.SortOrder ride_date?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder synced?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -453,6 +525,9 @@ export type ridesAvgOrderByAggregateInput = { km?: Prisma.SortOrder cost_per_km?: Prisma.SortOrder total?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder synced?: Prisma.SortOrder } @@ -464,6 +539,9 @@ export type ridesMaxOrderByAggregateInput = { cost_per_km?: Prisma.SortOrder total?: Prisma.SortOrder ride_date?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder synced?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -477,6 +555,9 @@ export type ridesMinOrderByAggregateInput = { cost_per_km?: Prisma.SortOrder total?: Prisma.SortOrder ride_date?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder synced?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder @@ -486,6 +567,9 @@ export type ridesSumOrderByAggregateInput = { km?: Prisma.SortOrder cost_per_km?: Prisma.SortOrder total?: Prisma.SortOrder + departures?: Prisma.SortOrder + failed_service?: Prisma.SortOrder + idle_hours?: Prisma.SortOrder synced?: Prisma.SortOrder } @@ -531,12 +615,12 @@ export type ridesUncheckedUpdateManyWithoutUsersNestedInput = { deleteMany?: Prisma.ridesScalarWhereInput | Prisma.ridesScalarWhereInput[] } -export type NullableIntFieldUpdateOperationsInput = { - set?: number | null - increment?: number - decrement?: number - multiply?: number - divide?: number +export type NullableDecimalFieldUpdateOperationsInput = { + set?: runtime.Decimal | runtime.DecimalJsLike | number | string | null + increment?: runtime.Decimal | runtime.DecimalJsLike | number | string + decrement?: runtime.Decimal | runtime.DecimalJsLike | number | string + multiply?: runtime.Decimal | runtime.DecimalJsLike | number | string + divide?: runtime.Decimal | runtime.DecimalJsLike | number | string } export type ridesCreateWithoutUsersInput = { @@ -546,6 +630,9 @@ export type ridesCreateWithoutUsersInput = { cost_per_km: runtime.Decimal | runtime.DecimalJsLike | number | string total: runtime.Decimal | runtime.DecimalJsLike | number | string ride_date: string + departures?: number | null + failed_service?: number | null + idle_hours?: runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: number | null createdAt?: Date | string | null updatedAt?: Date | string | null @@ -558,6 +645,9 @@ export type ridesUncheckedCreateWithoutUsersInput = { cost_per_km: runtime.Decimal | runtime.DecimalJsLike | number | string total: runtime.Decimal | runtime.DecimalJsLike | number | string ride_date: string + departures?: number | null + failed_service?: number | null + idle_hours?: runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: number | null createdAt?: Date | string | null updatedAt?: Date | string | null @@ -600,6 +690,9 @@ export type ridesScalarWhereInput = { cost_per_km?: Prisma.DecimalFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFilter<"rides"> | string + departures?: Prisma.IntNullableFilter<"rides"> | number | null + failed_service?: Prisma.IntNullableFilter<"rides"> | number | null + idle_hours?: Prisma.DecimalNullableFilter<"rides"> | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.IntNullableFilter<"rides"> | number | null createdAt?: Prisma.DateTimeNullableFilter<"rides"> | Date | string | null updatedAt?: Prisma.DateTimeNullableFilter<"rides"> | Date | string | null @@ -612,6 +705,9 @@ export type ridesCreateManyUsersInput = { cost_per_km: runtime.Decimal | runtime.DecimalJsLike | number | string total: runtime.Decimal | runtime.DecimalJsLike | number | string ride_date: string + departures?: number | null + failed_service?: number | null + idle_hours?: runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: number | null createdAt?: Date | string | null updatedAt?: Date | string | null @@ -624,6 +720,9 @@ export type ridesUpdateWithoutUsersInput = { cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFieldUpdateOperationsInput | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.NullableIntFieldUpdateOperationsInput | number | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -636,6 +735,9 @@ export type ridesUncheckedUpdateWithoutUsersInput = { cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFieldUpdateOperationsInput | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.NullableIntFieldUpdateOperationsInput | number | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -648,6 +750,9 @@ export type ridesUncheckedUpdateManyWithoutUsersInput = { cost_per_km?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string ride_date?: Prisma.StringFieldUpdateOperationsInput | string + departures?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + failed_service?: Prisma.NullableIntFieldUpdateOperationsInput | number | null + idle_hours?: Prisma.NullableDecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string | null synced?: Prisma.NullableIntFieldUpdateOperationsInput | number | null createdAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null updatedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null @@ -663,6 +768,9 @@ export type ridesSelect = runtime.Types.Extensions.GetOmit<"id" | "user_id" | "company" | "km" | "cost_per_km" | "total" | "ride_date" | "synced" | "createdAt" | "updatedAt", ExtArgs["result"]["rides"]> +export type ridesOmit = runtime.Types.Extensions.GetOmit<"id" | "user_id" | "company" | "km" | "cost_per_km" | "total" | "ride_date" | "departures" | "failed_service" | "idle_hours" | "synced" | "createdAt" | "updatedAt", ExtArgs["result"]["rides"]> export type ridesInclude = { users?: boolean | Prisma.usersDefaultArgs } @@ -734,6 +851,9 @@ export type $ridesPayload readonly total: Prisma.FieldRef<"rides", 'Decimal'> readonly ride_date: Prisma.FieldRef<"rides", 'String'> + readonly departures: Prisma.FieldRef<"rides", 'Int'> + readonly failed_service: Prisma.FieldRef<"rides", 'Int'> + readonly idle_hours: Prisma.FieldRef<"rides", 'Decimal'> readonly synced: Prisma.FieldRef<"rides", 'Int'> readonly createdAt: Prisma.FieldRef<"rides", 'DateTime'> readonly updatedAt: Prisma.FieldRef<"rides", 'DateTime'> diff --git a/backend/src/repositories/companies.repository.ts b/backend/src/repositories/companies.repository.ts index 64db4cb..09b4736 100644 --- a/backend/src/repositories/companies.repository.ts +++ b/backend/src/repositories/companies.repository.ts @@ -8,6 +8,9 @@ export async function createCompany(data: { id: string; name: string; cost_per_km: any; + departures?: number; + failed_service?: number; + idle_hours?: any; notes?: string; }) { return prisma.companies.create({ data }); @@ -18,6 +21,9 @@ export async function updateCompany( data: Partial<{ name: string; cost_per_km: any; + departures: number; + failed_service: number; + idle_hours: any; notes: string; }> ) { @@ -36,6 +42,9 @@ export async function upsertCompany(data: { id: string; name: string; cost_per_km: any; + departures?: number; + failed_service?: number; + idle_hours?: any; notes?: string; }) { return prisma.companies.upsert({ @@ -43,6 +52,9 @@ export async function upsertCompany(data: { update: { name: data.name, cost_per_km: data.cost_per_km, + departures: data.departures, + failed_service: data.failed_service, + idle_hours: data.idle_hours, notes: data.notes, }, create: data, diff --git a/backend/src/repositories/rides.repository.ts b/backend/src/repositories/rides.repository.ts index 9cf271e..feb1260 100644 --- a/backend/src/repositories/rides.repository.ts +++ b/backend/src/repositories/rides.repository.ts @@ -12,6 +12,9 @@ export async function createRide(data: { cost_per_km: any; total: any; ride_date: string; + departures?: number; + failed_service?: number; + idle_hours?: any; synced?: number; }) { return prisma.rides.create({ data }); @@ -26,6 +29,9 @@ export async function updateRide( cost_per_km: any; total: any; ride_date: string; + departures: number; + failed_service: number; + idle_hours: any; synced: number; }> ) { @@ -68,6 +74,9 @@ export async function upsertRide(data: { cost_per_km: any; total: any; ride_date: string; + departures?: number; + failed_service?: number; + idle_hours?: any; synced?: number; }) { return prisma.rides.upsert({ @@ -79,6 +88,9 @@ export async function upsertRide(data: { cost_per_km: data.cost_per_km, total: data.total, ride_date: data.ride_date, + departures: data.departures, + failed_service: data.failed_service, + idle_hours: data.idle_hours, synced: data.synced, }, create: data, diff --git a/backend/src/services/sync.service.ts b/backend/src/services/sync.service.ts index b4ecd61..87b777d 100644 --- a/backend/src/services/sync.service.ts +++ b/backend/src/services/sync.service.ts @@ -9,6 +9,9 @@ export const syncCompaniesSchema = z.object({ id: z.string(), name: z.string(), cost_per_km: z.number().or(z.string()), + departures: z.number().optional(), + failed_service: z.number().optional(), + idle_hours: z.number().or(z.string()).optional(), notes: z.string().optional(), }) ), @@ -24,6 +27,9 @@ export const syncRidesSchema = z.object({ cost_per_km: z.number().or(z.string()), total: z.number().or(z.string()), ride_date: z.string(), + departures: z.number().optional(), + failed_service: z.number().optional(), + idle_hours: z.number().or(z.string()).optional(), synced: z.number().optional(), }) ), @@ -38,6 +44,9 @@ export async function syncCompanies( id: company.id, name: company.name, cost_per_km: company.cost_per_km, + departures: company.departures, + failed_service: company.failed_service, + idle_hours: company.idle_hours, notes: company.notes, }); synced.push(result); @@ -58,6 +67,9 @@ export async function syncRides( cost_per_km: ride.cost_per_km, total: ride.total, ride_date: ride.ride_date, + departures: ride.departures, + failed_service: ride.failed_service, + idle_hours: ride.idle_hours, synced: ride.synced, }); synced.push(result); diff --git a/proposta-toptran.html b/proposta-toptran.html new file mode 100644 index 0000000..2d497e3 --- /dev/null +++ b/proposta-toptran.html @@ -0,0 +1,280 @@ + + + + +Proposta — TopTran + + + + +
+

Proposta Comercial — TopTran

+
Aplicativo mobile + backend para gestão de corridas de transporte
+
Análise técnica e estimativa de valor · Maio de 2026
+
+ +

1. Escopo entregue

+ +

Backend — API REST

+

Node.jsExpress 5TypeScriptPrisma 7PostgreSQLDocker

+
    +
  • ~1.100 linhas de código próprio, arquitetura em camadas (routes → middleware → controller → service → repository)
  • +
  • Autenticação JWT com access token (15 min) + refresh token (7 dias)
  • +
  • Validação de input com Zod, hash de senha com bcrypt
  • +
  • 13 endpoints REST: /auth (register, login, logout), /users (me, profile, update, delete), /sync (companies, rides — upload e download)
  • +
  • Deploy completo com Docker + Compose (ambientes development e production) e script de deploy automatizado
  • +
+ +

Aplicativo Mobile

+

React Native 0.83Expo SDK 55Expo RouterSQLiteTypeScript

+
    +
  • ~4.460 linhas de código distribuídas em 21 arquivos
  • +
  • 11 telas: login, cadastro, dashboard, lançamento de corrida, histórico, empresas (CRUD), relatório mensal com PDF, perfil (foto + bio), sincronização com timeline visual, hub de cadastros, redirect de corrida
  • +
  • Offline-first: SQLite local com 4 tabelas e sincronização inteligente (compara IDs locais com servidor)
  • +
  • Tema escuro customizado aplicado em todo o app
  • +
  • Geração e compartilhamento de relatório em PDF (expo-print + expo-sharing)
  • +
  • Upload de foto de perfil via expo-image-picker
  • +
  • Build Android nativo com keystore de produção assinado (.jks)
  • +
  • Configuração EAS pronta para futuros builds
  • +
+ +

2. Estimativa de esforço técnico

+ + + + + + + + + + + + + + +
Frente de trabalhoHoras estimadas
Backend (API + autenticação + sync + deploy Docker)50 – 70 h
Mobile — telas e UI (11 telas com tema custom)70 – 90 h
Mobile — sincronização offline-first + SQLite + lógica de negócio30 – 40 h
Relatório PDF + perfil + upload de imagem15 – 20 h
Build / assinatura Android + ajustes de New Architecture15 – 20 h
Testes, debug em dispositivo, polimento20 – 30 h
Total estimado200 – 270 h
+ +

3. Faixa de preço sugerida

+ +

Como o projeto é um aplicativo interno corporativo — sem publicação em loja pública, sem onboarding de usuário externo e sem complexidade de marketing — a precificação é mais direta:

+ + + + + + + + + + +
CenárioValor/horaPreço total
Mínimo — freelancer pleno, projeto diretoR$ 90/hR$ 18.000 – 24.000
Justo — fullstack experiente, entrega completaR$ 130/hR$ 26.000 – 35.000
Premium — sênior, com garantia e suporte inicialR$ 180/hR$ 36.000 – 48.000
+ +
+ O que justifica o valor: +
    +
  • Stack moderna e correta (Expo SDK 55, React Native 0.83, Prisma 7)
  • +
  • Arquitetura limpa no backend, com separação real de responsabilidades
  • +
  • Sincronização offline-first não trivial: bidirecional, com reconciliação de IDs e flag synced
  • +
  • App em produção, com APK assinado e pronto para distribuição interna
  • +
+
+ +

Itens não inclusos no preço de desenvolvimento

+ + + + + + + + + +
ItemCusto recorrente
Hospedagem do backend (VPS)R$ 60 – 150 / mês
Manutenção mensal e correçõesR$ 800 – 2.000 / mês
Novas features (push, dashboard web, multi-empresa real)sob orçamento
+ +

4. Modelo alternativo — Aluguel / SaaS

+ +

Em vez de venda única do código-fonte, o aplicativo pode ser disponibilizado em modelo de assinatura (SaaS): o cliente não compra o app, paga uma mensalidade pelo uso. Setup baixo, receita recorrente, atualizações contínuas inclusas.

+ +

Setup inicial (taxa única)

+ + + + + + + + +
FaixaValor
Setup enxuto — cliente fornece a VPSR$ 1.500
Setup completo — VPS, domínio e deploy gerenciadosR$ 2.500 – 3.500
+

Inclui deploy do backend, criação do banco, geração do APK assinado, cadastro inicial de empresas/usuários e treinamento de 1 – 2 h.

+ +

Planos mensais

+ + + + + + + + + +
PlanoLimiteMensalAnual (10% off)
Básicoaté 5 motoristas, 1 empresaR$ 349R$ 3.770
Profissionalaté 20 motoristas, até 5 empresas, suporte prioritárioR$ 899R$ 9.710
Empresarialusuários e empresas ilimitados, customizações leves, SLAR$ 1.890R$ 20.412
+ +

Alternativa por usuário ativo

+

Se o cliente preferir escalar conforme o uso real:

+
    +
  • R$ 29 por motorista / mês, mínimo de 5 usuários (R$ 145/mês)
  • +
  • Setup de R$ 2.500
  • +
  • Inclui hospedagem, atualizações e correções de bug
  • +
+ +

O que está incluso na mensalidade

+
    +
  • Hospedagem do backend em VPS gerenciada
  • +
  • Banco PostgreSQL com backups diários
  • +
  • Atualizações de versão e correções de bugs
  • +
  • Suporte por WhatsApp/e-mail (tempo de resposta conforme o plano)
  • +
  • Geração de novas versões do APK quando houver atualização
  • +
+ +

Não incluso (cobrado à parte)

+ + + + + + + + + + +
ItemValor
Novas funcionalidades sob demandaR$ 130 – 150 / h
Migração de dados de sistema legadosob orçamento
Integrações externas (ERP, gateways de pagamento, etc.)sob orçamento
Publicação na Play Store (taxa Google + serviço)USD 25 + R$ 600 – 1.000
+ +
+ Ponto de equilíbrio e benefícios do modelo: +
    +
  • Plano Profissional (R$ 899/mês) se equipara à venda de R$ 30.000 em aproximadamente 33 meses
  • +
  • Para o cliente: vira despesa operacional (OPEX) em vez de investimento (CAPEX) — geralmente mais fácil de aprovar
  • +
  • Para o fornecedor: receita previsível, atualizações contínuas e relação de longo prazo
  • +
  • Sem risco de o cliente ficar com versão desatualizada ou sem suporte
  • +
+
+ +

5. Recomendação final

+ +
+

Modelo de venda única: R$ 25.000 – R$ 30.000, com 30 dias de garantia para correção de bugs. Valor por hora alternativo: R$ 120 – R$ 150/hora.

+

Modelo SaaS recomendado: Setup R$ 2.500 + Plano Profissional R$ 899/mês — equilíbrio entre acessibilidade para o cliente e sustentabilidade do serviço.

+
+ +
+ Proposta gerada com base em análise direta do código-fonte do projeto TopTran · backend + toptran-app +
+ + + diff --git a/proposta-toptran.pdf b/proposta-toptran.pdf new file mode 100644 index 0000000..50a494e Binary files /dev/null and b/proposta-toptran.pdf differ diff --git a/toptran-app/.env.development b/toptran-app/.env.development new file mode 100644 index 0000000..60ccca6 --- /dev/null +++ b/toptran-app/.env.development @@ -0,0 +1 @@ +EXPO_PUBLIC_API_URL=http://175.15.15.93:4000/api diff --git a/toptran-app/.env.production b/toptran-app/.env.production new file mode 100644 index 0000000..628db25 --- /dev/null +++ b/toptran-app/.env.production @@ -0,0 +1 @@ +EXPO_PUBLIC_API_URL=https://toptran.olymp.com.br/api diff --git a/toptran-app/database/create_tables.sql b/toptran-app/database/create_tables.sql index d407f2f..35de6b1 100644 --- a/toptran-app/database/create_tables.sql +++ b/toptran-app/database/create_tables.sql @@ -39,30 +39,47 @@ CREATE TABLE IF NOT EXISTS tokens ( -- Companies -- ============================================================ CREATE TABLE IF NOT EXISTS companies ( - id TEXT PRIMARY KEY, - name TEXT NOT NULL, - cost_per_km NUMERIC(10,2) NOT NULL, - notes TEXT DEFAULT '', - "createdAt" TIMESTAMPTZ DEFAULT NOW(), - "updatedAt" TIMESTAMPTZ DEFAULT NOW() + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + cost_per_km NUMERIC(10,2) NOT NULL, + departures INTEGER DEFAULT 0, + failed_service INTEGER DEFAULT 0, + idle_hours NUMERIC(10,2) DEFAULT 0, + notes TEXT DEFAULT '', + "createdAt" TIMESTAMPTZ DEFAULT NOW(), + "updatedAt" TIMESTAMPTZ DEFAULT NOW() ); +ALTER TABLE companies ADD COLUMN IF NOT EXISTS departures INTEGER DEFAULT 0; +ALTER TABLE companies ADD COLUMN IF NOT EXISTS failed_service INTEGER DEFAULT 0; +ALTER TABLE companies ADD COLUMN IF NOT EXISTS idle_hours NUMERIC(10,2) DEFAULT 0; + -- ============================================================ -- Rides -- ============================================================ CREATE TABLE IF NOT EXISTS rides ( - id TEXT PRIMARY KEY, - user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE, - company TEXT NOT NULL, - km NUMERIC(10,2) NOT NULL, - cost_per_km NUMERIC(10,2) NOT NULL, - total NUMERIC(10,2) NOT NULL, - ride_date TEXT NOT NULL, - synced SMALLINT DEFAULT 0, - "createdAt" TIMESTAMPTZ DEFAULT NOW(), - "updatedAt" TIMESTAMPTZ DEFAULT NOW() + id TEXT PRIMARY KEY, + user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE, + company TEXT NOT NULL, + km NUMERIC(10,2) NOT NULL, + cost_per_km NUMERIC(10,2) NOT NULL, + total NUMERIC(10,2) NOT NULL, + ride_date TEXT NOT NULL, + departures INTEGER DEFAULT 0, + failed_service INTEGER DEFAULT 0, + idle_hours NUMERIC(10,2) DEFAULT 0, + synced SMALLINT DEFAULT 0, + "createdAt" TIMESTAMPTZ DEFAULT NOW(), + "updatedAt" TIMESTAMPTZ DEFAULT NOW() ); +-- ============================================================ +-- Migrations: add new columns if table already exists +-- ============================================================ +ALTER TABLE rides ADD COLUMN IF NOT EXISTS departures INTEGER DEFAULT 0; +ALTER TABLE rides ADD COLUMN IF NOT EXISTS failed_service INTEGER DEFAULT 0; +ALTER TABLE rides ADD COLUMN IF NOT EXISTS idle_hours NUMERIC(10,2) DEFAULT 0; + -- ============================================================ -- Indexes -- ============================================================ diff --git a/toptran-app/eas.json b/toptran-app/eas.json index e188fd7..3a60d22 100644 --- a/toptran-app/eas.json +++ b/toptran-app/eas.json @@ -11,7 +11,7 @@ "buildType": "apk" }, "env": { - "EXPO_PUBLIC_API_URL": "https://toptran.olymp.com.br/api" + "EXPO_PUBLIC_API_URL": "http://175.15.15.93:4000/api" } }, "preview": { diff --git a/toptran-app/src/app/cadastros.tsx b/toptran-app/src/app/cadastros.tsx index 7f3eca7..6ff41d2 100644 --- a/toptran-app/src/app/cadastros.tsx +++ b/toptran-app/src/app/cadastros.tsx @@ -2,6 +2,7 @@ import { BORDER_RADIUS, COLORS, SPACING } from "@/constants/theme"; import { router } from "expo-router"; import React from "react"; import { + Alert, ScrollView, StyleSheet, Text, @@ -31,19 +32,25 @@ export default function CadastrosPage() { icon: "👤", label: "Motoristas", description: "Cadastro de motoristas", - onPress: () => {}, + onPress: () => { + Alert.alert("Em desenvolvimento!"); + }, }, { icon: "🚛", label: "Veículos", description: "Cadastro de veículos", - onPress: () => {}, + onPress: () => { + Alert.alert("Em desenvolvimento!"); + }, }, { icon: "📍", label: "Rotas", description: "Rotas e destinos frequentes", - onPress: () => {}, + onPress: () => { + Alert.alert("Em desenvolvimento!"); + }, }, ]; @@ -66,9 +73,7 @@ export default function CadastrosPage() { > Cadastros - - Gerencie os dados base do sistema - + Gerencie os dados base do sistema Categorias diff --git a/toptran-app/src/app/empresas.tsx b/toptran-app/src/app/empresas.tsx index 123f3dc..4619e65 100644 --- a/toptran-app/src/app/empresas.tsx +++ b/toptran-app/src/app/empresas.tsx @@ -26,10 +26,20 @@ import { SafeAreaView } from "react-native-safe-area-context"; type FormState = { nome: string; custoPorKm: string; + partidas: string; + servicoFalho: string; + horasOciosas: string; observacoes: string; }; -const FORM_VAZIO: FormState = { nome: "", custoPorKm: "", observacoes: "" }; +const FORM_VAZIO: FormState = { + nome: "", + custoPorKm: "", + partidas: "", + servicoFalho: "", + horasOciosas: "", + observacoes: "", +}; export default function EmpresasPage() { const [empresas, setEmpresas] = useState([]); @@ -59,6 +69,9 @@ export default function EmpresasPage() { setForm({ nome: empresa.name, custoPorKm: empresa.cost_per_km.toString(), + partidas: (empresa.departures ?? 0).toString(), + servicoFalho: (empresa.failed_service ?? 0).toString(), + horasOciosas: (empresa.idle_hours ?? 0).toString(), observacoes: empresa.notes ?? "", }); setModalVisible(true); @@ -73,6 +86,9 @@ export default function EmpresasPage() { const handleSalvar = async () => { const nomeTrimmed = form.nome.trim(); const custo = parseFloat(form.custoPorKm.replace(",", ".")); + const partidas = parseInt(form.partidas, 10) || 0; + const servicoFalho = parseInt(form.servicoFalho, 10) || 0; + const horasOciosas = parseFloat(form.horasOciosas.replace(",", ".")) || 0; if (!nomeTrimmed) { Alert.alert("Validação", "Informe o nome da empresa."); @@ -90,6 +106,9 @@ export default function EmpresasPage() { id: editando.id, name: nomeTrimmed, cost_per_km: custo, + departures: partidas, + failed_service: servicoFalho, + idle_hours: horasOciosas, notes: form.observacoes.trim(), }); } else { @@ -97,6 +116,9 @@ export default function EmpresasPage() { id: Date.now().toString(), name: nomeTrimmed, cost_per_km: custo, + departures: partidas, + failed_service: servicoFalho, + idle_hours: horasOciosas, notes: form.observacoes.trim(), }); } @@ -258,6 +280,36 @@ export default function EmpresasPage() { /> + + Partidas + setForm((f) => ({ ...f, partidas: v }))} + /> + + + + Serviço falho + setForm((f) => ({ ...f, servicoFalho: v }))} + /> + + + + Horas ociosas + setForm((f) => ({ ...f, horasOciosas: v }))} + /> + + Observações (opcional) ([]); const [empresaId, setEmpresaId] = useState(""); const [custoPorKm, setCustoPorKm] = useState(0); + const [partidas, setPartidas] = useState(0); + const [servicoFalho, setServicoFalho] = useState(0); + const [horasOciosas, setHorasOciosas] = useState(0); const [distancia, setDistancia] = useState(""); const [loading, setLoading] = useState(false); @@ -56,6 +59,9 @@ export default function LancamentoPage() { setEmpresaId(id); const found = empresasDB.find((e) => e.id === id); setCustoPorKm(found?.cost_per_km ?? 0); + setPartidas(found?.departures ?? 0); + setServicoFalho(found?.failed_service ?? 0); + setHorasOciosas(found?.idle_hours ?? 0); }; const handleLancarCorrida = async () => { @@ -80,11 +86,17 @@ export default function LancamentoPage() { cost_per_km: custoPorKm, total: totalCorrida, ride_date: new Date().toLocaleString("pt-BR"), + departures: partidas, + failed_service: servicoFalho, + idle_hours: horasOciosas, synced: 0, }); setEmpresaId(""); setCustoPorKm(0); setDistancia(""); + setPartidas(0); + setServicoFalho(0); + setHorasOciosas(0); Alert.alert("Sucesso", "Corrida registrada com sucesso!", [ { text: "OK", onPress: () => router.back() }, ]); @@ -140,6 +152,27 @@ export default function LancamentoPage() { + + + Partidas + {partidas} + + + + + + Serviço falho + {servicoFalho} + + + + + + Horas ociosas + {horasOciosas.toFixed(2)} + + + Valor Total R$ {totalCorrida.toFixed(2)} diff --git a/toptran-app/src/app/sincronizar.tsx b/toptran-app/src/app/sincronizar.tsx index 624a04f..2d04903 100644 --- a/toptran-app/src/app/sincronizar.tsx +++ b/toptran-app/src/app/sincronizar.tsx @@ -105,6 +105,9 @@ export default function SincronizarPage() { id: c.id, name: c.name, cost_per_km: Number(c.cost_per_km), + departures: Number(c.departures ?? 0), + failed_service: Number(c.failed_service ?? 0), + idle_hours: Number(c.idle_hours ?? 0), notes: c.notes ?? "", }); } diff --git a/toptran-app/src/server/api.ts b/toptran-app/src/server/api.ts index 7bfefa9..f9b3800 100644 --- a/toptran-app/src/server/api.ts +++ b/toptran-app/src/server/api.ts @@ -1,6 +1,10 @@ import axios from "axios"; -const BASE_URL = process.env.EXPO_PUBLIC_API_URL ?? "http://175.15.15.93:3000"; +const BASE_URL = process.env.EXPO_PUBLIC_API_URL; + +if (!BASE_URL) { + throw new Error("EXPO_PUBLIC_API_URL não definida — verifique .env.development / .env.production"); +} export const api = axios.create({ baseURL: BASE_URL, diff --git a/toptran-app/src/services/db.ts b/toptran-app/src/services/db.ts index 69a913e..72ae661 100644 --- a/toptran-app/src/services/db.ts +++ b/toptran-app/src/services/db.ts @@ -18,6 +18,9 @@ export type RideDB = { cost_per_km: number; total: number; ride_date: string; + departures: number; + failed_service: number; + idle_hours: number; synced: 0 | 1; createdAt: string; }; @@ -26,6 +29,9 @@ export type CompanyDB = { id: string; name: string; cost_per_km: number; + departures: number; + failed_service: number; + idle_hours: number; notes: string; createdAt: string; }; @@ -51,11 +57,34 @@ export const initDB = async () => { cost_per_km REAL NOT NULL, total REAL NOT NULL, ride_date TEXT NOT NULL, + departures INTEGER DEFAULT 0, + failed_service INTEGER DEFAULT 0, + idle_hours REAL DEFAULT 0, synced INTEGER DEFAULT 0, createdAt TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) );`, ); + + const ridesCols = await db.getAllAsync<{ name: string }>( + `PRAGMA table_info(rides);`, + ); + const colNames = new Set(ridesCols.map((c) => c.name)); + if (!colNames.has("departures")) { + await db.execAsync( + `ALTER TABLE rides ADD COLUMN departures INTEGER DEFAULT 0;`, + ); + } + if (!colNames.has("failed_service")) { + await db.execAsync( + `ALTER TABLE rides ADD COLUMN failed_service INTEGER DEFAULT 0;`, + ); + } + if (!colNames.has("idle_hours")) { + await db.execAsync( + `ALTER TABLE rides ADD COLUMN idle_hours REAL DEFAULT 0;`, + ); + } await db.execAsync( `CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, @@ -67,10 +96,33 @@ export const initDB = async () => { id TEXT PRIMARY KEY, name TEXT NOT NULL, cost_per_km REAL NOT NULL, + departures INTEGER DEFAULT 0, + failed_service INTEGER DEFAULT 0, + idle_hours REAL DEFAULT 0, notes TEXT DEFAULT '', createdAt TEXT DEFAULT CURRENT_TIMESTAMP );`, ); + + const companiesCols = await db.getAllAsync<{ name: string }>( + `PRAGMA table_info(companies);`, + ); + const compColNames = new Set(companiesCols.map((c) => c.name)); + if (!compColNames.has("departures")) { + await db.execAsync( + `ALTER TABLE companies ADD COLUMN departures INTEGER DEFAULT 0;`, + ); + } + if (!compColNames.has("failed_service")) { + await db.execAsync( + `ALTER TABLE companies ADD COLUMN failed_service INTEGER DEFAULT 0;`, + ); + } + if (!compColNames.has("idle_hours")) { + await db.execAsync( + `ALTER TABLE companies ADD COLUMN idle_hours REAL DEFAULT 0;`, + ); + } } catch (error) { console.error("Failed to initialize database:", error); throw error; @@ -178,8 +230,8 @@ export const salvarCorrida = async (corrida: Omit) => { try { const db = await dbPromise; const result = await db.runAsync( - `INSERT INTO rides (id, user_id, company, km, cost_per_km, total, ride_date, synced) - VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, + `INSERT INTO rides (id, user_id, company, km, cost_per_km, total, ride_date, departures, failed_service, idle_hours, synced) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [ corrida.id, corrida.user_id, @@ -188,6 +240,9 @@ export const salvarCorrida = async (corrida: Omit) => { corrida.cost_per_km, corrida.total, corrida.ride_date, + corrida.departures, + corrida.failed_service, + corrida.idle_hours, corrida.synced, ], ); @@ -282,8 +337,17 @@ export const salvarEmpresa = async ( try { const db = await dbPromise; await db.runAsync( - `INSERT INTO companies (id, name, cost_per_km, notes) VALUES (?, ?, ?, ?)`, - [empresa.id, empresa.name, empresa.cost_per_km, empresa.notes], + `INSERT INTO companies (id, name, cost_per_km, departures, failed_service, idle_hours, notes) + VALUES (?, ?, ?, ?, ?, ?, ?)`, + [ + empresa.id, + empresa.name, + empresa.cost_per_km, + empresa.departures, + empresa.failed_service, + empresa.idle_hours, + empresa.notes, + ], ); } catch (error) { console.error("Error saving company:", error); @@ -297,8 +361,17 @@ export const upsertEmpresaLocal = async ( try { const db = await dbPromise; await db.runAsync( - `INSERT OR REPLACE INTO companies (id, name, cost_per_km, notes) VALUES (?, ?, ?, ?)`, - [empresa.id, empresa.name, empresa.cost_per_km, empresa.notes], + `INSERT OR REPLACE INTO companies (id, name, cost_per_km, departures, failed_service, idle_hours, notes) + VALUES (?, ?, ?, ?, ?, ?, ?)`, + [ + empresa.id, + empresa.name, + empresa.cost_per_km, + empresa.departures, + empresa.failed_service, + empresa.idle_hours, + empresa.notes, + ], ); } catch (error) { console.error("Error upserting company:", error); @@ -312,9 +385,20 @@ export const upsertCorridaLocal = async ( try { const db = await dbPromise; await db.runAsync( - `INSERT OR REPLACE INTO rides (id, user_id, company, km, cost_per_km, total, ride_date, synced) - VALUES (?, ?, ?, ?, ?, ?, ?, 1)`, - [corrida.id, corrida.user_id, corrida.company, corrida.km, corrida.cost_per_km, corrida.total, corrida.ride_date], + `INSERT OR REPLACE INTO rides (id, user_id, company, km, cost_per_km, total, ride_date, departures, failed_service, idle_hours, synced) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1)`, + [ + corrida.id, + corrida.user_id, + corrida.company, + corrida.km, + corrida.cost_per_km, + corrida.total, + corrida.ride_date, + corrida.departures, + corrida.failed_service, + corrida.idle_hours, + ], ); } catch (error) { console.error("Error upserting ride:", error); @@ -328,8 +412,16 @@ export const atualizarEmpresa = async ( try { const db = await dbPromise; await db.runAsync( - `UPDATE companies SET name = ?, cost_per_km = ?, notes = ? WHERE id = ?`, - [empresa.name, empresa.cost_per_km, empresa.notes, empresa.id], + `UPDATE companies SET name = ?, cost_per_km = ?, departures = ?, failed_service = ?, idle_hours = ?, notes = ? WHERE id = ?`, + [ + empresa.name, + empresa.cost_per_km, + empresa.departures, + empresa.failed_service, + empresa.idle_hours, + empresa.notes, + empresa.id, + ], ); } catch (error) { console.error("Error updating company:", error);