Skip to content

Commit b50057c

Browse files
authored
Backend implementation (#26)
* Backend implementation * formating * changes * remove useless examples
1 parent caf3354 commit b50057c

24 files changed

Lines changed: 1246 additions & 248 deletions

File tree

ainigma-backend/Cargo.toml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,24 @@ edition = "2024"
77
ainigma = { path = "../ainigma" }
88

99
# and any other dependencies you need:
10-
hyper = "1.6.0"
1110
axum = "0.8.4"
12-
tokio = { version = "1", features = ["full"] }
13-
uuid = { version = "1.17.0", features = ["v7", "serde"] }
11+
tokio = { version = "1", features = ["macros", "rt-multi-thread", "fs"] }
12+
uuid = { version = "1.17.0", features = ["v4", "v7", "serde"] }
1413
serde = { version = "1.0.211", features = ["derive"] }
1514
serde_json = "1"
1615
tower = "0.5.2"
17-
sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio-rustls"] }
16+
sqlx = { version = "0.8.6", features = ["postgres", "uuid", "runtime-tokio-rustls"] }
17+
thiserror = "2"
18+
lazy_static = "1.5.0"
19+
regex = "1.11.1"
20+
tracing = "0.1.41"
21+
tracing-subscriber = { version = "0.3.19", features = ["env-filter", "fmt"]}
22+
chrono = "0.4.41"
23+
anyhow = "1.0.98"
24+
mime_guess = "2.0.5"
25+
tokio-util = "0.7.16"
1826

1927
[dev-dependencies]
2028
reqwest = { version = "0.12.19", features = ["json"] }
21-
tokio = { version = "1", features = ["full"] }
29+
tokio = { version = "1", features = ["macros", "rt-multi-thread", "fs"] }
30+
httpc-test = "0.1.1"

ainigma-backend/README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@ Other things they need to take for backend to work
1414
## Software
1515

1616
Sqlx - Database
17-
Smithy - Generating code for backend
1817

1918
## Serverside structure
2019

2120
```
2221
/srv/ainigma/data/
2322
/courses/
24-
Index file (index for quick course lookup and listing)
2523
/<course_id>/ (or name)
2624
config.toml (defined name for pathing)
2725
/<category>/ (name)
@@ -39,10 +37,12 @@ Smithy - Generating code for backend
3937
courses (1) ── (many) categories (1) ── (many) tasks
4038
users (1) ── (many) user_task_progress (many) ── (1) tasks
4139

42-
## workflow
40+
## Workflow
4341

42+
```
4443
[Client]
4544
|
45+
|-- Request for structures course, category (static response figured at server start) -->
4646
|-- Request (uuid, task_id, course_id) -->
4747
|
4848
[Server]
@@ -53,8 +53,9 @@ users (1) ── (many) user_task_progress (many) ── (1) tasks
5353
| |-- Generate flags
5454
| |-- Build task using course config
5555
| |-- Save built task
56+
| |-- Add Correct flag / answer to database
5657
|-- Return task data -->
57-
|-- Add Correct flag / answer to database
58+
|
5859
[Client receives task and starts solving]
5960
[Client]
6061
|
@@ -67,15 +68,16 @@ users (1) ── (many) user_task_progress (many) ── (1) tasks
6768
|-- No: send feedback
6869
|
6970
[Client] receives feedback
70-
71+
```
7172
## Questions
7273

73-
- Category no identifier and task has String
74+
7475
- Course secret storage?
75-
- Changes only when server down? (configuration checked at start and expected to be correct during runtime)
76-
or updates? (updates to config during server runtime, checked in runtime with functionality locked during update process )
76+
- Database and authentication?
77+
7778

7879
## Feedback
7980

8081
- No support for v7 uuid in postgre only v4
81-
- New build function that takes a uuid, and just takes module and task_id
82+
- config catogories.tasks.build path made obsolete in backend - backend always knows what task to process
83+

ainigma-backend/backend.rs

Lines changed: 0 additions & 107 deletions
This file was deleted.

ainigma-backend/migrations/0001_ainigma.sql

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,61 @@ CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
22

33
CREATE TABLE users (
44
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
5-
email VARCHAR UNIQUE NOT NULL,
65
created_at TIMESTAMPTZ DEFAULT now()
76
);
87

98
CREATE TABLE courses (
109
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
11-
title VARCHAR NOT NULL,
10+
name VARCHAR NOT NULL,
1211
description TEXT,
1312
created_at TIMESTAMPTZ DEFAULT now()
1413
);
1514

1615
CREATE TABLE categories (
17-
id SERIAL PRIMARY KEY,
1816
course_id UUID NOT NULL REFERENCES courses(id) ON DELETE CASCADE,
1917
name VARCHAR NOT NULL,
20-
number INTEGER
18+
number INTEGER NOT NULL,
19+
PRIMARY KEY (course_id, name)
2120
);
2221

2322
CREATE TABLE tasks (
24-
id SERIAL PRIMARY KEY,
25-
category_id INTEGER NOT NULL REFERENCES categories(id) ON DELETE CASCADE,
26-
title VARCHAR NOT NULL,
23+
id VARCHAR NOT NULL,
24+
course_id UUID NOT NULL,
25+
category_name VARCHAR NOT NULL,
26+
name VARCHAR NOT NULL,
2727
description TEXT,
2828
points INTEGER DEFAULT 1,
29-
created_at TIMESTAMPTZ DEFAULT now()
29+
created_at TIMESTAMPTZ DEFAULT now(),
30+
PRIMARY KEY (course_id, category_name, id),
31+
FOREIGN KEY (course_id, category_name) REFERENCES categories(course_id, name) ON DELETE CASCADE
32+
);
33+
34+
CREATE TABLE task_stages (
35+
id VARCHAR NOT NULL, -- stage ID (e.g., "task001A")
36+
course_id UUID NOT NULL,
37+
category_name VARCHAR NOT NULL,
38+
task_id VARCHAR NOT NULL, -- parent task ID
39+
name VARCHAR NOT NULL,
40+
description TEXT,
41+
weight INTEGER DEFAULT 1,
42+
flag JSONB, -- metadata like { kind: "user_derived" }
43+
created_at TIMESTAMPTZ DEFAULT now(),
44+
PRIMARY KEY (course_id, category_name, task_id, id),
45+
FOREIGN KEY (course_id, category_name, task_id) REFERENCES tasks(course_id, category_name, id) ON DELETE CASCADE
3046
);
3147

3248

33-
CREATE TABLE user_task_progress (
34-
id SERIAL PRIMARY KEY,
49+
CREATE TABLE user_stage_progress (
3550
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
36-
task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
51+
course_id UUID NOT NULL,
52+
category_name VARCHAR NOT NULL,
53+
task_id VARCHAR NOT NULL,
54+
stage_id VARCHAR NOT NULL, -- stage ID
3755
completed_at TIMESTAMPTZ,
56+
completed BOOLEAN NOT NULL DEFAULT FALSE,
3857
score INTEGER,
39-
UNIQUE (user_id, task_id)
58+
PRIMARY KEY (user_id, course_id, category_name, task_id, stage_id),
59+
FOREIGN KEY (course_id, category_name, task_id, stage_id)
60+
REFERENCES task_stages(course_id, category_name, task_id, id)
61+
ON DELETE CASCADE
4062
);

ainigma-backend/model.smithy

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,18 @@ structure UserLoginOutput {
5353
}
5454

5555
operation ListCourses{
56+
output: ListCoursesOutput,
57+
}
58+
structure ListCoursesOutput {
59+
courses: Vec<Course>
60+
}
5661

62+
structure Course{
63+
name: String
64+
id: Uuid
5765
}
5866

67+
5968
operation GetCourseConfig{
6069
input: CourseConfigInput,
6170
output: CourseConfigOutput

0 commit comments

Comments
 (0)