Skip to content

Commit 3d58d2c

Browse files
committed
wip
1 parent 82170fc commit 3d58d2c

File tree

4 files changed

+142
-0
lines changed

4 files changed

+142
-0
lines changed

academy_models/src/course.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use std::time::Duration;
2+
3+
use chrono::{DateTime, Utc};
4+
5+
use crate::{macros::id, nutype_string, url::Url};
6+
7+
id!(CourseId);
8+
id!(CourseAuthorId);
9+
id!(CourseSectionId);
10+
id!(CourseLessonId);
11+
12+
#[derive(Debug, Clone)]
13+
pub struct Course {
14+
pub id: CourseId,
15+
pub title: CourseTitle,
16+
pub description: Option<CourseDescription>,
17+
pub updated_at: DateTime<Utc>,
18+
pub language: Option<CourseLanguage>,
19+
pub image: Option<Url>,
20+
pub price: u32,
21+
}
22+
23+
nutype_string!(CourseTitle(validate(not_empty, len_char_max = 64)));
24+
nutype_string!(CourseDescription(validate(not_empty, len_char_max = 4096)));
25+
26+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27+
pub enum CourseLanguage {
28+
English,
29+
German,
30+
}
31+
32+
#[derive(Debug, Clone)]
33+
pub struct CourseAuthor {
34+
pub id: CourseAuthorId,
35+
pub name: CourseAuthorName,
36+
pub url: Option<Url>,
37+
}
38+
39+
nutype_string!(CourseAuthorName(validate(not_empty, len_char_max = 64)));
40+
41+
#[derive(Debug, Clone)]
42+
pub struct CourseSection {
43+
pub id: CourseSectionId,
44+
pub course_id: CourseId,
45+
pub title: CourseSectionTitle,
46+
pub description: Option<CourseSectionDescription>,
47+
pub sort_key: u32,
48+
}
49+
50+
nutype_string!(CourseSectionTitle(validate(not_empty, len_char_max = 64)));
51+
nutype_string!(CourseSectionDescription(validate(
52+
not_empty,
53+
len_char_max = 4096
54+
)));
55+
56+
#[derive(Debug, Clone)]
57+
pub struct CourseLesson {
58+
pub id: CourseLessonId,
59+
pub section_id: CourseSectionId,
60+
pub title: CourseLessonTitle,
61+
pub description: Option<CourseLessonDescription>,
62+
pub duration: Duration,
63+
pub sort_key: u32,
64+
pub variant: CourseLessonVariant,
65+
}
66+
67+
nutype_string!(CourseLessonTitle(validate(not_empty, len_char_max = 64)));
68+
nutype_string!(CourseLessonDescription(validate(
69+
not_empty,
70+
len_char_max = 4096
71+
)));
72+
73+
#[derive(Debug, Clone)]
74+
pub enum CourseLessonVariant {
75+
Youtube(CourseYoutubeLesson),
76+
Mp4,
77+
}
78+
79+
#[derive(Debug, Clone)]
80+
pub struct CourseYoutubeLesson {
81+
pub video_id: YoutubeVideoId,
82+
}
83+
84+
nutype_string!(YoutubeVideoId(validate(not_empty, len_char_max = 16)));

academy_models/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
88
pub mod auth;
99
pub mod coin;
1010
pub mod contact;
11+
pub mod course;
1112
pub mod email_address;
1213
pub mod heart;
1314
mod macros;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
drop table course_lessons, course_youtube_lessons, course_mp4_lessons;
2+
drop table course_sections;
3+
drop table courses, course_authors, course_author_courses;
4+
drop type course_language;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
create type course_language as enum ('de', 'en');
2+
3+
create table courses (
4+
id uuid primary key,
5+
title text not null,
6+
description text,
7+
updated_at timestamp with time zone not null,
8+
language course_language,
9+
image text,
10+
price integer not null check (price >= 0)
11+
);
12+
create unique index courses_title_idx on courses (lower(title));
13+
14+
create table course_authors (
15+
id uuid primary key,
16+
name text not null,
17+
url text
18+
);
19+
create unique index course_authors_name_idx on course_authors (lower(name));
20+
21+
create table course_author_courses (
22+
course_id uuid not null references courses(id) on delete cascade,
23+
course_author_id uuid not null references course_authors(id) on delete cascade,
24+
primary key (course_id, course_author_id)
25+
);
26+
27+
create table course_sections (
28+
id uuid primary key,
29+
course_id uuid not null references courses(id) on delete cascade,
30+
title text not null,
31+
description text,
32+
sort_key integer unique not null check (sort_key >= 0)
33+
);
34+
create unique index course_sections_title_idx on course_sections (lower(title));
35+
36+
create table course_lessons (
37+
id uuid primary key,
38+
section_id uuid not null references course_sections(id) on delete cascade,
39+
title text not null,
40+
description text,
41+
duration interval not null,
42+
sort_key integer unique not null check (sort_key >= 0)
43+
);
44+
create unique index course_lessons_title_idx on course_lessons (lower(title));
45+
46+
create table course_youtube_lessons (
47+
id uuid primary key references course_lessons (id) on delete cascade,
48+
video_id text not null
49+
);
50+
51+
create table course_mp4_lessons (
52+
id uuid primary key references course_lessons (id) on delete cascade
53+
);

0 commit comments

Comments
 (0)