Skip to content

Commit 26ec299

Browse files
Merge pull request #10 from CropWatchDevelopment/alerts-endpoints
adding in rules endpoint to api
2 parents 0408b55 + 9d68dd0 commit 26ec299

13 files changed

Lines changed: 496 additions & 3 deletions

.vscode/launch.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"type": "node",
6+
"request": "launch",
7+
"name": "Debug NestJS (start:debug)",
8+
"runtimeExecutable": "pnpm",
9+
"runtimeArgs": ["run", "start:debug"],
10+
"cwd": "${workspaceFolder}",
11+
"console": "integratedTerminal",
12+
"sourceMaps": true,
13+
"autoAttachChildProcesses": true,
14+
"envFile": "${workspaceFolder}/.env",
15+
"skipFiles": ["<node_internals>/**"]
16+
}
17+
]
18+
}

src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { join } from 'path';
1414
import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
1515
import { APP_GUARD } from '@nestjs/core';
1616
import { DevicesModule } from './devices/devices.module';
17+
import { RulesModule } from './rules/rules.module';
1718

1819
@Module({
1920
imports: [
@@ -37,6 +38,7 @@ import { DevicesModule } from './devices/devices.module';
3738
},
3839
]),
3940
DevicesModule,
41+
RulesModule,
4042
],
4143
controllers: [AppController],
4244
providers: [AppService, { provide: APP_GUARD, useClass: ThrottlerGuard }],

src/main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ async function bootstrap() {
3131
customSwaggerUiPath: join(process.cwd(), 'static', 'docs'),
3232
customCssUrl: '/cw-swagger.css',
3333
customfavIcon: '/favicon.svg',
34+
swaggerOptions: {
35+
persistAuthorization: true,
36+
},
3437
});
3538
app.use(
3639
helmet({

src/rules/dto/create-rule.dto.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { Database } from '../../../database.types';
3+
4+
type RuleInsert = Database['public']['Tables']['cw_rules']['Insert'];
5+
6+
export class CreateRuleDto implements RuleInsert {
7+
@ApiProperty()
8+
action_recipient: string;
9+
10+
@ApiProperty()
11+
name: string;
12+
13+
@ApiProperty()
14+
notifier_type: number;
15+
16+
@ApiProperty()
17+
ruleGroupId: string;
18+
19+
@ApiProperty({ required: false })
20+
created_at?: string;
21+
22+
@ApiProperty({ required: false, nullable: true })
23+
dev_eui?: string | null;
24+
25+
@ApiProperty({ required: false })
26+
id?: number;
27+
28+
@ApiProperty({ required: false })
29+
is_triggered?: boolean;
30+
31+
@ApiProperty({ required: false, nullable: true })
32+
last_triggered?: string | null;
33+
34+
@ApiProperty({ required: false })
35+
profile_id?: string;
36+
37+
@ApiProperty({ required: false, nullable: true })
38+
send_using?: string | null;
39+
40+
@ApiProperty({ required: false })
41+
trigger_count?: number;
42+
}

src/rules/dto/rule.dto.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { Database } from '../../../database.types';
3+
4+
type RuleRow = Database['public']['Tables']['cw_rules']['Row'];
5+
6+
export class RuleDto implements RuleRow {
7+
@ApiProperty()
8+
id: number;
9+
10+
@ApiProperty()
11+
name: string;
12+
13+
@ApiProperty()
14+
action_recipient: string;
15+
16+
@ApiProperty()
17+
notifier_type: number;
18+
19+
@ApiProperty()
20+
ruleGroupId: string;
21+
22+
@ApiProperty()
23+
profile_id: string;
24+
25+
@ApiProperty({ nullable: true, required: false })
26+
dev_eui: string | null;
27+
28+
@ApiProperty({ nullable: true, required: false })
29+
send_using: string | null;
30+
31+
@ApiProperty()
32+
is_triggered: boolean;
33+
34+
@ApiProperty()
35+
trigger_count: number;
36+
37+
@ApiProperty({ format: 'date-time' })
38+
created_at: string;
39+
40+
@ApiProperty({ nullable: true, required: false, format: 'date-time' })
41+
last_triggered: string | null;
42+
}

src/rules/dto/update-rule.dto.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { PartialType } from '@nestjs/swagger';
2+
import { Database } from '../../../database.types';
3+
import { CreateRuleDto } from './create-rule.dto';
4+
5+
type RuleUpdate = Database['public']['Tables']['cw_rules']['Update'];
6+
7+
export class UpdateRuleDto
8+
extends PartialType(CreateRuleDto)
9+
implements RuleUpdate {}

src/rules/entities/rule.entity.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export class Rule {}

src/rules/rules.controller.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Test, TestingModule } from '@nestjs/testing';
2+
import { RulesController } from './rules.controller';
3+
import { RulesService } from './rules.service';
4+
5+
describe('RulesController', () => {
6+
let controller: RulesController;
7+
8+
beforeEach(async () => {
9+
const module: TestingModule = await Test.createTestingModule({
10+
controllers: [RulesController],
11+
providers: [
12+
{
13+
provide: RulesService,
14+
useValue: {},
15+
},
16+
],
17+
}).compile();
18+
19+
controller = module.get<RulesController>(RulesController);
20+
});
21+
22+
it('should be defined', () => {
23+
expect(controller).toBeDefined();
24+
});
25+
});

src/rules/rules.controller.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { Controller, Get, Post, Body, Patch, Param, Delete, Req, UseGuards } from '@nestjs/common';
2+
import { RulesService } from './rules.service';
3+
import { CreateRuleDto } from './dto/create-rule.dto';
4+
import { UpdateRuleDto } from './dto/update-rule.dto';
5+
import { ApiBearerAuth, ApiOkResponse, ApiSecurity } from '@nestjs/swagger';
6+
import { JwtAuthGuard } from '../auth/guards/jwt.auth.guard';
7+
import { RuleDto } from './dto/rule.dto';
8+
9+
@ApiBearerAuth('bearerAuth')
10+
@ApiSecurity('apiKey')
11+
@Controller('rules')
12+
export class RulesController {
13+
constructor(private readonly rulesService: RulesService) { }
14+
15+
@UseGuards(JwtAuthGuard)
16+
@ApiOkResponse({
17+
description:
18+
"Create a new rule configuration. Only the fields included in the request body will be used.",
19+
type: RuleDto,
20+
isArray: false,
21+
})
22+
@Post()
23+
create(@Body() createRuleDto: CreateRuleDto, @Req() req) {
24+
const authHeader = req.headers?.authorization;
25+
if (!authHeader) {
26+
throw new Error('Authorization header is required');
27+
}
28+
return this.rulesService.create(createRuleDto, req.user, authHeader);
29+
}
30+
31+
@UseGuards(JwtAuthGuard)
32+
@ApiOkResponse({
33+
description:
34+
"Current all of the user's rules configurations.",
35+
type: RuleDto,
36+
isArray: true,
37+
})
38+
@Get()
39+
findAll(@Req() req) {
40+
const authHeader = req.headers?.authorization ?? '';
41+
return this.rulesService.findAll(req.user, authHeader);
42+
}
43+
44+
@UseGuards(JwtAuthGuard)
45+
@ApiOkResponse({
46+
description:
47+
"Gets a user's rule configuration by ID.",
48+
type: RuleDto,
49+
isArray: false,
50+
})
51+
@Get(':id')
52+
findOne(@Param('id') id: number, @Req() req) {
53+
const authHeader = req.headers?.authorization ?? '';
54+
return this.rulesService.findOne(id, req.user, authHeader);
55+
}
56+
57+
@UseGuards(JwtAuthGuard)
58+
@ApiOkResponse({
59+
description:
60+
"Update a single rule configuration by ID. Only the fields included in the request body will be updated.",
61+
type: RuleDto,
62+
isArray: false,
63+
})
64+
@Patch(':id')
65+
update(@Param('id') id: number, @Body() updateRuleDto: UpdateRuleDto, @Req() req) {
66+
const authHeader = req.headers?.authorization ?? '';
67+
return this.rulesService.update(id, updateRuleDto, req.user, authHeader);
68+
}
69+
70+
@UseGuards(JwtAuthGuard)
71+
@ApiOkResponse({
72+
description:
73+
"Delete a user's rule configuration by ID.",
74+
type: Number,
75+
isArray: false,
76+
})
77+
@Delete(':id')
78+
remove(@Param('id') id: number, @Req() req) {
79+
const authHeader = req.headers?.authorization ?? '';
80+
return this.rulesService.remove(id, req.user, authHeader);
81+
}
82+
}

src/rules/rules.module.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Module } from '@nestjs/common';
2+
import { RulesService } from './rules.service';
3+
import { RulesController } from './rules.controller';
4+
import { SupabaseModule } from '../supabase/supabase.module';
5+
6+
@Module({
7+
imports: [SupabaseModule],
8+
controllers: [RulesController],
9+
providers: [RulesService],
10+
})
11+
export class RulesModule { }

0 commit comments

Comments
 (0)