diff --git a/app/components/landing/header/header.tsx b/app/components/landing/header/header.tsx
index 79efc9cd..dd97b47f 100644
--- a/app/components/landing/header/header.tsx
+++ b/app/components/landing/header/header.tsx
@@ -1,8 +1,8 @@
import { useState } from 'react'
+import { useTranslation } from 'react-i18next'
import { Link } from 'react-router'
// import { ModeToggle } from "../../mode-toggle";
import LanguageSelector from './language-selector'
-import { useTranslation } from 'react-i18next'
const links = [
{
diff --git a/app/components/mydevices/dt/columns.tsx b/app/components/mydevices/dt/columns.tsx
index c6442fd6..19a9b35b 100644
--- a/app/components/mydevices/dt/columns.tsx
+++ b/app/components/mydevices/dt/columns.tsx
@@ -19,6 +19,7 @@ export type SenseBox = {
name: string
exposure: Device['exposure']
createdAt: Date
+ archivedAt: Date | null
// model: string;
}
@@ -31,20 +32,37 @@ export function getColumns(
const { t } = useTranslation
const isOwner = opts?.isOwner ?? false
return [
- {
+ {
accessorKey: 'name',
- header: ({ column }) => {
- return (
-
- )
- },
+ header: ({ column }) => {
+ return (
+
+ )
+ },
+ cell: ({ row }) => {
+ const device = row.original
+ const isArchived = !!device.archivedAt
+
+ return (
+
+
+ {device.name}
+
+ {isArchived ? (
+
+ {t('archived')}
+
+ ) : null}
+
+ )
+ },
},
{
accessorKey: 'createdAt',
@@ -102,16 +120,15 @@ export function getColumns(
{t('sensebox_id')}
),
cell: ({ row }) => {
- const senseBox = row.original
+ const device = row.original
return (
- //
- {senseBox?.id}
+ {device?.id}
navigator.clipboard.writeText(senseBox?.id)}
+ onClick={() => navigator.clipboard.writeText(device?.id)}
className="ml-[6px] mr-1 inline-block h-4 w-4 cursor-pointer align-text-bottom text-[#818a91] dark:text-white"
/>
@@ -124,7 +141,8 @@ export function getColumns(
{t('actions')}
),
cell: ({ row }) => {
- const senseBox = row.original
+ const device = row.original
+ const isArchived = !!device.archivedAt
return (
@@ -134,49 +152,66 @@ export function getColumns(
+
- Actions
+ {t('actions')}
+
- {t('overview')}
+ {t('overview')}
-
- {t('show_on_map')}
+
+
+ {t('show_on_map')}
+
{isOwner ? (
<>
-
- {t('edit')}
-
-
-
- {t('data_upload')}
-
-
-
-
- {t('support')}
-
-
- navigator.clipboard.writeText(senseBox?.id)}
- className="cursor-pointer"
- >
- {t('copy_id')}
-
- >
- ): null }
+
+ {isArchived ? (
+ {t('edit')}
+ ) : (
+
+ {t('edit')}
+
+ )}
+
+
+
+ {isArchived ? (
+ {t('data_upload')}
+ ) : (
+
+ {t('data_upload')}
+
+ )}
+
+
+
+
+ {t('support')}
+
+
+
+ navigator.clipboard.writeText(device.id)}
+ className="cursor-pointer"
+ >
+ {t('copy_id')}
+
+ >
+ ) : null}
)
},
- },
+ }
]
}
diff --git a/app/components/mydevices/dt/data-table.tsx b/app/components/mydevices/dt/data-table.tsx
index 51711a66..189f4101 100644
--- a/app/components/mydevices/dt/data-table.tsx
+++ b/app/components/mydevices/dt/data-table.tsx
@@ -40,11 +40,13 @@ import {
interface DataTableProps
{
columns: ColumnDef[]
data: TData[]
+ getRowClassName?: (row: TData) => string
}
export function DataTable({
columns,
data,
+ getRowClassName,
}: DataTableProps) {
const [sorting, setSorting] = React.useState([
{ id: 'createdAt', desc: true },
@@ -72,8 +74,8 @@ export function DataTable({
},
},
})
- const tableColsWidth = [30, 30, 30, 40]
+ const tableColsWidth = [30, 30, 30, 40]
const { t } = useTranslation('data-table')
return (
@@ -94,27 +96,27 @@ export function DataTable({
{table.getHeaderGroups().map((headerGroup) => (
- {headerGroup.headers.map((header) => {
- return (
-
- {header.isPlaceholder
- ? null
- : flexRender(
- header.column.columnDef.header,
- header.getContext(),
- )}
-
- )
- })}
+ {headerGroup.headers.map((header) => (
+
+ {header.isPlaceholder
+ ? null
+ : flexRender(
+ header.column.columnDef.header,
+ header.getContext(),
+ )}
+
+ ))}
))}
+
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
{row.getVisibleCells().map((cell, index) => (
({
onValueChange={(value) => {
table.setPageSize(Number(value))
}}
- // disabled={isPending}
>
@@ -218,4 +219,4 @@ export function DataTable({
)
-}
+}
\ No newline at end of file
diff --git a/app/models/device.server.ts b/app/models/device.server.ts
index 42039ed7..f5f2ceb6 100644
--- a/app/models/device.server.ts
+++ b/app/models/device.server.ts
@@ -7,7 +7,9 @@ import {
arrayContains,
and,
between,
+ isNull,
type ExtractTablesWithRelations,
+ isNotNull,
} from 'drizzle-orm'
import { type PgTransaction } from 'drizzle-orm/pg-core'
import { type PostgresJsQueryResultHKT } from 'drizzle-orm/postgres-js'
@@ -47,6 +49,7 @@ const BASE_DEVICE_COLUMNS = {
status: true,
createdAt: true,
updatedAt: true,
+ archivedAt: true,
expiresAt: true,
useAuth: true,
apiKey: true,
@@ -433,6 +436,7 @@ export async function getDevices(
export async function getDevices(format: DevicesFormat = 'json') {
const devices = await drizzleClient.query.device.findMany({
+ where: (device) => isNull(device.archivedAt),
columns: {
id: true,
name: true,
@@ -463,6 +467,24 @@ export async function getDevices(format: DevicesFormat = 'json') {
return devices
}
+export async function getArchivedDevices(){
+ const devices = await drizzleClient.query.device.findMany({
+ where: (device) => isNotNull(device.archivedAt),
+ columns: {
+ id: true,
+ name: true,
+ latitude: true,
+ longitude: true,
+ exposure: true,
+ status: true,
+ createdAt: true,
+ tags: true,
+ archivedAt: true
+ },
+ })
+ return devices
+}
+
export async function getDevicesWithSensors() {
const rows = await drizzleClient
.select({
@@ -476,6 +498,8 @@ export async function getDevicesWithSensors() {
})
.from(device)
.leftJoin(sensor, eq(sensor.deviceId, device.id))
+ .where(isNull(device.archivedAt))
+
const geojson: GeoJSON.FeatureCollection = {
type: 'FeatureCollection',
features: [],
diff --git a/app/routes/profile.$username.tsx b/app/routes/profile.$username.tsx
index d4c95c79..efac7883 100644
--- a/app/routes/profile.$username.tsx
+++ b/app/routes/profile.$username.tsx
@@ -199,6 +199,11 @@ export default function ProfilePage() {
+ device.archivedAt
+ ? 'opacity-60 bg-slate-100 dark:bg-slate-900/40'
+ : ''
+ }
/>
)}
diff --git a/app/schema/device.ts b/app/schema/device.ts
index db58f8a6..20d5a6c5 100644
--- a/app/schema/device.ts
+++ b/app/schema/device.ts
@@ -46,6 +46,7 @@ export const device = pgTable('device', {
public: boolean('public').default(false),
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at').defaultNow().notNull(),
+ archivedAt: timestamp('archived_at'),
expiresAt: date('expires_at', { mode: 'date' }),
latitude: doublePrecision('latitude').notNull(),
longitude: doublePrecision('longitude').notNull(),
diff --git a/drizzle/0034_mute_ultragirl.sql b/drizzle/0034_mute_ultragirl.sql
new file mode 100644
index 00000000..13e0b7f9
--- /dev/null
+++ b/drizzle/0034_mute_ultragirl.sql
@@ -0,0 +1 @@
+ALTER TABLE "device" ADD COLUMN "archived_at" timestamp;
\ No newline at end of file
diff --git a/drizzle/0035_handy_rawhide_kid.sql b/drizzle/0035_handy_rawhide_kid.sql
new file mode 100644
index 00000000..b377b19b
--- /dev/null
+++ b/drizzle/0035_handy_rawhide_kid.sql
@@ -0,0 +1,23 @@
+CREATE OR REPLACE PROCEDURE archive_inactive_devices()
+LANGUAGE SQL
+AS $$
+ UPDATE device d
+ SET
+ archived_at = now(),
+ updated_at = now()
+ WHERE d.archived_at IS NULL
+ AND d.created_at < now() - interval '12 months'
+ AND NOT EXISTS (
+ SELECT 1
+ FROM sensor s
+ JOIN measurement m ON m.sensor_id = s.id
+ WHERE s.device_id = d.id
+ AND m.time >= now() - interval '12 months'
+ );
+$$;
+
+SELECT cron.schedule(
+ 'device-archive-inactive',
+ '0 2 * * *',
+ 'CALL archive_inactive_devices()'
+);
\ No newline at end of file
diff --git a/drizzle/meta/0034_snapshot.json b/drizzle/meta/0034_snapshot.json
new file mode 100644
index 00000000..9a6f889b
--- /dev/null
+++ b/drizzle/meta/0034_snapshot.json
@@ -0,0 +1,1336 @@
+{
+ "id": "70db0852-369c-47bf-9b12-f9b6f8295fbf",
+ "prevId": "2df45cfc-982c-4c7c-b2e7-6fe47039d121",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.device": {
+ "name": "device",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "website": {
+ "name": "website",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tags": {
+ "name": "tags",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "ARRAY[]::text[]"
+ },
+ "link": {
+ "name": "link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "use_auth": {
+ "name": "use_auth",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "apiKey": {
+ "name": "apiKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exposure": {
+ "name": "exposure",
+ "type": "exposure",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'inactive'"
+ },
+ "model": {
+ "name": "model",
+ "type": "model",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'custom'"
+ },
+ "public": {
+ "name": "public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "latitude": {
+ "name": "latitude",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "longitude": {
+ "name": "longitude",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sensor_wiki_model": {
+ "name": "sensor_wiki_model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.device_to_location": {
+ "name": "device_to_location",
+ "schema": "",
+ "columns": {
+ "device_id": {
+ "name": "device_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "location_id": {
+ "name": "location_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "device_to_location_device_id_device_id_fk": {
+ "name": "device_to_location_device_id_device_id_fk",
+ "tableFrom": "device_to_location",
+ "tableTo": "device",
+ "columnsFrom": [
+ "device_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "cascade"
+ },
+ "device_to_location_location_id_location_id_fk": {
+ "name": "device_to_location_location_id_location_id_fk",
+ "tableFrom": "device_to_location",
+ "tableTo": "location",
+ "columnsFrom": [
+ "location_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "device_to_location_device_id_location_id_time_pk": {
+ "name": "device_to_location_device_id_location_id_time_pk",
+ "columns": [
+ "device_id",
+ "location_id",
+ "time"
+ ]
+ }
+ },
+ "uniqueConstraints": {
+ "device_to_location_device_id_location_id_time_unique": {
+ "name": "device_to_location_device_id_location_id_time_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "device_id",
+ "location_id",
+ "time"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.measurement": {
+ "name": "measurement",
+ "schema": "",
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "value": {
+ "name": "value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "location_id": {
+ "name": "location_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "measurement_location_id_location_id_fk": {
+ "name": "measurement_location_id_location_id_fk",
+ "tableFrom": "measurement",
+ "tableTo": "location",
+ "columnsFrom": [
+ "location_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "measurement_sensor_id_time_unique": {
+ "name": "measurement_sensor_id_time_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "sensor_id",
+ "time"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.password": {
+ "name": "password",
+ "schema": "",
+ "columns": {
+ "hash": {
+ "name": "hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "password_user_id_user_id_fk": {
+ "name": "password_user_id_user_id_fk",
+ "tableFrom": "password",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.password_reset_request": {
+ "name": "password_reset_request",
+ "schema": "",
+ "columns": {
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "password_reset_request_user_id_user_id_fk": {
+ "name": "password_reset_request_user_id_user_id_fk",
+ "tableFrom": "password_reset_request",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "password_reset_request_user_id_unique": {
+ "name": "password_reset_request_user_id_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "user_id"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.profile": {
+ "name": "profile",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "public": {
+ "name": "public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "profile_user_id_user_id_fk": {
+ "name": "profile_user_id_user_id_fk",
+ "tableFrom": "profile",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "profile_username_unique": {
+ "name": "profile_username_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "username"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.profile_image": {
+ "name": "profile_image",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "alt_text": {
+ "name": "alt_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "blob": {
+ "name": "blob",
+ "type": "bytea",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "profile_id": {
+ "name": "profile_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "profile_image_profile_id_profile_id_fk": {
+ "name": "profile_image_profile_id_profile_id_fk",
+ "tableFrom": "profile_image",
+ "tableTo": "profile",
+ "columnsFrom": [
+ "profile_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sensor": {
+ "name": "sensor",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "unit": {
+ "name": "unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensor_type": {
+ "name": "sensor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'inactive'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "device_id": {
+ "name": "device_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sensor_wiki_type": {
+ "name": "sensor_wiki_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensor_wiki_phenomenon": {
+ "name": "sensor_wiki_phenomenon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensor_wiki_unit": {
+ "name": "sensor_wiki_unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lastMeasurement": {
+ "name": "lastMeasurement",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "data": {
+ "name": "data",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "sensor_device_id_device_id_fk": {
+ "name": "sensor_device_id_device_id_fk",
+ "tableFrom": "sensor",
+ "tableTo": "device",
+ "columnsFrom": [
+ "device_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "unconfirmed_email": {
+ "name": "unconfirmed_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'user'"
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'en_US'"
+ },
+ "email_is_confirmed": {
+ "name": "email_is_confirmed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "email_confirmation_token": {
+ "name": "email_confirmation_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "email"
+ ]
+ },
+ "user_unconfirmed_email_unique": {
+ "name": "user_unconfirmed_email_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "unconfirmed_email"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.location": {
+ "name": "location",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "location": {
+ "name": "location",
+ "type": "geometry(point)",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "location_index": {
+ "name": "location_index",
+ "columns": [
+ {
+ "expression": "location",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "gist",
+ "with": {}
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "location_location_unique": {
+ "name": "location_location_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "location"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.log_entry": {
+ "name": "log_entry",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "public": {
+ "name": "public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "device_id": {
+ "name": "device_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.refresh_token": {
+ "name": "refresh_token",
+ "schema": "",
+ "columns": {
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "refresh_token_user_id_user_id_fk": {
+ "name": "refresh_token_user_id_user_id_fk",
+ "tableFrom": "refresh_token",
+ "tableTo": "user",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.token_revocation": {
+ "name": "token_revocation",
+ "schema": "",
+ "columns": {
+ "hash": {
+ "name": "hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.claim": {
+ "name": "claim",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "box_id": {
+ "name": "box_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "claim_expires_at_idx": {
+ "name": "claim_expires_at_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "claim_box_id_device_id_fk": {
+ "name": "claim_box_id_device_id_fk",
+ "tableFrom": "claim",
+ "tableTo": "device",
+ "columnsFrom": [
+ "box_id"
+ ],
+ "columnsTo": [
+ "id"
+ ],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "unique_box_id": {
+ "name": "unique_box_id",
+ "nullsNotDistinct": false,
+ "columns": [
+ "box_id"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.integration": {
+ "name": "integration",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "service_url": {
+ "name": "service_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "service_key": {
+ "name": "service_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "order": {
+ "name": "order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "integration_slug_unique": {
+ "name": "integration_slug_unique",
+ "nullsNotDistinct": false,
+ "columns": [
+ "slug"
+ ]
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {
+ "public.exposure": {
+ "name": "exposure",
+ "schema": "public",
+ "values": [
+ "indoor",
+ "outdoor",
+ "mobile",
+ "unknown"
+ ]
+ },
+ "public.model": {
+ "name": "model",
+ "schema": "public",
+ "values": [
+ "homeV2Lora",
+ "homeV2Ethernet",
+ "homeV2Wifi",
+ "homeEthernet",
+ "homeWifi",
+ "homeEthernetFeinstaub",
+ "homeWifiFeinstaub",
+ "luftdaten_sds011",
+ "luftdaten_sds011_dht11",
+ "luftdaten_sds011_dht22",
+ "luftdaten_sds011_bmp180",
+ "luftdaten_sds011_bme280",
+ "hackair_home_v2",
+ "senseBox:Edu",
+ "luftdaten.info",
+ "custom"
+ ]
+ },
+ "public.status": {
+ "name": "status",
+ "schema": "public",
+ "values": [
+ "active",
+ "inactive",
+ "old"
+ ]
+ }
+ },
+ "schemas": {},
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "views": {
+ "public.measurement_10min": {
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "name": "measurement_10min",
+ "schema": "public",
+ "isExisting": true,
+ "materialized": true
+ },
+ "public.measurement_1day": {
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "name": "measurement_1day",
+ "schema": "public",
+ "isExisting": true,
+ "materialized": true
+ },
+ "public.measurement_1hour": {
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "name": "measurement_1hour",
+ "schema": "public",
+ "isExisting": true,
+ "materialized": true
+ },
+ "public.measurement_1month": {
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "name": "measurement_1month",
+ "schema": "public",
+ "isExisting": true,
+ "materialized": true
+ },
+ "public.measurement_1year": {
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "name": "measurement_1year",
+ "schema": "public",
+ "isExisting": true,
+ "materialized": true
+ }
+ },
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/drizzle/meta/0035_snapshot.json b/drizzle/meta/0035_snapshot.json
new file mode 100644
index 00000000..52b7c1fc
--- /dev/null
+++ b/drizzle/meta/0035_snapshot.json
@@ -0,0 +1,1336 @@
+{
+ "id": "3a3aef01-9339-43fd-8bd4-330319cac9c9",
+ "prevId": "70db0852-369c-47bf-9b12-f9b6f8295fbf",
+ "version": "7",
+ "dialect": "postgresql",
+ "tables": {
+ "public.device": {
+ "name": "device",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "image": {
+ "name": "image",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "website": {
+ "name": "website",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "tags": {
+ "name": "tags",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "ARRAY[]::text[]"
+ },
+ "link": {
+ "name": "link",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "use_auth": {
+ "name": "use_auth",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "apiKey": {
+ "name": "apiKey",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "exposure": {
+ "name": "exposure",
+ "type": "exposure",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'inactive'"
+ },
+ "model": {
+ "name": "model",
+ "type": "model",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'custom'"
+ },
+ "public": {
+ "name": "public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "archived_at": {
+ "name": "archived_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "date",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "latitude": {
+ "name": "latitude",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "longitude": {
+ "name": "longitude",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sensor_wiki_model": {
+ "name": "sensor_wiki_model",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.device_to_location": {
+ "name": "device_to_location",
+ "schema": "",
+ "columns": {
+ "device_id": {
+ "name": "device_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "location_id": {
+ "name": "location_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "device_to_location_device_id_device_id_fk": {
+ "name": "device_to_location_device_id_device_id_fk",
+ "tableFrom": "device_to_location",
+ "columnsFrom": [
+ "device_id"
+ ],
+ "tableTo": "device",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "cascade",
+ "onDelete": "cascade"
+ },
+ "device_to_location_location_id_location_id_fk": {
+ "name": "device_to_location_location_id_location_id_fk",
+ "tableFrom": "device_to_location",
+ "columnsFrom": [
+ "location_id"
+ ],
+ "tableTo": "location",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {
+ "device_to_location_device_id_location_id_time_pk": {
+ "name": "device_to_location_device_id_location_id_time_pk",
+ "columns": [
+ "device_id",
+ "location_id",
+ "time"
+ ]
+ }
+ },
+ "uniqueConstraints": {
+ "device_to_location_device_id_location_id_time_unique": {
+ "name": "device_to_location_device_id_location_id_time_unique",
+ "columns": [
+ "device_id",
+ "location_id",
+ "time"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.measurement": {
+ "name": "measurement",
+ "schema": "",
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "value": {
+ "name": "value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "location_id": {
+ "name": "location_id",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "measurement_location_id_location_id_fk": {
+ "name": "measurement_location_id_location_id_fk",
+ "tableFrom": "measurement",
+ "columnsFrom": [
+ "location_id"
+ ],
+ "tableTo": "location",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "measurement_sensor_id_time_unique": {
+ "name": "measurement_sensor_id_time_unique",
+ "columns": [
+ "sensor_id",
+ "time"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.password": {
+ "name": "password",
+ "schema": "",
+ "columns": {
+ "hash": {
+ "name": "hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "password_user_id_user_id_fk": {
+ "name": "password_user_id_user_id_fk",
+ "tableFrom": "password",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "cascade",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.password_reset_request": {
+ "name": "password_reset_request",
+ "schema": "",
+ "columns": {
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "password_reset_request_user_id_user_id_fk": {
+ "name": "password_reset_request_user_id_user_id_fk",
+ "tableFrom": "password_reset_request",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "password_reset_request_user_id_unique": {
+ "name": "password_reset_request_user_id_unique",
+ "columns": [
+ "user_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.profile": {
+ "name": "profile",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "username": {
+ "name": "username",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "public": {
+ "name": "public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "profile_user_id_user_id_fk": {
+ "name": "profile_user_id_user_id_fk",
+ "tableFrom": "profile",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "cascade",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "profile_username_unique": {
+ "name": "profile_username_unique",
+ "columns": [
+ "username"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.profile_image": {
+ "name": "profile_image",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "alt_text": {
+ "name": "alt_text",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "content_type": {
+ "name": "content_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "blob": {
+ "name": "blob",
+ "type": "bytea",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "profile_id": {
+ "name": "profile_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "profile_image_profile_id_profile_id_fk": {
+ "name": "profile_image_profile_id_profile_id_fk",
+ "tableFrom": "profile_image",
+ "columnsFrom": [
+ "profile_id"
+ ],
+ "tableTo": "profile",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "cascade",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.sensor": {
+ "name": "sensor",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "title": {
+ "name": "title",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "unit": {
+ "name": "unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensor_type": {
+ "name": "sensor_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "status": {
+ "name": "status",
+ "type": "status",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'inactive'"
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "device_id": {
+ "name": "device_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "sensor_wiki_type": {
+ "name": "sensor_wiki_type",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensor_wiki_phenomenon": {
+ "name": "sensor_wiki_phenomenon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "sensor_wiki_unit": {
+ "name": "sensor_wiki_unit",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "lastMeasurement": {
+ "name": "lastMeasurement",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "data": {
+ "name": "data",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "sensor_device_id_device_id_fk": {
+ "name": "sensor_device_id_device_id_fk",
+ "tableFrom": "sensor",
+ "columnsFrom": [
+ "device_id"
+ ],
+ "tableTo": "device",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.user": {
+ "name": "user",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "email": {
+ "name": "email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "unconfirmed_email": {
+ "name": "unconfirmed_email",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "role": {
+ "name": "role",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'user'"
+ },
+ "language": {
+ "name": "language",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "'en_US'"
+ },
+ "email_is_confirmed": {
+ "name": "email_is_confirmed",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": false,
+ "default": false
+ },
+ "email_confirmation_token": {
+ "name": "email_confirmation_token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "user_email_unique": {
+ "name": "user_email_unique",
+ "columns": [
+ "email"
+ ],
+ "nullsNotDistinct": false
+ },
+ "user_unconfirmed_email_unique": {
+ "name": "user_unconfirmed_email_unique",
+ "columns": [
+ "unconfirmed_email"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.location": {
+ "name": "location",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "bigserial",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "location": {
+ "name": "location",
+ "type": "geometry(point)",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "location_index": {
+ "name": "location_index",
+ "columns": [
+ {
+ "expression": "location",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "gist",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "location_location_unique": {
+ "name": "location_location_unique",
+ "columns": [
+ "location"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.log_entry": {
+ "name": "log_entry",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "content": {
+ "name": "content",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "public": {
+ "name": "public",
+ "type": "boolean",
+ "primaryKey": false,
+ "notNull": true,
+ "default": false
+ },
+ "device_id": {
+ "name": "device_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.refresh_token": {
+ "name": "refresh_token",
+ "schema": "",
+ "columns": {
+ "user_id": {
+ "name": "user_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "refresh_token_user_id_user_id_fk": {
+ "name": "refresh_token_user_id_user_id_fk",
+ "tableFrom": "refresh_token",
+ "columnsFrom": [
+ "user_id"
+ ],
+ "tableTo": "user",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.token_revocation": {
+ "name": "token_revocation",
+ "schema": "",
+ "columns": {
+ "hash": {
+ "name": "hash",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {},
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.claim": {
+ "name": "claim",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "box_id": {
+ "name": "box_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "token": {
+ "name": "token",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "expires_at": {
+ "name": "expires_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "claim_expires_at_idx": {
+ "name": "claim_expires_at_idx",
+ "columns": [
+ {
+ "expression": "expires_at",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": false,
+ "with": {},
+ "method": "btree",
+ "concurrently": false
+ }
+ },
+ "foreignKeys": {
+ "claim_box_id_device_id_fk": {
+ "name": "claim_box_id_device_id_fk",
+ "tableFrom": "claim",
+ "columnsFrom": [
+ "box_id"
+ ],
+ "tableTo": "device",
+ "columnsTo": [
+ "id"
+ ],
+ "onUpdate": "no action",
+ "onDelete": "cascade"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "unique_box_id": {
+ "name": "unique_box_id",
+ "columns": [
+ "box_id"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ },
+ "public.integration": {
+ "name": "integration",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "text",
+ "primaryKey": true,
+ "notNull": true
+ },
+ "name": {
+ "name": "name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "slug": {
+ "name": "slug",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "service_url": {
+ "name": "service_url",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "service_key": {
+ "name": "service_key",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "icon": {
+ "name": "icon",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "description": {
+ "name": "description",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "order": {
+ "name": "order",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "created_at": {
+ "name": "created_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {},
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {
+ "integration_slug_unique": {
+ "name": "integration_slug_unique",
+ "columns": [
+ "slug"
+ ],
+ "nullsNotDistinct": false
+ }
+ },
+ "policies": {},
+ "checkConstraints": {},
+ "isRLSEnabled": false
+ }
+ },
+ "enums": {
+ "public.exposure": {
+ "name": "exposure",
+ "schema": "public",
+ "values": [
+ "indoor",
+ "outdoor",
+ "mobile",
+ "unknown"
+ ]
+ },
+ "public.model": {
+ "name": "model",
+ "schema": "public",
+ "values": [
+ "homeV2Lora",
+ "homeV2Ethernet",
+ "homeV2Wifi",
+ "homeEthernet",
+ "homeWifi",
+ "homeEthernetFeinstaub",
+ "homeWifiFeinstaub",
+ "luftdaten_sds011",
+ "luftdaten_sds011_dht11",
+ "luftdaten_sds011_dht22",
+ "luftdaten_sds011_bmp180",
+ "luftdaten_sds011_bme280",
+ "hackair_home_v2",
+ "senseBox:Edu",
+ "luftdaten.info",
+ "custom"
+ ]
+ },
+ "public.status": {
+ "name": "status",
+ "schema": "public",
+ "values": [
+ "active",
+ "inactive",
+ "old"
+ ]
+ }
+ },
+ "schemas": {},
+ "views": {
+ "public.measurement_10min": {
+ "name": "measurement_10min",
+ "schema": "public",
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "materialized": true,
+ "isExisting": true
+ },
+ "public.measurement_1day": {
+ "name": "measurement_1day",
+ "schema": "public",
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "materialized": true,
+ "isExisting": true
+ },
+ "public.measurement_1hour": {
+ "name": "measurement_1hour",
+ "schema": "public",
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "materialized": true,
+ "isExisting": true
+ },
+ "public.measurement_1month": {
+ "name": "measurement_1month",
+ "schema": "public",
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "materialized": true,
+ "isExisting": true
+ },
+ "public.measurement_1year": {
+ "name": "measurement_1year",
+ "schema": "public",
+ "columns": {
+ "sensor_id": {
+ "name": "sensor_id",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "time": {
+ "name": "time",
+ "type": "timestamp (3) with time zone",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "avg_value": {
+ "name": "avg_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "total_values": {
+ "name": "total_values",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "min_value": {
+ "name": "min_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "max_value": {
+ "name": "max_value",
+ "type": "double precision",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "materialized": true,
+ "isExisting": true
+ }
+ },
+ "sequences": {},
+ "roles": {},
+ "policies": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
\ No newline at end of file
diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json
index 07a2283d..6053429e 100644
--- a/drizzle/meta/_journal.json
+++ b/drizzle/meta/_journal.json
@@ -239,6 +239,20 @@
"when": 1772009671134,
"tag": "0033_caag-retention-policies",
"breakpoints": true
+ },
+ {
+ "idx": 34,
+ "version": "7",
+ "when": 1773145800241,
+ "tag": "0034_mute_ultragirl",
+ "breakpoints": true
+ },
+ {
+ "idx": 35,
+ "version": "7",
+ "when": 1773145838146,
+ "tag": "0035_handy_rawhide_kid",
+ "breakpoints": true
}
]
}
\ No newline at end of file