3v324v23 commited on
Commit
11c79a7
·
1 Parent(s): 51df0c1

feat: add API endpoints and documentation

Browse files
Files changed (2) hide show
  1. README.md +63 -0
  2. app.js +90 -0
README.md CHANGED
@@ -30,3 +30,66 @@ Simply click the **Duplicate this Space** button in the settings menu of this Sp
30
  2. Select **Docker** as the SDK.
31
  3. Upload these files to your Space.
32
  4. The application will build and run automatically (Port 7860).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  2. Select **Docker** as the SDK.
31
  3. Upload these files to your Space.
32
  4. The application will build and run automatically (Port 7860).
33
+
34
+ ## 📡 API Documentation
35
+
36
+ You can interact with the application programmatically using the following JSON endpoints.
37
+
38
+ ### 1. Analyze Student (`POST /api/analyze`)
39
+
40
+ Submit student marks to get grade and personality trait.
41
+
42
+ **Request:**
43
+
44
+ ```json
45
+ POST /api/analyze
46
+ Content-Type: application/json
47
+
48
+ {
49
+ "name": "John Doe",
50
+ "sub1": 85,
51
+ "sub2": 90,
52
+ "sub3": 88
53
+ }
54
+ ```
55
+
56
+ **Response:**
57
+
58
+ ```json
59
+ {
60
+ "success": true,
61
+ "data": {
62
+ "name": "John Doe",
63
+ "average": 88,
64
+ "grade": "A",
65
+ "trait": "Extroverted"
66
+ }
67
+ }
68
+ ```
69
+
70
+ ### 2. Get Recent Students (`GET /api/students`)
71
+
72
+ Returns a list of the 10 most recently analyzed students.
73
+
74
+ **Response:**
75
+
76
+ ```json
77
+ [
78
+ {
79
+ "id": 1,
80
+ "name": "Alice",
81
+ "subject1": 80,
82
+ "subject2": 85,
83
+ "subject3": 90
84
+ },
85
+ ...
86
+ ]
87
+ ```
88
+
89
+ ### 3. Get Rules (`GET /api/rules`)
90
+
91
+ Returns the grading rules and score ranges.
92
+
93
+ ### 4. Get Traits (`GET /api/traits`)
94
+
95
+ Returns the mapping of grades to personality traits.
app.js CHANGED
@@ -7,6 +7,7 @@ const app = express();
7
  const PORT = process.env.PORT || 7860;
8
  app.set("view engine", "ejs");
9
  app.use(bodyParser.urlencoded({ extended: true }));
 
10
  app.use(express.static(path.join(__dirname, 'public')));
11
 
12
  // Connect to SQLite Database (File-based)
@@ -37,6 +38,95 @@ app.get("/", (req, res) => {
37
  });
38
  });
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  app.post("/result", (req, res) => {
41
  const { name, sub1, sub2, sub3 } = req.body;
42
 
 
7
  const PORT = process.env.PORT || 7860;
8
  app.set("view engine", "ejs");
9
  app.use(bodyParser.urlencoded({ extended: true }));
10
+ app.use(express.json()); // Support JSON bodies for API
11
  app.use(express.static(path.join(__dirname, 'public')));
12
 
13
  // Connect to SQLite Database (File-based)
 
38
  });
39
  });
40
 
41
+ // --- API Endpoints ---
42
+
43
+ // Get recent students
44
+ app.get("/api/students", (req, res) => {
45
+ db.all("SELECT * FROM sampleStudent ORDER BY id DESC LIMIT 10", [], (err, rows) => {
46
+ if (err) {
47
+ res.status(500).json({ error: err.message });
48
+ return;
49
+ }
50
+ res.json(rows);
51
+ });
52
+ });
53
+
54
+ // Get grading rules
55
+ app.get("/api/rules", (req, res) => {
56
+ db.all("SELECT * FROM grade_rules ORDER BY min_avg DESC", [], (err, rows) => {
57
+ if (err) {
58
+ res.status(500).json({ error: err.message });
59
+ return;
60
+ }
61
+ res.json(rows);
62
+ });
63
+ });
64
+
65
+ // Get personality traits
66
+ app.get("/api/traits", (req, res) => {
67
+ db.all("SELECT * FROM personality_traits", [], (err, rows) => {
68
+ if (err) {
69
+ res.status(500).json({ error: err.message });
70
+ return;
71
+ }
72
+ res.json(rows);
73
+ });
74
+ });
75
+
76
+ // Analyze student and save result
77
+ app.post("/api/analyze", (req, res) => {
78
+ const { name, sub1, sub2, sub3 } = req.body;
79
+
80
+ if (!name || sub1 === undefined || sub2 === undefined || sub3 === undefined) {
81
+ return res.status(400).json({ error: "Missing required fields: name, sub1, sub2, sub3" });
82
+ }
83
+
84
+ const s1 = parseInt(sub1);
85
+ const s2 = parseInt(sub2);
86
+ const s3 = parseInt(sub3);
87
+ const avg = Math.round((s1 + s2 + s3) / 3);
88
+
89
+ // 1. Insert Student
90
+ const insertQuery = `INSERT INTO sampleStudent (name, subject1, subject2, subject3) VALUES (?, ?, ?, ?)`;
91
+
92
+ db.run(insertQuery, [name, s1, s2, s3], function(err) {
93
+ if (err) {
94
+ return res.status(500).json({ error: "Error saving student data: " + err.message });
95
+ }
96
+
97
+ // 2. Find Grade
98
+ const gradeQuery = `SELECT grade FROM grade_rules WHERE ? >= min_avg AND ? <= max_avg LIMIT 1`;
99
+
100
+ db.get(gradeQuery, [avg, avg], (err, gradeRow) => {
101
+ if (err || !gradeRow) {
102
+ return res.status(404).json({ error: "Grade not found for average: " + avg });
103
+ }
104
+
105
+ const grade = gradeRow.grade;
106
+
107
+ // 3. Find Trait
108
+ const traitQuery = `SELECT trait FROM personality_traits WHERE grade = ?`;
109
+ db.get(traitQuery, [grade], (err, traitRow) => {
110
+ if (err || !traitRow) {
111
+ return res.status(404).json({ error: "Trait not found for grade: " + grade });
112
+ }
113
+
114
+ res.json({
115
+ success: true,
116
+ data: {
117
+ name,
118
+ average: avg,
119
+ grade,
120
+ trait: traitRow.trait
121
+ }
122
+ });
123
+ });
124
+ });
125
+ });
126
+ });
127
+
128
+ // --- End API Endpoints ---
129
+
130
  app.post("/result", (req, res) => {
131
  const { name, sub1, sub2, sub3 } = req.body;
132