Fix validation, add sensor last contact field, add alert status formatting
This commit is contained in:
parent
e1b0d16ce6
commit
e6438ad0f1
|
|
@ -1,5 +1,12 @@
|
|||
import { request } from './request'
|
||||
|
||||
export enum AlertStatuses {
|
||||
OK = 'ok',
|
||||
ALERT_PENDING = 'alert_pending',
|
||||
ALERTING = 'alerting',
|
||||
OK_PENDING = 'ok_pending',
|
||||
}
|
||||
|
||||
export type AlertInfo = {
|
||||
id: number
|
||||
name: string
|
||||
|
|
@ -8,8 +15,8 @@ export type AlertInfo = {
|
|||
customMessage: string
|
||||
customResolvedMessage: string
|
||||
triggerInterval: number
|
||||
lastStatus: string
|
||||
lastStatusAt: string
|
||||
lastStatus: AlertStatuses
|
||||
lastStatusAt: number
|
||||
}
|
||||
|
||||
export const getAlerts = () => request<AlertInfo[]>('/api/alerts')
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export const updateContactPoint = ({ id, ...body }: ContactPointInfo) =>
|
|||
})
|
||||
|
||||
export const deleteContactPoint = (id: number) =>
|
||||
request<ContactPointInfo>(
|
||||
request<void, 'void'>(
|
||||
`/api/contact-points/${id}`,
|
||||
{ method: 'DELETE' },
|
||||
'void'
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export const updateDashboard = ({
|
|||
})
|
||||
|
||||
export const deleteDashboard = (id: number) =>
|
||||
request<DashboardInfo>(
|
||||
request<void, 'void'>(
|
||||
`/api/dashboards/${id}`,
|
||||
{
|
||||
method: 'DELETE',
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ export type SensorInfo = {
|
|||
id: number
|
||||
name: string
|
||||
authKey: string
|
||||
lastContactAt?: number
|
||||
}
|
||||
|
||||
export const getSensors = () => request<SensorInfo[]>('/api/sensors')
|
||||
|
|
@ -23,4 +24,4 @@ export const updateSensor = ({ id, ...body }: { id: number; name: string }) =>
|
|||
})
|
||||
|
||||
export const deleteSensor = (id: number) =>
|
||||
request<SensorInfo>(`/api/sensors/${id}`, { method: 'DELETE' }, 'void')
|
||||
request<void, 'void'>(`/api/sensors/${id}`, { method: 'DELETE' }, 'void')
|
||||
|
|
|
|||
|
|
@ -5,4 +5,27 @@
|
|||
.contact-points {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.alert-status {
|
||||
text-transform: uppercase;
|
||||
padding: 0.2rem 0.4rem;
|
||||
border-radius: var(--border-radius);
|
||||
display: inline-flex;
|
||||
|
||||
&.status-ok {
|
||||
background-color: #016101;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.status-alert_pending,
|
||||
&.status-ok_pending {
|
||||
background-color: #ff8c00;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.status-alerting {
|
||||
background-color: #d22424;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import { AlertInfo, AlertStatuses } from '@/api/alerts'
|
||||
import { cn } from '@/utils/cn'
|
||||
import { formatDateTime } from '@/utils/formatDateTime'
|
||||
|
||||
type Props = {
|
||||
alert: Pick<AlertInfo, 'lastStatus' | 'lastStatusAt'>
|
||||
}
|
||||
|
||||
const statusToStr = {
|
||||
[AlertStatuses.OK]: 'OK',
|
||||
[AlertStatuses.ALERT_PENDING]: 'Alert pending',
|
||||
[AlertStatuses.ALERTING]: 'Alerting',
|
||||
[AlertStatuses.OK_PENDING]: 'OK pending',
|
||||
} as const
|
||||
|
||||
export const AlertStatus = ({ alert }: Props) => {
|
||||
return (
|
||||
<div
|
||||
className={cn('alert-status', `status-${alert.lastStatus}`)}
|
||||
title={`Last update at ${formatDateTime(alert.lastStatusAt)}`}
|
||||
>
|
||||
{statusToStr[alert.lastStatus]}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import { useState } from 'preact/hooks'
|
|||
import { useMutation, useQuery } from 'react-query'
|
||||
import { AlertFormModal } from './components/AlertFormModal'
|
||||
import { NoAlerts } from '../NoAlerts'
|
||||
import { AlertStatus } from '../AlertStatus'
|
||||
|
||||
export const AlertsTable = () => {
|
||||
const alerts = useQuery('/alerts', getAlerts, {
|
||||
|
|
@ -43,8 +44,8 @@ export const AlertsTable = () => {
|
|||
{
|
||||
key: 'lastStatus',
|
||||
title: 'Last status',
|
||||
render: (c) => c.lastStatus,
|
||||
width: '10rem',
|
||||
render: (c) => <AlertStatus alert={c} />,
|
||||
width: '6rem',
|
||||
},
|
||||
{
|
||||
key: 'actions',
|
||||
|
|
|
|||
|
|
@ -53,7 +53,10 @@ export const ContactPointsTable = () => {
|
|||
className: 'actions',
|
||||
render: (c) => (
|
||||
<div>
|
||||
<button onClick={() => setShowDelete(c)} className="remove">
|
||||
<button
|
||||
onClick={() => setShowDelete(c)}
|
||||
className="danger-variant"
|
||||
>
|
||||
<TrashIcon /> Delete
|
||||
</button>
|
||||
<button onClick={() => setEdited(c)}>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { SensorFormModal } from './components/SensorFormModal'
|
|||
import { useConfirmModal } from '@/contexts/ConfirmModalsContext'
|
||||
import { SensorDetailModal } from './components/SensorDetailModal'
|
||||
import { NoSensors } from './components/NoSensors'
|
||||
import { formatDateTime } from '@/utils/formatDateTime'
|
||||
|
||||
export const SensorsPage = () => {
|
||||
const sensors = useQuery(['/sensors'], getSensors)
|
||||
|
|
@ -43,6 +44,13 @@ export const SensorsPage = () => {
|
|||
columns={[
|
||||
{ key: 'type', title: 'ID', render: (c) => c.id, width: '1rem' },
|
||||
{ key: 'name', title: 'Name', render: (c) => c.name, scale: 1 },
|
||||
{
|
||||
key: 'lastContact',
|
||||
title: 'Last Contact At',
|
||||
render: (c) =>
|
||||
c.lastContactAt ? formatDateTime(c.lastContactAt) : 'Never',
|
||||
width: '10rem',
|
||||
},
|
||||
{
|
||||
key: 'actions',
|
||||
title: 'Actions',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
export const formatDateTime = (unixInSeconds: number) => {
|
||||
const date = new Date(unixInSeconds * 1000)
|
||||
|
||||
return date.toLocaleDateString(undefined, {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE sensors ADD COLUMN last_contact_at INTEGER;
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
package models
|
||||
|
||||
type SensorItem struct {
|
||||
Id int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
AuthKey string `json:"authKey"`
|
||||
Id int64 `json:"id" db:"id"`
|
||||
Name string `json:"name" db:"name"`
|
||||
AuthKey string `json:"authKey" db:"auth_key"`
|
||||
LastContactAt *int64 `json:"lastContactAt" db:"last_contact_at"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ type postAndPutAlertsBody struct {
|
|||
Name string `json:"name" binding:"required"`
|
||||
Condition string `json:"condition" binding:"required"`
|
||||
TriggerInterval int64 `json:"triggerInterval" binding:"required"`
|
||||
CustomMessage string `json:"customMessage" binding:"required"`
|
||||
CustomResolvedMessage string `json:"customResolvedMessage" binding:"required"`
|
||||
CustomMessage string `json:"customMessage"`
|
||||
CustomResolvedMessage string `json:"customResolvedMessage"`
|
||||
}
|
||||
|
||||
func GetAlerts(s *app.Server) gin.HandlerFunc {
|
||||
|
|
@ -32,7 +32,9 @@ func GetAlerts(s *app.Server) gin.HandlerFunc {
|
|||
func PostAlerts(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
body := postAndPutAlertsBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
alert, err := s.Services.Alerts.Create(body.ContactPointId, body.Name, body.Condition, body.TriggerInterval, body.CustomMessage, body.CustomResolvedMessage)
|
||||
|
||||
|
|
@ -47,10 +49,15 @@ func PostAlerts(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func PutAlert(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
alertId := getIntParamOrAbort(c, "alertId")
|
||||
alertId, err := getIntParamOrAbort(c, "alertId")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
body := postAndPutAlertsBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
alert, err := s.Services.Alerts.Update(alertId, body.ContactPointId, body.Name, body.Condition, body.TriggerInterval, body.CustomMessage, body.CustomResolvedMessage)
|
||||
|
||||
|
|
@ -65,7 +72,10 @@ func PutAlert(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func GetAlert(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
alertId := getIntParamOrAbort(c, "alertId")
|
||||
alertId, err := getIntParamOrAbort(c, "alertId")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
alert, err := s.Services.Alerts.GetById(alertId)
|
||||
|
||||
|
|
@ -80,7 +90,10 @@ func GetAlert(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func DeleteAlert(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
alertId := getIntParamOrAbort(c, "alertId")
|
||||
alertId, err := getIntParamOrAbort(c, "alertId")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.Services.Alerts.DeleteById(alertId); err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,9 @@ type postLoginBody struct {
|
|||
func Login(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
body := postLoginBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if body.Password != s.Config.AuthPassword || body.Username != s.Config.AuthUsername {
|
||||
c.AbortWithStatus(401)
|
||||
|
|
|
|||
|
|
@ -34,8 +34,10 @@ func GetContactPoints(s *app.Server) gin.HandlerFunc {
|
|||
func PostContactPoints(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
body := postOrPutContactPointsBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
contactPoint, err := s.Services.ContactPoints.Create(body.Name, body.Type, body.TypeConfig)
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -49,10 +51,15 @@ func PostContactPoints(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func PutContactPoint(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
contactPointId := getIntParamOrAbort(c, "contactPointId")
|
||||
contactPointId, err := getIntParamOrAbort(c, "contactPointId")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
body := postOrPutContactPointsBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
contactPoint, err := s.Services.ContactPoints.Update(contactPointId, body.Name, body.Type, body.TypeConfig)
|
||||
|
||||
|
|
@ -67,7 +74,10 @@ func PutContactPoint(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func GetContactPoint(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
contactPointId := getIntParamOrAbort(c, "contactPointId")
|
||||
contactPointId, err := getIntParamOrAbort(c, "contactPointId")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
contactPoint, err := s.Services.ContactPoints.GetById(contactPointId)
|
||||
|
||||
|
|
@ -82,9 +92,12 @@ func GetContactPoint(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func DeleteContactPoint(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
contactPointId := getIntParamOrAbort(c, "contactPointId")
|
||||
contactPointId, err := getIntParamOrAbort(c, "contactPointId")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := s.Services.ContactPoints.Delete(contactPointId)
|
||||
err = s.Services.ContactPoints.Delete(contactPointId)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
|
|
@ -98,7 +111,9 @@ func DeleteContactPoint(s *app.Server) gin.HandlerFunc {
|
|||
func TestContactPoint(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
body := testContactPointBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := s.Services.ContactPoints.Test(body.Type, body.TypeConfig)
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,10 @@ func GetDashboards(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func GetDashboardById(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id := getIntParamOrAbort(c, "id")
|
||||
id, err := getIntParamOrAbort(c, "id")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
item, err := s.Services.Dashboards.GetById(id)
|
||||
|
||||
|
|
@ -54,7 +57,10 @@ func GetDashboardById(s *app.Server) gin.HandlerFunc {
|
|||
func PostDashboard(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
body := postDashboardBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
item, err := s.Services.Dashboards.Create(body.Name, body.Contents)
|
||||
|
||||
|
|
@ -69,11 +75,16 @@ func PostDashboard(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func PutDashboard(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id := getIntParamOrAbort(c, "id")
|
||||
id, err := getIntParamOrAbort(c, "id")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
body := putDashboardBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
item, err := s.Services.Dashboards.Update(id, body.Name, body.Contents)
|
||||
|
||||
if err != nil {
|
||||
|
|
@ -87,9 +98,12 @@ func PutDashboard(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func DeleteDashboard(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
id := getIntParamOrAbort(c, "id")
|
||||
id, err := getIntParamOrAbort(c, "id")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := s.Services.Dashboards.Delete(id)
|
||||
err = s.Services.Dashboards.Delete(id)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithError(500, err)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ func PutSensorConfig(s *app.Server) gin.HandlerFunc {
|
|||
sensor := c.Param("sensor")
|
||||
key := c.Param("key")
|
||||
|
||||
bindJSONBodyOrAbort(c, &configValue)
|
||||
if err := bindJSONBodyOrAbort(c, &configValue); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := s.Services.SensorConfig.SetValue(sensor, key, configValue.Value); err != nil {
|
||||
c.AbortWithError(500, err)
|
||||
|
|
|
|||
|
|
@ -25,9 +25,14 @@ func PostSensorValues(s *app.Server) gin.HandlerFunc {
|
|||
return func(c *gin.Context) {
|
||||
var newValue postSensorValueBody
|
||||
|
||||
bindJSONBodyOrAbort(c, &newValue)
|
||||
if err := bindJSONBodyOrAbort(c, &newValue); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sensorId := getIntParamOrAbort(c, "sensor")
|
||||
sensorId, err := getIntParamOrAbort(c, "sensor")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := s.Services.SensorValues.Push(sensorId, newValue.Value); err != nil {
|
||||
c.AbortWithError(400, err)
|
||||
|
|
@ -42,7 +47,10 @@ func GetSensorValues(s *app.Server) gin.HandlerFunc {
|
|||
return func(c *gin.Context) {
|
||||
var query getSensorValuesQuery
|
||||
|
||||
sensorId := getIntParamOrAbort(c, "sensor")
|
||||
sensorId, err := getIntParamOrAbort(c, "sensor")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
|
|
@ -63,7 +71,10 @@ func GetSensorLatestValue(s *app.Server) gin.HandlerFunc {
|
|||
return func(c *gin.Context) {
|
||||
var query getLatestSensorValueQuery
|
||||
|
||||
sensorId := getIntParamOrAbort(c, "sensor")
|
||||
sensorId, err := getIntParamOrAbort(c, "sensor")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := c.ShouldBindQuery(&query); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ func GetSensors(s *app.Server) gin.HandlerFunc {
|
|||
func PostSensors(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
body := postOrPutSensorsBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sensor, err := s.Services.Sensors.Create(body.Name)
|
||||
|
||||
|
|
@ -44,10 +46,15 @@ func PostSensors(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func PutSensor(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
sensorId := getIntParamOrAbort(c, "sensor")
|
||||
sensorId, err := getIntParamOrAbort(c, "sensor")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
body := postOrPutSensorsBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sensor, err := s.Services.Sensors.Update(sensorId, body.Name)
|
||||
|
||||
|
|
@ -62,10 +69,15 @@ func PutSensor(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func GetSensor(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
sensorId := getIntParamOrAbort(c, "sensor")
|
||||
sensorId, err := getIntParamOrAbort(c, "sensor")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
body := postOrPutSensorsBody{}
|
||||
bindJSONBodyOrAbort(c, &body)
|
||||
if err := bindJSONBodyOrAbort(c, &body); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sensor, err := s.Services.Sensors.GetById(sensorId)
|
||||
|
||||
|
|
@ -80,9 +92,12 @@ func GetSensor(s *app.Server) gin.HandlerFunc {
|
|||
|
||||
func DeleteSensor(s *app.Server) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
sensorId := getIntParamOrAbort(c, "sensor")
|
||||
sensorId, err := getIntParamOrAbort(c, "sensor")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := s.Services.Sensors.DeleteById(sensorId)
|
||||
err = s.Services.Sensors.DeleteById(sensorId)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
|
|
|
|||
|
|
@ -6,19 +6,24 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func getIntParamOrAbort(c *gin.Context, key string) int64 {
|
||||
func getIntParamOrAbort(c *gin.Context, key string) (int64, error) {
|
||||
value := c.Param(key)
|
||||
val, err := strconv.ParseInt(value, 10, 64)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(400, gin.H{"error": "Invalid " + key})
|
||||
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return val
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func bindJSONBodyOrAbort(c *gin.Context, body interface{}) {
|
||||
func bindJSONBodyOrAbort(c *gin.Context, body interface{}) error {
|
||||
if err := c.ShouldBindJSON(body); err != nil {
|
||||
c.AbortWithStatusJSON(400, gin.H{"error": err.Error()})
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,13 @@ func (s *SensorValuesService) Push(sensorId int64, value float64) (int64, error)
|
|||
res, err := s.ctx.DB.Exec("INSERT INTO sensor_values (timestamp, sensor_id, value) VALUES (?, ?, ?)", time.Now().Unix(), sensorId, value)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return 0, fmt.Errorf("failed to insert sensor value: %v", err)
|
||||
}
|
||||
|
||||
_, err = s.ctx.DB.Exec("UPDATE sensors SET last_contact_at = ? WHERE id = ?", time.Now().Unix(), sensorId)
|
||||
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to update last_contact_at: %v", err)
|
||||
}
|
||||
|
||||
return res.LastInsertId()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package services
|
|||
import (
|
||||
"basic-sensor-receiver/models"
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
|
|
@ -12,32 +11,10 @@ type SensorsService struct {
|
|||
}
|
||||
|
||||
func (s *SensorsService) GetList() ([]models.SensorItem, error) {
|
||||
sensors := make([]models.SensorItem, 0)
|
||||
sensors := []models.SensorItem{}
|
||||
|
||||
rows, err := s.ctx.DB.Query("SELECT id, name, auth_key FROM sensors")
|
||||
err := s.ctx.DB.Select(&sensors, "SELECT id, name, auth_key, last_contact_at FROM sensors")
|
||||
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return sensors, nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
item := models.SensorItem{}
|
||||
|
||||
err := rows.Scan(&item.Id, &item.Name, &item.AuthKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sensors = append(sensors, item)
|
||||
}
|
||||
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -75,9 +52,8 @@ func (s *SensorsService) Create(name string) (*models.SensorItem, error) {
|
|||
func (s *SensorsService) GetById(id int64) (*models.SensorItem, error) {
|
||||
item := models.SensorItem{}
|
||||
|
||||
row := s.ctx.DB.QueryRow("SELECT id, name, auth_key FROM sensors WHERE id = ?", id)
|
||||
err := s.ctx.DB.Get(&item, "SELECT id, name, auth_key, last_contact_at FROM sensors WHERE id = $1", id)
|
||||
|
||||
err := row.Scan(&item.Id, &item.Name, &item.AuthKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue