Skip to content

Commit 0af49fd

Browse files
committed
Add Mock AI assesment
1 parent c9277ae commit 0af49fd

7 files changed

Lines changed: 331 additions & 222 deletions

File tree

backend/pom.xml

Lines changed: 77 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,93 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4-
<modelVersion>4.0.0</modelVersion>
5-
<parent>
6-
<groupId>org.springframework.boot</groupId>
7-
<artifactId>spring-boot-starter-parent</artifactId>
8-
<version>4.0.2</version>
9-
<relativePath/> <!-- lookup parent from repository -->
10-
</parent>
11-
<groupId>com.aiman</groupId>
12-
<artifactId>api</artifactId>
13-
<version>0.0.1-SNAPSHOT</version>
14-
<name>api</name>
15-
<description>Nafath Mock Integration</description>
16-
<url/>
17-
<licenses>
18-
<license/>
19-
</licenses>
20-
<developers>
21-
<developer/>
22-
</developers>
23-
<scm>
24-
<connection/>
25-
<developerConnection/>
26-
<tag/>
27-
<url/>
28-
</scm>
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<parent>
7+
<groupId>org.springframework.boot</groupId>
8+
<artifactId>spring-boot-starter-parent</artifactId>
9+
<version>3.4.1</version> <relativePath/>
10+
</parent>
11+
12+
<groupId>com.aiman</groupId>
13+
<artifactId>api</artifactId>
14+
<version>0.0.1-SNAPSHOT</version>
15+
<name>api</name>
16+
<description>AI-Enhanced Nafath Mock Service</description>
17+
2918
<properties>
3019
<java.version>21</java.version>
31-
<maven.compiler.source>21</maven.compiler.source>
32-
<maven.compiler.target>21</maven.compiler.target>
20+
<spring-ai.version>1.0.0-M4</spring-ai.version>
3321
</properties>
34-
<dependencies>
35-
<dependency>
36-
<groupId>org.springframework.boot</groupId>
37-
<artifactId>spring-boot-h2console</artifactId>
38-
</dependency>
39-
<dependency>
40-
<groupId>org.springframework.boot</groupId>
41-
<artifactId>spring-boot-starter-data-jpa</artifactId>
42-
</dependency>
43-
<dependency>
44-
<groupId>org.springframework.boot</groupId>
45-
<artifactId>spring-boot-starter-webmvc</artifactId>
46-
</dependency>
4722

48-
<dependency>
49-
<groupId>com.h2database</groupId>
50-
<artifactId>h2</artifactId>
51-
<scope>runtime</scope>
52-
</dependency>
53-
<dependency>
54-
<groupId>org.springframework.boot</groupId>
55-
<artifactId>spring-boot-starter-data-jpa-test</artifactId>
56-
<scope>test</scope>
57-
</dependency>
58-
<dependency>
59-
<groupId>org.springframework.boot</groupId>
60-
<artifactId>spring-boot-starter-webmvc-test</artifactId>
61-
<scope>test</scope>
62-
</dependency>
63-
<dependency>
64-
<groupId>com.microsoft.sqlserver</groupId>
65-
<artifactId>mssql-jdbc</artifactId>
66-
<scope>runtime</scope>
67-
</dependency>
68-
<dependency>
69-
<groupId>jakarta.validation</groupId>
70-
<artifactId>jakarta.validation-api</artifactId>
71-
<version>3.1.1</version>
72-
<scope>compile</scope>
73-
</dependency>
74-
<dependency>
75-
<groupId>org.projectlombok</groupId>
76-
<artifactId>lombok</artifactId>
77-
<version>1.18.42</version>
78-
<scope>provided</scope>
79-
</dependency>
80-
</dependencies>
23+
<dependencies>
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-starter-web</artifactId>
27+
</dependency>
28+
29+
<dependency>
30+
<groupId>org.springframework.boot</groupId>
31+
<artifactId>spring-boot-starter-data-jpa</artifactId>
32+
</dependency>
33+
34+
<dependency>
35+
<groupId>org.springframework.boot</groupId>
36+
<artifactId>spring-boot-starter-validation</artifactId>
37+
</dependency>
38+
39+
<dependency>
40+
<groupId>com.h2database</groupId>
41+
<artifactId>h2</artifactId>
42+
<scope>runtime</scope>
43+
</dependency>
44+
<dependency>
45+
<groupId>com.microsoft.sqlserver</groupId>
46+
<artifactId>mssql-jdbc</artifactId>
47+
<scope>runtime</scope>
48+
</dependency>
49+
50+
<!-- <dependency>
51+
<groupId>org.springframework.ai</groupId>
52+
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
53+
</dependency> -->
54+
55+
<dependency>
56+
<groupId>org.springframework.boot</groupId>
57+
<artifactId>spring-boot-starter-test</artifactId>
58+
<scope>test</scope>
59+
</dependency>
60+
</dependencies>
61+
62+
<!-- <dependencyManagement>
63+
<dependencies>
64+
<dependency>
65+
<groupId>org.springframework.ai</groupId>
66+
<artifactId>spring-ai-bom</artifactId>
67+
<version>${spring-ai.version}</version>
68+
<type>pom</type>
69+
<scope>import</scope>
70+
</dependency>
71+
</dependencies>
72+
</dependencyManagement> -->
8173

8274
<build>
8375
<plugins>
84-
<plugin>
85-
<groupId>org.springframework.boot</groupId>
86-
<artifactId>spring-boot-maven-plugin</artifactId>
87-
</plugin>
8876
<plugin>
8977
<groupId>org.apache.maven.plugins</groupId>
9078
<artifactId>maven-compiler-plugin</artifactId>
91-
<version>3.14.1</version>
92-
<configuration>
93-
<source>21</source>
94-
<target>21</target>
95-
<annotationProcessorPaths>
96-
<path>
97-
<groupId>org.projectlombok</groupId>
98-
<artifactId>lombok</artifactId>
99-
<version>1.18.42</version>
100-
</path>
101-
</annotationProcessorPaths>
102-
</configuration>
10379
</plugin>
10480
</plugins>
10581
</build>
10682

107-
</project>
83+
<repositories>
84+
<repository>
85+
<id>spring-milestones</id>
86+
<name>Spring Milestones</name>
87+
<url>https://repo.spring.io/milestone</url>
88+
<snapshots>
89+
<enabled>false</enabled>
90+
</snapshots>
91+
</repository>
92+
</repositories>
93+
</project>

backend/src/main/java/com/aiman/api/controller/NafathController.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
import com.aiman.api.dto.NafathResponse;
1616
import com.aiman.api.entity.NafathRequest;
1717
import com.aiman.api.service.NafathService;
18+
import com.aiman.api.service.RiskAssessmentService;
1819

20+
import jakarta.servlet.http.HttpServletRequest;
1921
import jakarta.validation.Valid;
2022

2123
import org.springframework.web.bind.annotation.GetMapping;
@@ -35,11 +37,25 @@
3537
public class NafathController {
3638

3739
@Autowired private NafathService nafathService;
40+
@Autowired private RiskAssessmentService riskService;
3841

39-
// 1. Initiate the request
4042
@PostMapping("/initiate")
41-
public ResponseEntity<NafathRequest> initiateNafathRequest(@Valid @RequestBody InitiateRequest req){
42-
return ResponseEntity.ok(nafathService.initiateNafathRequest(req.nationalId()));
43+
public ResponseEntity<?> initiate(@RequestBody InitiateRequest req, HttpServletRequest request) {
44+
// 1. Context Collection
45+
String ip = request.getRemoteAddr();
46+
String ua = request.getHeader("User-Agent");
47+
48+
// 2. AI Risk Assessment (The "Gatekeeper")
49+
var risk = riskService.analyze(req.nationalId(), ip, ua);
50+
51+
if ("BLOCK".equals(risk.status()) || risk.score() > 0.85) {
52+
return ResponseEntity.status(HttpStatus.FORBIDDEN)
53+
.body(Map.of("error", "Security Block", "reason", risk.reason()));
54+
}
55+
56+
// 3. Only if safe, proceed to business logic
57+
NafathRequest nafath = nafathService.initiateNafathRequest(req.nationalId());
58+
return ResponseEntity.ok(Map.of("nafath", nafath, "aiInsight", risk));
4359
}
4460
// 2. Poll for status
4561
@GetMapping("/status/{id}")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.aiman.api.dto;
2+
3+
public record AssessmentResult(double score, String status, String reason) {}

backend/src/main/java/com/aiman/api/entity/NafathRequest.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,11 @@
22

33
import java.sql.Timestamp;
44
import java.util.UUID;
5-
65
import org.hibernate.annotations.CreationTimestamp;
76
import org.hibernate.annotations.UpdateTimestamp;
8-
9-
import jakarta.persistence.Column;
10-
import jakarta.persistence.Entity;
11-
import jakarta.persistence.Id;
12-
import jakarta.persistence.Table;
13-
import lombok.AllArgsConstructor;
14-
import lombok.Data;
15-
import lombok.NoArgsConstructor;
7+
import jakarta.persistence.*;
168

179
@Entity
18-
@Data
19-
@NoArgsConstructor
20-
@AllArgsConstructor
2110
@Table(name = "nafath_request")
2211
public class NafathRequest {
2312
@Id
@@ -40,4 +29,22 @@ public class NafathRequest {
4029
@UpdateTimestamp
4130
@Column(name = "updated_at")
4231
private Timestamp updatedAt;
43-
}
32+
33+
// Standard Boilerplate (Guarantees the compiler won't fail)
34+
public NafathRequest() {}
35+
36+
public UUID getId() { return id; }
37+
public void setId(UUID id) { this.id = id; }
38+
39+
public String getNationalId() { return nationalId; }
40+
public void setNationalId(String nationalId) { this.nationalId = nationalId; }
41+
42+
public Integer getRandomCode() { return randomCode; }
43+
public void setRandomCode(Integer randomCode) { this.randomCode = randomCode; }
44+
45+
public String getStatus() { return status; }
46+
public void setStatus(String status) { this.status = status; }
47+
48+
public Timestamp getCreatedAt() { return createdAt; }
49+
public Timestamp getUpdatedAt() { return updatedAt; }
50+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.aiman.api.service;
2+
3+
// import org.springframework.ai.chat.client.ChatClient;
4+
import org.springframework.stereotype.Service;
5+
import java.time.LocalDateTime;
6+
import java.util.Map;
7+
@Service
8+
public class RiskAssessmentService {
9+
10+
// private final ChatClient chatClient;
11+
12+
// public RiskAssessmentService(ChatClient.Builder builder) {
13+
// this.chatClient = builder.build();
14+
// }
15+
16+
public AssessmentResult analyze(String nationalId, String ip, String userAgent) {
17+
// String userPromptTemplate = """
18+
// Evaluate the security risk of this Saudi Nafath login attempt:
19+
// - National ID: {id}
20+
// - Origin IP: {ip}
21+
// - Device: {ua}
22+
// - Time: {time}
23+
24+
// Return JSON only: { "score": 0.0-1.0, "status": "SAFE|CAUTION|BLOCK", "reason": "string" }
25+
// """;
26+
27+
// return chatClient.prompt()
28+
// .user(u -> u.text(userPromptTemplate)
29+
// .params(Map.of(
30+
// "id", nationalId,
31+
// "ip", ip,
32+
// "ua", userAgent,
33+
// "time", LocalDateTime.now().toString()
34+
// )))
35+
// .call()
36+
// .entity(AssessmentResult.class);
37+
38+
// Mock Assesment begin
39+
double score = Math.random();
40+
String status = (score > 0.9) ? "BLOCK" : "SAFE";
41+
return new AssessmentResult(score, status, "Mocked AI Assessment for testing");
42+
// Mock Assesment end
43+
44+
}
45+
46+
public record AssessmentResult(double score, String status, String reason) {}
47+
}

backend/src/main/resources/application.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ spring.sql.init.mode=never
1111
spring.jpa.hibernate.ddl-auto=update
1212
spring.jpa.show-sql=true
1313

14+
# Spring AI OpenAI Configuration
15+
# spring.ai.openai.api-key=${OPENAI_API_KEY}
16+
# spring.ai.openai.chat.options.model=gpt-4o
17+
# spring.ai.openai.chat.options.temperature=0.7

0 commit comments

Comments
 (0)