Acert script on database
This commit is contained in:
parent
92aa1cb2bb
commit
d508e27bac
27 changed files with 1136 additions and 139 deletions
|
|
@ -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=$?\")"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
130
README.md
130
README.md
|
|
@ -107,6 +107,9 @@ model rides {
|
|||
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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
11
backend/[teste.env]
Normal file
11
backend/[teste.env]
Normal file
|
|
@ -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
|
||||
46
backend/package-lock.json
generated
46
backend/package-lock.json
generated
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ model companies {
|
|||
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)
|
||||
|
|
@ -51,6 +54,9 @@ model rides {
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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<ExtArgs extends runtime.Types.Extensions.InternalArg
|
|||
id?: boolean
|
||||
name?: boolean
|
||||
cost_per_km?: boolean
|
||||
departures?: boolean
|
||||
failed_service?: boolean
|
||||
idle_hours?: boolean
|
||||
notes?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
|
|
@ -398,6 +493,9 @@ export type companiesSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Ext
|
|||
id?: boolean
|
||||
name?: boolean
|
||||
cost_per_km?: boolean
|
||||
departures?: boolean
|
||||
failed_service?: boolean
|
||||
idle_hours?: boolean
|
||||
notes?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
|
|
@ -407,6 +505,9 @@ export type companiesSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Ext
|
|||
id?: boolean
|
||||
name?: boolean
|
||||
cost_per_km?: boolean
|
||||
departures?: boolean
|
||||
failed_service?: boolean
|
||||
idle_hours?: boolean
|
||||
notes?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
|
|
@ -416,12 +517,15 @@ export type companiesSelectScalar = {
|
|||
id?: boolean
|
||||
name?: boolean
|
||||
cost_per_km?: boolean
|
||||
departures?: boolean
|
||||
failed_service?: boolean
|
||||
idle_hours?: boolean
|
||||
notes?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}
|
||||
|
||||
export type companiesOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "cost_per_km" | "notes" | "createdAt" | "updatedAt", ExtArgs["result"]["companies"]>
|
||||
export type companiesOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "name" | "cost_per_km" | "departures" | "failed_service" | "idle_hours" | "notes" | "createdAt" | "updatedAt", ExtArgs["result"]["companies"]>
|
||||
|
||||
export type $companiesPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "companies"
|
||||
|
|
@ -430,6 +534,9 @@ export type $companiesPayload<ExtArgs extends runtime.Types.Extensions.InternalA
|
|||
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
|
||||
|
|
@ -859,6 +966,9 @@ export interface companiesFieldRefs {
|
|||
readonly id: Prisma.FieldRef<"companies", 'String'>
|
||||
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'>
|
||||
|
|
|
|||
|
|
@ -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<ExtArgs extends runtime.Types.Extensions.InternalArgs =
|
|||
cost_per_km?: boolean
|
||||
total?: boolean
|
||||
ride_date?: boolean
|
||||
departures?: boolean
|
||||
failed_service?: boolean
|
||||
idle_hours?: boolean
|
||||
synced?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
|
|
@ -677,6 +785,9 @@ export type ridesSelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensi
|
|||
cost_per_km?: boolean
|
||||
total?: boolean
|
||||
ride_date?: boolean
|
||||
departures?: boolean
|
||||
failed_service?: boolean
|
||||
idle_hours?: boolean
|
||||
synced?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
|
|
@ -691,6 +802,9 @@ export type ridesSelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensi
|
|||
cost_per_km?: boolean
|
||||
total?: boolean
|
||||
ride_date?: boolean
|
||||
departures?: boolean
|
||||
failed_service?: boolean
|
||||
idle_hours?: boolean
|
||||
synced?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
|
|
@ -705,12 +819,15 @@ export type ridesSelectScalar = {
|
|||
cost_per_km?: boolean
|
||||
total?: boolean
|
||||
ride_date?: boolean
|
||||
departures?: boolean
|
||||
failed_service?: boolean
|
||||
idle_hours?: boolean
|
||||
synced?: boolean
|
||||
createdAt?: boolean
|
||||
updatedAt?: boolean
|
||||
}
|
||||
|
||||
export type ridesOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "user_id" | "company" | "km" | "cost_per_km" | "total" | "ride_date" | "synced" | "createdAt" | "updatedAt", ExtArgs["result"]["rides"]>
|
||||
export type ridesOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = 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<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
users?: boolean | Prisma.usersDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
|
@ -734,6 +851,9 @@ export type $ridesPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs
|
|||
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
|
||||
|
|
@ -1168,6 +1288,9 @@ export interface ridesFieldRefs {
|
|||
readonly cost_per_km: Prisma.FieldRef<"rides", 'Decimal'>
|
||||
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'>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
280
proposta-toptran.html
Normal file
280
proposta-toptran.html
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Proposta — TopTran</title>
|
||||
<style>
|
||||
@page {
|
||||
size: A4;
|
||||
margin: 18mm 16mm;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.5;
|
||||
font-size: 10.5pt;
|
||||
margin: 0;
|
||||
}
|
||||
header {
|
||||
border-bottom: 3px solid #0a0a0a;
|
||||
padding-bottom: 12px;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
header h1 {
|
||||
margin: 0 0 4px 0;
|
||||
font-size: 22pt;
|
||||
color: #0a0a0a;
|
||||
}
|
||||
header .subtitle {
|
||||
color: #555;
|
||||
font-size: 11pt;
|
||||
}
|
||||
header .meta {
|
||||
margin-top: 8px;
|
||||
font-size: 9pt;
|
||||
color: #777;
|
||||
}
|
||||
h2 {
|
||||
font-size: 13.5pt;
|
||||
color: #0a0a0a;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding-bottom: 4px;
|
||||
margin-top: 22px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
h3 {
|
||||
font-size: 11.5pt;
|
||||
color: #222;
|
||||
margin-top: 14px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
p { margin: 6px 0; }
|
||||
ul { margin: 6px 0; padding-left: 22px; }
|
||||
li { margin: 3px 0; }
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 10px 0;
|
||||
font-size: 10pt;
|
||||
}
|
||||
th, td {
|
||||
text-align: left;
|
||||
padding: 7px 10px;
|
||||
border-bottom: 1px solid #e3e3e3;
|
||||
}
|
||||
th {
|
||||
background-color: #f4f4f4;
|
||||
font-weight: 600;
|
||||
}
|
||||
td.num, th.num { text-align: right; }
|
||||
.price-table td:last-child { font-weight: 600; }
|
||||
.highlight-box {
|
||||
background-color: #f8f8f8;
|
||||
border-left: 4px solid #0a0a0a;
|
||||
padding: 12px 16px;
|
||||
margin: 14px 0;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.recommendation {
|
||||
background-color: #fff8e6;
|
||||
border: 1px solid #f0d480;
|
||||
padding: 14px 18px;
|
||||
margin-top: 14px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.recommendation strong { color: #6b4f00; }
|
||||
code {
|
||||
font-family: "SF Mono", Consolas, monospace;
|
||||
background-color: #f0f0f0;
|
||||
padding: 1px 5px;
|
||||
border-radius: 3px;
|
||||
font-size: 9.5pt;
|
||||
}
|
||||
footer {
|
||||
margin-top: 30px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #ddd;
|
||||
font-size: 8.5pt;
|
||||
color: #888;
|
||||
text-align: center;
|
||||
}
|
||||
.badge {
|
||||
display: inline-block;
|
||||
background: #0a0a0a;
|
||||
color: #fff;
|
||||
font-size: 8pt;
|
||||
padding: 2px 7px;
|
||||
border-radius: 3px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>Proposta Comercial — TopTran</h1>
|
||||
<div class="subtitle">Aplicativo mobile + backend para gestão de corridas de transporte</div>
|
||||
<div class="meta">Análise técnica e estimativa de valor · Maio de 2026</div>
|
||||
</header>
|
||||
|
||||
<h2>1. Escopo entregue</h2>
|
||||
|
||||
<h3>Backend — API REST</h3>
|
||||
<p><span class="badge">Node.js</span><span class="badge">Express 5</span><span class="badge">TypeScript</span><span class="badge">Prisma 7</span><span class="badge">PostgreSQL</span><span class="badge">Docker</span></p>
|
||||
<ul>
|
||||
<li>~1.100 linhas de código próprio, arquitetura em camadas (routes → middleware → controller → service → repository)</li>
|
||||
<li>Autenticação JWT com access token (15 min) + refresh token (7 dias)</li>
|
||||
<li>Validação de input com Zod, hash de senha com bcrypt</li>
|
||||
<li>13 endpoints REST: <code>/auth</code> (register, login, logout), <code>/users</code> (me, profile, update, delete), <code>/sync</code> (companies, rides — upload e download)</li>
|
||||
<li>Deploy completo com Docker + Compose (ambientes <em>development</em> e <em>production</em>) e script de deploy automatizado</li>
|
||||
</ul>
|
||||
|
||||
<h3>Aplicativo Mobile</h3>
|
||||
<p><span class="badge">React Native 0.83</span><span class="badge">Expo SDK 55</span><span class="badge">Expo Router</span><span class="badge">SQLite</span><span class="badge">TypeScript</span></p>
|
||||
<ul>
|
||||
<li>~4.460 linhas de código distribuídas em 21 arquivos</li>
|
||||
<li><strong>11 telas:</strong> 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</li>
|
||||
<li><strong>Offline-first:</strong> SQLite local com 4 tabelas e sincronização inteligente (compara IDs locais com servidor)</li>
|
||||
<li>Tema escuro customizado aplicado em todo o app</li>
|
||||
<li>Geração e compartilhamento de relatório em PDF (<code>expo-print</code> + <code>expo-sharing</code>)</li>
|
||||
<li>Upload de foto de perfil via <code>expo-image-picker</code></li>
|
||||
<li>Build Android nativo com <em>keystore</em> de produção assinado (<code>.jks</code>)</li>
|
||||
<li>Configuração EAS pronta para futuros builds</li>
|
||||
</ul>
|
||||
|
||||
<h2>2. Estimativa de esforço técnico</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Frente de trabalho</th><th class="num">Horas estimadas</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>Backend (API + autenticação + sync + deploy Docker)</td><td class="num">50 – 70 h</td></tr>
|
||||
<tr><td>Mobile — telas e UI (11 telas com tema custom)</td><td class="num">70 – 90 h</td></tr>
|
||||
<tr><td>Mobile — sincronização offline-first + SQLite + lógica de negócio</td><td class="num">30 – 40 h</td></tr>
|
||||
<tr><td>Relatório PDF + perfil + upload de imagem</td><td class="num">15 – 20 h</td></tr>
|
||||
<tr><td>Build / assinatura Android + ajustes de New Architecture</td><td class="num">15 – 20 h</td></tr>
|
||||
<tr><td>Testes, debug em dispositivo, polimento</td><td class="num">20 – 30 h</td></tr>
|
||||
<tr style="background-color: #f4f4f4;"><td><strong>Total estimado</strong></td><td class="num"><strong>200 – 270 h</strong></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>3. Faixa de preço sugerida</h2>
|
||||
|
||||
<p>Como o projeto é um <strong>aplicativo interno corporativo</strong> — sem publicação em loja pública, sem onboarding de usuário externo e sem complexidade de marketing — a precificação é mais direta:</p>
|
||||
|
||||
<table class="price-table">
|
||||
<thead>
|
||||
<tr><th>Cenário</th><th class="num">Valor/hora</th><th class="num">Preço total</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><strong>Mínimo</strong> — freelancer pleno, projeto direto</td><td class="num">R$ 90/h</td><td class="num">R$ 18.000 – 24.000</td></tr>
|
||||
<tr><td><strong>Justo</strong> — fullstack experiente, entrega completa</td><td class="num">R$ 130/h</td><td class="num">R$ 26.000 – 35.000</td></tr>
|
||||
<tr><td><strong>Premium</strong> — sênior, com garantia e suporte inicial</td><td class="num">R$ 180/h</td><td class="num">R$ 36.000 – 48.000</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="highlight-box">
|
||||
<strong>O que justifica o valor:</strong>
|
||||
<ul style="margin-top: 6px;">
|
||||
<li>Stack moderna e correta (Expo SDK 55, React Native 0.83, Prisma 7)</li>
|
||||
<li>Arquitetura limpa no backend, com separação real de responsabilidades</li>
|
||||
<li>Sincronização offline-first não trivial: bidirecional, com reconciliação de IDs e flag <code>synced</code></li>
|
||||
<li>App em produção, com APK assinado e pronto para distribuição interna</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h3>Itens não inclusos no preço de desenvolvimento</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Item</th><th class="num">Custo recorrente</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>Hospedagem do backend (VPS)</td><td class="num">R$ 60 – 150 / mês</td></tr>
|
||||
<tr><td>Manutenção mensal e correções</td><td class="num">R$ 800 – 2.000 / mês</td></tr>
|
||||
<tr><td>Novas features (push, dashboard web, multi-empresa real)</td><td class="num">sob orçamento</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>4. Modelo alternativo — Aluguel / SaaS</h2>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<h3>Setup inicial (taxa única)</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Faixa</th><th class="num">Valor</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>Setup enxuto — cliente fornece a VPS</td><td class="num">R$ 1.500</td></tr>
|
||||
<tr><td>Setup completo — VPS, domínio e deploy gerenciados</td><td class="num">R$ 2.500 – 3.500</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p style="font-size: 9.5pt; color: #555;">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.</p>
|
||||
|
||||
<h3>Planos mensais</h3>
|
||||
<table class="price-table">
|
||||
<thead>
|
||||
<tr><th>Plano</th><th>Limite</th><th class="num">Mensal</th><th class="num">Anual (10% off)</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td><strong>Básico</strong></td><td>até 5 motoristas, 1 empresa</td><td class="num">R$ 349</td><td class="num">R$ 3.770</td></tr>
|
||||
<tr><td><strong>Profissional</strong></td><td>até 20 motoristas, até 5 empresas, suporte prioritário</td><td class="num">R$ 899</td><td class="num">R$ 9.710</td></tr>
|
||||
<tr><td><strong>Empresarial</strong></td><td>usuários e empresas ilimitados, customizações leves, SLA</td><td class="num">R$ 1.890</td><td class="num">R$ 20.412</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Alternativa por usuário ativo</h3>
|
||||
<p>Se o cliente preferir escalar conforme o uso real:</p>
|
||||
<ul>
|
||||
<li><strong>R$ 29 por motorista / mês</strong>, mínimo de 5 usuários (R$ 145/mês)</li>
|
||||
<li>Setup de R$ 2.500</li>
|
||||
<li>Inclui hospedagem, atualizações e correções de bug</li>
|
||||
</ul>
|
||||
|
||||
<h3>O que está incluso na mensalidade</h3>
|
||||
<ul>
|
||||
<li>Hospedagem do backend em VPS gerenciada</li>
|
||||
<li>Banco PostgreSQL com backups diários</li>
|
||||
<li>Atualizações de versão e correções de bugs</li>
|
||||
<li>Suporte por WhatsApp/e-mail (tempo de resposta conforme o plano)</li>
|
||||
<li>Geração de novas versões do APK quando houver atualização</li>
|
||||
</ul>
|
||||
|
||||
<h3>Não incluso (cobrado à parte)</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Item</th><th class="num">Valor</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>Novas funcionalidades sob demanda</td><td class="num">R$ 130 – 150 / h</td></tr>
|
||||
<tr><td>Migração de dados de sistema legado</td><td class="num">sob orçamento</td></tr>
|
||||
<tr><td>Integrações externas (ERP, gateways de pagamento, etc.)</td><td class="num">sob orçamento</td></tr>
|
||||
<tr><td>Publicação na Play Store (taxa Google + serviço)</td><td class="num">USD 25 + R$ 600 – 1.000</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="highlight-box">
|
||||
<strong>Ponto de equilíbrio e benefícios do modelo:</strong>
|
||||
<ul style="margin-top: 6px;">
|
||||
<li>Plano Profissional (R$ 899/mês) se equipara à venda de R$ 30.000 em aproximadamente 33 meses</li>
|
||||
<li>Para o cliente: vira despesa operacional (OPEX) em vez de investimento (CAPEX) — geralmente mais fácil de aprovar</li>
|
||||
<li>Para o fornecedor: receita previsível, atualizações contínuas e relação de longo prazo</li>
|
||||
<li>Sem risco de o cliente ficar com versão desatualizada ou sem suporte</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2>5. Recomendação final</h2>
|
||||
|
||||
<div class="recommendation">
|
||||
<p style="margin-top: 0;"><strong>Modelo de venda única:</strong> 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.</p>
|
||||
<p style="margin-bottom: 0;"><strong>Modelo SaaS recomendado:</strong> Setup R$ 2.500 + Plano Profissional R$ 899/mês — equilíbrio entre acessibilidade para o cliente e sustentabilidade do serviço.</p>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
Proposta gerada com base em análise direta do código-fonte do projeto TopTran · backend + toptran-app
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
BIN
proposta-toptran.pdf
Normal file
BIN
proposta-toptran.pdf
Normal file
Binary file not shown.
1
toptran-app/.env.development
Normal file
1
toptran-app/.env.development
Normal file
|
|
@ -0,0 +1 @@
|
|||
EXPO_PUBLIC_API_URL=http://175.15.15.93:4000/api
|
||||
1
toptran-app/.env.production
Normal file
1
toptran-app/.env.production
Normal file
|
|
@ -0,0 +1 @@
|
|||
EXPO_PUBLIC_API_URL=https://toptran.olymp.com.br/api
|
||||
|
|
@ -42,11 +42,18 @@ CREATE TABLE IF NOT EXISTS companies (
|
|||
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
|
||||
-- ============================================================
|
||||
|
|
@ -58,11 +65,21 @@ CREATE TABLE IF NOT EXISTS rides (
|
|||
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
|
||||
-- ============================================================
|
||||
|
|
|
|||
|
|
@ -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": {
|
||||
|
|
|
|||
|
|
@ -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() {
|
|||
>
|
||||
<View style={styles.titleSection}>
|
||||
<Text style={styles.title}>Cadastros</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Gerencie os dados base do sistema
|
||||
</Text>
|
||||
<Text style={styles.subtitle}>Gerencie os dados base do sistema</Text>
|
||||
</View>
|
||||
|
||||
<Text style={styles.sectionTitle}>Categorias</Text>
|
||||
|
|
|
|||
|
|
@ -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<CompanyDB[]>([]);
|
||||
|
|
@ -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() {
|
|||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formGroup}>
|
||||
<Text style={styles.formLabel}>Partidas</Text>
|
||||
<Input
|
||||
placeholder="0"
|
||||
keyboardType="number-pad"
|
||||
value={form.partidas}
|
||||
onChangeText={(v) => setForm((f) => ({ ...f, partidas: v }))}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formGroup}>
|
||||
<Text style={styles.formLabel}>Serviço falho</Text>
|
||||
<Input
|
||||
placeholder="0"
|
||||
keyboardType="number-pad"
|
||||
value={form.servicoFalho}
|
||||
onChangeText={(v) => setForm((f) => ({ ...f, servicoFalho: v }))}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formGroup}>
|
||||
<Text style={styles.formLabel}>Horas ociosas</Text>
|
||||
<Input
|
||||
placeholder="0,00"
|
||||
keyboardType="decimal-pad"
|
||||
value={form.horasOciosas}
|
||||
onChangeText={(v) => setForm((f) => ({ ...f, horasOciosas: v }))}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.formGroup}>
|
||||
<Text style={styles.formLabel}>Observações (opcional)</Text>
|
||||
<Input
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ export default function LancamentoPage() {
|
|||
const [empresasDB, setEmpresasDB] = useState<CompanyDB[]>([]);
|
||||
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() {
|
|||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.card}>
|
||||
<View style={styles.infoRow}>
|
||||
<Text style={styles.infoLabel}>Partidas</Text>
|
||||
<Text style={styles.infoValue}>{partidas}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.card}>
|
||||
<View style={styles.infoRow}>
|
||||
<Text style={styles.infoLabel}>Serviço falho</Text>
|
||||
<Text style={styles.infoValue}>{servicoFalho}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.card}>
|
||||
<View style={styles.infoRow}>
|
||||
<Text style={styles.infoLabel}>Horas ociosas</Text>
|
||||
<Text style={styles.infoValue}>{horasOciosas.toFixed(2)}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={[styles.card, styles.totalCard]}>
|
||||
<Text style={styles.totalLabel}>Valor Total</Text>
|
||||
<Text style={styles.totalAmount}>R$ {totalCorrida.toFixed(2)}</Text>
|
||||
|
|
|
|||
|
|
@ -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 ?? "",
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<RideDB, "createdAt">) => {
|
|||
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<RideDB, "createdAt">) => {
|
|||
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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue